835b2102a5a39f7a1f6c3465a12e926740a79d15 — Michael Rees 4 months ago 589b737
Allow customizing the navigation keys
2 files changed, 15 insertions(+), 11 deletions(-)

M README.md
M src/pagerpkg/pager.nim
M README.md => README.md +2 -0
@@ 23,6 23,8 @@ This will split the value of `longString` onto lines that can be stepped through
 - `Ctrl-D`: go down one-half of the screen
 - `q`: quit
 
+These keys can be customized by passing optional arguments to `page`. See the function signature of `page` for details.
+
 ## Project Goals
 
 `pager` was written for [roman](https://git.sr.ht/~reesmichael1/roman), and currently only has the flexibility and features required for that task. However, any patches or requests for extension would be welcome!

M src/pagerpkg/pager.nim => src/pagerpkg/pager.nim +13 -11
@@ 25,9 25,11 @@ proc displayLines(allLines: seq[string], ix: int) =
     cursorBackward(stdout, line.len)
 
 
-proc page*(contents: string) =
-  ## Clear the screen and write chunks of `s` as they fit onto stdout
-
+proc page*(contents: string, goToBottom = 'G', goToTop = 'g', upOne = 'k',
+    quitChar = 'q', downOne = 'j', upHalf = chr(21), downHalf = chr(4)) =
+  ## Clear the screen and write chunks of `s` as they fit onto stdout.
+  ## The navigation keys can be customized # by passing the relevant characters
+  ## as arguments.
   # wrapWords doesn't handle newlines that are already in the text well,
   # so we split the contents into chunks, wrap the chunks, and then join them
   var wrappedLines: seq[string] = @[]


@@ 51,21 53,21 @@ proc page*(contents: string) =
     let height = terminalHeight() # in case the terminal has been resized
     let stepSize = int(height / 2)
     displayLines(wrappedLines, lineIx)
-    case getch():
-    of 'j': # scroll down
+    let c = getch()
+    if c == downOne: # scroll down
       lineIx = min(lineIx + 1, wrappedLines.len - height)
-    of 'k': # scroll up
+    elif c == upOne: # scroll up
       if lineIx >= 1: # but only if not already at the top
         lineIx -= 1
-    of 'G': # go to the last line
+    elif c == goToBottom: # go to the last line
       lineIx = max(0, wrappedLines.len - height)
-    of 'g': # go back to the start
+    elif c == goToTop: # go back to the start
       lineIx = 0
-    of chr(21): # Ctrl-U: go up one half-screen's worth
+    elif c == upHalf: # Ctrl-U: go up one half-screen's worth
       lineIx = max(0, lineIx - stepSize)
-    of chr(4): # Ctrl-D: go down one half-screen's worth
+    elif c == downHalf: # Ctrl-D: go down one half-screen's worth
       lineIx = min(lineIx + stepSize, wrappedLines.len - height)
-    of '\3', 'q': # keyboard interrupt or quit
+    elif c == '\3' or c == quitChar: # keyboard interrupt or quit
       stdout.write "\n"
       showCursor(stdout)
       return