Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
ollama
Commits
89d99001
"vscode:/vscode.git/clone" did not exist on "e92de75844e55c272f047c85264811085cf6a328"
Unverified
Commit
89d99001
authored
Jun 04, 2024
by
Michael Yang
Committed by
GitHub
Jun 04, 2024
Browse files
Merge pull request #4570 from ollama/mxyng/slices
lint some of the things
parents
4a048715
6297f856
Changes
54
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
64 additions
and
78 deletions
+64
-78
convert/torch.go
convert/torch.go
+1
-2
envconfig/config.go
envconfig/config.go
+4
-3
format/format_test.go
format/format_test.go
+0
-1
gpu/amd_windows.go
gpu/amd_windows.go
+1
-1
gpu/assets.go
gpu/assets.go
+1
-1
gpu/cuda_common.go
gpu/cuda_common.go
+0
-1
gpu/gpu.go
gpu/gpu.go
+3
-3
gpu/gpu_test.go
gpu/gpu_test.go
+3
-2
llm/gguf.go
llm/gguf.go
+4
-4
llm/memory.go
llm/memory.go
+2
-2
llm/payload.go
llm/payload.go
+1
-1
llm/server.go
llm/server.go
+9
-9
openai/openai.go
openai/openai.go
+0
-1
parser/parser_test.go
parser/parser_test.go
+15
-16
progress/progress.go
progress/progress.go
+2
-2
readline/buffer.go
readline/buffer.go
+7
-17
readline/history.go
readline/history.go
+2
-2
readline/readline.go
readline/readline.go
+7
-8
readline/readline_unix.go
readline/readline_unix.go
+1
-1
readline/readline_windows.go
readline/readline_windows.go
+1
-1
No files found.
convert/torch.go
View file @
89d99001
...
@@ -88,7 +88,7 @@ func (tf *TorchFormat) GetTensors(dirpath string, params *Params) ([]llm.Tensor,
...
@@ -88,7 +88,7 @@ func (tf *TorchFormat) GetTensors(dirpath string, params *Params) ([]llm.Tensor,
Name
:
ggufName
,
Name
:
ggufName
,
Kind
:
kind
,
Kind
:
kind
,
Offset
:
offset
,
// calculate the offset
Offset
:
offset
,
// calculate the offset
Shape
:
shape
[
:
]
,
Shape
:
shape
,
}
}
tensor
.
WriterTo
=
torchWriterTo
{
tensor
.
WriterTo
=
torchWriterTo
{
...
@@ -104,7 +104,6 @@ func (tf *TorchFormat) GetTensors(dirpath string, params *Params) ([]llm.Tensor,
...
@@ -104,7 +104,6 @@ func (tf *TorchFormat) GetTensors(dirpath string, params *Params) ([]llm.Tensor,
}
}
return
tensors
,
nil
return
tensors
,
nil
}
}
func
getAltParams
(
dirpath
string
)
(
*
Params
,
error
)
{
func
getAltParams
(
dirpath
string
)
(
*
Params
,
error
)
{
...
...
envconfig/config.go
View file @
89d99001
...
@@ -3,6 +3,7 @@ package envconfig
...
@@ -3,6 +3,7 @@ package envconfig
import
(
import
(
"fmt"
"fmt"
"log/slog"
"log/slog"
"net"
"os"
"os"
"path/filepath"
"path/filepath"
"runtime"
"runtime"
...
@@ -126,7 +127,7 @@ func LoadConfig() {
...
@@ -126,7 +127,7 @@ func LoadConfig() {
var
paths
[]
string
var
paths
[]
string
for
_
,
root
:=
range
[]
string
{
filepath
.
Dir
(
appExe
),
cwd
}
{
for
_
,
root
:=
range
[]
string
{
filepath
.
Dir
(
appExe
),
cwd
}
{
paths
=
append
(
paths
,
paths
=
append
(
paths
,
filepath
.
Join
(
root
)
,
root
,
filepath
.
Join
(
root
,
"windows-"
+
runtime
.
GOARCH
),
filepath
.
Join
(
root
,
"windows-"
+
runtime
.
GOARCH
),
filepath
.
Join
(
root
,
"dist"
,
"windows-"
+
runtime
.
GOARCH
),
filepath
.
Join
(
root
,
"dist"
,
"windows-"
+
runtime
.
GOARCH
),
)
)
...
@@ -184,8 +185,8 @@ func LoadConfig() {
...
@@ -184,8 +185,8 @@ func LoadConfig() {
AllowOrigins
=
append
(
AllowOrigins
,
AllowOrigins
=
append
(
AllowOrigins
,
fmt
.
Sprintf
(
"http://%s"
,
allowOrigin
),
fmt
.
Sprintf
(
"http://%s"
,
allowOrigin
),
fmt
.
Sprintf
(
"https://%s"
,
allowOrigin
),
fmt
.
Sprintf
(
"https://%s"
,
allowOrigin
),
fmt
.
Sprintf
(
"http://%s
:*
"
,
allowOrigin
),
fmt
.
Sprintf
(
"http://%s"
,
net
.
JoinHostPort
(
allowOrigin
,
"*"
)
),
fmt
.
Sprintf
(
"https://%s
:*
"
,
allowOrigin
),
fmt
.
Sprintf
(
"https://%s"
,
net
.
JoinHostPort
(
allowOrigin
,
"*"
)
),
)
)
}
}
...
...
format/format_test.go
View file @
89d99001
...
@@ -5,7 +5,6 @@ import (
...
@@ -5,7 +5,6 @@ import (
)
)
func
TestHumanNumber
(
t
*
testing
.
T
)
{
func
TestHumanNumber
(
t
*
testing
.
T
)
{
type
testCase
struct
{
type
testCase
struct
{
input
uint64
input
uint64
expected
string
expected
string
...
...
gpu/amd_windows.go
View file @
89d99001
...
@@ -65,7 +65,7 @@ func AMDGetGPUInfo() []GpuInfo {
...
@@ -65,7 +65,7 @@ func AMDGetGPUInfo() []GpuInfo {
slog
.
Debug
(
"detected hip devices"
,
"count"
,
count
)
slog
.
Debug
(
"detected hip devices"
,
"count"
,
count
)
// TODO how to determine the underlying device ID when visible devices is causing this to subset?
// TODO how to determine the underlying device ID when visible devices is causing this to subset?
for
i
:=
0
;
i
<
count
;
i
++
{
for
i
:=
range
count
{
err
=
hl
.
HipSetDevice
(
i
)
err
=
hl
.
HipSetDevice
(
i
)
if
err
!=
nil
{
if
err
!=
nil
{
slog
.
Warn
(
"set device"
,
"id"
,
i
,
"error"
,
err
)
slog
.
Warn
(
"set device"
,
"id"
,
i
,
"error"
,
err
)
...
...
gpu/assets.go
View file @
89d99001
...
@@ -80,7 +80,7 @@ func cleanupTmpDirs() {
...
@@ -80,7 +80,7 @@ func cleanupTmpDirs() {
if
err
==
nil
{
if
err
==
nil
{
pid
,
err
:=
strconv
.
Atoi
(
string
(
raw
))
pid
,
err
:=
strconv
.
Atoi
(
string
(
raw
))
if
err
==
nil
{
if
err
==
nil
{
if
proc
,
err
:=
os
.
FindProcess
(
int
(
pid
)
)
;
err
==
nil
&&
!
errors
.
Is
(
proc
.
Signal
(
syscall
.
Signal
(
0
)),
os
.
ErrProcessDone
)
{
if
proc
,
err
:=
os
.
FindProcess
(
pid
);
err
==
nil
&&
!
errors
.
Is
(
proc
.
Signal
(
syscall
.
Signal
(
0
)),
os
.
ErrProcessDone
)
{
// Another running ollama, ignore this tmpdir
// Another running ollama, ignore this tmpdir
continue
continue
}
}
...
...
gpu/cuda_common.go
View file @
89d99001
...
@@ -18,5 +18,4 @@ func cudaGetVisibleDevicesEnv(gpuInfo []GpuInfo) (string, string) {
...
@@ -18,5 +18,4 @@ func cudaGetVisibleDevicesEnv(gpuInfo []GpuInfo) (string, string) {
ids
=
append
(
ids
,
info
.
ID
)
ids
=
append
(
ids
,
info
.
ID
)
}
}
return
"CUDA_VISIBLE_DEVICES"
,
strings
.
Join
(
ids
,
","
)
return
"CUDA_VISIBLE_DEVICES"
,
strings
.
Join
(
ids
,
","
)
}
}
gpu/gpu.go
View file @
89d99001
...
@@ -187,7 +187,7 @@ func GetGPUInfo() GpuInfoList {
...
@@ -187,7 +187,7 @@ func GetGPUInfo() GpuInfoList {
resp
:=
[]
GpuInfo
{}
resp
:=
[]
GpuInfo
{}
// NVIDIA first
// NVIDIA first
for
i
:=
0
;
i
<
gpuHandles
.
deviceCount
;
i
++
{
for
i
:=
range
gpuHandles
.
deviceCount
{
// TODO once we support CPU compilation variants of GPU libraries refine this...
// TODO once we support CPU compilation variants of GPU libraries refine this...
if
cpuVariant
==
""
&&
runtime
.
GOARCH
==
"amd64"
{
if
cpuVariant
==
""
&&
runtime
.
GOARCH
==
"amd64"
{
continue
continue
...
@@ -221,8 +221,8 @@ func GetGPUInfo() GpuInfoList {
...
@@ -221,8 +221,8 @@ func GetGPUInfo() GpuInfoList {
gpuInfo
.
MinimumMemory
=
cudaMinimumMemory
gpuInfo
.
MinimumMemory
=
cudaMinimumMemory
gpuInfo
.
DependencyPath
=
depPath
gpuInfo
.
DependencyPath
=
depPath
gpuInfo
.
Name
=
C
.
GoString
(
&
memInfo
.
gpu_name
[
0
])
gpuInfo
.
Name
=
C
.
GoString
(
&
memInfo
.
gpu_name
[
0
])
gpuInfo
.
DriverMajor
=
int
(
driverMajor
)
gpuInfo
.
DriverMajor
=
driverMajor
gpuInfo
.
DriverMinor
=
int
(
driverMinor
)
gpuInfo
.
DriverMinor
=
driverMinor
// TODO potentially sort on our own algorithm instead of what the underlying GPU library does...
// TODO potentially sort on our own algorithm instead of what the underlying GPU library does...
resp
=
append
(
resp
,
gpuInfo
)
resp
=
append
(
resp
,
gpuInfo
)
...
...
gpu/gpu_test.go
View file @
89d99001
...
@@ -5,11 +5,12 @@ import (
...
@@ -5,11 +5,12 @@ import (
"testing"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
)
func
TestBasicGetGPUInfo
(
t
*
testing
.
T
)
{
func
TestBasicGetGPUInfo
(
t
*
testing
.
T
)
{
info
:=
GetGPUInfo
()
info
:=
GetGPUInfo
()
assert
.
Greater
(
t
,
len
(
info
)
,
0
)
assert
.
NotEmpty
(
t
,
len
(
info
))
assert
.
Contains
(
t
,
"cuda rocm cpu metal"
,
info
[
0
]
.
Library
)
assert
.
Contains
(
t
,
"cuda rocm cpu metal"
,
info
[
0
]
.
Library
)
if
info
[
0
]
.
Library
!=
"cpu"
{
if
info
[
0
]
.
Library
!=
"cpu"
{
assert
.
Greater
(
t
,
info
[
0
]
.
TotalMemory
,
uint64
(
0
))
assert
.
Greater
(
t
,
info
[
0
]
.
TotalMemory
,
uint64
(
0
))
...
@@ -19,7 +20,7 @@ func TestBasicGetGPUInfo(t *testing.T) {
...
@@ -19,7 +20,7 @@ func TestBasicGetGPUInfo(t *testing.T) {
func
TestCPUMemInfo
(
t
*
testing
.
T
)
{
func
TestCPUMemInfo
(
t
*
testing
.
T
)
{
info
,
err
:=
GetCPUMem
()
info
,
err
:=
GetCPUMem
()
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
switch
runtime
.
GOOS
{
switch
runtime
.
GOOS
{
case
"darwin"
:
case
"darwin"
:
t
.
Skip
(
"CPU memory not populated on darwin"
)
t
.
Skip
(
"CPU memory not populated on darwin"
)
...
...
llm/gguf.go
View file @
89d99001
...
@@ -592,8 +592,8 @@ func (llm *gguf) Encode(ws io.WriteSeeker, kv KV, tensors []Tensor) error {
...
@@ -592,8 +592,8 @@ func (llm *gguf) Encode(ws io.WriteSeeker, kv KV, tensors []Tensor) error {
return
err
return
err
}
}
dims
:=
0
var
dims
int
for
cnt
:=
0
;
cnt
<
len
(
tensor
.
Shape
)
;
cnt
++
{
for
cnt
:=
range
len
(
tensor
.
Shape
)
{
if
tensor
.
Shape
[
cnt
]
>
0
{
if
tensor
.
Shape
[
cnt
]
>
0
{
dims
++
dims
++
}
}
...
@@ -603,8 +603,8 @@ func (llm *gguf) Encode(ws io.WriteSeeker, kv KV, tensors []Tensor) error {
...
@@ -603,8 +603,8 @@ func (llm *gguf) Encode(ws io.WriteSeeker, kv KV, tensors []Tensor) error {
return
err
return
err
}
}
for
i
:=
0
;
i
<
dims
;
i
++
{
for
i
:=
range
dims
{
if
err
:=
binary
.
Write
(
ws
,
llm
.
ByteOrder
,
uint64
(
tensor
.
Shape
[
dims
-
1
-
i
])
)
;
err
!=
nil
{
if
err
:=
binary
.
Write
(
ws
,
llm
.
ByteOrder
,
tensor
.
Shape
[
dims
-
1
-
i
]);
err
!=
nil
{
return
err
return
err
}
}
}
}
...
...
llm/memory.go
View file @
89d99001
...
@@ -5,9 +5,9 @@ import (
...
@@ -5,9 +5,9 @@ import (
"log/slog"
"log/slog"
"github.com/ollama/ollama/api"
"github.com/ollama/ollama/api"
"github.com/ollama/ollama/envconfig"
"github.com/ollama/ollama/format"
"github.com/ollama/ollama/format"
"github.com/ollama/ollama/gpu"
"github.com/ollama/ollama/gpu"
"github.com/ollama/ollama/envconfig"
)
)
// This algorithm looks for a complete fit to determine if we need to unload other models
// This algorithm looks for a complete fit to determine if we need to unload other models
...
@@ -103,7 +103,7 @@ func EstimateGPULayers(gpus []gpu.GpuInfo, ggml *GGML, projectors []string, opts
...
@@ -103,7 +103,7 @@ func EstimateGPULayers(gpus []gpu.GpuInfo, ggml *GGML, projectors []string, opts
}
}
var
layerCount
int
var
layerCount
int
for
i
:=
0
;
i
<
int
(
ggml
.
KV
()
.
BlockCount
())
;
i
++
{
for
i
:=
range
int
(
ggml
.
KV
()
.
BlockCount
())
{
if
blk
,
ok
:=
layers
[
fmt
.
Sprintf
(
"blk.%d"
,
i
)];
ok
{
if
blk
,
ok
:=
layers
[
fmt
.
Sprintf
(
"blk.%d"
,
i
)];
ok
{
memoryLayer
:=
blk
.
size
()
memoryLayer
:=
blk
.
size
()
...
...
llm/payload.go
View file @
89d99001
...
@@ -10,9 +10,9 @@ import (
...
@@ -10,9 +10,9 @@ import (
"os"
"os"
"path/filepath"
"path/filepath"
"runtime"
"runtime"
"slices"
"strings"
"strings"
"golang.org/x/exp/slices"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/errgroup"
"github.com/ollama/ollama/gpu"
"github.com/ollama/ollama/gpu"
...
...
llm/server.go
View file @
89d99001
...
@@ -85,7 +85,6 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
...
@@ -85,7 +85,6 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
var
systemMemory
uint64
var
systemMemory
uint64
gpuCount
:=
len
(
gpus
)
gpuCount
:=
len
(
gpus
)
if
(
len
(
gpus
)
==
1
&&
gpus
[
0
]
.
Library
==
"cpu"
)
||
opts
.
NumGPU
==
0
{
if
(
len
(
gpus
)
==
1
&&
gpus
[
0
]
.
Library
==
"cpu"
)
||
opts
.
NumGPU
==
0
{
// TODO evaluate system memory to see if we should block the load, or force an unload of another CPU runner
// TODO evaluate system memory to see if we should block the load, or force an unload of another CPU runner
cpuRunner
=
serverForCpu
()
cpuRunner
=
serverForCpu
()
...
@@ -104,21 +103,22 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
...
@@ -104,21 +103,22 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
var
layers
int
var
layers
int
layers
,
estimatedVRAM
,
estimatedTotal
=
EstimateGPULayers
(
gpus
,
ggml
,
projectors
,
opts
)
layers
,
estimatedVRAM
,
estimatedTotal
=
EstimateGPULayers
(
gpus
,
ggml
,
projectors
,
opts
)
if
gpus
[
0
]
.
Library
==
"metal"
&&
estimatedVRAM
>
systemMemory
{
switch
{
case
gpus
[
0
]
.
Library
==
"metal"
&&
estimatedVRAM
>
systemMemory
:
// disable partial offloading when model is greater than total system memory as this
// disable partial offloading when model is greater than total system memory as this
// can lead to locking up the system
// can lead to locking up the system
opts
.
NumGPU
=
0
opts
.
NumGPU
=
0
}
else
if
gpus
[
0
]
.
Library
!=
"metal"
&&
layers
==
0
{
case
gpus
[
0
]
.
Library
!=
"metal"
&&
layers
==
0
:
// Don't bother loading into the GPU if no layers can fit
// Don't bother loading into the GPU if no layers can fit
cpuRunner
=
serverForCpu
()
cpuRunner
=
serverForCpu
()
gpuCount
=
0
gpuCount
=
0
}
else
if
opts
.
NumGPU
<
0
&&
layers
>
0
&&
gpus
[
0
]
.
Library
!=
"cpu"
{
case
opts
.
NumGPU
<
0
&&
layers
>
0
&&
gpus
[
0
]
.
Library
!=
"cpu"
:
opts
.
NumGPU
=
layers
opts
.
NumGPU
=
layers
}
}
}
}
// Loop through potential servers
// Loop through potential servers
finalErr
:=
fmt
.
Errorf
(
"no suitable llama servers found"
)
finalErr
:=
errors
.
New
(
"no suitable llama servers found"
)
if
len
(
adapters
)
>
1
{
if
len
(
adapters
)
>
1
{
return
nil
,
errors
.
New
(
"ollama supports only one lora adapter, but multiple were provided"
)
return
nil
,
errors
.
New
(
"ollama supports only one lora adapter, but multiple were provided"
)
...
@@ -232,7 +232,7 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
...
@@ -232,7 +232,7 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
params
=
append
(
params
,
"--parallel"
,
fmt
.
Sprintf
(
"%d"
,
numParallel
))
params
=
append
(
params
,
"--parallel"
,
fmt
.
Sprintf
(
"%d"
,
numParallel
))
for
i
:=
0
;
i
<
len
(
servers
)
;
i
++
{
for
i
:=
range
len
(
servers
)
{
dir
:=
availableServers
[
servers
[
i
]]
dir
:=
availableServers
[
servers
[
i
]]
if
dir
==
""
{
if
dir
==
""
{
// Shouldn't happen
// Shouldn't happen
...
@@ -284,7 +284,7 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
...
@@ -284,7 +284,7 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
server
:=
filepath
.
Join
(
dir
,
"ollama_llama_server"
)
server
:=
filepath
.
Join
(
dir
,
"ollama_llama_server"
)
if
runtime
.
GOOS
==
"windows"
{
if
runtime
.
GOOS
==
"windows"
{
server
=
server
+
".exe"
server
+
=
".exe"
}
}
// Detect tmp cleaners wiping out the file
// Detect tmp cleaners wiping out the file
...
@@ -315,7 +315,7 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
...
@@ -315,7 +315,7 @@ func NewLlamaServer(gpus gpu.GpuInfoList, model string, ggml *GGML, adapters, pr
s
.
cmd
.
Stdout
=
os
.
Stdout
s
.
cmd
.
Stdout
=
os
.
Stdout
s
.
cmd
.
Stderr
=
s
.
status
s
.
cmd
.
Stderr
=
s
.
status
visibleDevicesEnv
,
visibleDevicesEnvVal
:=
gpu
.
GpuInfoList
(
gpus
)
.
GetVisibleDevicesEnv
()
visibleDevicesEnv
,
visibleDevicesEnvVal
:=
gpu
s
.
GetVisibleDevicesEnv
()
pathEnvVal
:=
strings
.
Join
(
libraryPaths
,
string
(
filepath
.
ListSeparator
))
pathEnvVal
:=
strings
.
Join
(
libraryPaths
,
string
(
filepath
.
ListSeparator
))
// Update or add the path and visible devices variable with our adjusted version
// Update or add the path and visible devices variable with our adjusted version
...
@@ -459,7 +459,7 @@ func (s *llmServer) getServerStatus(ctx context.Context) (ServerStatus, error) {
...
@@ -459,7 +459,7 @@ func (s *llmServer) getServerStatus(ctx context.Context) (ServerStatus, error) {
resp
,
err
:=
http
.
DefaultClient
.
Do
(
req
)
resp
,
err
:=
http
.
DefaultClient
.
Do
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
if
errors
.
Is
(
err
,
context
.
DeadlineExceeded
)
{
if
errors
.
Is
(
err
,
context
.
DeadlineExceeded
)
{
return
ServerStatusNotResponding
,
fmt
.
Errorf
(
"server not responding"
)
return
ServerStatusNotResponding
,
errors
.
New
(
"server not responding"
)
}
}
return
ServerStatusError
,
fmt
.
Errorf
(
"health resp: %w"
,
err
)
return
ServerStatusError
,
fmt
.
Errorf
(
"health resp: %w"
,
err
)
}
}
...
...
openai/openai.go
View file @
89d99001
...
@@ -245,7 +245,6 @@ func (w *writer) writeResponse(data []byte) (int, error) {
...
@@ -245,7 +245,6 @@ func (w *writer) writeResponse(data []byte) (int, error) {
d
,
err
:=
json
.
Marshal
(
toChunk
(
w
.
id
,
chatResponse
))
d
,
err
:=
json
.
Marshal
(
toChunk
(
w
.
id
,
chatResponse
))
if
err
!=
nil
{
if
err
!=
nil
{
return
0
,
err
return
0
,
err
}
}
w
.
ResponseWriter
.
Header
()
.
Set
(
"Content-Type"
,
"text/event-stream"
)
w
.
ResponseWriter
.
Header
()
.
Set
(
"Content-Type"
,
"text/event-stream"
)
...
...
parser/parser_test.go
View file @
89d99001
...
@@ -10,6 +10,7 @@ import (
...
@@ -10,6 +10,7 @@ import (
"unicode/utf16"
"unicode/utf16"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
)
func
TestParseFileFile
(
t
*
testing
.
T
)
{
func
TestParseFileFile
(
t
*
testing
.
T
)
{
...
@@ -25,7 +26,7 @@ TEMPLATE template1
...
@@ -25,7 +26,7 @@ TEMPLATE template1
reader
:=
strings
.
NewReader
(
input
)
reader
:=
strings
.
NewReader
(
input
)
modelfile
,
err
:=
ParseFile
(
reader
)
modelfile
,
err
:=
ParseFile
(
reader
)
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
expectedCommands
:=
[]
Command
{
expectedCommands
:=
[]
Command
{
{
Name
:
"model"
,
Args
:
"model1"
},
{
Name
:
"model"
,
Args
:
"model1"
},
...
@@ -88,7 +89,7 @@ func TestParseFileFrom(t *testing.T) {
...
@@ -88,7 +89,7 @@ func TestParseFileFrom(t *testing.T) {
for
_
,
c
:=
range
cases
{
for
_
,
c
:=
range
cases
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
input
))
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
input
))
assert
.
ErrorIs
(
t
,
err
,
c
.
err
)
require
.
ErrorIs
(
t
,
err
,
c
.
err
)
if
modelfile
!=
nil
{
if
modelfile
!=
nil
{
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
}
}
...
@@ -105,7 +106,7 @@ PARAMETER param1
...
@@ -105,7 +106,7 @@ PARAMETER param1
reader
:=
strings
.
NewReader
(
input
)
reader
:=
strings
.
NewReader
(
input
)
_
,
err
:=
ParseFile
(
reader
)
_
,
err
:=
ParseFile
(
reader
)
assert
.
ErrorIs
(
t
,
err
,
io
.
ErrUnexpectedEOF
)
require
.
ErrorIs
(
t
,
err
,
io
.
ErrUnexpectedEOF
)
}
}
func
TestParseFileBadCommand
(
t
*
testing
.
T
)
{
func
TestParseFileBadCommand
(
t
*
testing
.
T
)
{
...
@@ -114,8 +115,7 @@ FROM foo
...
@@ -114,8 +115,7 @@ FROM foo
BADCOMMAND param1 value1
BADCOMMAND param1 value1
`
`
_
,
err
:=
ParseFile
(
strings
.
NewReader
(
input
))
_
,
err
:=
ParseFile
(
strings
.
NewReader
(
input
))
assert
.
ErrorIs
(
t
,
err
,
errInvalidCommand
)
require
.
ErrorIs
(
t
,
err
,
errInvalidCommand
)
}
}
func
TestParseFileMessages
(
t
*
testing
.
T
)
{
func
TestParseFileMessages
(
t
*
testing
.
T
)
{
...
@@ -201,7 +201,7 @@ MESSAGE system`,
...
@@ -201,7 +201,7 @@ MESSAGE system`,
for
_
,
c
:=
range
cases
{
for
_
,
c
:=
range
cases
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
input
))
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
input
))
assert
.
ErrorIs
(
t
,
err
,
c
.
err
)
require
.
ErrorIs
(
t
,
err
,
c
.
err
)
if
modelfile
!=
nil
{
if
modelfile
!=
nil
{
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
}
}
...
@@ -355,7 +355,7 @@ TEMPLATE """
...
@@ -355,7 +355,7 @@ TEMPLATE """
for
_
,
c
:=
range
cases
{
for
_
,
c
:=
range
cases
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
multiline
))
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
multiline
))
assert
.
ErrorIs
(
t
,
err
,
c
.
err
)
require
.
ErrorIs
(
t
,
err
,
c
.
err
)
if
modelfile
!=
nil
{
if
modelfile
!=
nil
{
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
}
}
...
@@ -413,7 +413,7 @@ func TestParseFileParameters(t *testing.T) {
...
@@ -413,7 +413,7 @@ func TestParseFileParameters(t *testing.T) {
fmt
.
Fprintln
(
&
b
,
"FROM foo"
)
fmt
.
Fprintln
(
&
b
,
"FROM foo"
)
fmt
.
Fprintln
(
&
b
,
"PARAMETER"
,
k
)
fmt
.
Fprintln
(
&
b
,
"PARAMETER"
,
k
)
modelfile
,
err
:=
ParseFile
(
&
b
)
modelfile
,
err
:=
ParseFile
(
&
b
)
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
[]
Command
{
assert
.
Equal
(
t
,
[]
Command
{
{
Name
:
"model"
,
Args
:
"foo"
},
{
Name
:
"model"
,
Args
:
"foo"
},
...
@@ -442,7 +442,7 @@ FROM foo
...
@@ -442,7 +442,7 @@ FROM foo
for
_
,
c
:=
range
cases
{
for
_
,
c
:=
range
cases
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
input
))
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
.
input
))
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
assert
.
Equal
(
t
,
c
.
expected
,
modelfile
.
Commands
)
})
})
}
}
...
@@ -501,15 +501,14 @@ SYSTEM ""
...
@@ -501,15 +501,14 @@ SYSTEM ""
for
_
,
c
:=
range
cases
{
for
_
,
c
:=
range
cases
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
t
.
Run
(
""
,
func
(
t
*
testing
.
T
)
{
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
))
modelfile
,
err
:=
ParseFile
(
strings
.
NewReader
(
c
))
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
modelfile2
,
err
:=
ParseFile
(
strings
.
NewReader
(
modelfile
.
String
()))
modelfile2
,
err
:=
ParseFile
(
strings
.
NewReader
(
modelfile
.
String
()))
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
modelfile
,
modelfile2
)
assert
.
Equal
(
t
,
modelfile
,
modelfile2
)
})
})
}
}
}
}
func
TestParseFileUTF16ParseFile
(
t
*
testing
.
T
)
{
func
TestParseFileUTF16ParseFile
(
t
*
testing
.
T
)
{
...
@@ -522,10 +521,10 @@ SYSTEM You are a utf16 file.
...
@@ -522,10 +521,10 @@ SYSTEM You are a utf16 file.
utf16File
:=
utf16
.
Encode
(
append
([]
rune
{
'\ufffe'
},
[]
rune
(
data
)
...
))
utf16File
:=
utf16
.
Encode
(
append
([]
rune
{
'\ufffe'
},
[]
rune
(
data
)
...
))
buf
:=
new
(
bytes
.
Buffer
)
buf
:=
new
(
bytes
.
Buffer
)
err
:=
binary
.
Write
(
buf
,
binary
.
LittleEndian
,
utf16File
)
err
:=
binary
.
Write
(
buf
,
binary
.
LittleEndian
,
utf16File
)
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
actual
,
err
:=
ParseFile
(
buf
)
actual
,
err
:=
ParseFile
(
buf
)
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
expected
:=
[]
Command
{
expected
:=
[]
Command
{
{
Name
:
"model"
,
Args
:
"bob"
},
{
Name
:
"model"
,
Args
:
"bob"
},
...
@@ -539,9 +538,9 @@ SYSTEM You are a utf16 file.
...
@@ -539,9 +538,9 @@ SYSTEM You are a utf16 file.
// simulate a utf16 be file
// simulate a utf16 be file
buf
=
new
(
bytes
.
Buffer
)
buf
=
new
(
bytes
.
Buffer
)
err
=
binary
.
Write
(
buf
,
binary
.
BigEndian
,
utf16File
)
err
=
binary
.
Write
(
buf
,
binary
.
BigEndian
,
utf16File
)
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
actual
,
err
=
ParseFile
(
buf
)
actual
,
err
=
ParseFile
(
buf
)
assert
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
assert
.
Equal
(
t
,
expected
,
actual
.
Commands
)
assert
.
Equal
(
t
,
expected
,
actual
.
Commands
)
}
}
progress/progress.go
View file @
89d99001
...
@@ -59,7 +59,7 @@ func (p *Progress) StopAndClear() bool {
...
@@ -59,7 +59,7 @@ func (p *Progress) StopAndClear() bool {
stopped
:=
p
.
stop
()
stopped
:=
p
.
stop
()
if
stopped
{
if
stopped
{
// clear all progress lines
// clear all progress lines
for
i
:=
0
;
i
<
p
.
pos
;
i
++
{
for
i
:=
range
p
.
pos
{
if
i
>
0
{
if
i
>
0
{
fmt
.
Fprint
(
p
.
w
,
"
\0
33[A"
)
fmt
.
Fprint
(
p
.
w
,
"
\0
33[A"
)
}
}
...
@@ -85,7 +85,7 @@ func (p *Progress) render() {
...
@@ -85,7 +85,7 @@ func (p *Progress) render() {
defer
fmt
.
Fprint
(
p
.
w
,
"
\0
33[?25h"
)
defer
fmt
.
Fprint
(
p
.
w
,
"
\0
33[?25h"
)
// clear already rendered progress lines
// clear already rendered progress lines
for
i
:=
0
;
i
<
p
.
pos
;
i
++
{
for
i
:=
range
p
.
pos
{
if
i
>
0
{
if
i
>
0
{
fmt
.
Fprint
(
p
.
w
,
"
\0
33[A"
)
fmt
.
Fprint
(
p
.
w
,
"
\0
33[A"
)
}
}
...
...
readline/buffer.go
View file @
89d99001
...
@@ -52,7 +52,6 @@ func (b *Buffer) GetLineSpacing(line int) bool {
...
@@ -52,7 +52,6 @@ func (b *Buffer) GetLineSpacing(line int) bool {
}
}
return
hasSpace
.
(
bool
)
return
hasSpace
.
(
bool
)
}
}
func
(
b
*
Buffer
)
MoveLeft
()
{
func
(
b
*
Buffer
)
MoveLeft
()
{
...
@@ -117,15 +116,12 @@ func (b *Buffer) MoveRight() {
...
@@ -117,15 +116,12 @@ func (b *Buffer) MoveRight() {
if
b
.
DisplayPos
%
b
.
LineWidth
==
0
{
if
b
.
DisplayPos
%
b
.
LineWidth
==
0
{
fmt
.
Printf
(
CursorDown
+
CursorBOL
+
cursorRightN
(
len
(
b
.
Prompt
.
prompt
())))
fmt
.
Printf
(
CursorDown
+
CursorBOL
+
cursorRightN
(
len
(
b
.
Prompt
.
prompt
())))
}
else
if
(
b
.
DisplayPos
-
rLength
)
%
b
.
LineWidth
==
b
.
LineWidth
-
1
&&
hasSpace
{
}
else
if
(
b
.
DisplayPos
-
rLength
)
%
b
.
LineWidth
==
b
.
LineWidth
-
1
&&
hasSpace
{
fmt
.
Printf
(
CursorDown
+
CursorBOL
+
cursorRightN
(
len
(
b
.
Prompt
.
prompt
())
+
rLength
))
fmt
.
Printf
(
CursorDown
+
CursorBOL
+
cursorRightN
(
len
(
b
.
Prompt
.
prompt
())
+
rLength
))
b
.
DisplayPos
+=
1
b
.
DisplayPos
+=
1
}
else
if
b
.
LineHasSpace
.
Size
()
>
0
&&
b
.
DisplayPos
%
b
.
LineWidth
==
b
.
LineWidth
-
1
&&
hasSpace
{
}
else
if
b
.
LineHasSpace
.
Size
()
>
0
&&
b
.
DisplayPos
%
b
.
LineWidth
==
b
.
LineWidth
-
1
&&
hasSpace
{
fmt
.
Printf
(
CursorDown
+
CursorBOL
+
cursorRightN
(
len
(
b
.
Prompt
.
prompt
())))
fmt
.
Printf
(
CursorDown
+
CursorBOL
+
cursorRightN
(
len
(
b
.
Prompt
.
prompt
())))
b
.
DisplayPos
+=
1
b
.
DisplayPos
+=
1
}
else
{
}
else
{
fmt
.
Print
(
cursorRightN
(
rLength
))
fmt
.
Print
(
cursorRightN
(
rLength
))
}
}
...
@@ -154,7 +150,7 @@ func (b *Buffer) MoveToStart() {
...
@@ -154,7 +150,7 @@ func (b *Buffer) MoveToStart() {
if
b
.
Pos
>
0
{
if
b
.
Pos
>
0
{
currLine
:=
b
.
DisplayPos
/
b
.
LineWidth
currLine
:=
b
.
DisplayPos
/
b
.
LineWidth
if
currLine
>
0
{
if
currLine
>
0
{
for
cnt
:=
0
;
cnt
<
currLine
;
cnt
++
{
for
range
currLine
{
fmt
.
Print
(
CursorUp
)
fmt
.
Print
(
CursorUp
)
}
}
}
}
...
@@ -169,7 +165,7 @@ func (b *Buffer) MoveToEnd() {
...
@@ -169,7 +165,7 @@ func (b *Buffer) MoveToEnd() {
currLine
:=
b
.
DisplayPos
/
b
.
LineWidth
currLine
:=
b
.
DisplayPos
/
b
.
LineWidth
totalLines
:=
b
.
DisplaySize
()
/
b
.
LineWidth
totalLines
:=
b
.
DisplaySize
()
/
b
.
LineWidth
if
currLine
<
totalLines
{
if
currLine
<
totalLines
{
for
cnt
:=
0
;
cnt
<
totalLines
-
currLine
;
cnt
++
{
for
range
totalLines
-
currLine
{
fmt
.
Print
(
CursorDown
)
fmt
.
Print
(
CursorDown
)
}
}
remainder
:=
b
.
DisplaySize
()
%
b
.
LineWidth
remainder
:=
b
.
DisplaySize
()
%
b
.
LineWidth
...
@@ -185,7 +181,7 @@ func (b *Buffer) MoveToEnd() {
...
@@ -185,7 +181,7 @@ func (b *Buffer) MoveToEnd() {
func
(
b
*
Buffer
)
DisplaySize
()
int
{
func
(
b
*
Buffer
)
DisplaySize
()
int
{
sum
:=
0
sum
:=
0
for
i
:=
0
;
i
<
b
.
Buf
.
Size
()
;
i
++
{
for
i
:=
range
b
.
Buf
.
Size
()
{
if
e
,
ok
:=
b
.
Buf
.
Get
(
i
);
ok
{
if
e
,
ok
:=
b
.
Buf
.
Get
(
i
);
ok
{
if
r
,
ok
:=
e
.
(
rune
);
ok
{
if
r
,
ok
:=
e
.
(
rune
);
ok
{
sum
+=
runewidth
.
RuneWidth
(
r
)
sum
+=
runewidth
.
RuneWidth
(
r
)
...
@@ -197,7 +193,6 @@ func (b *Buffer) DisplaySize() int {
...
@@ -197,7 +193,6 @@ func (b *Buffer) DisplaySize() int {
}
}
func
(
b
*
Buffer
)
Add
(
r
rune
)
{
func
(
b
*
Buffer
)
Add
(
r
rune
)
{
if
b
.
Pos
==
b
.
Buf
.
Size
()
{
if
b
.
Pos
==
b
.
Buf
.
Size
()
{
b
.
AddChar
(
r
,
false
)
b
.
AddChar
(
r
,
false
)
}
else
{
}
else
{
...
@@ -210,7 +205,6 @@ func (b *Buffer) AddChar(r rune, insert bool) {
...
@@ -210,7 +205,6 @@ func (b *Buffer) AddChar(r rune, insert bool) {
b
.
DisplayPos
+=
rLength
b
.
DisplayPos
+=
rLength
if
b
.
Pos
>
0
{
if
b
.
Pos
>
0
{
if
b
.
DisplayPos
%
b
.
LineWidth
==
0
{
if
b
.
DisplayPos
%
b
.
LineWidth
==
0
{
fmt
.
Printf
(
"%c"
,
r
)
fmt
.
Printf
(
"%c"
,
r
)
fmt
.
Printf
(
"
\n
%s"
,
b
.
Prompt
.
AltPrompt
)
fmt
.
Printf
(
"
\n
%s"
,
b
.
Prompt
.
AltPrompt
)
...
@@ -235,7 +229,6 @@ func (b *Buffer) AddChar(r rune, insert bool) {
...
@@ -235,7 +229,6 @@ func (b *Buffer) AddChar(r rune, insert bool) {
}
else
{
}
else
{
b
.
LineHasSpace
.
Add
(
true
)
b
.
LineHasSpace
.
Add
(
true
)
}
}
}
else
{
}
else
{
fmt
.
Printf
(
"%c"
,
r
)
fmt
.
Printf
(
"%c"
,
r
)
}
}
...
@@ -356,7 +349,6 @@ func (b *Buffer) drawRemaining() {
...
@@ -356,7 +349,6 @@ func (b *Buffer) drawRemaining() {
func
(
b
*
Buffer
)
Remove
()
{
func
(
b
*
Buffer
)
Remove
()
{
if
b
.
Buf
.
Size
()
>
0
&&
b
.
Pos
>
0
{
if
b
.
Buf
.
Size
()
>
0
&&
b
.
Pos
>
0
{
if
e
,
ok
:=
b
.
Buf
.
Get
(
b
.
Pos
-
1
);
ok
{
if
e
,
ok
:=
b
.
Buf
.
Get
(
b
.
Pos
-
1
);
ok
{
if
r
,
ok
:=
e
.
(
rune
);
ok
{
if
r
,
ok
:=
e
.
(
rune
);
ok
{
rLength
:=
runewidth
.
RuneWidth
(
r
)
rLength
:=
runewidth
.
RuneWidth
(
r
)
...
@@ -382,7 +374,6 @@ func (b *Buffer) Remove() {
...
@@ -382,7 +374,6 @@ func (b *Buffer) Remove() {
}
else
{
}
else
{
fmt
.
Print
(
" "
+
CursorLeft
)
fmt
.
Print
(
" "
+
CursorLeft
)
}
}
}
else
if
(
b
.
DisplayPos
-
rLength
)
%
b
.
LineWidth
==
0
&&
hasSpace
{
}
else
if
(
b
.
DisplayPos
-
rLength
)
%
b
.
LineWidth
==
0
&&
hasSpace
{
fmt
.
Printf
(
CursorBOL
+
ClearToEOL
)
fmt
.
Printf
(
CursorBOL
+
ClearToEOL
)
fmt
.
Printf
(
CursorUp
+
CursorBOL
+
cursorRightN
(
b
.
Width
))
fmt
.
Printf
(
CursorUp
+
CursorBOL
+
cursorRightN
(
b
.
Width
))
...
@@ -391,10 +382,9 @@ func (b *Buffer) Remove() {
...
@@ -391,10 +382,9 @@ func (b *Buffer) Remove() {
b
.
LineHasSpace
.
Remove
(
b
.
DisplayPos
/
b
.
LineWidth
-
1
)
b
.
LineHasSpace
.
Remove
(
b
.
DisplayPos
/
b
.
LineWidth
-
1
)
}
}
b
.
DisplayPos
-=
1
b
.
DisplayPos
-=
1
}
else
{
}
else
{
fmt
.
Print
(
cursorLeftN
(
rLength
))
fmt
.
Print
(
cursorLeftN
(
rLength
))
for
i
:=
0
;
i
<
rLength
;
i
++
{
for
range
rLength
{
fmt
.
Print
(
" "
)
fmt
.
Print
(
" "
)
}
}
fmt
.
Print
(
cursorLeftN
(
rLength
))
fmt
.
Print
(
cursorLeftN
(
rLength
))
...
@@ -451,7 +441,7 @@ func (b *Buffer) DeleteBefore() {
...
@@ -451,7 +441,7 @@ func (b *Buffer) DeleteBefore() {
func
(
b
*
Buffer
)
DeleteRemaining
()
{
func
(
b
*
Buffer
)
DeleteRemaining
()
{
if
b
.
DisplaySize
()
>
0
&&
b
.
Pos
<
b
.
DisplaySize
()
{
if
b
.
DisplaySize
()
>
0
&&
b
.
Pos
<
b
.
DisplaySize
()
{
charsToDel
:=
b
.
Buf
.
Size
()
-
b
.
Pos
charsToDel
:=
b
.
Buf
.
Size
()
-
b
.
Pos
for
cnt
:=
0
;
cnt
<
charsToDel
;
cnt
++
{
for
range
charsToDel
{
b
.
Delete
()
b
.
Delete
()
}
}
}
}
...
@@ -495,7 +485,7 @@ func (b *Buffer) ClearScreen() {
...
@@ -495,7 +485,7 @@ func (b *Buffer) ClearScreen() {
if
currPos
>
0
{
if
currPos
>
0
{
targetLine
:=
currPos
/
b
.
LineWidth
targetLine
:=
currPos
/
b
.
LineWidth
if
targetLine
>
0
{
if
targetLine
>
0
{
for
cnt
:=
0
;
cnt
<
targetLine
;
cnt
++
{
for
range
targetLine
{
fmt
.
Print
(
CursorDown
)
fmt
.
Print
(
CursorDown
)
}
}
}
}
...
@@ -525,7 +515,7 @@ func (b *Buffer) Replace(r []rune) {
...
@@ -525,7 +515,7 @@ func (b *Buffer) Replace(r []rune) {
fmt
.
Printf
(
CursorBOL
+
ClearToEOL
)
fmt
.
Printf
(
CursorBOL
+
ClearToEOL
)
for
i
:=
0
;
i
<
lineNums
;
i
++
{
for
range
lineNums
{
fmt
.
Print
(
CursorUp
+
CursorBOL
+
ClearToEOL
)
fmt
.
Print
(
CursorUp
+
CursorBOL
+
ClearToEOL
)
}
}
...
...
readline/history.go
View file @
89d99001
...
@@ -91,7 +91,7 @@ func (h *History) Add(l []rune) {
...
@@ -91,7 +91,7 @@ func (h *History) Add(l []rune) {
func
(
h
*
History
)
Compact
()
{
func
(
h
*
History
)
Compact
()
{
s
:=
h
.
Buf
.
Size
()
s
:=
h
.
Buf
.
Size
()
if
s
>
h
.
Limit
{
if
s
>
h
.
Limit
{
for
cnt
:=
0
;
cnt
<
s
-
h
.
Limit
;
cnt
++
{
for
range
s
-
h
.
Limit
{
h
.
Buf
.
Remove
(
0
)
h
.
Buf
.
Remove
(
0
)
}
}
}
}
...
@@ -139,7 +139,7 @@ func (h *History) Save() error {
...
@@ -139,7 +139,7 @@ func (h *History) Save() error {
defer
f
.
Close
()
defer
f
.
Close
()
buf
:=
bufio
.
NewWriter
(
f
)
buf
:=
bufio
.
NewWriter
(
f
)
for
cnt
:=
0
;
cnt
<
h
.
Size
()
;
cnt
++
{
for
cnt
:=
range
h
.
Size
()
{
v
,
_
:=
h
.
Buf
.
Get
(
cnt
)
v
,
_
:=
h
.
Buf
.
Get
(
cnt
)
line
,
_
:=
v
.
([]
rune
)
line
,
_
:=
v
.
([]
rune
)
if
_
,
err
:=
buf
.
WriteString
(
string
(
line
)
+
"
\n
"
);
err
!=
nil
{
if
_
,
err
:=
buf
.
WriteString
(
string
(
line
)
+
"
\n
"
);
err
!=
nil
{
...
...
readline/readline.go
View file @
89d99001
...
@@ -5,7 +5,6 @@ import (
...
@@ -5,7 +5,6 @@ import (
"fmt"
"fmt"
"io"
"io"
"os"
"os"
"syscall"
)
)
type
Prompt
struct
{
type
Prompt
struct
{
...
@@ -63,7 +62,7 @@ func New(prompt Prompt) (*Instance, error) {
...
@@ -63,7 +62,7 @@ func New(prompt Prompt) (*Instance, error) {
func
(
i
*
Instance
)
Readline
()
(
string
,
error
)
{
func
(
i
*
Instance
)
Readline
()
(
string
,
error
)
{
if
!
i
.
Terminal
.
rawmode
{
if
!
i
.
Terminal
.
rawmode
{
fd
:=
int
(
syscall
.
Stdin
)
fd
:=
os
.
Stdin
.
Fd
(
)
termios
,
err
:=
SetRawMode
(
fd
)
termios
,
err
:=
SetRawMode
(
fd
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
...
@@ -80,8 +79,8 @@ func (i *Instance) Readline() (string, error) {
...
@@ -80,8 +79,8 @@ func (i *Instance) Readline() (string, error) {
fmt
.
Print
(
prompt
)
fmt
.
Print
(
prompt
)
defer
func
()
{
defer
func
()
{
fd
:=
int
(
syscall
.
Stdin
)
fd
:=
os
.
Stdin
.
Fd
(
)
//
nolint:
errcheck
//nolint:errcheck
UnsetRawMode
(
fd
,
i
.
Terminal
.
termios
)
UnsetRawMode
(
fd
,
i
.
Terminal
.
termios
)
i
.
Terminal
.
rawmode
=
false
i
.
Terminal
.
rawmode
=
false
}()
}()
...
@@ -136,7 +135,7 @@ func (i *Instance) Readline() (string, error) {
...
@@ -136,7 +135,7 @@ func (i *Instance) Readline() (string, error) {
buf
.
MoveRight
()
buf
.
MoveRight
()
case
CharBracketedPaste
:
case
CharBracketedPaste
:
var
code
string
var
code
string
for
cnt
:=
0
;
cnt
<
3
;
cnt
++
{
for
range
3
{
r
,
err
=
i
.
Terminal
.
Read
()
r
,
err
=
i
.
Terminal
.
Read
()
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
io
.
EOF
return
""
,
io
.
EOF
...
@@ -198,7 +197,7 @@ func (i *Instance) Readline() (string, error) {
...
@@ -198,7 +197,7 @@ func (i *Instance) Readline() (string, error) {
buf
.
Remove
()
buf
.
Remove
()
case
CharTab
:
case
CharTab
:
// todo: convert back to real tabs
// todo: convert back to real tabs
for
cnt
:=
0
;
cnt
<
8
;
cnt
++
{
for
range
8
{
buf
.
Add
(
' '
)
buf
.
Add
(
' '
)
}
}
case
CharDelete
:
case
CharDelete
:
...
@@ -216,7 +215,7 @@ func (i *Instance) Readline() (string, error) {
...
@@ -216,7 +215,7 @@ func (i *Instance) Readline() (string, error) {
case
CharCtrlW
:
case
CharCtrlW
:
buf
.
DeleteWord
()
buf
.
DeleteWord
()
case
CharCtrlZ
:
case
CharCtrlZ
:
fd
:=
int
(
syscall
.
Stdin
)
fd
:=
os
.
Stdin
.
Fd
(
)
return
handleCharCtrlZ
(
fd
,
i
.
Terminal
.
termios
)
return
handleCharCtrlZ
(
fd
,
i
.
Terminal
.
termios
)
case
CharEnter
,
CharCtrlJ
:
case
CharEnter
,
CharCtrlJ
:
output
:=
buf
.
String
()
output
:=
buf
.
String
()
...
@@ -248,7 +247,7 @@ func (i *Instance) HistoryDisable() {
...
@@ -248,7 +247,7 @@ func (i *Instance) HistoryDisable() {
}
}
func
NewTerminal
()
(
*
Terminal
,
error
)
{
func
NewTerminal
()
(
*
Terminal
,
error
)
{
fd
:=
int
(
syscall
.
Stdin
)
fd
:=
os
.
Stdin
.
Fd
(
)
termios
,
err
:=
SetRawMode
(
fd
)
termios
,
err
:=
SetRawMode
(
fd
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
...
readline/readline_unix.go
View file @
89d99001
...
@@ -6,7 +6,7 @@ import (
...
@@ -6,7 +6,7 @@ import (
"syscall"
"syscall"
)
)
func
handleCharCtrlZ
(
fd
int
,
termios
any
)
(
string
,
error
)
{
func
handleCharCtrlZ
(
fd
u
int
ptr
,
termios
any
)
(
string
,
error
)
{
t
:=
termios
.
(
*
Termios
)
t
:=
termios
.
(
*
Termios
)
if
err
:=
UnsetRawMode
(
fd
,
t
);
err
!=
nil
{
if
err
:=
UnsetRawMode
(
fd
,
t
);
err
!=
nil
{
return
""
,
err
return
""
,
err
...
...
readline/readline_windows.go
View file @
89d99001
package
readline
package
readline
func
handleCharCtrlZ
(
fd
int
,
state
any
)
(
string
,
error
)
{
func
handleCharCtrlZ
(
fd
u
int
ptr
,
state
any
)
(
string
,
error
)
{
// not supported
// not supported
return
""
,
nil
return
""
,
nil
}
}
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment