Skip to content

Commit 5da9c30

Browse files
readline: add cursor movement using Ctrl+{a, e, b, f}
1 parent 53e296c commit 5da9c30

File tree

1 file changed

+71
-35
lines changed

1 file changed

+71
-35
lines changed

src/readline.nim

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,84 @@ type
88
PrCanceled,
99
PrComplete,
1010

11+
proc editMoveLeft(input: string, cursorPos: var int) =
12+
if cursorPos > 0:
13+
let (_, runeLen) = lastRune(input, cursorPos - 1)
14+
cursorPos -= runeLen
15+
16+
proc editMoveRight(input: string, cursorPos: var int) =
17+
if cursorPos < input.len:
18+
let runeLen = runeLenAt(input, cursorPos)
19+
cursorPos += runeLen
20+
21+
proc editBackspace(input: var string, cursorPos: var int) =
22+
if cursorPos > 0:
23+
let (_, runeLen) = lastRune(input, cursorPos - 1)
24+
input = input[0..cursorPos - 1 - runeLen] & input.substr(cursorPos)
25+
cursorPos -= runeLen
26+
27+
proc editDelete(input: var string, cursorPos: int) =
28+
if cursorPos < input.len:
29+
let runeLen = runeLenAt(input, cursorPos)
30+
input = input[0..cursorPos - 1] & input.substr(cursorPos + runeLen)
31+
1132
proc processInputTextMode*(event: nimboxext.Event,
1233
input: var string,
1334
cursorPos: var int): ProcessInputTextModeResult =
1435
## common input processing for MdInputText and MdSearch
1536
case event.kind
1637
of EventType.Key:
17-
case event.sym
18-
of Symbol.Escape:
19-
return PrCanceled
20-
of Symbol.Backspace:
21-
if cursorPos > 0:
22-
let (_, runeLen) = lastRune(input, cursorPos - 1)
23-
input = input[0..cursorPos - 1 - runeLen] & input.substr(cursorPos)
24-
cursorPos -= runeLen
25-
of Symbol.Delete:
26-
if cursorPos < input.len:
27-
let runeLen = runeLenAt(input, cursorPos)
28-
input = input[0..cursorPos - 1] & input.substr(cursorPos + runeLen)
29-
of Symbol.Enter:
30-
return PrComplete
31-
of Symbol.Space:
32-
let inserted = " "
33-
input.insert(inserted, cursorPos)
34-
cursorPos += inserted.len
35-
of Symbol.Character:
36-
let inserted = $event.ch.Rune
37-
input.insert(inserted, cursorPos)
38-
cursorPos += inserted.len
39-
of Symbol.Left:
40-
if cursorPos > 0:
41-
let (_, runeLen) = lastRune(input, cursorPos - 1)
42-
cursorPos -= runeLen
43-
of Symbol.Right:
44-
if cursorPos < input.len:
45-
let runeLen = runeLenAt(input, cursorPos)
46-
cursorPos += runeLen
47-
of Symbol.Home:
48-
cursorPos = 0;
49-
of Symbol.End:
50-
cursorPos = input.len;
51-
else:
38+
if event.mods == @[Modifier.Ctrl]:
39+
case event.sym
40+
# normal escape key press, no ctrl, but still here
41+
of Symbol.Escape:
42+
return PrCanceled
43+
# normal backspace key press, no ctrl, but still here
44+
of Symbol.Backspace:
45+
editBackspace(input, cursorPos)
46+
# normal enter key press, no ctrl, but still here
47+
of Symbol.Enter:
48+
return PrComplete
49+
of Symbol.Character:
50+
case event.ch
51+
of 'C':
52+
return PrCanceled
53+
of 'B':
54+
editMoveLeft(input, cursorPos)
55+
of 'F':
56+
editMoveRight(input, cursorPos)
57+
of 'A':
58+
cursorPos = 0;
59+
of 'E':
60+
cursorPos = input.len;
61+
else:
62+
discard
63+
else:
64+
discard
65+
elif event.mods == @[Modifier.Alt]:
5266
discard
67+
else:
68+
case event.sym
69+
of Symbol.Delete:
70+
editDelete(input, cursorPos)
71+
of Symbol.Space:
72+
let inserted = " "
73+
input.insert(inserted, cursorPos)
74+
cursorPos += inserted.len
75+
of Symbol.Character:
76+
let inserted = $event.ch.Rune
77+
input.insert(inserted, cursorPos)
78+
cursorPos += inserted.len
79+
of Symbol.Left:
80+
editMoveLeft(input, cursorPos)
81+
of Symbol.Right:
82+
editMoveRight(input, cursorPos)
83+
of Symbol.Home:
84+
cursorPos = 0;
85+
of Symbol.End:
86+
cursorPos = input.len;
87+
else:
88+
discard
5389
of EventType.Mouse, EventType.Resize, EventType.None:
5490
discard
5591

0 commit comments

Comments
 (0)