You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-16 00:14:34 +02:00
Desktop: CodeMirror 6 plugin API: Improve ability to register custom commands (#9956)
This commit is contained in:
@ -398,7 +398,7 @@ export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.execCommand(commandName);
|
return this.execCommand(commandName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public commandExists(commandName: string) {
|
public commandExists(commandName: string) {
|
||||||
@ -411,7 +411,7 @@ export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeMirror5Emulation.commands[name as (keyof typeof CodeMirror5Emulation.commands)](this);
|
return CodeMirror5Emulation.commands[name as (keyof typeof CodeMirror5Emulation.commands)](this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,4 +60,14 @@ describe('CodeMirrorControl', () => {
|
|||||||
control.insertText('Test...');
|
control.insertText('Test...');
|
||||||
expect(updateFn).toHaveBeenCalled();
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { EditorView } from '@codemirror/view';
|
import { EditorView } from '@codemirror/view';
|
||||||
import { EditorCommandType, EditorControl, EditorSettings, LogMessageCallback, PluginData, SearchState } from '../types';
|
import { EditorCommandType, EditorControl, EditorSettings, LogMessageCallback, PluginData, SearchState } from '../types';
|
||||||
import CodeMirror5Emulation from './CodeMirror5Emulation/CodeMirror5Emulation';
|
import CodeMirror5Emulation from './CodeMirror5Emulation/CodeMirror5Emulation';
|
||||||
import editorCommands from './editorCommands/editorCommands';
|
import editorCommands, { EditorCommandFunction } from './editorCommands/editorCommands';
|
||||||
import { EditorSelection, Extension, StateEffect } from '@codemirror/state';
|
import { EditorSelection, Extension, StateEffect } from '@codemirror/state';
|
||||||
import { updateLink } from './markdown/markdownCommands';
|
import { updateLink } from './markdown/markdownCommands';
|
||||||
import { SearchQuery, setSearchQuery } from '@codemirror/search';
|
import { SearchQuery, setSearchQuery } from '@codemirror/search';
|
||||||
@ -17,6 +17,7 @@ interface Callbacks {
|
|||||||
|
|
||||||
export default class CodeMirrorControl extends CodeMirror5Emulation implements EditorControl {
|
export default class CodeMirrorControl extends CodeMirror5Emulation implements EditorControl {
|
||||||
private _pluginControl: PluginLoader;
|
private _pluginControl: PluginLoader;
|
||||||
|
private _userCommands: Map<string, EditorCommandFunction> = new Map();
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
editor: EditorView,
|
editor: EditorView,
|
||||||
@ -28,19 +29,28 @@ export default class CodeMirrorControl extends CodeMirror5Emulation implements E
|
|||||||
}
|
}
|
||||||
|
|
||||||
public supportsCommand(name: string) {
|
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) {
|
public override execCommand(name: string) {
|
||||||
if (name in editorCommands) {
|
let commandOutput;
|
||||||
editorCommands[name as EditorCommandType](this.editor);
|
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)) {
|
} else if (super.commandExists(name)) {
|
||||||
super.execCommand(name);
|
commandOutput = super.execCommand(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name === EditorCommandType.Undo || name === EditorCommandType.Redo) {
|
if (name === EditorCommandType.Undo || name === EditorCommandType.Redo) {
|
||||||
this._callbacks.onUndoRedo();
|
this._callbacks.onUndoRedo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return commandOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public registerCommand(name: string, command: EditorCommandFunction) {
|
||||||
|
this._userCommands.set(name, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public undo() {
|
public undo() {
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
import swapLine, { SwapLineDirection } from './swapLine';
|
import swapLine, { SwapLineDirection } from './swapLine';
|
||||||
import { closeSearchPanel, findNext, findPrevious, openSearchPanel, replaceAll, replaceNext } from '@codemirror/search';
|
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> = {
|
const editorCommands: Record<EditorCommandType, EditorCommandFunction> = {
|
||||||
[EditorCommandType.Undo]: undo,
|
[EditorCommandType.Undo]: undo,
|
||||||
|
Reference in New Issue
Block a user