From add1dd8c31708a79cd47fa86f6bc864445272c85 Mon Sep 17 00:00:00 2001 From: Productive2 <48047721+Productive2@users.noreply.github.com> Date: Wed, 24 Feb 2021 00:31:58 +0100 Subject: [PATCH] terminal resize awareness --- examples/editor.nim | 2 ++ src/jale/editor.nim | 9 +++++++-- src/jale/plugin/defaults.nim | 3 ++- src/jale/plugin/resize.nim | 17 +++++++++++++++++ src/jale/plugin/viewprotector.nim | 27 +++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/jale/plugin/resize.nim create mode 100644 src/jale/plugin/viewprotector.nim diff --git a/examples/editor.nim b/examples/editor.nim index a4fd24a..77efff6 100644 --- a/examples/editor.nim +++ b/examples/editor.nim @@ -1,4 +1,5 @@ import jale/plugin/defaults +import jale/plugin/viewprotector import jale/editor import jale/templates import jale/multiline @@ -22,6 +23,7 @@ e.bindKey("ctrl+s"): e.prompt = "" e.populateDefaults(enterSubmits = false, ctrlForVerticalMove = false) +e.setViewBehavior(vbFullscreen) e.scrollMode = sbAllScroll let result = e.read() if save and paramCount() > 0: diff --git a/src/jale/editor.nim b/src/jale/editor.nim index 0dbf447..fb4deb5 100644 --- a/src/jale/editor.nim +++ b/src/jale/editor.nim @@ -12,7 +12,8 @@ import os type JaleEvent* = enum - jeKeypress, jeQuit, jeFinish, jePreRead, jePostRead + jeKeypress, jeQuit, jeFinish, jePreRead, jePostRead, jePreFullRender, + jePreKey, jePostKey, jeResize EditorState = enum esOutside, esTyping, esFinishing, esQuitting @@ -37,7 +38,7 @@ type rendered: int # how many lines were printed last full refresh forceRedraw: bool hscroll: int - vmax: int + vmax*: int vscroll: int # getter/setter sorts @@ -108,6 +109,8 @@ proc fullRender(editor: LineEditor) = # from the top cursor pos, it draws the entire multiline prompt, then # moves cursor to current y + editor.events.call(jePreFullRender) + let lastY = min(editor.content.high(), editor.vscroll + editor.vmax - 1) for i in countup(editor.vscroll, lastY): editor.render(i) @@ -156,7 +159,9 @@ proc read*(editor: LineEditor): string = # call the events editor.lastKeystroke = key editor.keystrokes.call(key) + editor.events.call(jePreKey) editor.events.call(jeKeypress) + editor.events.call(jePostKey) # autoscroll horizontally based on current scroll and x pos # last x rendered diff --git a/src/jale/plugin/defaults.nim b/src/jale/plugin/defaults.nim index 7c37435..81375e5 100644 --- a/src/jale/plugin/defaults.nim +++ b/src/jale/plugin/defaults.nim @@ -3,6 +3,7 @@ import ../keycodes import ../multiline import ../event import ../templates +import resize import tables @@ -20,10 +21,10 @@ proc bindTerminate*(editor: LineEditor) = if editor.content.getContent() == "": editor.quit() - proc populateDefaults*(editor: LineEditor, enterSubmits = true, ctrlForVerticalMove = true) = editor.bindInput() editor.bindTerminate() + editor.bindResize() editor.bindKey("left"): editor.content.left() editor.bindKey("right"): diff --git a/src/jale/plugin/resize.nim b/src/jale/plugin/resize.nim new file mode 100644 index 0000000..b80fee9 --- /dev/null +++ b/src/jale/plugin/resize.nim @@ -0,0 +1,17 @@ +# only works on posix (through handling SIGWINCH signals) + +import ../editor +import ../event + +when defined(posix): + import posix + +var editors: seq[LineEditor] + +proc bindResize*(ed: LineEditor) = + editors.add(ed) + +when defined(posix): + onSignal(28): + for ed in editors: + ed.events.call(jeResize) diff --git a/src/jale/plugin/viewprotector.nim b/src/jale/plugin/viewprotector.nim new file mode 100644 index 0000000..320d174 --- /dev/null +++ b/src/jale/plugin/viewprotector.nim @@ -0,0 +1,27 @@ +import ../editor +import ../templates + +import terminal + +type ViewBehavior* = enum + vbLines, vbLinesLimited, vbFullscreen + +proc setViewBehavior*(ed: LineEditor, behavior: ViewBehavior) = + case behavior: + of vbLines: + ed.bindEvent(jeResize): + ed.vmax = terminalHeight() - 1 + of vbLinesLimited: + discard + of vbFullscreen: + var resized = false + ed.bindEvent(jeResize): + ed.vmax = terminalHeight() - 1 + ed.redraw() + resized = true + ed.bindEvent(jePreFullRender): + if resized: + eraseScreen() + setCursorPos(0,0) + resized = false +