Merge pull request #1480 from tridactyl/improve_editor

Improve editor
This commit is contained in:
Oliver Blanthorn 2019-04-18 12:32:14 +01:00 committed by GitHub
commit 5447f5ea23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 13 deletions

View file

@ -85,6 +85,7 @@ import * as CSS from "css"
import * as Perf from "@src/perf"
import * as Metadata from "@src/.metadata.generated"
import * as Native from "@src/lib/native"
import * as tri_editor from "@src/lib/editor"
/** @hidden **/
const TRI_VERSION = "REPLACE_ME_WITH_THE_VERSION_USING_SED"
@ -251,9 +252,9 @@ export function removeTridactylEditorClass(selector: string) {
*
* Uses the `editorcmd` config option, default = `auto` looks through a list defined in lib/native.ts try find a sensible combination. If it's a bit slow, or chooses the wrong editor, or gives up completely, set editorcmd to something you want. The command must stay in the foreground until the editor exits.
*
* The editorcmd needs to accept a filename, stay in the foreground while it's edited, save the file and exit. By default the filename is added to the end of editorcmd, if you require control over the position of that argument, the first occurrence of %f in editorcmd is replaced with the filename:
* The editorcmd needs to accept a filename, stay in the foreground while it's edited, save the file and exit. By default the filename is added to the end of editorcmd, if you require control over the position of that argument, the first occurrence of %f in editorcmd is replaced with the filename. %l, if it exists, is replaced with the line number of the cursor and %c with the column number. For example:
* ```
* set editorcmd terminator -u -e "vim %f"
* set editorcmd terminator -u -e "vim %f -c 'normal %lG%cl'"
* ```
*
* You're probably better off using the default insert mode bind of `<C-i>` (Ctrl-i) to access this.
@ -277,12 +278,23 @@ export async function editor() {
}
try {
const file = (await Native.temp(getinput(), document.location.hostname)).content
const content = (await Native.editor(file)).content
fillinput(selector, content)
let text = ""
let line = 0
let col = 0
tri_editor.wrap_input((t, start, end) => {
[text, line, col] = tri_editor.getLineAndColNumber(t, start, end)
return [null, null, null]
})(elem)
const file = (await Native.temp(text, document.location.hostname)).content
const exec = await Native.editor(file, line, col)
if (exec.code == 0) {
fillinput(selector, exec.content)
// TODO: add annoying "This message was written with [Tridactyl](https://addons.mozilla.org/en-US/firefox/addon/tridactyl-vim/)" to everything written using editor
return [file, content]
// TODO: add annoying "This message was written with [Tridactyl](https://addons.mozilla.org/en-US/firefox/addon/tridactyl-vim/)" to everything written using editor
return [file, exec.content]
} else {
logger.debug(`Editor terminated with non-zero exit code: ${exec.code}`)
}
} catch (e) {
throw `:editor failed: ${e}`
} finally {
@ -2639,8 +2651,6 @@ const cmdframe_fns: { [key: string]: [string, any[]] } = {
prev_history: ["prev_history", []],
}
import * as tri_editor from "@src/lib/editor"
//#content_helper
// {
for (const editorfn of Object.keys(tri_editor)) {

View file

@ -141,7 +141,7 @@ function setContentEditableValues(e, text, start, end) {
* @return boolean Whether the editor function was actually called or not
*
**/
function wrap_input(
export function wrap_input(
fn: editor_function,
): (e: HTMLElement, arg?: any) => boolean {
return (e: HTMLElement, arg?: any) => {
@ -183,6 +183,22 @@ function needs_text(fn: editor_function, arg?: any): editor_function {
}
}
/** @hidden
* Returns line and column number.
*/
export function getLineAndColNumber(text: string, start: number, end: number): [string, number, number] {
const lines = text.split("\n")
let totalChars = 0
for (let i = 0; i < lines.length; ++i) {
// +1 because we also need to take '\n' into account
if (totalChars + lines[i].length + 1 > start) {
return [text, i + 1, start - totalChars]
}
totalChars += lines[i].length + 1
}
return [text, lines.length, 1]
}
/** @hidden
* Detects the boundaries of a word in text according to the wordpattern setting. If POSITION is in a word, the boundaries of this word are returned. If POSITION is out of a word and BEFORE is true, the word before POSITION is returned. If BEFORE is false, the word after the caret is returned.
*/

View file

@ -242,12 +242,14 @@ export async function firstinpath(cmdarray) {
return cmd
}
export async function editor(file: string, content?: string) {
export async function editor(file: string, line: number, col: number, content?: string) {
if (content !== undefined) await write(file, content)
const editorcmd =
config.get("editorcmd") === "auto"
(config.get("editorcmd") === "auto"
? await getBestEditor()
: config.get("editorcmd")
: config.get("editorcmd"))
.replace(/%l/, line)
.replace(/%c/, col)
if (editorcmd.indexOf("%f") !== -1) {
await run(editorcmd.replace(/%f/, file))
} else {