Document ex.* functions

This commit is contained in:
glacambre 2018-11-02 06:26:24 +01:00
parent cfe5b5c597
commit def94f795d
No known key found for this signature in database
GPG key ID: B9625DB1767553AC
4 changed files with 108 additions and 21 deletions

View file

@ -1,3 +1,21 @@
/** # Command line functions
*
* This file contains functions to interact with the command line.
*
* If you want to bind them to keyboard shortcuts, be sure to prefix them with "ex.". For example, if you want to bind control-p to `prev_completion`, use:
*
* ```
* bind --mode=ex <C-p> ex.prev_completion
* ```
*
* Note that you can also bind Tridactyl's [editor functions](/static/docs/modules/_lib_editor_.html) in the command line.
*
* 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 */
/** Script used in the commandline iframe. Communicates with background. */
import * as perf from "@src/perf"
@ -23,12 +41,16 @@ import { theme } from "@src/content/styling"
import * as genericParser from "@src/parsers/genericmode"
import * as tri_editor from "@src/lib/editor"
/** @hidden **/
const logger = new Logger("cmdline")
/** @hidden **/
let activeCompletions: Completions.CompletionSource[] = undefined
/** @hidden **/
let completionsDiv = window.document.getElementById(
"completions",
) as HTMLElement
/** @hidden **/
let clInput = window.document.getElementById(
"tridactyl-input",
) as HTMLInputElement
@ -36,13 +58,15 @@ let clInput = window.document.getElementById(
// first theming of commandline iframe
theme(document.querySelector(":root"))
/* This is to handle Escape key which, while the cmdline is focused,
/** @hidden
* This is to handle Escape key which, while the cmdline is focused,
* ends up firing both keydown and input listeners. In the worst case
* hides the cmdline, shows and refocuses it and replaces its text
* which could be the prefix to generate a completion.
* tl;dr TODO: delete this and better resolve race condition
*/
let isVisible = false
/** @hidden **/
function resizeArea() {
if (isVisible) {
Messaging.messageOwnTab("commandline_content", "show")
@ -51,8 +75,10 @@ function resizeArea() {
}
}
// This is a bit loosely defined at the moment.
// Should work so long as there's only one completion source per prefix.
/** @hidden
* This is a bit loosely defined at the moment.
* Should work so long as there's only one completion source per prefix.
*/
function getCompletion() {
if (!activeCompletions) return undefined
@ -63,6 +89,7 @@ function getCompletion() {
}
}
/** @hidden **/
export function enableCompletions() {
if (!activeCompletions) {
activeCompletions = [
@ -85,23 +112,30 @@ export function enableCompletions() {
}
/* document.addEventListener("DOMContentLoaded", enableCompletions) */
/** @hidden **/
let noblur = e => setTimeout(() => clInput.focus(), 0)
/** @hidden **/
export function focus() {
clInput.focus()
clInput.addEventListener("blur", noblur)
}
/** @hidden **/
async function sendExstr(exstr) {
Messaging.message("commandline_background", "recvExStr", [exstr])
}
/** @hidden **/
let HISTORY_SEARCH_STRING: string
/* Command line keybindings */
/** @hidden
* Command line keybindings
**/
let keyParser = keys => genericParser.parser("exmaps", keys)
/** @hidden **/
let keyEvents = []
/** @hidden **/
clInput.addEventListener("keydown", function(keyevent: KeyboardEvent) {
keyEvents.push(keyevent)
let response = keyParser(keyEvents)
@ -117,16 +151,36 @@ clInput.addEventListener("keydown", function(keyevent: KeyboardEvent) {
}
}, true)
/**
* Insert the first command line history line that starts with the content of the command line in the command line.
*/
export function complete() {
let fragment = clInput.value
let matches = state.cmdHistory.filter(key => key.startsWith(fragment))
let mostrecent = matches[matches.length - 1]
if (mostrecent != undefined) clInput.value = mostrecent
}
/**
* Selects the next completion.
*/
export function next_completion() {
if (activeCompletions)
activeCompletions.forEach(comp => comp.next())
}
/**
* Selects the previous completion.
*/
export function prev_completion() {
if (activeCompletions)
activeCompletions.forEach(comp => comp.prev())
}
/**
* Inserts the currently selected completion and a space in the command line.
* If no completion option is selected, inserts a space in the command line.
*/
export function insert_completion() {
const command = getCompletion()
activeCompletions.forEach(comp => (comp.completion = undefined))
@ -135,8 +189,11 @@ export function insert_completion() {
clInput.dispatchEvent(new Event("input")) // dirty hack for completions
}
/** @hidden **/
let timeoutId: any = 0
/** @hidden **/
let onInputPromise: Promise<any> = Promise.resolve()
/** @hidden **/
clInput.addEventListener("input", () => {
const exstr = clInput.value
// Prevent starting previous completion computation if possible
@ -164,11 +221,14 @@ clInput.addEventListener("input", () => {
timeoutId = myTimeoutId
})
/** @hidden **/
let cmdline_history_position = 0
/** @hidden **/
let cmdline_history_current = ""
/** Clears the command line.
* If you intend to close the command line after this, set evlistener to true in order to enable losing focus.
/** @hidden
* Clears the command line.
* If you intend to close the command line after this, set evlistener to true in order to enable losing focus.
* Otherwise, no need to pass an argument.
*/
export function clear(evlistener = false) {
@ -178,6 +238,7 @@ export function clear(evlistener = false) {
cmdline_history_current = ""
}
/** Hide the command line and clear its content without executing it. **/
export async function hide_and_clear() {
clear(true)
keyEvents = []
@ -193,11 +254,27 @@ export async function hide_and_clear() {
isVisible = false
}
/** @hidden **/
function setCursor(n = 0) {
clInput.setSelectionRange(n, n, "none")
}
export function history(n) {
/**
* Selects the next history line.
*/
export function next_history() {
return history(1)
}
/**
* Selects the prev history line.
*/
export function prev_history() {
return history(-1)
}
/** @hidden **/
function history(n) {
HISTORY_SEARCH_STRING =
HISTORY_SEARCH_STRING === undefined
? clInput.value
@ -221,8 +298,10 @@ export function history(n) {
cmdline_history_position = cmdline_history_position - n
}
/* Send the commandline to the background script and await response. */
export function process() {
/**
* Execute the content of the command line and hide it.
**/
export function accept_line() {
const command = getCompletion() || clInput.value
hide_and_clear()
@ -245,6 +324,7 @@ export function process() {
sendExstr(command)
}
/** @hidden **/
export function fillcmdline(
newcommand?: string,
trailspace = true,
@ -260,10 +340,11 @@ export function fillcmdline(
}
}
/** Create a temporary textarea and give it to fn. Remove the textarea afterwards
Useful for document.execCommand
*/
/** @hidden
* Create a temporary textarea and give it to fn. Remove the textarea afterwards
*
* Useful for document.execCommand
**/
function applyWithTmpTextArea(fn) {
let textarea
try {
@ -280,6 +361,7 @@ function applyWithTmpTextArea(fn) {
}
}
/** @hidden **/
export async function setClipboard(content: string) {
applyWithTmpTextArea(scratchpad => {
scratchpad.value = content
@ -294,6 +376,7 @@ export async function setClipboard(content: string) {
Messaging.messageOwnTab("commandline_content", "blur")
}
/** @hidden **/
export function getClipboard() {
const result = applyWithTmpTextArea(scratchpad => {
scratchpad.focus()
@ -306,10 +389,12 @@ export function getClipboard() {
return result
}
/** @hidden **/
export function getContent() {
return clInput.value
}
/** @hidden **/
export function editor_function(fn_name) {
if (tri_editor[fn_name]) {
tri_editor[fn_name](clInput)

View file

@ -6,7 +6,7 @@
The default keybinds and settings can be found [here](/static/docs/classes/_lib_config_.default_config.html) and active binds can be seen with `:viewconfig nmaps` or with [[bind]].
Tridactyl also provides a few functions to manipulate text in the command line or text areas that can be found [here](/static/docs/modules/_lib_editor_.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/_lib_editor_.html). There are also a few commands only available in the command line which can be found [here](/static/docs/modules/_commandline_frame_.html).
## How to use this help page
@ -2375,13 +2375,13 @@ export async function fillcmdline_tmp(ms: number, ...strarr: string[]) {
/** @hidden **/
const cmdframe_fns: {[key:string]: [string, any[]]} = {
"accept_line": ["process", []],
"previous_history": ["history", [-1]],
"next_history": ["history", [1]],
"accept_line": ["accept_line", []],
"next_history": ["next_history", []],
"prev_history": ["prev_history", []],
"next_completion": ["next_completion", []],
"prev_completion": ["prev_completion", []],
"insert_completion": ["insert_completion", []],
"complete": ["tabcomplete", []],
"complete": ["complete", []],
"hide_and_clear": ["hide_and_clear", []],
}

View file

@ -75,14 +75,14 @@ class default_config {
"<C-j>": "ex.accept_line",
"<C-m>": "ex.accept_line",
"<Escape>": "ex.hide_and_clear",
"<ArrowUp>": "ex.previous_history",
"<ArrowUp>": "ex.prev_history",
"<ArrowDown>": "ex.next_history",
"<C-a>": "text.beginning_of_line",
"<C-e>": "text.end_of_line",
"<C-u>": "text.backward_kill_line",
"<C-k>": "text.kill_line",
"<C-c>": "text.kill_whole_line",
"<C-f>": "text.complete",
"<C-f>": "ex.complete",
"<Tab>": "ex.next_completion",
"<S-Tab>": "ex.prev_completion",
"<Space>": "ex.insert_completion",

View file

@ -13,6 +13,8 @@
*
* Also keep in mind that if you want to bind something in insert mode, you'll probably also want to bind it in input mode (insert mode is entered by clicking on text areas while input mode is entered by using `gi`).
*
* If you're looking for command-line only functions, go [there](/static/docs/modules/_commandline_frame_.html).
*
* 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 with `:bind` and `:viewconfig`.
*
*/