about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/config.md97
-rw-r--r--readme.md6
-rw-r--r--res/config33
-rw-r--r--src/config/config.nim13
-rw-r--r--src/io/buffer.nim36
-rw-r--r--src/io/term.nim3
6 files changed, 139 insertions, 49 deletions
diff --git a/doc/config.md b/doc/config.md
new file mode 100644
index 00000000..14a34608
--- /dev/null
+++ b/doc/config.md
@@ -0,0 +1,97 @@
+# Configuration
+
+Currently keybindings and a user stylesheet can be configured.
+
+twt will look for a config file in the ~/.config/twt/ directory, so you can
+just copy the one from res/ there and customize that to your liking.
+
+A list of configurable options follows.
+
+## Stylesheets
+
+To set a user stylesheet, use the format `stylesheet "path-to-user.css"`.
+Relative paths are interpreted as relative to the config directory.
+
+For now, specifying a second stylesheet will override the first one.
+
+## Keybindings
+"Normal" (default pager browsing) mode keybindings are configured using the
+syntax
+
+	nmap <keybinding> <action>
+
+Similarly, "Line-edit" (line editing) mode keybindings are configured
+using the syntax
+
+	lemap <keybinding> <action>
+
+Where `<keybinding>` is a combination of unicode characters with or without
+modifiers. Modifiers are the prefixes `C-` and `M-`, which add control or
+escape to the keybinding respectively (essentially making `M-` the same as
+`C-[`).
+
+`<action>` is a valid normal or line-edit mode action. A detailed
+description of these follows.
+
+### Normal mode actions
+
+<table>
+<tr><th>**Name**<th>**Function**
+<tr><td>`NULL`<td>Do nothing
+<tr><td>`QUIT`<td>Exit the browser
+<tr><td>`CURSOR_UP`<td>Move the cursor to the previous line
+<tr><td>`CURSOR_DOWN`<td>Move cursor to the next line
+<tr><td>`CURSOR_LEFT`<td>Move cursor to the previous cell
+<tr><td>`CURSOR_RIGHT`<td>Move cursor to the next cell
+<tr><td>`CURSOR_LEFT`<td>Move cursor to the previous cell
+<tr><td>`CURSOR_LINEBEGIN`<td>Move cursor to the first cell of the line
+<tr><td>`CURSOR_LINEEND`<td>Move cursor to the last cell of the line
+<tr><td>`CURSOR_NEXT_WORD`<td>Move cursor to the beginning of the next word
+<tr><td>`CURSOR_PREV_WORD`<td>Move cursor to the end of the previous word
+<tr><td>`CURSOR_NEXT_LINK`<td>Move cursor to the beginning of the next clickable element
+<tr><td>`CURSOR_PREV_LINK`<td>Move cursor to the beginning of the previous clickable element
+<tr><td>`PAGE_DOWN`<td>Move screen down by one page
+<tr><td>`PAGE_UP`<td>Move screen up by one page
+<tr><td>`PAGE_LEFT`<td>Move screen to the left by one page
+<tr><td>`PAGE_RIGHT`<td>Move screen to the right by one page
+<tr><td>`HALF_PAGE_DOWN`<td>Move screen down by half a page
+<tr><td>`HALF_PAGE_UP`<td>Move screen up by half a page
+<tr><td>`SCROLL_DOWN`<td>Move screen down by one line
+<tr><td>`SCROLL_UP`<td>Move screen up by one line
+<tr><td>`SCROLL_LEFT`<td>Move screen to the left by one line
+<tr><td>`SCROLL_RIGHT`<td>Move screen to the right by one line
+<tr><td>`CLICK`<td>Click element currently under cursor
+<tr><td>`CHANGE_LOCATION`<td>Go to URL
+<tr><td>`RELOAD`<td>Reload page
+<tr><td>`RESHAPE`<td>Reshape buffer (=render page anew)
+<tr><td>`REDRAW`<td>Redraw buffer (=redraw screen)
+<tr><td>`TOGGLE_SOURCE`<td>Source view
+<tr><td>`CURSOR_FIRST_LINE`<td>Move cursor to the first line of the buffer
+<tr><td>`CURSOR_LAST_LINE`<td>Move cursor to the last line of the buffer
+<tr><td>`CURSOR_TOP`<td>Move cursor to the first line of the page
+<tr><td>`CURSOR_MIDDLE`<td>Move cursor to the middle of the page
+<tr><td>`CURSOR_BOTTOM`<td>Move cursor to the last line of the page
+<tr><td>`CENTER_LINE`<td>Center screen around line
+<tr><td>`LINE_INFO`<td>Display information about line
+</table>
+
+### Line-edit mode actions
+
+<table>
+<tr><th>**Name**<th>**Function**
+<tr><td>`NULL`<td>Do nothing
+<tr><td>`SUBMIT`<td>Submit line
+<tr><td>`CANCEL`<td>Cancel operation
+<tr><td>`BACKSPACE`<td>Delete character before cursor
+<tr><td>`DELETE`<td>Delete character after cursor
+<tr><td>`CLEAR`<td>Clear text before cursor
+<tr><td>`KILL`<td>Clear text after cursor
+<tr><td>`KILL_WORD`<td>Delete previous word
+<tr><td>`BACK`<td>Move cursor back by one character
+<tr><td>`FORWARD`<td>Move cursor forward by one character
+<tr><td>`PREV_WORD`<td>Move cursor to the previous word by one character
+<tr><td>`NEXT_WORD`<td>Move cursor to the previous word by one character
+<tr><td>`BEGIN`<td>Move cursor to the previous word by one character
+<tr><td>`END`<td>Move cursor to the previous word by one character
+<tr><td>`ESC`<td>Ignore keybindings for next character
+</table>
diff --git a/readme.md b/readme.md
index c825f29f..f1e01aef 100644
--- a/readme.md
+++ b/readme.md
@@ -61,8 +61,4 @@ Planned features (roughly in order of importance):
 
 ## How do I configure stuff?
 
