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
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