From 698fc6ad368fcca6a75bdfeda95fc5ce06771ed6 Mon Sep 17 00:00:00 2001 From: glacambre Date: Thu, 11 Oct 2018 16:55:01 +0200 Subject: [PATCH] Add FileSystem completion --- native/native_main.py | 12 ++++- src/background/native_background.ts | 14 ++++-- src/commandline_frame.ts | 2 + src/completions/FileSystem.ts | 73 +++++++++++++++++++++++++++++ src/lib/messaging.ts | 1 + 5 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 src/completions/FileSystem.ts diff --git a/native/native_main.py b/native/native_main.py index cf14ded8..5a9b17e1 100755 --- a/native/native_main.py +++ b/native/native_main.py @@ -14,7 +14,7 @@ import time import unicodedata DEBUG = False -VERSION = "0.1.9" +VERSION = "0.1.10" class NoConnectionError(Exception): @@ -488,6 +488,16 @@ def handleMessage(message): elif cmd == "win_firefox_restart": reply = win_firefox_restart(message) + elif cmd == "list_dir": + path = os.path.expanduser(message.get("path")) + reply["sep"] = os.sep + reply["isDir"] = os.path.isdir(path) + if not reply["isDir"]: + path = os.path.dirname(path) + if not path: + path = "./" + reply["files"] = os.listdir(path) + else: reply = {"cmd": "error", "error": "Unhandled message"} eprint("Unhandled message: {}".format(message)) diff --git a/src/background/native_background.ts b/src/background/native_background.ts index 9d1775bd..9b04cb59 100644 --- a/src/background/native_background.ts +++ b/src/background/native_background.ts @@ -2,6 +2,7 @@ * Background functions for the native messenger interface */ +import * as Messaging from "@src/lib/messaging" import * as semverCompare from "semver-compare" import * as config from "@src/lib/config" import { browserBg } from "@src/lib/webext" @@ -16,6 +17,7 @@ type MessageCommand = | "read" | "write" | "temp" + | "list_dir" | "mkdir" | "move" | "eval" @@ -54,11 +56,10 @@ async function sendNativeMsg( } } -export async function getrcpath(): Promise { +export async function getrcpath(): Promise { const res = await sendNativeMsg("getconfigpath", {}) - if (res.code != 0) - throw new Error("getrcpath error: " + res.code) + if (res.code != 0) throw new Error("getrcpath error: " + res.code) return res.content } @@ -260,6 +261,10 @@ export async function move(from: string, to: string) { return sendNativeMsg("move", { from, to }) } +export async function listDir(dir: string) { + return sendNativeMsg("list_dir", { path: dir }) +} + export async function winFirefoxRestart( profiledir: string, browsercmd: string, @@ -582,3 +587,6 @@ export async function writePref(name: string, value: any) { write(file, text.replace(substr, `pref("${name}", ${value})`)) } } + +import * as SELF from "@src/background/native_background" +Messaging.addListener("native_background", Messaging.attributeCaller(SELF)) diff --git a/src/commandline_frame.ts b/src/commandline_frame.ts index b52de358..2b35869c 100644 --- a/src/commandline_frame.ts +++ b/src/commandline_frame.ts @@ -8,6 +8,7 @@ import { BufferAllCompletionSource } from "@src/completions/BufferAll" import { BufferCompletionSource } from "@src/completions/Buffer" import { BmarkCompletionSource } from "@src/completions/Bmark" import { ExcmdCompletionSource } from "@src/completions/Excmd" +import { FileSystemCompletionSource } from "@src/completions/FileSystem" import { HelpCompletionSource } from "@src/completions/Help" import { HistoryCompletionSource } from "@src/completions/History" import { SettingsCompletionSource } from "@src/completions/Settings" @@ -66,6 +67,7 @@ function enableCompletions() { new BufferAllCompletionSource(completionsDiv), new BufferCompletionSource(completionsDiv), new ExcmdCompletionSource(completionsDiv), + new FileSystemCompletionSource(completionsDiv), new HelpCompletionSource(completionsDiv), new HistoryCompletionSource(completionsDiv), new SettingsCompletionSource(completionsDiv), diff --git a/src/completions/FileSystem.ts b/src/completions/FileSystem.ts new file mode 100644 index 00000000..e8b6b417 --- /dev/null +++ b/src/completions/FileSystem.ts @@ -0,0 +1,73 @@ +import * as Completions from "@src/completions" +import * as Messaging from "@src/lib/messaging" +import * as config from "@src/lib/config" + +class FileSystemCompletionOption extends Completions.CompletionOptionHTML + implements Completions.CompletionOptionFuse { + public fuseKeys = [] + + constructor(public value: string) { + super() + this.fuseKeys = [value] + this.html = html` + ${value} + ` + } +} + +export class FileSystemCompletionSource extends Completions.CompletionSourceFuse { + public options: FileSystemCompletionOption[] + + constructor(private _parent) { + super(["saveas"], "FileSystemCompletionSource", "FileSystem") + + this._parent.appendChild(this.node) + } + + public async onInput(exstr) { + this.filter(exstr) + } + + public async filter(exstr: string) { + if (!exstr || exstr.indexOf(" ") == -1) { + this.state = "hidden" + return + } + + let [cmd, path] = this.splitOnPrefix(exstr) + if (!path) path = "." + + if (!["/", "$", "~", "."].find(s => path.startsWith(s))) { + // If the path doesn't start with a special character, it is relative to the native messenger, thus use "." as starting point + // Does this work on windows? + path = "./" + path + } + + // Update lastExstr because we modified the path and scoreOptions uses that in order to assign scores + this.lastExstr = cmd + path + + let req + try { + req = await Messaging.message("native_background", "listDir", [ + path, + ]) + } catch (e) { + // Failing silently because we can't nativegate (the user is typing stuff in the commandline) + this.state = "hidden" + return + } + + if (req.isDir) { + if (!path.endsWith(req.sep)) path += req.sep + } else { + path = path.substring(0, path.lastIndexOf("/") + 1) + } + + this.options = req.files.map( + p => new FileSystemCompletionOption(path + p), + ) + + this.state = "normal" + this.updateChain() + } +} diff --git a/src/lib/messaging.ts b/src/lib/messaging.ts index 9e96ef88..98b4bbb6 100644 --- a/src/lib/messaging.ts +++ b/src/lib/messaging.ts @@ -11,6 +11,7 @@ export type NonTabMessageType = | "commandline_background" | "controller_background" | "browser_proxy_background" + | "native_background" | "download_background" | "performance_background" export type MessageType = TabMessageType | NonTabMessageType