Merge pull request #4116 from tridactyl/implement_goto

implement goto
This commit is contained in:
Oliver Blanthorn 2022-02-24 13:31:15 +00:00 committed by GitHub
commit e4b1dab9e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 0 deletions

View file

@ -26,6 +26,7 @@ import { CompositeCompletionSource } from "@src/completions/Composite"
import { ExcmdCompletionSource } from "@src/completions/Excmd"
import { ExtensionsCompletionSource } from "@src/completions/Extensions"
import { FileSystemCompletionSource } from "@src/completions/FileSystem"
import { GotoCompletionSource } from "@src/completions/Goto"
import { GuisetCompletionSource } from "@src/completions/Guiset"
import { HelpCompletionSource } from "@src/completions/Help"
import { HistoryCompletionSource } from "@src/completions/History"
@ -119,6 +120,7 @@ export function enableCompletions() {
ThemeCompletionSource,
CompositeCompletionSource,
FileSystemCompletionSource,
GotoCompletionSource,
GuisetCompletionSource,
HelpCompletionSource,
AproposCompletionSource,

78
src/completions/Goto.ts Normal file
View file

@ -0,0 +1,78 @@
import * as Messaging from "@src/lib/messaging"
import * as Completions from "@src/completions"
import * as config from "@src/lib/config"
class GotoCompletionOption
extends Completions.CompletionOptionHTML
implements Completions.CompletionOptionFuse {
public fuseKeys = []
constructor(public level, public y, public title, public value) {
super()
this.fuseKeys.push(title)
this.html = html`<tr class="GotoCompletionOption option">
<td class="title" style="padding-left: ${level * 4}ch">${title}</td>
</tr>`
}
}
export class GotoCompletionSource extends Completions.CompletionSourceFuse {
public options: GotoCompletionOption[] = []
private shouldSetStateFromScore = true
constructor(private _parent) {
super(["goto"], "GotoCompletionSource", "Headings")
this.updateOptions()
this.shouldSetStateFromScore =
config.get("completions", "Goto", "autoselect") === "true"
this._parent.appendChild(this.node)
}
setStateFromScore(scoredOpts: Completions.ScoredOption[]) {
super.setStateFromScore(scoredOpts, this.shouldSetStateFromScore)
}
onInput(...whatever) {
return this.updateOptions(...whatever)
}
private async updateOptions(exstr = "") {
this.lastExstr = exstr
const [prefix] = this.splitOnPrefix(exstr)
// 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
}
if (this.options.length < 1) {
this.options = (
await Messaging.messageOwnTab(
"excmd_content",
"getGotoSelectors",
[],
)
)
.sort((a, b) => a.y - b.y)
.map(heading => {
const opt = new GotoCompletionOption(
heading.level,
heading.y,
heading.title,
heading.selector,
)
opt.state = "normal"
return opt
})
}
return this.updateChain()
}
}

View file

@ -4782,6 +4782,36 @@ export async function gobble(nChars: number, endCmd: string) {
// }}}
/** @hidden
* This function is used by goto completions.
*/
//#content
export async function getGotoSelectors(): Promise<Array<{ level: number; y: number; title: string; selector: string }>> {
const result = []
let level = 1
for (const selector of config.get("gotoselector").split(",")) {
result.push(
...(Array.from(document.querySelectorAll(selector)) as HTMLElement[])
.filter(e => e.innerText)
.map(e => ({ level, y: e.getClientRects()[0]?.y, title: e.innerText, selector: DOM.getSelector(e) }))
.filter(e => e.y !== undefined),
)
level += 1
}
return result
}
/**
* Jump to selector.
*/
//#content
export async function goto(...selector: string[]) {
const element = document.querySelector(selector.join(" "))
if (element) {
element.scrollIntoView()
}
}
/**
* Initialize n [mode] mode.
*

View file

@ -1029,10 +1029,18 @@ export class default_config {
*/
bmarkweight = 100
/**
* Default selector for :goto command.
*/
gotoselector = "h1, h2, h3, h4, h5, h6"
/**
* General completions options - NB: options are set according to our internal completion source name - see - `src/completions/[name].ts` in the Tridactyl source.
*/
completions = {
Goto: {
autoselect: "true",
},
Tab: {
/**
* Whether to automatically select the closest matching completion