From cbe0af277ee92927bde82b949c93698a7198bc0b Mon Sep 17 00:00:00 2001 From: Max Anstie Date: Sun, 26 Nov 2023 19:02:58 +0800 Subject: [PATCH 1/4] feat: add hotkeys for deleting words --- src/editor-model/commands-delete.ts | 14 +++----------- src/editor-model/commands.ts | 17 ++++++++++++++--- src/editor/keybindings-definitions.ts | 6 +++--- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/editor-model/commands-delete.ts b/src/editor-model/commands-delete.ts index da8db82ce..1f3b318a8 100644 --- a/src/editor-model/commands-delete.ts +++ b/src/editor-model/commands-delete.ts @@ -1,7 +1,7 @@ import { register } from '../editor/commands'; import type { ModelPrivate } from './model-private'; import { deleteForward, deleteBackward, deleteRange } from './delete'; -import { wordBoundaryOffset } from './commands'; +import { skip } from './commands'; register( { @@ -12,18 +12,10 @@ register( deleteBackward: (model: ModelPrivate): boolean => deleteBackward(model), deleteNextWord: (model: ModelPrivate): boolean => model.contentWillChange({ inputType: 'deleteWordForward' }) && - deleteRange( - model, - [model.anchor, wordBoundaryOffset(model, model.position, 'forward')], - 'deleteWordForward' - ), + skip(model, 'forward', { delete: true }), deletePreviousWord: (model: ModelPrivate): boolean => model.contentWillChange({ inputType: 'deleteWordBackward' }) && - deleteRange( - model, - [model.anchor, wordBoundaryOffset(model, model.position, 'backward')], - 'deleteWordBackward' - ), + skip(model, 'backward', { delete: true }), deleteToGroupStart: (model: ModelPrivate): boolean => model.contentWillChange({ inputType: 'deleteSoftLineBackward' }) && deleteRange( diff --git a/src/editor-model/commands.ts b/src/editor-model/commands.ts index b10fe0822..ae4e30e57 100644 --- a/src/editor-model/commands.ts +++ b/src/editor-model/commands.ts @@ -8,6 +8,7 @@ import { LETTER_AND_DIGITS } from '../core-definitions/definitions-utils'; import type { Offset, Selection } from '../public/mathfield'; import { getCommandSuggestionRange } from '../editor-mathfield/mode-editor-latex'; import { PromptAtom } from '../core-atoms/prompt'; +import { deleteRange } from './delete'; /* * Calculates the offset of the "next word". @@ -115,12 +116,13 @@ export function wordBoundaryOffset( * than the current focus. * If `extend` is true, the selection will be extended. Otherwise, it is * collapsed, then moved. + * If `delete` is true, the skipped range is removed. * @todo array */ export function skip( model: ModelPrivate, direction: 'forward' | 'backward', - options?: { extend: boolean } + options?: { extend?: boolean; delete?: boolean } ): boolean { const previousPosition = model.position; @@ -273,16 +275,25 @@ export function skip( model.announce('plonk'); return false; } + model.announce('move', previousPosition); } else { if (offset === model.position) { model.announce('plonk'); return false; } - model.position = offset; + if (options?.delete ?? false) { + deleteRange( + model, + [previousPosition, offset], + direction === 'forward' ? 'deleteWordForward' : 'deleteWordBackward' + ); + } else { + model.position = offset; + model.announce('move', previousPosition); + } } - model.announce('move', previousPosition); model.mathfield.stopCoalescingUndo(); return true; } diff --git a/src/editor/keybindings-definitions.ts b/src/editor/keybindings-definitions.ts index d966b2d55..8d2afade9 100644 --- a/src/editor/keybindings-definitions.ts +++ b/src/editor/keybindings-definitions.ts @@ -13,10 +13,10 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [ { key: 'shift+[ArrowDown]', command: 'extendSelectionDownward' }, { key: '[Backspace]', command: 'deleteBackward' }, - { key: 'alt+[Delete]', command: 'deleteBackward' }, - { key: '[Delete]', command: 'deleteForward' }, - { key: 'alt+[Backspace]', command: 'deleteForward' }, + + { key: 'alt+[Backspace]', command: 'deletePreviousWord' }, + { key: 'alt+[Delete]', command: 'deleteNextWord' }, { key: 'alt+[ArrowLeft]', command: 'moveToPreviousWord' }, { key: 'alt+[ArrowRight]', command: 'moveToNextWord' }, From ee969b8b281f0808afb7cc869de77b5432dbc35e Mon Sep 17 00:00:00 2001 From: Max Anstie Date: Sun, 26 Nov 2023 19:41:45 +0800 Subject: [PATCH 2/4] feat: add hotkeys for deleting groups, alter removeRow hotkey --- src/editor-model/commands-delete.ts | 45 ++++++++++++++++++--------- src/editor/keybindings-definitions.ts | 18 +++++------ 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/editor-model/commands-delete.ts b/src/editor-model/commands-delete.ts index 1f3b318a8..8612904cc 100644 --- a/src/editor-model/commands-delete.ts +++ b/src/editor-model/commands-delete.ts @@ -16,20 +16,37 @@ register( deletePreviousWord: (model: ModelPrivate): boolean => model.contentWillChange({ inputType: 'deleteWordBackward' }) && skip(model, 'backward', { delete: true }), - deleteToGroupStart: (model: ModelPrivate): boolean => - model.contentWillChange({ inputType: 'deleteSoftLineBackward' }) && - deleteRange( - model, - [model.anchor, model.offsetOf(model.at(model.position).firstSibling)], - 'deleteSoftLineBackward' - ), - deleteToGroupEnd: (model: ModelPrivate): boolean => - model.contentWillChange({ inputType: 'deleteSoftLineForward' }) && - deleteRange( - model, - [model.anchor, model.offsetOf(model.at(model.position).lastSibling)], - 'deleteSoftLineForward' - ), + deleteToGroupStart: (model: ModelPrivate): boolean => { + if (!model.contentWillChange({ inputType: 'deleteSoftLineBackward' })) + return false; + const pos = model.offsetOf(model.at(model.position).firstSibling); + if (pos === model.position) { + model.announce('plonk'); + return false; + } + + model.deferNotifications( + { content: true, selection: true, type: 'deleteSoftLineBackward' }, + () => model.deleteAtoms([model.anchor, pos]) + ); + model.position = pos; + return true; + }, + deleteToGroupEnd: (model: ModelPrivate): boolean => { + if (!model.contentWillChange({ inputType: 'deleteSoftLineForward' })) + return false; + const pos = model.offsetOf(model.at(model.position).lastSibling); + if (pos === model.position) { + model.announce('plonk'); + return false; + } + + model.deferNotifications( + { content: true, selection: true, type: 'deleteSoftLineForward' }, + () => model.deleteAtoms([model.anchor, pos]) + ); + return true; + }, deleteToMathFieldStart: (model: ModelPrivate): boolean => model.contentWillChange({ inputType: 'deleteHardLineBackward' }) && deleteRange(model, [model.anchor, 0], 'deleteHardLineBackward'), diff --git a/src/editor/keybindings-definitions.ts b/src/editor/keybindings-definitions.ts index 8d2afade9..7c517a7ec 100644 --- a/src/editor/keybindings-definitions.ts +++ b/src/editor/keybindings-definitions.ts @@ -18,6 +18,9 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [ { key: 'alt+[Backspace]', command: 'deletePreviousWord' }, { key: 'alt+[Delete]', command: 'deleteNextWord' }, + { key: 'ctrl+[Backspace]', command: 'deleteToGroupStart' }, + { key: 'ctrl+[Delete]', command: 'deleteToGroupEnd' }, + { key: 'alt+[ArrowLeft]', command: 'moveToPreviousWord' }, { key: 'alt+[ArrowRight]', command: 'moveToNextWord' }, @@ -330,16 +333,6 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [ ifMode: 'math', command: 'addRowBefore', }, - { - key: 'ctrl+[Backspace]', - ifMode: 'math', - command: 'removeRow', - }, - { - key: 'cmd+[Backspace]', - ifMode: 'math', - command: 'removeRow', - }, // { // key: 'ctrl+[Comma]', @@ -378,6 +371,11 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [ ifMode: 'math', command: 'removeColumn', }, + { + key: 'shift+[Delete]', + ifMode: 'math', + command: 'removeRow', + }, { key: 'alt+[Digit5]', From dd59a117dbfeac30279c16f75ea0418b6cca15c4 Mon Sep 17 00:00:00 2001 From: Max Anstie Date: Sun, 26 Nov 2023 20:01:42 +0800 Subject: [PATCH 3/4] fix: cursor position after deleteWordBackward --- src/editor-model/commands.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/editor-model/commands.ts b/src/editor-model/commands.ts index ae4e30e57..26fcf9200 100644 --- a/src/editor-model/commands.ts +++ b/src/editor-model/commands.ts @@ -283,11 +283,12 @@ export function skip( } if (options?.delete ?? false) { - deleteRange( - model, - [previousPosition, offset], - direction === 'forward' ? 'deleteWordForward' : 'deleteWordBackward' - ); + if (direction === 'forward') + deleteRange(model, [previousPosition, offset], 'deleteWordForward'); + else { + deleteRange(model, [previousPosition, offset], 'deleteWordBackward'); + model.position = offset; + } } else { model.position = offset; model.announce('move', previousPosition); From 5bea1de85e77f6295406203a7480c5d95c5a4b14 Mon Sep 17 00:00:00 2001 From: Max Anstie Date: Sun, 10 Dec 2023 13:14:57 +0800 Subject: [PATCH 4/4] feat: add alternative backspace hotkeys for delete hotkeys --- src/editor/keybindings-definitions.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/editor/keybindings-definitions.ts b/src/editor/keybindings-definitions.ts index 615ed5432..45ae2b60b 100644 --- a/src/editor/keybindings-definitions.ts +++ b/src/editor/keybindings-definitions.ts @@ -13,13 +13,17 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [ { key: 'shift+[ArrowDown]', command: 'extendSelectionDownward' }, { key: '[Backspace]', command: 'deleteBackward' }, + { key: '[Delete]', command: 'deleteForward' }, + { key: 'shift+[Backspace]', command: 'deleteForward' }, { key: 'alt+[Backspace]', command: 'deletePreviousWord' }, { key: 'alt+[Delete]', command: 'deleteNextWord' }, { key: 'ctrl+[Backspace]', command: 'deleteToGroupStart' }, + { key: 'ctrl+[Delete]', command: 'deleteToGroupEnd' }, + { key: 'ctrl+shift+[Backspace]', command: 'deleteToGroupEnd' }, { key: 'alt+[ArrowLeft]', command: 'moveToPreviousWord' }, { key: 'alt+[ArrowRight]', command: 'moveToNextWord' }, @@ -382,6 +386,11 @@ export const DEFAULT_KEYBINDINGS: Keybinding[] = [ ifMode: 'math', command: 'removeRow', }, + { + key: 'shift+alt+[Backspace]', + ifMode: 'math', + command: 'removeRow', + }, { key: 'alt+[Digit5]',