about summary refs log tree commit diff stats
path: root/src/local
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-03-14 20:41:08 +0100
committerbptato <nincsnevem662@gmail.com>2024-03-14 20:41:57 +0100
commita8f05f18fdd64485c26b453e62e8073b50e271ef (patch)
tree855b2ba978707197c69338bd5ae6a937d05332a4 /src/local
parentb5c7a63a3dccf0ea7490d635ee5a8d56d3d49ce1 (diff)
downloadchawan-a8f05f18fdd64485c26b453e62e8073b50e271ef.tar.gz
pager: add "open in editor" keybinding (sE)
only for source for now, rendered document is a bit more complicated

(also, get rid of useless extern/editor module)
Diffstat (limited to 'src/local')
-rw-r--r--src/local/client.nim5
-rw-r--r--src/local/container.nim6
-rw-r--r--src/local/pager.nim60
3 files changed, 62 insertions, 9 deletions
diff --git a/src/local/client.nim b/src/local/client.nim
index 07f493e6..4f7d9f2b 100644
--- a/src/local/client.nim
+++ b/src/local/client.nim
@@ -486,14 +486,15 @@ proc acceptBuffers(client: Client) =
     if item.fdin != -1:
       let outputId = item.istreamOutputId
       if container.cacheId == -1:
-        container.cacheId = loader.addCacheFile(outputId, loader.clientPid)
+        (container.cacheId, container.cacheFile) = loader.addCacheFile(outputId,
+          loader.clientPid)
       var outCacheId = container.cacheId
       let pid = container.process
       if item.fdout == item.fdin:
         loader.shareCachedItem(container.cacheId, pid)
         loader.resume(@[item.istreamOutputId])
       else:
-        outCacheId = loader.addCacheFile(item.ostreamOutputId, pid)
+        outCacheId = loader.addCacheFile(item.ostreamOutputId, pid).outputId
         loader.resume(@[item.istreamOutputId, item.ostreamOutputId])
       # pass down fdout
       container.setStream(stream, registerFun, item.fdout, outCacheId)
diff --git a/src/local/container.nim b/src/local/container.nim
index a2b78aa5..7946200a 100644
--- a/src/local/container.nim
+++ b/src/local/container.nim
@@ -145,6 +145,7 @@ type
     filter*: BufferFilter
     bgcolor*: CellColor
     tailOnLoad*: bool
+    cacheFile* {.jsget.}: string
 
 jsDestructor(Highlight)
 jsDestructor(Container)
@@ -152,7 +153,7 @@ jsDestructor(Container)
 proc newContainer*(config: BufferConfig; url: URL; request: Request;
     attrs: WindowAttributes; title: string; redirectdepth: int;
     canreinterpret: bool; contentType: Option[string];
-    charsetStack: seq[Charset]; cacheId: int): Container =
+    charsetStack: seq[Charset]; cacheId: int; cacheFile: string): Container =
   return Container(
     url: url,
     request: request,
@@ -167,7 +168,8 @@ proc newContainer*(config: BufferConfig; url: URL; request: Request;
     ),
     canreinterpret: canreinterpret,
     loadinfo: "Connecting to " & request.url.host & "...",
-    cacheId: cacheId
+    cacheId: cacheId,
+    cacheFile: cacheFile
   )
 
 func location(container: Container): URL {.jsfget.} =
diff --git a/src/local/pager.nim b/src/local/pager.nim
index de80b9b6..bf9d3168 100644
--- a/src/local/pager.nim
+++ b/src/local/pager.nim
@@ -18,7 +18,6 @@ import config/mailcap
 import config/mimetypes
 import display/lineedit
 import display/term
-import extern/editor
 import extern/runproc
 import extern/stdio
 import extern/tempfile
@@ -523,7 +522,7 @@ proc onSetLoadInfo(pager: Pager; container: Container) =
 proc newContainer(pager: Pager; bufferConfig: BufferConfig; request: Request;
     title = ""; redirectdepth = 0; canreinterpret = true;
     contentType = none(string); charsetStack: seq[Charset] = @[];
-    url: URL = request.url; cacheId = -1): Container =
+    url: URL = request.url; cacheId = -1; cacheFile = ""): Container =
   request.suspended = true
   if bufferConfig.loaderConfig.cookieJar != nil:
     # loader stores cookie jars per client, but we have no client yet.
@@ -549,7 +548,8 @@ proc newContainer(pager: Pager; bufferConfig: BufferConfig; request: Request;
     canreinterpret,
     contentType,
     charsetStack,
-    cacheId
+    cacheId,
+    cacheFile
   )
   pager.connectingContainers.add(ConnectingContainerItem(
     state: ccsBeforeResult,
@@ -568,7 +568,8 @@ proc newContainerFrom(pager: Pager; container: Container; contentType: string):
     contentType = some(contentType),
     charsetStack = container.charsetStack,
     url = container.url,
-    cacheId = container.cacheId
+    cacheId = container.cacheId,
+    cacheFile = container.cacheFile
   )
 
 func findConnectingContainer*(pager: Pager; fd: int): int =
@@ -762,6 +763,55 @@ proc toggleSource(pager: Pager) {.jsfunc.} =
       pager.container.sourcepair = container
       pager.addContainer(container)
 
+func formatEditorName(editor, file: string; line: int): string =
+  result = newStringOfCap(editor.len + file.len)
+  var i = 0
+  var filefound = false
+  while i < editor.len:
+    if editor[i] == '%' and i < editor.high:
+      if editor[i + 1] == 's':
+        result &= file
+        filefound = true
+        i += 2
+        continue
+      elif editor[i + 1] == 'd':
+        result &= $line
+        i += 2
+        continue
+      elif editor[i + 1] == '%':
+        result &= '%'
+        i += 2
+        continue
+    result &= editor[i]
+    inc i
+  if not filefound:
+    if result[^1] != ' ':
+      result &= ' '
+    result &= file
+
+func getEditorCommand(pager: Pager; file: string; line = 1): string {.jsfunc.} =
+  var editor = pager.config.external.editor
+  if editor == "":
+    editor = getEnv("EDITOR")
+    if editor == "":
+      editor = "vi %s +%d"
+  return formatEditorName(editor, file, line)
+
+proc openInEditor(pager: Pager; input: var string): bool =
+  try:
+    let tmpf = getTempFile(pager.tmpdir)
+    if input != "":
+      writeFile(tmpf, input)
+    let cmd = pager.getEditorCommand(tmpf)
+    if pager.term.runProcess(cmd):
+      if fileExists(tmpf):
+        input = readFile(tmpf)
+        removeFile(tmpf)
+        return true
+  except IOError:
+    discard
+  return false
+
 proc windowChange*(pager: Pager) =
   let oldAttrs = pager.attrs
   pager.term.windowChange()
@@ -1531,7 +1581,7 @@ proc handleEvent0(pager: Pager; container: Container; event: ContainerEvent):
   of cetReadArea:
     if container == pager.container:
       var s = event.tvalue
-      if openInEditor(pager.term, pager.config, pager.tmpdir, s):
+      if pager.openInEditor(s):
         pager.container.readSuccess(s)
       else:
         pager.container.readCanceled()