-Currently only keybindings can be configured. See the res/config file for the
-default (built-in) configuration.
-
-twt will look for a config file in the ~/.config/twt/ directory, so you can
-just copy the one from res/ there and customize that to your liking.
+See [doc/config.md](doc/config.md).
diff --git a/res/config b/res/config
index 872593c1..0f4e5603 100644
--- a/res/config
+++ b/res/config
@@ -46,20 +46,19 @@ nmap C-g LINE_INFO
 nmap gh TOGGLE_SOURCE
 
 #line editing keybindings
-lemap C-m LINED_SUBMIT
-lemap C-j LINED_SUBMIT
-lemap C-h LINED_BACKSPACE
-lemap C-? LINED_BACKSPACE
-lemap C-d LINED_DELETE
-lemap C-c LINED_CANCEL
-lemap M-b LINED_PREV_WORD
-lemap M-f LINED_NEXT_WORD
-lemap C-b LINED_BACK
-lemap C-f LINED_FORWARD
-lemap C-u LINED_CLEAR
-lemap C-k LINED_KILL
-lemap C-w LINED_KILL_WORD
-lemap C-a LINED_BEGIN
-lemap C-e LINED_END
-lemap C-v LINED_ESC
-lemap M-j LINED_COMPOSE_TOGGLE
+lemap C-m SUBMIT
+lemap C-j SUBMIT
+lemap C-h BACKSPACE
+lemap C-? BACKSPACE
+lemap C-d DELETE
+lemap C-c CANCEL
+lemap M-b PREV_WORD
+lemap M-f NEXT_WORD
+lemap C-b BACK
+lemap C-f FORWARD
+lemap C-u CLEAR
+lemap C-k KILL
+lemap C-w KILL_WORD
+lemap C-a BEGIN
+lemap C-e END
+lemap C-v ESC
diff --git a/src/config/config.nim b/src/config/config.nim
index 89f80fae..91b17dda 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -14,7 +14,6 @@ type
     ACTION_CURSOR_UP, ACTION_CURSOR_DOWN, ACTION_CURSOR_LEFT, ACTION_CURSOR_RIGHT,
     ACTION_CURSOR_LINEEND, ACTION_CURSOR_LINEBEGIN,
     ACTION_CURSOR_NEXT_WORD, ACTION_CURSOR_PREV_WORD,
-    ACTION_CURSOR_NEXT_NODE, ACTION_CURSOR_PREV_NODE,
     ACTION_CURSOR_NEXT_LINK, ACTION_CURSOR_PREV_LINK,
     ACTION_PAGE_DOWN, ACTION_PAGE_UP, ACTION_PAGE_LEFT, ACTION_PAGE_RIGHT,
     ACTION_HALF_PAGE_DOWN, ACTION_HALF_PAGE_UP,
@@ -31,7 +30,7 @@ type
     ACTION_LINED_BACK, ACTION_LINED_FORWARD,
     ACTION_LINED_PREV_WORD, ACTION_LINED_NEXT_WORD,
     ACTION_LINED_BEGIN, ACTION_LINED_END,
-    ACTION_LINED_COMPOSE_TOGGLE, ACTION_LINED_ESC
+    ACTION_LINED_ESC
 
   ActionMap = Table[string, TwtAction]
   StaticConfig = object
@@ -148,9 +147,15 @@ proc parseConfigLine[T](line: string, config: var T) =
 
   if cmd.len == 3:
     if cmd[0] == "nmap":
