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
913306f4
Unverified
Commit
913306f4
authored
Mar 26, 2024
by
Jeffrey Morgan
Committed by
GitHub
Mar 26, 2024
Browse files
Detect arrow keys on windows (#3363)
* detect arrow keys on windows * add some helpful comments
parent
f5ca7f8c
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
14 additions
and
39 deletions
+14
-39
readline/term_windows.go
readline/term_windows.go
+14
-39
No files found.
readline/term_windows.go
View file @
913306f4
package
readline
package
readline
import
(
import
(
"syscall"
"golang.org/x/sys/windows"
"unsafe"
)
const
(
enableLineInput
=
2
enableWindowInput
=
8
enableMouseInput
=
16
enableInsertMode
=
32
enableQuickEditMode
=
64
enableExtendedFlags
=
128
enableProcessedOutput
=
1
enableWrapAtEolOutput
=
2
enableAutoPosition
=
256
// Cursor position is not affected by writing data to the console.
enableEchoInput
=
4
// Characters are written to the console as they're read.
enableProcessedInput
=
1
// Enables input processing (like recognizing Ctrl+C).
)
var
kernel32
=
syscall
.
NewLazyDLL
(
"kernel32.dll"
)
var
(
procGetConsoleMode
=
kernel32
.
NewProc
(
"GetConsoleMode"
)
procSetConsoleMode
=
kernel32
.
NewProc
(
"SetConsoleMode"
)
)
)
type
State
struct
{
type
State
struct
{
...
@@ -33,31 +11,28 @@ type State struct {
...
@@ -33,31 +11,28 @@ type State struct {
// IsTerminal checks if the given file descriptor is associated with a terminal
// IsTerminal checks if the given file descriptor is associated with a terminal
func
IsTerminal
(
fd
int
)
bool
{
func
IsTerminal
(
fd
int
)
bool
{
var
st
uint32
var
st
uint32
r
,
_
,
e
:=
syscall
.
SyscallN
(
procGetConsoleMode
.
Addr
(),
uintptr
(
fd
),
uintptr
(
unsafe
.
Pointer
(
&
st
)),
0
)
err
:=
windows
.
GetConsoleMode
(
windows
.
Handle
(
fd
),
&
st
)
// if the call succeeds and doesn't produce an error, it's a terminal
return
err
==
nil
return
r
!=
0
&&
e
==
0
}
}
func
SetRawMode
(
fd
int
)
(
*
State
,
error
)
{
func
SetRawMode
(
fd
int
)
(
*
State
,
error
)
{
var
st
uint32
var
st
uint32
// retrieve the current mode of the terminal
if
err
:=
windows
.
GetConsoleMode
(
windows
.
Handle
(
fd
),
&
st
);
err
!=
nil
{
_
,
_
,
e
:=
syscall
.
SyscallN
(
procGetConsoleMode
.
Addr
(),
uintptr
(
fd
),
uintptr
(
unsafe
.
Pointer
(
&
st
)),
0
)
return
nil
,
err
if
e
!=
0
{
return
nil
,
error
(
e
)
}
}
// modify the mode to set it to raw
raw
:=
st
&^
(
enableEchoInput
|
enableProcessedInput
|
enableLineInput
|
enableProcessedOutput
)
// this enables raw mode by turning off various flags in the console mode: https://pkg.go.dev/golang.org/x/sys/windows#pkg-constants
// apply the new mode to the terminal
raw
:=
st
&^
(
windows
.
ENABLE_ECHO_INPUT
|
windows
.
ENABLE_PROCESSED_INPUT
|
windows
.
ENABLE_LINE_INPUT
|
windows
.
ENABLE_PROCESSED_OUTPUT
)
_
,
_
,
e
=
syscall
.
SyscallN
(
procSetConsoleMode
.
Addr
(),
uintptr
(
fd
),
uintptr
(
raw
),
0
)
if
e
!=
0
{
// turn on ENABLE_VIRTUAL_TERMINAL_INPUT to enable escape sequences
return
nil
,
error
(
e
)
raw
|=
windows
.
ENABLE_VIRTUAL_TERMINAL_INPUT
if
err
:=
windows
.
SetConsoleMode
(
windows
.
Handle
(
fd
),
raw
);
err
!=
nil
{
return
nil
,
err
}
}
// return the original state so that it can be restored later
return
&
State
{
st
},
nil
return
&
State
{
st
},
nil
}
}
func
UnsetRawMode
(
fd
int
,
state
any
)
error
{
func
UnsetRawMode
(
fd
int
,
state
any
)
error
{
s
:=
state
.
(
*
State
)
s
:=
state
.
(
*
State
)
_
,
_
,
err
:=
syscall
.
SyscallN
(
procSetConsoleMode
.
Addr
(),
uintptr
(
fd
),
uintptr
(
s
.
mode
),
0
)
return
windows
.
SetConsoleMode
(
windows
.
Handle
(
fd
),
s
.
mode
)
return
err
}
}
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