diff options
Diffstat (limited to 'twtio.nim')
-rw-r--r-- | twtio.nim | 213 |
1 files changed, 174 insertions, 39 deletions
diff --git a/twtio.nim b/twtio.nim index 0a19bfbf..acb4add7 100644 --- a/twtio.nim +++ b/twtio.nim @@ -40,23 +40,188 @@ proc getLinedAction*(s: string): TwtAction = return linedActionRemap[s] return NO_ACTION -proc readLine*(prompt: string, current: var string): bool = +const breakWord = [ + Rune('\n'), Rune('/'), Rune('\\'), Rune(' '), Rune('&'), Rune('=') +] + +#proc readLine*(prompt: string, current: var string, termwidth: int): bool = +# var new = current +# print(prompt) +# let maxlen = termwidth - prompt.len +# printesc(new) +# var s = "" +# var feedNext = false +# var escNext = false +# var cursor = new.runeLen +# var shift = 0 +# while true: +# var rl = new.runeLen() +# +# if cursor < shift: +# shift = cursor +# elif cursor - shift > maxlen: +# shift += cursor - maxlen +# +# if not feedNext: +# s = "" +# else: +# feedNext = false +# let c = getch() +# s &= c +# var action = getLinedAction(s) +# if escNext: +# action = NO_ACTION +# case action +# of ACTION_LINED_CANCEL: +# return false +# of ACTION_LINED_SUBMIT: +# current = new +# return true +# of ACTION_LINED_BACKSPACE: +# if cursor > 0: +# print(' '.repeat(rl - cursor + 1)) +# print('\b'.repeat(rl - cursor + 1)) +# print("\b \b") +# new = new.runeSubstr(0, cursor - 1) & new.runeSubstr(cursor) +# rl = new.runeLen() +# cursor -= 1 +# printesc(new.runeSubstr(cursor)) +# print('\b'.repeat(rl - cursor)) +# of ACTION_LINED_ESC: +# escNext = true +# of ACTION_LINED_CLEAR: +# print('\r') +# print(' '.repeat(termwidth)) +# print('\r') +# new = new.runeSubstr(cursor) +# rl = new.runeLen() +# printesc(prompt) +# printesc(new.maxString(maxlen + 1)) +# print('\r') +# printesc(prompt) +# cursor = 0 +# of ACTION_LINED_KILL: +# print(' '.repeat(rl - cursor + 1)) +# print('\b'.repeat(rl - cursor + 1)) +# new = new.runeSubstr(0, cursor) +# of ACTION_LINED_BACK: +# if cursor > 0: +# if cursor < maxlen: +# print('\b') +# dec cursor +# of ACTION_LINED_FORWARD: +# if cursor < rl: +# if cursor + 1 < maxlen: +# var rune: Rune +# new.fastRuneAt(cursor, rune, false) +# printesc($rune) +# elif cursor + 1 == maxlen: +# print('$') +# inc cursor +# of ACTION_LINED_PREV_WORD: +# while cursor > 0: +# print('\b') +# cursor -= 1 +# var rune: Rune +# new.fastRuneAt(cursor, rune, false) +# if rune in breakWord: +# break +# of ACTION_LINED_NEXT_WORD: +# while cursor < rl: +# var rune: Rune +# new.fastRuneAt(cursor, rune, false) +# printesc($rune) +# inc cursor +# if cursor < rl: +# new.fastRuneAt(cursor, rune, false) +# if rune in breakWord: +# break +# of ACTION_LINED_KILL_WORD: +# var chars = 0 +# while cursor > chars: +# inc chars +# var rune: Rune +# new.fastRuneAt(cursor - chars, rune, false) +# if rune in breakWord: +# break +# if chars > 0: +# print(' '.repeat(rl - cursor + 1)) +# print('\b'.repeat(rl - cursor + 1)) +# print("\b \b".repeat(chars)) +# new = new.runeSubstr(0, cursor - chars) & new.runeSubstr(cursor) +# rl = new.runeLen() +# cursor -= chars +# printesc(new.runeSubstr(cursor)) +# print('\b'.repeat(rl - cursor)) +# of ACTION_FEED_NEXT: +# feedNext = true +# elif validateUtf8(s) == -1: +# var cs = "" +# for c in s: +# if not c.isControlChar(): +# cs &= c +# elif escNext: +# cs &= c +# escNext = false +# escNext = false +# if cs.len == 0: +# continue +# if rl + 1 < maxlen: +# print(' '.repeat(rl - cursor + 1)) +# print('\b'.repeat(rl - cursor + 1)) +# new = new.runeSubstr(0, cursor) & cs & new.runeSubstr(cursor) +# rl = new.runeLen() +# if cursor - shift > maxlen: +# shift += maxlen - cursor +# if shift == 0: +# printesc(new.runeSubstr(cursor, min(maxlen - cursor - 1, rl))) +# print('\b'.repeat(max(min(maxlen - cursor - 2, rl - cursor - 1), 0))) +# else: +# print('\r') +# print(' '.repeat(termwidth)) +# print('\r') +# print(prompt) +# print(new.runeSubstr(shift, min(maxlen - 1, rl - shift))) +# if maxlen < rl - shift: +# print(new.runeSubstr(shift, maxlen - 1)) +# print('\b'.repeat(maxlen - cursor + shift)) +# else: +# print(new.runeSubstr(shift, rl - shift)) +# print('\b'.repeat(rl + shift - cursor)) +# inc cursor +# else: +# feedNext = true + +proc readLine*(prompt: string, current: var string, termwidth: int): bool = var new = current print(prompt) - print(' ') + let maxlen = termwidth - prompt.len printesc(new) var s = "" var feedNext = false var escNext = false var cursor = new.runeLen + var shift = 0 while true: + var rl = new.runeLen() + print('\r') + print(' '.repeat(termwidth)) + print('\r') + printesc(prompt & new) + print('\r') + cursorForward(prompt.len + cursor) + + if cursor < shift: + shift = cursor + elif cursor - shift > maxlen: + shift += cursor - maxlen + if not feedNext: s = "" else: feedNext = false let c = getch() s &= c - var rl = new.runeLen() var action = getLinedAction(s) if escNext: action = NO_ACTION @@ -68,58 +233,37 @@ proc readLine*(prompt: string, current: var string): bool = return true of ACTION_LINED_BACKSPACE: if cursor > 0: - print(' '.repeat(rl - cursor + 1)) - print('\b'.repeat(rl - cursor + 1)) - print("\b \b") new = new.runeSubstr(0, cursor - 1) & new.runeSubstr(cursor) rl = new.runeLen() - cursor -= 1 - printesc(new.runeSubstr(cursor)) - print('\b'.repeat(rl - cursor)) + dec cursor of ACTION_LINED_ESC: escNext = true of ACTION_LINED_CLEAR: - print(' '.repeat(rl - cursor + 1)) - print('\b'.repeat(rl - cursor + 1)) - print('\b'.repeat(cursor)) - print(' '.repeat(cursor)) - print('\b'.repeat(cursor)) new = new.runeSubstr(cursor) rl = new.runeLen() - printesc(new) - print('\b'.repeat(rl)) cursor = 0 of ACTION_LINED_KILL: - print(' '.repeat(rl - cursor + 1)) - print('\b'.repeat(rl - cursor + 1)) new = new.runeSubstr(0, cursor) of ACTION_LINED_BACK: if cursor > 0: - cursor -= 1 - print("\b") + dec cursor of ACTION_LINED_FORWARD: if cursor < rl: - var rune: Rune - new.fastRuneAt(cursor, rune, false) - printesc($rune) inc cursor of ACTION_LINED_PREV_WORD: while cursor > 0: - print('\b') - cursor -= 1 + dec cursor var rune: Rune new.fastRuneAt(cursor, rune, false) - if rune == Rune(' '): + if rune in breakWord: break of ACTION_LINED_NEXT_WORD: while cursor < rl: var rune: Rune - new.fastRuneAt(cursor, rune, false) - printesc($rune) inc cursor if cursor < rl: new.fastRuneAt(cursor, rune, false) - if rune == Rune(' '): + if rune in breakWord: break of ACTION_LINED_KILL_WORD: var chars = 0 @@ -127,17 +271,12 @@ proc readLine*(prompt: string, current: var string): bool = inc chars var rune: Rune new.fastRuneAt(cursor - chars, rune, false) - if rune == Rune(' '): + if rune in breakWord: break if chars > 0: - print(' '.repeat(rl - cursor + 1)) - print('\b'.repeat(rl - cursor + 1)) - print("\b \b".repeat(chars)) new = new.runeSubstr(0, cursor - chars) & new.runeSubstr(cursor) rl = new.runeLen() cursor -= chars - printesc(new.runeSubstr(cursor)) - print('\b'.repeat(rl - cursor)) of ACTION_FEED_NEXT: feedNext = true elif validateUtf8(s) == -1: @@ -151,12 +290,8 @@ proc readLine*(prompt: string, current: var string): bool = escNext = false if cs.len == 0: continue - print(' '.repeat(rl - cursor + 1)) - print('\b'.repeat(rl - cursor + 1)) new = new.runeSubstr(0, cursor) & cs & new.runeSubstr(cursor) rl = new.runeLen() - printesc(new.runeSubstr(cursor)) - print('\b'.repeat(rl - cursor - 1)) inc cursor else: feedNext = true |