mirror of
https://github.com/laurent22/joplin.git
synced 2025-01-11 18:24:43 +02:00
Desktop: Plugins: Allow commands registered within the beta markdown editor to take arguments (#9963)
This commit is contained in:
parent
e5e191110c
commit
fbeaf31a14
@ -533,6 +533,8 @@ export interface MarkdownItContentScriptModule extends Omit<ContentScriptModule,
|
||||
plugin: (markdownIt: any, options: any)=> any;
|
||||
}
|
||||
|
||||
type EditorCommandCallback = (...args: any[])=> any;
|
||||
|
||||
export interface CodeMirrorControl {
|
||||
/** Points to a CodeMirror 6 EditorView instance. */
|
||||
editor: any;
|
||||
@ -541,8 +543,9 @@ export interface CodeMirrorControl {
|
||||
/** `extension` should be a [CodeMirror 6 extension](https://codemirror.net/docs/ref/#state.Extension). */
|
||||
addExtension(extension: any|any[]): void;
|
||||
|
||||
execCommand(name: string): any;
|
||||
supportsCommand(name: string): boolean;
|
||||
execCommand(name: string, ...args: any[]): any;
|
||||
registerCommand(name: string, callback: EditorCommandCallback): void;
|
||||
|
||||
joplinExtensions: {
|
||||
/**
|
||||
|
@ -4,9 +4,9 @@
|
||||
// This is necessary. Having multiple copies of the CodeMirror libraries loaded can cause
|
||||
// the editor to not work properly.
|
||||
//
|
||||
import { lineNumbers, highlightActiveLineGutter, } from '@codemirror/view';
|
||||
import { lineNumbers, highlightActiveLineGutter, EditorView } from '@codemirror/view';
|
||||
import { completeFromList } from '@codemirror/autocomplete';
|
||||
import { CodeMirrorContentScriptModule, CodeMirrorControl } from 'api/types';
|
||||
import { CodeMirrorContentScriptModule, ContentScriptContext } from 'api/types';
|
||||
//
|
||||
// For the above import to work, you may also need to add @codemirror/view as a dev dependency
|
||||
// to package.json. (For the type information only).
|
||||
@ -15,7 +15,7 @@ import { CodeMirrorContentScriptModule, CodeMirrorControl } from 'api/types';
|
||||
// const { lineNumbers } = joplin.require('@codemirror/view');
|
||||
|
||||
|
||||
export default (_context: { contentScriptId: string }): CodeMirrorContentScriptModule => {
|
||||
export default (_context: ContentScriptContext): CodeMirrorContentScriptModule => {
|
||||
return {
|
||||
// - codeMirrorWrapper: A thin wrapper around CodeMirror 6, designed to be similar to the
|
||||
// CodeMirror 5 API. If running in CodeMirror 5, a CodeMirror object is provided instead.
|
||||
@ -27,12 +27,11 @@ export default (_context: { contentScriptId: string }): CodeMirrorContentScriptM
|
||||
|
||||
// We can include multiple extensions here:
|
||||
highlightActiveLineGutter(),
|
||||
|
||||
// See https://codemirror.net/ for more built-in extensions and configuration
|
||||
// options.
|
||||
]);
|
||||
|
||||
// See https://codemirror.net/ for more built-in extensions and configuration
|
||||
// options.
|
||||
|
||||
|
||||
// Joplin also exposes extensions for autocompletion.
|
||||
// CodeMirror's built-in `autocompletion(...)` doesn't work if multiple plugins
|
||||
// try to use its `override` option.
|
||||
@ -45,6 +44,28 @@ export default (_context: { contentScriptId: string }): CodeMirrorContentScriptM
|
||||
// built-in autocompletions. These apply, for example, to HTML tags.
|
||||
codeMirrorWrapper.joplinExtensions.enableLanguageDataAutocomplete.of(true),
|
||||
]);
|
||||
|
||||
// We can also register editor commands. These commands can be later executed with:
|
||||
// joplin.commands.execute('editor.execCommand', { name: 'name-here', args: [] })
|
||||
codeMirrorWrapper.registerCommand('wrap-selection-with-tag', (tagName: string) => {
|
||||
const editor: EditorView = codeMirrorWrapper.editor;
|
||||
|
||||
// See https://codemirror.net/examples/change/
|
||||
editor.dispatch(editor.state.changeByRange(range => {
|
||||
const insertBefore = `<${tagName}>`;
|
||||
const insertAfter = `</${tagName}>`;
|
||||
return {
|
||||
changes: [
|
||||
{from: range.from, insert: insertBefore},
|
||||
{from: range.to, insert: insertAfter},
|
||||
],
|
||||
range: range.extend(
|
||||
range.from,
|
||||
range.to + insertBefore.length + insertAfter.length,
|
||||
),
|
||||
};
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
// There are two main ways to style the CodeMirror editor:
|
||||
|
@ -8,5 +8,17 @@ joplin.plugins.register({
|
||||
'cm6-example',
|
||||
'./contentScript.js',
|
||||
);
|
||||
|
||||
// Calls an editor command registered in contentScript.ts.
|
||||
joplin.commands.register({
|
||||
name: 'underlineSelection',
|
||||
label: 'Underline selected text',
|
||||
execute: async () => {
|
||||
joplin.commands.execute('editor.execCommand', {
|
||||
name: 'wrap-selection-with-tag',
|
||||
args: [ 'u' ],
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -107,8 +107,8 @@ const useEditorCommands = (props: Props) => {
|
||||
if ((editorRef.current as any)[value.name]) {
|
||||
const result = (editorRef.current as any)[value.name](...value.args);
|
||||
return result;
|
||||
} else if (editorRef.current.commandExists(value.name)) {
|
||||
const result = editorRef.current.execCommand(value.name);
|
||||
} else if (editorRef.current.supportsCommand(value.name)) {
|
||||
const result = editorRef.current.execCommand(value.name, ...value.args);
|
||||
return result;
|
||||
} else {
|
||||
logger.warn('CodeMirror execCommand: unsupported command: ', value.name);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import { EditorCommandType, EditorControl, EditorSettings, LogMessageCallback, ContentScriptData, SearchState } from '../types';
|
||||
import CodeMirror5Emulation from './CodeMirror5Emulation/CodeMirror5Emulation';
|
||||
import editorCommands, { EditorCommandFunction } from './editorCommands/editorCommands';
|
||||
import editorCommands from './editorCommands/editorCommands';
|
||||
import { EditorSelection, Extension, StateEffect } from '@codemirror/state';
|
||||
import { updateLink } from './markdown/markdownCommands';
|
||||
import { SearchQuery, setSearchQuery } from '@codemirror/search';
|
||||
@ -17,9 +17,11 @@ interface Callbacks {
|
||||
onLogMessage: LogMessageCallback;
|
||||
}
|
||||
|
||||
type EditorUserCommand = (...args: any[])=> any;
|
||||
|
||||
export default class CodeMirrorControl extends CodeMirror5Emulation implements EditorControl {
|
||||
private _pluginControl: PluginLoader;
|
||||
private _userCommands: Map<string, EditorCommandFunction> = new Map();
|
||||
private _userCommands: Map<string, EditorUserCommand> = new Map();
|
||||
|
||||
public constructor(
|
||||
editor: EditorView,
|
||||
@ -36,10 +38,10 @@ export default class CodeMirrorControl extends CodeMirror5Emulation implements E
|
||||
return name in editorCommands || this._userCommands.has(name) || super.commandExists(name);
|
||||
}
|
||||
|
||||
public override execCommand(name: string) {
|
||||
public override execCommand(name: string, ...args: any[]) {
|
||||
let commandOutput;
|
||||
if (this._userCommands.has(name)) {
|
||||
commandOutput = this._userCommands.get(name)(this.editor);
|
||||
commandOutput = this._userCommands.get(name)(...args);
|
||||
} else if (name in editorCommands) {
|
||||
commandOutput = editorCommands[name as EditorCommandType](this.editor);
|
||||
} else if (super.commandExists(name)) {
|
||||
@ -53,7 +55,7 @@ export default class CodeMirrorControl extends CodeMirror5Emulation implements E
|
||||
return commandOutput;
|
||||
}
|
||||
|
||||
public registerCommand(name: string, command: EditorCommandFunction) {
|
||||
public registerCommand(name: string, command: EditorUserCommand) {
|
||||
this._userCommands.set(name, command);
|
||||
}
|
||||
|
||||
|
@ -533,6 +533,8 @@ export interface MarkdownItContentScriptModule extends Omit<ContentScriptModule,
|
||||
plugin: (markdownIt: any, options: any)=> any;
|
||||
}
|
||||
|
||||
type EditorCommandCallback = (...args: any[])=> any;
|
||||
|
||||
export interface CodeMirrorControl {
|
||||
/** Points to a CodeMirror 6 EditorView instance. */
|
||||
editor: any;
|
||||
@ -541,8 +543,9 @@ export interface CodeMirrorControl {
|
||||
/** `extension` should be a [CodeMirror 6 extension](https://codemirror.net/docs/ref/#state.Extension). */
|
||||
addExtension(extension: any|any[]): void;
|
||||
|
||||
execCommand(name: string): any;
|
||||
supportsCommand(name: string): boolean;
|
||||
execCommand(name: string, ...args: any[]): any;
|
||||
registerCommand(name: string, callback: EditorCommandCallback): void;
|
||||
|
||||
joplinExtensions: {
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user