-      config.nmap[getRealKey(cmd[1])] = parseEnum[TwtAction]("ACTION_" & cmd[2])
+      if cmd[2] == "NULL":
+        config.nmap[getRealKey(cmd[1])] = NO_ACTION
+      else:
+        config.nmap[getRealKey(cmd[1])] = parseEnum[TwtAction]("ACTION_" & cmd[2])
     elif cmd[0] == "lemap":
-      config.lemap[getRealKey(cmd[1])] = parseEnum[TwtAction]("ACTION_" & cmd[2])
+      if cmd[2] == "NULL":
+        config.lemap[getRealKey(cmd[1])] = NO_ACTION
+      else:
+        config.lemap[getRealKey(cmd[1])] = parseEnum[TwtAction]("ACTION_LINED_" & cmd[2])
   elif cmd.len == 2:
     if cmd[0] == "stylesheet":
       config.stylesheet = cmd[1]
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 35f5f0f3..e0751964 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -56,25 +56,26 @@ func newBuffer*(attrs: TermAttributes): Buffer =
   result.prevdisplay = newFixedGrid(result.width, result.height)
   result.statusmsg = newFixedGrid(result.width)
 
-func generateFullOutput*(buffer: Buffer): seq[string] =
+func generateFullOutput*(buffer: Buffer): string =
   var x = 0
-  var y = 0
-  var s = ""
+  var w = 0
   var formatting = newFormatting()
 
   for cell in buffer.display:
     if x >= buffer.width:
-      inc y
-      result.add(s)
+      if w < buffer.width:
+        result &= EL()
+      result &= '\n'
       x = 0
-      s = ""
+      w = 0
 
-    s &= formatting.processFormatting(cell.formatting)
+    result &= formatting.processFormatting(cell.formatting)
 
-    s &= $cell.runes
+    result &= $cell.runes
+    w += cell.runes.width()
     inc x
 
-  result.add(s)
+  result &= EL()
 
 # generate a sequence of instructions to replace the previous frame with the
 # current one. ideally should be used when small changes are made (e.g. hover
@@ -725,7 +726,7 @@ proc reshapeBuffer*(buffer: Buffer) =
 proc cursorBufferPos(buffer: Buffer) =
   let x = max(buffer.cursorx - buffer.fromx, 0)
   let y = buffer.cursory - buffer.fromy
-  termGoto(x, y)
+  print(HVP(y + 1, x + 1))
 
 proc clearStatusMessage(buffer: Buffer) =
   buffer.statusmsg = newFixedGrid(buffer.width)
@@ -753,15 +754,11 @@ proc displayBufferSwapOutput(buffer: Buffer) =
   print(buffer.generateSwapOutput())
 
 proc displayBuffer(buffer: Buffer) =
-  termGoto(0, 0)
-  let full = buffer.generateFullOutput()
-  for line in full:
-    print(line)
-    print(EL())
-    print('\n')
+  print(HVP(1, 1))
+  print(buffer.generateFullOutput())
 
 proc displayStatusMessage(buffer: Buffer) =
-  termGoto(0, buffer.height)
+  print(HVP(buffer.height + 1, 1))
   print(SGR())
   print(buffer.generateStatusMessage())
   print(EL())
@@ -786,7 +783,7 @@ proc inputLoop(attrs: TermAttributes, buffer: Buffer): bool =
     case action
     of ACTION_QUIT:
       eraseScreen()
-      setCursorPos(0, 0)
+      print(HVP(0, 0))
       return false
     of ACTION_CURSOR_LEFT: buffer.cursorLeft()
     of ACTION_CURSOR_DOWN: buffer.cursorDown()
@@ -819,7 +816,7 @@ proc inputLoop(attrs: TermAttributes, buffer: Buffer): bool =
     of ACTION_CHANGE_LOCATION:
       var url = $buffer.location
 
-      termGoto(0, buffer.height)
+      print(HVP(buffer.height + 1, 1))
       print(EL())
       let status = readLine("URL: ", url, buffer.width)
       if status:
@@ -850,7 +847,6 @@ proc inputLoop(attrs: TermAttributes, buffer: Buffer): bool =
       buffer.displayBuffer()
       buffer.redraw = false
 
-    #TODO
     buffer.updateHover()
     if buffer.reshape:
       buffer.reshapeBuffer()
diff --git a/src/io/term.nim b/src/io/term.nim
index d60d5746..dc54a34c 100644
--- a/src/io/term.nim
+++ b/src/io/term.nim
@@ -26,6 +26,3 @@ proc getTermAttributes*(): TermAttributes =
     result.height = 24
   result.ppc = 9
   result.ppl = 18
-
-proc termGoto*(x: int, y: int) =
-  setCursorPos(stdout, x, y)