mirror of
https://github.com/vale981/tridactyl
synced 2025-03-05 09:31:41 -05:00
Implement :goto
This command lets you jump to an arbitrary selector. It has completions that give you a list of elements you may jump to. This list defaults to heading elements but is configurable through the 'gotoselector' configuration option.
This commit is contained in:
parent
165db262ac
commit
44ee294af1
4 changed files with 118 additions and 0 deletions
|
@ -26,6 +26,7 @@ import { CompositeCompletionSource } from "@src/completions/Composite"
|
||||||
import { ExcmdCompletionSource } from "@src/completions/Excmd"
|
import { ExcmdCompletionSource } from "@src/completions/Excmd"
|
||||||
import { ExtensionsCompletionSource } from "@src/completions/Extensions"
|
import { ExtensionsCompletionSource } from "@src/completions/Extensions"
|
||||||
import { FileSystemCompletionSource } from "@src/completions/FileSystem"
|
import { FileSystemCompletionSource } from "@src/completions/FileSystem"
|
||||||
|
import { GotoCompletionSource } from "@src/completions/Goto"
|
||||||
import { GuisetCompletionSource } from "@src/completions/Guiset"
|
import { GuisetCompletionSource } from "@src/completions/Guiset"
|
||||||
import { HelpCompletionSource } from "@src/completions/Help"
|
import { HelpCompletionSource } from "@src/completions/Help"
|
||||||
import { HistoryCompletionSource } from "@src/completions/History"
|
import { HistoryCompletionSource } from "@src/completions/History"
|
||||||
|
@ -119,6 +120,7 @@ export function enableCompletions() {
|
||||||
ThemeCompletionSource,
|
ThemeCompletionSource,
|
||||||
CompositeCompletionSource,
|
CompositeCompletionSource,
|
||||||
FileSystemCompletionSource,
|
FileSystemCompletionSource,
|
||||||
|
GotoCompletionSource,
|
||||||
GuisetCompletionSource,
|
GuisetCompletionSource,
|
||||||
HelpCompletionSource,
|
HelpCompletionSource,
|
||||||
AproposCompletionSource,
|
AproposCompletionSource,
|
||||||
|
|
78
src/completions/Goto.ts
Normal file
78
src/completions/Goto.ts
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -4769,6 +4769,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.
|
* Initialize n [mode] mode.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1029,10 +1029,18 @@ export class default_config {
|
||||||
*/
|
*/
|
||||||
bmarkweight = 100
|
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.
|
* General completions options - NB: options are set according to our internal completion source name - see - `src/completions/[name].ts` in the Tridactyl source.
|
||||||
*/
|
*/
|
||||||
completions = {
|
completions = {
|
||||||
|
Goto: {
|
||||||
|
autoselect: "true",
|
||||||
|
},
|
||||||
Tab: {
|
Tab: {
|
||||||
/**
|
/**
|
||||||
* Whether to automatically select the closest matching completion
|
* Whether to automatically select the closest matching completion
|
||||||
|
|
Loading…
Add table
Reference in a new issue