diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-14 20:41:08 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-14 20:41:57 +0100 |
commit | a8f05f18fdd64485c26b453e62e8073b50e271ef (patch) | |
tree | 855b2ba978707197c69338bd5ae6a937d05332a4 /src | |
parent | b5c7a63a3dccf0ea7490d635ee5a8d56d3d49ce1 (diff) | |
download | chawan-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')
-rw-r--r-- | src/extern/editor.nim | 57 | ||||
-rw-r--r-- | src/loader/loader.nim | 28 | ||||
-rw-r--r-- | src/local/client.nim | 5 | ||||
-rw-r--r-- | src/local/container.nim | 6 | ||||
-rw-r--r-- | src/local/pager.nim | 60 |
5 files changed, 80 insertions, 76 deletions
diff --git a/src/extern/editor.nim b/src/extern/editor.nim deleted file mode 100644 index f0abd4a9..00000000 --- a/src/extern/editor.nim +++ /dev/null @@ -1,57 +0,0 @@ -import std/os - -import config/config -import display/term -import extern/runproc -import extern/tempfile - -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 - -proc openEditor*(term: Terminal, config: Config, file: string, line = 1): bool = - var editor = config.external.editor - if editor == "": - editor = getEnv("EDITOR") - if editor == "": - editor = "vi %s +%d" - let cmd = formatEditorName(editor, file, line) - return runProcess(term, cmd) - -proc openInEditor*(term: Terminal, config: Config, tmpdir: string, - input: var string): bool = - try: - let tmpf = getTempFile(tmpdir) - if input != "": - writeFile(tmpf, input) - if openEditor(term, config, tmpf): - if fileExists(tmpf): - input = readFile(tmpf) - removeFile(tmpf) - return true - else: - return false - except IOError: - discard diff --git a/src/loader/loader.nim b/src/loader/loader.nim index 83212444..b1bcce38 100644 --- a/src/loader/loader.nim +++ b/src/loader/loader.nim @@ -201,25 +201,27 @@ proc getOutputId(ctx: LoaderContext): int = result = ctx.outputNum inc ctx.outputNum +type AddCacheFileResult = tuple[outputId: int; cacheFile: string] + proc addCacheFile(ctx: LoaderContext; client: ClientData; output: OutputHandle): - int = + AddCacheFileResult = if output.parent != nil and output.parent.cacheId != -1: # may happen e.g. if client tries to cache a `cache:' URL - return output.parent.cacheId + return (output.parent.cacheId, "") #TODO can we get the file name somehow? let tmpf = getTempFile(ctx.config.tmpdir) let ps = newPosixStream(tmpf, O_CREAT or O_WRONLY, 0o600) if unlikely(ps == nil): - return -1 + return (-1, "") if output.currentBuffer != nil: let n = ps.sendData(output.currentBuffer, output.currentBufferIdx) if unlikely(n < output.currentBuffer.len - output.currentBufferIdx): ps.close() - return -1 + return (-1, "") for buffer in output.buffers: let n = ps.sendData(buffer) if unlikely(n < buffer.len): ps.close() - return -1 + return (-1, "") let cacheId = output.outputId if output.parent != nil: output.parent.cacheId = cacheId @@ -230,7 +232,7 @@ proc addCacheFile(ctx: LoaderContext; client: ClientData; output: OutputHandle): outputId: ctx.getOutputId() )) client.cacheMap.add(CachedItem(id: cacheId, path: tmpf, refc: 1)) - return cacheId + return (cacheId, tmpf) proc addFd(ctx: LoaderContext; handle: LoaderHandle) = let output = handle.output @@ -485,8 +487,9 @@ proc addCacheFile(ctx: LoaderContext; stream: SocketStream) = let output = ctx.findOutput(outputId) assert output != nil let targetClient = ctx.clientData[targetPid] - let id = ctx.addCacheFile(targetClient, output) + let (id, file) = ctx.addCacheFile(targetClient, output) stream.swrite(id) + stream.swrite(file) stream.close() proc shareCachedItem(ctx: LoaderContext; stream: SocketStream) = @@ -857,14 +860,19 @@ proc tee*(loader: FileLoader; sourceId, targetPid: int): (SocketStream, int) = stream.sread(outputId) return (stream, outputId) -proc addCacheFile*(loader: FileLoader; outputId, targetPid: int): int = +proc addCacheFile*(loader: FileLoader; outputId, targetPid: int): + AddCacheFileResult = let stream = loader.connect() if stream == nil: - return -1 + return (-1, "") stream.swrite(lcAddCacheFile) stream.swrite(outputId) stream.swrite(targetPid) - stream.sread(result) + var outputId: int + var cacheFile: string + stream.sread(outputId) + stream.sread(cacheFile) + return (outputId, cacheFile) const BufferSize = 4096 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() |