mirror of
https://github.com/laurent22/joplin.git
synced 2024-11-27 08:21:03 +02:00
This commit is contained in:
parent
629e968878
commit
b17f28ce94
@ -762,8 +762,6 @@ packages/editor/CodeMirror/markdown/markdownCommands.toggleList.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.js
|
||||
packages/editor/CodeMirror/markdown/markdownMathParser.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownMathParser.js
|
||||
packages/editor/CodeMirror/markdown/markdownReformatter.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownReformatter.js
|
||||
packages/editor/CodeMirror/pluginApi/PluginLoader.js
|
||||
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
|
||||
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
|
||||
@ -776,6 +774,8 @@ packages/editor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
|
||||
packages/editor/CodeMirror/testUtil/typeText.js
|
||||
packages/editor/CodeMirror/theme.js
|
||||
packages/editor/CodeMirror/util/editorStateUtils.test.js
|
||||
packages/editor/CodeMirror/util/editorStateUtils.js
|
||||
packages/editor/CodeMirror/util/isInSyntaxNode.js
|
||||
packages/editor/CodeMirror/util/setupVim.js
|
||||
packages/editor/SelectionFormatting.js
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -741,8 +741,6 @@ packages/editor/CodeMirror/markdown/markdownCommands.toggleList.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownCommands.js
|
||||
packages/editor/CodeMirror/markdown/markdownMathParser.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownMathParser.js
|
||||
packages/editor/CodeMirror/markdown/markdownReformatter.test.js
|
||||
packages/editor/CodeMirror/markdown/markdownReformatter.js
|
||||
packages/editor/CodeMirror/pluginApi/PluginLoader.js
|
||||
packages/editor/CodeMirror/pluginApi/codeMirrorRequire.js
|
||||
packages/editor/CodeMirror/pluginApi/customEditorCompletion.test.js
|
||||
@ -755,6 +753,8 @@ packages/editor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/editor/CodeMirror/testUtil/pressReleaseKey.js
|
||||
packages/editor/CodeMirror/testUtil/typeText.js
|
||||
packages/editor/CodeMirror/theme.js
|
||||
packages/editor/CodeMirror/util/editorStateUtils.test.js
|
||||
packages/editor/CodeMirror/util/editorStateUtils.js
|
||||
packages/editor/CodeMirror/util/isInSyntaxNode.js
|
||||
packages/editor/CodeMirror/util/setupVim.js
|
||||
packages/editor/SelectionFormatting.js
|
||||
|
@ -12,25 +12,6 @@ import { focus } from '@joplin/lib/utils/focusHandler';
|
||||
|
||||
const logger = Logger.create('CodeMirror 6 commands');
|
||||
|
||||
const wrapSelectionWithStrings = (editor: CodeMirrorControl, string1: string, string2 = '', defaultText = '') => {
|
||||
if (editor.somethingSelected()) {
|
||||
editor.wrapSelections(string1, string2);
|
||||
} else {
|
||||
editor.wrapSelections(string1 + defaultText, string2);
|
||||
|
||||
// Now select the default text so the user can replace it
|
||||
const selections = editor.listSelections();
|
||||
const newSelections = [];
|
||||
for (let i = 0; i < selections.length; i++) {
|
||||
const s = selections[i];
|
||||
const anchor = { line: s.anchor.line, ch: s.anchor.ch + string1.length };
|
||||
const head = { line: s.head.line, ch: s.head.ch - string2.length };
|
||||
newSelections.push({ anchor: anchor, head: head });
|
||||
}
|
||||
editor.setSelections(newSelections);
|
||||
}
|
||||
};
|
||||
|
||||
interface Props {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
webviewRef: RefObject<any>;
|
||||
@ -92,7 +73,9 @@ const useEditorCommands = (props: Props) => {
|
||||
textLink: async () => {
|
||||
const url = await dialogs.prompt(_('Insert Hyperlink'));
|
||||
focus('useEditorCommands::textLink', editorRef.current);
|
||||
if (url) wrapSelectionWithStrings(editorRef.current, '[', `](${url})`);
|
||||
if (url) {
|
||||
editorRef.current.wrapSelections('[', `](${url})`);
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
insertText: (value: any) => editorRef.current.insertText(value),
|
||||
|
@ -426,34 +426,6 @@ export default class CodeMirror5Emulation extends BaseCodeMirror5Emulation {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Currently copied from useCursorUtils.ts.
|
||||
// TODO: Remove the duplicate code when CodeMirror 5 is eventually removed.
|
||||
public wrapSelections(string1: string, string2: string) {
|
||||
const selectedStrings = this.getSelections();
|
||||
|
||||
// Batches the insert operations, if this wasn't done the inserts
|
||||
// could potentially overwrite one another
|
||||
this.operation(() => {
|
||||
for (let i = 0; i < selectedStrings.length; i++) {
|
||||
const selected = selectedStrings[i];
|
||||
|
||||
// Remove white space on either side of selection
|
||||
const start = selected.search(/[^\s]/);
|
||||
const end = selected.search(/[^\s](?=[\s]*$)/);
|
||||
const core = selected.substring(start, end - start + 1);
|
||||
|
||||
// If selection can be toggled do that
|
||||
if (core.startsWith(string1) && core.endsWith(string2)) {
|
||||
const inside = core.substring(string1.length, core.length - string1.length - string2.length);
|
||||
selectedStrings[i] = selected.substring(0, start) + inside + selected.substring(end + 1);
|
||||
} else {
|
||||
selectedStrings[i] = selected.substring(0, start) + string1 + core + string2 + selected.substring(end + 1);
|
||||
}
|
||||
}
|
||||
this.replaceSelections(selectedStrings);
|
||||
});
|
||||
}
|
||||
|
||||
public static commands = (() => {
|
||||
const commands: Record<string, CodeMirror5Command> = {
|
||||
...BaseCodeMirror5Emulation.commands,
|
||||
|
@ -2,6 +2,7 @@ import { ViewPlugin } from '@codemirror/view';
|
||||
import createEditorControl from './testUtil/createEditorControl';
|
||||
import { EditorCommandType } from '../types';
|
||||
import pressReleaseKey from './testUtil/pressReleaseKey';
|
||||
import { EditorSelection } from '@codemirror/state';
|
||||
|
||||
describe('CodeMirrorControl', () => {
|
||||
it('clearHistory should clear the undo/redo history', () => {
|
||||
@ -113,4 +114,71 @@ describe('CodeMirrorControl', () => {
|
||||
control.updateBody('Hello\r\nWorld\r\ntest');
|
||||
control.updateBody('Hello\r\n');
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
initialText: 'Hello\nWorld',
|
||||
selection: EditorSelection.cursor(5),
|
||||
left: '[[',
|
||||
right: ']].',
|
||||
typeText: null,
|
||||
expected: 'Hello[[]].\nWorld',
|
||||
},
|
||||
{
|
||||
initialText: 'Hello\nWorld',
|
||||
selection: EditorSelection.cursor(0),
|
||||
left: 'before',
|
||||
right: 'after.',
|
||||
typeText: ' cursor ',
|
||||
expected: 'before cursor after.Hello\nWorld',
|
||||
},
|
||||
{
|
||||
initialText: 'Hello\nWorld',
|
||||
selection: EditorSelection.range(0, 5),
|
||||
left: '[',
|
||||
right: '](test)',
|
||||
typeText: null,
|
||||
expected: '[Hello](test)\nWorld',
|
||||
},
|
||||
{
|
||||
initialText: 'Hello\nWorld',
|
||||
selection: EditorSelection.range(0, 5),
|
||||
left: '[',
|
||||
right: '](test)',
|
||||
typeText: 'replaced',
|
||||
expected: '[replaced](test)\nWorld',
|
||||
},
|
||||
{
|
||||
initialText: 'Hello\nWorld',
|
||||
selection: EditorSelection.create([
|
||||
EditorSelection.cursor(0), EditorSelection.cursor(5),
|
||||
]),
|
||||
left: '[',
|
||||
right: '](test)',
|
||||
typeText: 'cursor',
|
||||
expected: '[cursor](test)Hello[cursor](test)\nWorld',
|
||||
},
|
||||
{
|
||||
initialText: 'This is a\ntest',
|
||||
selection: EditorSelection.create([
|
||||
EditorSelection.range(5, 9), EditorSelection.cursor(14),
|
||||
]),
|
||||
left: '[',
|
||||
right: ']',
|
||||
typeText: 'cursor',
|
||||
expected: 'This [cursor]\ntest[cursor]',
|
||||
},
|
||||
])('wrapSelections should surround all selections with the given text (case %#)', ({ initialText, selection, typeText, left, right, expected }) => {
|
||||
const control = createEditorControl(initialText);
|
||||
control.editor.dispatch({
|
||||
selection,
|
||||
});
|
||||
control.wrapSelections(left, right);
|
||||
|
||||
if (typeText) {
|
||||
control.insertText(typeText);
|
||||
}
|
||||
|
||||
expect(control.editor.state.doc.toString()).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
@ -8,6 +8,7 @@ import { SearchQuery, setSearchQuery } from '@codemirror/search';
|
||||
import PluginLoader from './pluginApi/PluginLoader';
|
||||
import customEditorCompletion, { editorCompletionSource, enableLanguageDataAutocomplete } from './pluginApi/customEditorCompletion';
|
||||
import { CompletionSource } from '@codemirror/autocomplete';
|
||||
import { RegionSpec, toggleInlineSelectionFormat } from './util/editorStateUtils';
|
||||
|
||||
interface Callbacks {
|
||||
onUndoRedo(): void;
|
||||
@ -93,6 +94,25 @@ export default class CodeMirrorControl extends CodeMirror5Emulation implements E
|
||||
this.editor.dispatch(this.editor.state.replaceSelection(text), { userEvent });
|
||||
}
|
||||
|
||||
public wrapSelections(start: string, end: string) {
|
||||
const regionSpec = RegionSpec.of({ template: { start, end } });
|
||||
|
||||
this.editor.dispatch(
|
||||
this.editor.state.changeByRange(range => {
|
||||
const update = toggleInlineSelectionFormat(this.editor.state, regionSpec, range);
|
||||
if (!update.range.empty) {
|
||||
// Deselect the start and end characters (roughly preserve the original
|
||||
// selection).
|
||||
update.range = EditorSelection.range(
|
||||
update.range.from + start.length,
|
||||
update.range.to - end.length,
|
||||
);
|
||||
}
|
||||
return update;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public updateBody(newBody: string) {
|
||||
// TODO: doc.toString() can be slow for large documents.
|
||||
const currentBody = this.editor.state.doc.toString();
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
RegionSpec, growSelectionToNode, renumberSelectedLists,
|
||||
toggleInlineFormatGlobally, toggleRegionFormatGlobally, toggleSelectedLinesStartWith,
|
||||
isIndentationEquivalent, stripBlockquote, tabsToSpaces,
|
||||
} from './markdownReformatter';
|
||||
} from '../util/editorStateUtils';
|
||||
import intersectsSyntaxNode from '../util/isInSyntaxNode';
|
||||
|
||||
const startingSpaceRegex = /^(\s*)/;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
findInlineMatch, MatchSide, RegionSpec, renumberSelectedLists, tabsToSpaces, toggleRegionFormatGlobally,
|
||||
} from './markdownReformatter';
|
||||
} from './editorStateUtils';
|
||||
import { Text as DocumentText, EditorSelection, EditorState } from '@codemirror/state';
|
||||
import { indentUnit } from '@codemirror/language';
|
||||
import createTestEditor from '../testUtil/createTestEditor';
|
@ -268,7 +268,7 @@ const toggleInlineRegionSurrounded = (
|
||||
|
||||
changes.push({
|
||||
from: sel.to,
|
||||
insert: spec.template.start,
|
||||
insert: spec.template.end,
|
||||
});
|
||||
|
||||
// If not a caret,
|
Loading…
Reference in New Issue
Block a user