mirror of
https://github.com/vale981/tridactyl
synced 2025-03-05 17:41:40 -05:00
Add completions for key bindings
This commit is contained in:
parent
d66db550c6
commit
37b8b99999
2 changed files with 154 additions and 0 deletions
|
@ -21,6 +21,7 @@ import * as perf from "@src/perf"
|
|||
import "@src/lib/number.clamp"
|
||||
import "@src/lib/html-tagged-template"
|
||||
import { TabAllCompletionSource } from "@src/completions/TabAll"
|
||||
import { BindingsCompletionSource } from "@src/completions/Bindings"
|
||||
import { BufferCompletionSource } from "@src/completions/Tab"
|
||||
import { BmarkCompletionSource } from "@src/completions/Bmark"
|
||||
import { ExcmdCompletionSource } from "@src/completions/Excmd"
|
||||
|
@ -102,6 +103,7 @@ export function enableCompletions() {
|
|||
if (!commandline_state.activeCompletions) {
|
||||
commandline_state.activeCompletions = [
|
||||
// FindCompletionSource,
|
||||
BindingsCompletionSource,
|
||||
BmarkCompletionSource,
|
||||
TabAllCompletionSource,
|
||||
BufferCompletionSource,
|
||||
|
|
152
src/completions/Bindings.ts
Normal file
152
src/completions/Bindings.ts
Normal file
|
@ -0,0 +1,152 @@
|
|||
import * as Completions from "@src/completions"
|
||||
import * as config from "@src/lib/config"
|
||||
|
||||
class BindingsCompletionOption extends Completions.CompletionOptionHTML
|
||||
implements Completions.CompletionOptionFuse {
|
||||
public fuseKeys = []
|
||||
|
||||
constructor(
|
||||
public value: string,
|
||||
binding: { name: string; value: string; mode: string },
|
||||
) {
|
||||
super()
|
||||
this.html = html`<tr class="BindingsCompletionOption option">
|
||||
<td class="name">${binding.name}</td>
|
||||
<td class="content">${binding.value}</td>
|
||||
<td class="type">${binding.mode}</td>
|
||||
</tr>`
|
||||
}
|
||||
}
|
||||
|
||||
export class BindingsCompletionSource extends Completions.CompletionSourceFuse {
|
||||
public options: BindingsCompletionOption[]
|
||||
|
||||
constructor(private _parent) {
|
||||
super(
|
||||
["bind", "unbind", "bindurl", "unbindurl", "reset", "reseturl"],
|
||||
"BindingsCompletionSource",
|
||||
"Bindings",
|
||||
)
|
||||
|
||||
this._parent.appendChild(this.node)
|
||||
}
|
||||
|
||||
public async filter(exstr: string) {
|
||||
this.lastExstr = exstr
|
||||
let options = ""
|
||||
let [prefix, query] = this.splitOnPrefix(exstr)
|
||||
const args = query ? query.split(/\s+/) : []
|
||||
let configName: string = "nmaps"
|
||||
let modeName = "normal"
|
||||
let urlPattern: string = null
|
||||
|
||||
// Hide self and stop if prefixes don't match
|
||||
if (prefix) {
|
||||
// Show self if prefix and currently hidden
|
||||
if (this.state === "hidden") {
|
||||
this.state = "normal"
|
||||
}
|
||||
} else {
|
||||
this.state = "hidden"
|
||||
return
|
||||
}
|
||||
|
||||
// url pattern is mandatory: bindurl, unbindurl, reseturl
|
||||
if (prefix.trim().endsWith("url")) {
|
||||
urlPattern = args.length > 0 ? args.shift() : ""
|
||||
options += urlPattern ? urlPattern + " " : ""
|
||||
|
||||
if (args.length === 0) {
|
||||
const patterns = config.get("subconfigs")
|
||||
this.options = Object.keys(patterns)
|
||||
.filter(pattern => pattern.startsWith(urlPattern))
|
||||
.sort()
|
||||
.map(pattern => {
|
||||
return new BindingsCompletionOption(
|
||||
pattern, {
|
||||
name: pattern,
|
||||
value: "",
|
||||
mode: "URL Pattern",
|
||||
})
|
||||
})
|
||||
|
||||
return this.updateChain()
|
||||
}
|
||||
}
|
||||
|
||||
const mode2maps = new Map([
|
||||
["normal", "nmaps"], ["ignore", "ignoremaps"],
|
||||
["insert", "imaps"], ["input", "inputmaps"], ["ex", "exmaps"],
|
||||
["hint", "hintmaps"], ["visual", "vmaps"]])
|
||||
const maps2mode = new Map(
|
||||
Array.from(mode2maps.keys()).map(k => [mode2maps.get(k), k]))
|
||||
|
||||
// completion maps mode
|
||||
if (args.length === 1 && args[0].startsWith("--m")) {
|
||||
const margs = args[0].split("=")
|
||||
if ("--mode".includes(margs[0])) {
|
||||
const modeStr = margs.length > 1 ? margs[1] : ""
|
||||
this.options = Array.from(mode2maps.keys())
|
||||
.filter(k => k.startsWith(modeStr))
|
||||
.map(name => {
|
||||
return new BindingsCompletionOption(
|
||||
options + "--mode=" + name, {
|
||||
name,
|
||||
value: "",
|
||||
mode: "Mode Name",
|
||||
})
|
||||
})
|
||||
return this.updateChain()
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length > 0 && args[0].startsWith("--mode=")) {
|
||||
const modeStr = args.shift()
|
||||
const mode = modeStr.replace("--mode=", "")
|
||||
|
||||
modeName = mode
|
||||
if (maps2mode.has(mode + "maps")) {
|
||||
modeName = maps2mode.get(mode + "maps")
|
||||
}
|
||||
configName = mode2maps.get(modeName)
|
||||
options += `--mode=${modeName} `
|
||||
}
|
||||
|
||||
if (!configName) {
|
||||
this.options = []
|
||||
return this.updateChain()
|
||||
}
|
||||
|
||||
const bindings = urlPattern ? config.getURL(urlPattern, [configName]) : config.get(configName as any)
|
||||
|
||||
if (bindings === undefined) {
|
||||
this.options = []
|
||||
return this.updateChain()
|
||||
}
|
||||
|
||||
query = args.join(" ").toLowerCase()
|
||||
this.options = Object.keys(bindings)
|
||||
.filter(x => x.toLowerCase().startsWith(query) )
|
||||
.sort()
|
||||
.map(keystr => {
|
||||
return new BindingsCompletionOption(
|
||||
options + keystr + " " + bindings[keystr], {
|
||||
name: keystr,
|
||||
value: JSON.stringify(bindings[keystr]),
|
||||
mode: `${configName} (${modeName})`,
|
||||
})
|
||||
})
|
||||
|
||||
return this.updateChain()
|
||||
}
|
||||
|
||||
updateChain() {
|
||||
// Options are pre-trimmed to the right length.
|
||||
this.options.forEach(option => (option.state = "normal"))
|
||||
|
||||
// Call concrete class
|
||||
return this.updateDisplay()
|
||||
}
|
||||
|
||||
onInput() {}
|
||||
}
|
Loading…
Add table
Reference in a new issue