mirror of
https://github.com/vale981/tridactyl
synced 2025-03-06 01:51:40 -05:00
Document hint mode binds
This commit is contained in:
parent
f050f68740
commit
51c73d028e
2 changed files with 70 additions and 11 deletions
|
@ -1,3 +1,18 @@
|
||||||
|
/** # Hint mode functions
|
||||||
|
*
|
||||||
|
* This file contains functions to interact with hint mode.
|
||||||
|
*
|
||||||
|
* If you want to bind them to keyboard shortcuts, be sure to prefix them with "hint.". For example, if you want to bind control-[ to `reset`, use:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* bind --mode=hint <C-[> hint.reset
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Contrary to the main tridactyl help page, this one doesn't tell you whether a specific function is bound to something. For now, you'll have to make do with `:bind` and `:viewconfig`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/** ignore this line */
|
||||||
|
|
||||||
/** Hint links.
|
/** Hint links.
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
|
@ -22,10 +37,14 @@ import {
|
||||||
import { contentState } from "@src/content/state_content"
|
import { contentState } from "@src/content/state_content"
|
||||||
import * as config from "@src/lib/config"
|
import * as config from "@src/lib/config"
|
||||||
import Logger from "@src/lib/logging"
|
import Logger from "@src/lib/logging"
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
const logger = new Logger("hinting")
|
const logger = new Logger("hinting")
|
||||||
import * as keyseq from "@src/lib/keyseq"
|
import * as keyseq from "@src/lib/keyseq"
|
||||||
|
|
||||||
/** Calclate the distance between two segments. */
|
/** Calclate the distance between two segments.
|
||||||
|
* @hidden
|
||||||
|
* */
|
||||||
function distance(l1: number, r1: number, l2: number, r2: number): number {
|
function distance(l1: number, r1: number, l2: number, r2: number): number {
|
||||||
if (l1 < r2 && r1 > l2) {
|
if (l1 < r2 && r1 > l2) {
|
||||||
return 0
|
return 0
|
||||||
|
@ -34,7 +53,9 @@ function distance(l1: number, r1: number, l2: number, r2: number): number {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Simple container for the state of a single frame's hints. */
|
/** Simple container for the state of a single frame's hints.
|
||||||
|
* @hidden
|
||||||
|
* */
|
||||||
class HintState {
|
class HintState {
|
||||||
public focusedHint: Hint
|
public focusedHint: Hint
|
||||||
readonly hintHost = document.createElement("div")
|
readonly hintHost = document.createElement("div")
|
||||||
|
@ -235,9 +256,12 @@ class HintState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden*/
|
||||||
let modeState: HintState
|
let modeState: HintState
|
||||||
|
|
||||||
/** For each hintable element, add a hint */
|
/** For each hintable element, add a hint
|
||||||
|
* @hidden
|
||||||
|
* */
|
||||||
export function hintPage(
|
export function hintPage(
|
||||||
hintableElements: Element[],
|
hintableElements: Element[],
|
||||||
onSelect: HintSelectedCallback,
|
onSelect: HintSelectedCallback,
|
||||||
|
@ -313,6 +337,7 @@ export function hintPage(
|
||||||
document.documentElement.appendChild(modeState.hintHost)
|
document.documentElement.appendChild(modeState.hintHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function defaultHintBuilder() {
|
function defaultHintBuilder() {
|
||||||
switch (config.get("hintfiltermode")) {
|
switch (config.get("hintfiltermode")) {
|
||||||
case "simple":
|
case "simple":
|
||||||
|
@ -324,6 +349,7 @@ function defaultHintBuilder() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function defaultHintFilter() {
|
function defaultHintFilter() {
|
||||||
switch (config.get("hintfiltermode")) {
|
switch (config.get("hintfiltermode")) {
|
||||||
case "simple":
|
case "simple":
|
||||||
|
@ -335,6 +361,7 @@ function defaultHintFilter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function defaultHintChars() {
|
function defaultHintChars() {
|
||||||
if (config.get("hintnames") === "numeric") {
|
if (config.get("hintnames") === "numeric") {
|
||||||
return "1234567890"
|
return "1234567890"
|
||||||
|
@ -344,6 +371,7 @@ function defaultHintChars() {
|
||||||
|
|
||||||
/** An infinite stream of hints
|
/** An infinite stream of hints
|
||||||
|
|
||||||
|
@hidden
|
||||||
Earlier hints prefix later hints
|
Earlier hints prefix later hints
|
||||||
*/
|
*/
|
||||||
function* hintnames_simple(
|
function* hintnames_simple(
|
||||||
|
@ -369,6 +397,7 @@ function* hintnames_simple(
|
||||||
h + (n - h**2 - h) / h ** 2
|
h + (n - h**2 - h) / h ** 2
|
||||||
and so on, but we hardly ever see that many hints, so whatever.
|
and so on, but we hardly ever see that many hints, so whatever.
|
||||||
|
|
||||||
|
@hidden
|
||||||
*/
|
*/
|
||||||
function* hintnames_short(
|
function* hintnames_short(
|
||||||
n: number,
|
n: number,
|
||||||
|
@ -379,7 +408,9 @@ function* hintnames_short(
|
||||||
yield* islice(source, num2skip, n + num2skip)
|
yield* islice(source, num2skip, n + num2skip)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Uniform length hintnames */
|
/** Uniform length hintnames
|
||||||
|
* @hidden
|
||||||
|
* */
|
||||||
function* hintnames_uniform(
|
function* hintnames_uniform(
|
||||||
n: number,
|
n: number,
|
||||||
hintchars = defaultHintChars(),
|
hintchars = defaultHintChars(),
|
||||||
|
@ -397,13 +428,14 @@ function* hintnames_uniform(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** @hidden */
|
||||||
function* hintnames_numeric(n: number): IterableIterator<string> {
|
function* hintnames_numeric(n: number): IterableIterator<string> {
|
||||||
for (let i = 1; i <= n; i++) {
|
for (let i = 1; i <= n; i++) {
|
||||||
yield String(i)
|
yield String(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function* hintnames(
|
function* hintnames(
|
||||||
n: number,
|
n: number,
|
||||||
hintchars = defaultHintChars(),
|
hintchars = defaultHintChars(),
|
||||||
|
@ -418,9 +450,11 @@ function* hintnames(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
type HintSelectedCallback = (x: any) => any
|
type HintSelectedCallback = (x: any) => any
|
||||||
|
|
||||||
/** Place a flag by each hintworthy element */
|
/** Place a flag by each hintworthy element
|
||||||
|
@hidden */
|
||||||
class Hint {
|
class Hint {
|
||||||
public readonly flag = document.createElement("span")
|
public readonly flag = document.createElement("span")
|
||||||
public readonly rect: ClientRect = null
|
public readonly rect: ClientRect = null
|
||||||
|
@ -495,8 +529,10 @@ class Hint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
type HintBuilder = (els: Element[], onSelect: HintSelectedCallback) => void
|
type HintBuilder = (els: Element[], onSelect: HintSelectedCallback) => void
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function buildHintsSimple(els: Element[], onSelect: HintSelectedCallback) {
|
function buildHintsSimple(els: Element[], onSelect: HintSelectedCallback) {
|
||||||
const names = hintnames(els.length)
|
const names = hintnames(els.length)
|
||||||
for (const [el, name] of izip(els, names)) {
|
for (const [el, name] of izip(els, names)) {
|
||||||
|
@ -506,6 +542,7 @@ function buildHintsSimple(els: Element[], onSelect: HintSelectedCallback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function buildHintsVimperator(els: Element[], onSelect: HintSelectedCallback) {
|
function buildHintsVimperator(els: Element[], onSelect: HintSelectedCallback) {
|
||||||
const names = hintnames(els.length)
|
const names = hintnames(els.length)
|
||||||
// escape the hintchars string so that strange things don't happen
|
// escape the hintchars string so that strange things don't happen
|
||||||
|
@ -522,6 +559,7 @@ function buildHintsVimperator(els: Element[], onSelect: HintSelectedCallback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
function elementFilterableText(el: Element): string {
|
function elementFilterableText(el: Element): string {
|
||||||
const nodename = el.nodeName.toLowerCase()
|
const nodename = el.nodeName.toLowerCase()
|
||||||
let text: string
|
let text: string
|
||||||
|
@ -538,9 +576,11 @@ function elementFilterableText(el: Element): string {
|
||||||
return text.slice(0, 2048).toLowerCase() || ""
|
return text.slice(0, 2048).toLowerCase() || ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
type HintFilter = (s: string) => void
|
type HintFilter = (s: string) => void
|
||||||
|
|
||||||
/** Show only hints prefixed by fstr. Focus first match */
|
/** Show only hints prefixed by fstr. Focus first match
|
||||||
|
@hidden */
|
||||||
function filterHintsSimple(fstr) {
|
function filterHintsSimple(fstr) {
|
||||||
const active: Hint[] = []
|
const active: Hint[] = []
|
||||||
let foundMatch
|
let foundMatch
|
||||||
|
@ -569,6 +609,8 @@ function filterHintsSimple(fstr) {
|
||||||
Consider: This is a poster child for separating data and display. If they
|
Consider: This is a poster child for separating data and display. If they
|
||||||
weren't so tied here we could do a neat dynamic programming thing and just
|
weren't so tied here we could do a neat dynamic programming thing and just
|
||||||
throw the data at a reactalike.
|
throw the data at a reactalike.
|
||||||
|
|
||||||
|
@hidden
|
||||||
*/
|
*/
|
||||||
function filterHintsVimperator(fstr, reflow = false) {
|
function filterHintsVimperator(fstr, reflow = false) {
|
||||||
/** Partition a fstr into a tagged array of substrings */
|
/** Partition a fstr into a tagged array of substrings */
|
||||||
|
@ -645,7 +687,8 @@ function filterHintsVimperator(fstr, reflow = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove all hints, reset STATE.
|
/**
|
||||||
|
* Remove all hints, reset STATE.
|
||||||
**/
|
**/
|
||||||
function reset() {
|
function reset() {
|
||||||
if (modeState) {
|
if (modeState) {
|
||||||
|
@ -682,6 +725,8 @@ function pushKey(key) {
|
||||||
2. they're visible
|
2. they're visible
|
||||||
1. Within viewport
|
1. Within viewport
|
||||||
2. Not hidden by another element
|
2. Not hidden by another element
|
||||||
|
|
||||||
|
@hidden
|
||||||
*/
|
*/
|
||||||
export function hintables(selectors = DOM.HINTTAGS_selectors, withjs = false) {
|
export function hintables(selectors = DOM.HINTTAGS_selectors, withjs = false) {
|
||||||
let elems = DOM.getElemsBySelector(selectors, [])
|
let elems = DOM.getElemsBySelector(selectors, [])
|
||||||
|
@ -693,17 +738,20 @@ export function hintables(selectors = DOM.HINTTAGS_selectors, withjs = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns elements that point to a saveable resource
|
/** Returns elements that point to a saveable resource
|
||||||
|
* @hidden
|
||||||
*/
|
*/
|
||||||
export function saveableElements() {
|
export function saveableElements() {
|
||||||
return DOM.getElemsBySelector(DOM.HINTTAGS_saveable, [DOM.isVisible])
|
return DOM.getElemsBySelector(DOM.HINTTAGS_saveable, [DOM.isVisible])
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get array of images in the viewport
|
/** Get array of images in the viewport
|
||||||
|
* @hidden
|
||||||
*/
|
*/
|
||||||
export function hintableImages() {
|
export function hintableImages() {
|
||||||
return DOM.getElemsBySelector(DOM.HINTTAGS_img_selectors, [DOM.isVisible])
|
return DOM.getElemsBySelector(DOM.HINTTAGS_img_selectors, [DOM.isVisible])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
export function hintByText(match) {
|
export function hintByText(match) {
|
||||||
return DOM.getElemsBySelector(DOM.HINTTAGS_filter_by_text_selectors, [
|
return DOM.getElemsBySelector(DOM.HINTTAGS_filter_by_text_selectors, [
|
||||||
DOM.isVisible,
|
DOM.isVisible,
|
||||||
|
@ -721,6 +769,7 @@ export function hintByText(match) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Array of items that can be killed with hint kill
|
/** Array of items that can be killed with hint kill
|
||||||
|
@hidden
|
||||||
*/
|
*/
|
||||||
export function killables() {
|
export function killables() {
|
||||||
return DOM.getElemsBySelector(DOM.HINTTAGS_killable_selectors, [
|
return DOM.getElemsBySelector(DOM.HINTTAGS_killable_selectors, [
|
||||||
|
@ -728,7 +777,9 @@ export function killables() {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
/** HintPage wrapper, accepts CSS selectors to build a list of elements */
|
/** HintPage wrapper, accepts CSS selectors to build a list of elements
|
||||||
|
* @hidden
|
||||||
|
* */
|
||||||
export function pipe(
|
export function pipe(
|
||||||
selectors = DOM.HINTTAGS_selectors,
|
selectors = DOM.HINTTAGS_selectors,
|
||||||
action: HintSelectedCallback = _ => _,
|
action: HintSelectedCallback = _ => _,
|
||||||
|
@ -740,7 +791,9 @@ export function pipe(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** HintPage wrapper, accepts array of elements to hint */
|
/** HintPage wrapper, accepts array of elements to hint
|
||||||
|
* @hidden
|
||||||
|
* */
|
||||||
export function pipe_elements(
|
export function pipe_elements(
|
||||||
elements: any = DOM.elementsWithText,
|
elements: any = DOM.elementsWithText,
|
||||||
action: HintSelectedCallback = _ => _,
|
action: HintSelectedCallback = _ => _,
|
||||||
|
@ -793,6 +846,7 @@ function focusRightHint() {
|
||||||
modeState.changeFocusedHintRight()
|
modeState.changeFocusedHintRight()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
export function parser(keys: KeyboardEvent[]) {
|
export function parser(keys: KeyboardEvent[]) {
|
||||||
const keymap = {}
|
const keymap = {}
|
||||||
// Build a map of actions that will match hint names
|
// Build a map of actions that will match hint names
|
||||||
|
@ -826,6 +880,7 @@ export function parser(keys: KeyboardEvent[]) {
|
||||||
return { keys: [], isMatch: false }
|
return { keys: [], isMatch: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hidden*/
|
||||||
export function getHintCommands() {
|
export function getHintCommands() {
|
||||||
return {
|
return {
|
||||||
reset,
|
reset,
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
Tridactyl also provides a few functions to manipulate text in the command line or text areas that can be found [here](/static/docs/modules/_src_lib_editor_.html). There are also a few commands only available in the command line which can be found [here](/static/docs/modules/_src_commandline_frame_.html).
|
Tridactyl also provides a few functions to manipulate text in the command line or text areas that can be found [here](/static/docs/modules/_src_lib_editor_.html). There are also a few commands only available in the command line which can be found [here](/static/docs/modules/_src_commandline_frame_.html).
|
||||||
|
|
||||||
|
Ex-commands available exclusively in hint mode are listed [here](/static/docs/modules/_src_content_hinting_.html)
|
||||||
|
|
||||||
## How to use this help page
|
## How to use this help page
|
||||||
|
|
||||||
Every function (excmd) on this page can be called via Tridactyl's command line which we call "ex". There is a slight change in syntax, however. Wherever you see:
|
Every function (excmd) on this page can be called via Tridactyl's command line which we call "ex". There is a slight change in syntax, however. Wherever you see:
|
||||||
|
@ -3005,7 +3007,7 @@ function parse_bind_args(...args: string[]): bind_args {
|
||||||
[[fillcmdline]] to put a string in the cmdline and focus the cmdline
|
[[fillcmdline]] to put a string in the cmdline and focus the cmdline
|
||||||
(otherwise the string is executed immediately).
|
(otherwise the string is executed immediately).
|
||||||
|
|
||||||
You can bind to other modes with `bind --mode={insert|ignore|normal|input} ...`, e.g, `bind --mode=insert emacs qall` (NB: unlike vim, all preceeding characters will not be input).
|
You can bind to other modes with `bind --mode={insert|ignore|normal|input|ex|hint} ...`, e.g, `bind --mode=insert emacs qall` (NB: unlike vim, all preceeding characters will not be input), or `bind --mode=hint <C-[> hint.reset`.
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
|
@ -3567,6 +3569,8 @@ export function unset(...keys: string[]) {
|
||||||
|
|
||||||
To open a hint in the background, the default bind is `F`.
|
To open a hint in the background, the default bind is `F`.
|
||||||
|
|
||||||
|
Ex-commands available exclusively in hint mode are listed [here](/static/docs/modules/_src_content_hinting_.html)
|
||||||
|
|
||||||
Related settings:
|
Related settings:
|
||||||
- "hintchars": "hjklasdfgyuiopqwertnmzxcvb"
|
- "hintchars": "hjklasdfgyuiopqwertnmzxcvb"
|
||||||
- "hintfiltermode": "simple" | "vimperator" | "vimperator-reflow"
|
- "hintfiltermode": "simple" | "vimperator" | "vimperator-reflow"
|
||||||
|
|
Loading…
Add table
Reference in a new issue