Desktop: CodeMirror 6 plugin API: Improve ability to register custom commands (#9956)

pull/9968/head
Henry Heino 2024-02-19 02:04:20 -08:00 committed by GitHub
parent 0b2bb80bb8
commit 2d0a53eaca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 8 deletions

View File

@ -398,7 +398,7 @@ export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
return;
}
this.execCommand(commandName);
return this.execCommand(commandName);
}
public commandExists(commandName: string) {
@ -411,7 +411,7 @@ export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
return;
}
CodeMirror5Emulation.commands[name as (keyof typeof CodeMirror5Emulation.commands)](this);
return CodeMirror5Emulation.commands[name as (keyof typeof CodeMirror5Emulation.commands)](this);
}
}

View File

@ -60,4 +60,14 @@ describe('CodeMirrorControl', () => {
control.insertText('Test...');
expect(updateFn).toHaveBeenCalled();
});
it('should support adding custom editor commands', () => {
const control = createEditorControl('');
const command = jest.fn(() => 'test');
control.registerCommand('myTestCommand', command);
expect(control.supportsCommand('myTestCommand')).toBe(true);
expect(control.execCommand('myTestCommand')).toBe('test');
expect(command).toHaveBeenCalledTimes(1);
});
});

View File

@ -1,7 +1,7 @@
import { EditorView } from '@codemirror/view';
import { EditorCommandType, EditorControl, EditorSettings, LogMessageCallback, PluginData, SearchState } from '../types';
import CodeMirror5Emulation from './CodeMirror5Emulation/CodeMirror5Emulation';
import editorCommands from './editorCommands/editorCommands';
import editorCommands, { EditorCommandFunction } from './editorCommands/editorCommands';
import { EditorSelection, Extension, StateEffect } from '@codemirror/state';
import { updateLink } from './markdown/markdownCommands';
import { SearchQuery, setSearchQuery } from '@codemirror/search';
@ -17,6 +17,7 @@ interface Callbacks {
export default class CodeMirrorControl extends CodeMirror5Emulation implements EditorControl {
private _pluginControl: PluginLoader;
private _userCommands: Map<string, EditorCommandFunction> = new Map();
public constructor(
editor: EditorView,
@ -28,19 +29,28 @@ export default class CodeMirrorControl extends CodeMirror5Emulation implements E
}
public supportsCommand(name: string) {
return name in editorCommands || super.commandExists(name);
return name in editorCommands || this._userCommands.has(name) || super.commandExists(name);
}
public override execCommand(name: string) {
if (name in editorCommands) {
editorCommands[name as EditorCommandType](this.editor);
let commandOutput;
if (this._userCommands.has(name)) {
commandOutput = this._userCommands.get(name)(this.editor);
} else if (name in editorCommands) {
commandOutput = editorCommands[name as EditorCommandType](this.editor);
} else if (super.commandExists(name)) {
super.execCommand(name);
commandOutput = super.execCommand(name);
}
if (name === EditorCommandType.Undo || name === EditorCommandType.Redo) {
this._callbacks.onUndoRedo();
}
return commandOutput;
}
public registerCommand(name: string, command: EditorCommandFunction) {
this._userCommands.set(name, command);
}
public undo() {

View File

@ -10,7 +10,7 @@ import {
import swapLine, { SwapLineDirection } from './swapLine';
import { closeSearchPanel, findNext, findPrevious, openSearchPanel, replaceAll, replaceNext } from '@codemirror/search';
type EditorCommandFunction = (editor: EditorView)=> void;
export type EditorCommandFunction = (editor: EditorView)=> void;
const editorCommands: Record<EditorCommandType, EditorCommandFunction> = {
[EditorCommandType.Undo]: undo,