mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: Fixes #9104: Beta editor: Allow tab key to insert tabs at cursor rather than indent in some cases (#9107)
This commit is contained in:
parent
d3744b0e6e
commit
0e6891fd88
@ -534,6 +534,7 @@ packages/editor/CodeMirror/testUtil/createTestEditor.js
|
||||
packages/editor/CodeMirror/testUtil/forceFullParse.js
|
||||
packages/editor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/editor/CodeMirror/theme.js
|
||||
packages/editor/CodeMirror/util/isInSyntaxNode.js
|
||||
packages/editor/SelectionFormatting.js
|
||||
packages/editor/events.js
|
||||
packages/editor/types.js
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -516,6 +516,7 @@ packages/editor/CodeMirror/testUtil/createTestEditor.js
|
||||
packages/editor/CodeMirror/testUtil/forceFullParse.js
|
||||
packages/editor/CodeMirror/testUtil/loadLanguages.js
|
||||
packages/editor/CodeMirror/theme.js
|
||||
packages/editor/CodeMirror/util/isInSyntaxNode.js
|
||||
packages/editor/SelectionFormatting.js
|
||||
packages/editor/events.js
|
||||
packages/editor/types.js
|
||||
|
@ -20,6 +20,7 @@ import { SearchState, EditorProps, EditorSettings } from '../types';
|
||||
import { EditorEventType, SelectionRangeChangeEvent } from '../events';
|
||||
import {
|
||||
decreaseIndent, increaseIndent,
|
||||
insertOrIncreaseIndent,
|
||||
toggleBolded, toggleCode,
|
||||
toggleItalicized, toggleMath,
|
||||
} from './markdown/markdownCommands';
|
||||
@ -254,7 +255,7 @@ const createEditor = (
|
||||
notifyLinkEditRequest();
|
||||
return true;
|
||||
}),
|
||||
keyCommand('Tab', increaseIndent, true),
|
||||
keyCommand('Tab', insertOrIncreaseIndent, true),
|
||||
keyCommand('Shift-Tab', decreaseIndent, true),
|
||||
|
||||
...standardKeymap, ...historyKeymap, ...searchKeymap,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { EditorSelection } from '@codemirror/state';
|
||||
import {
|
||||
insertOrIncreaseIndent,
|
||||
toggleBolded, toggleCode, toggleHeaderLevel, toggleItalicized, toggleMath, updateLink,
|
||||
} from './markdownCommands';
|
||||
import createTestEditor from '../testUtil/createTestEditor';
|
||||
@ -238,5 +239,41 @@ describe('markdownCommands', () => {
|
||||
expect(sel.from).toBe('> Testing...> \n> \n'.length);
|
||||
expect(sel.to).toBe(editor.state.doc.length);
|
||||
});
|
||||
|
||||
it('insertOrIncreaseIndent should indent when text is selected', async () => {
|
||||
const initialText = '> Testing...\n> Test.';
|
||||
const editor = await createTestEditor(
|
||||
initialText,
|
||||
EditorSelection.range(0, initialText.length),
|
||||
['Blockquote'],
|
||||
);
|
||||
|
||||
insertOrIncreaseIndent(editor);
|
||||
|
||||
expect(editor.state.doc.toString()).toBe('> \tTesting...\n> \tTest.');
|
||||
});
|
||||
|
||||
it('insertOrIncreaseIndent should insert tabs when selection is empty, in a paragraph', async () => {
|
||||
const initialText = 'This is a test\nof indentation.';
|
||||
const editor = await createTestEditor(
|
||||
initialText,
|
||||
EditorSelection.cursor(initialText.length),
|
||||
[],
|
||||
);
|
||||
|
||||
insertOrIncreaseIndent(editor);
|
||||
|
||||
const finalText = editor.state.doc.toString();
|
||||
|
||||
// Should add tab character at the cursor
|
||||
expect(finalText).toBe('This is a test\nof indentation.\t');
|
||||
|
||||
// Should move the selection after the tab
|
||||
expect(editor.state.selection.ranges).toHaveLength(1);
|
||||
expect(editor.state.selection.main).toMatchObject({
|
||||
from: finalText.length,
|
||||
to: finalText.length,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
toggleInlineFormatGlobally, toggleRegionFormatGlobally, toggleSelectedLinesStartWith,
|
||||
isIndentationEquivalent, stripBlockquote, tabsToSpaces,
|
||||
} from './markdownReformatter';
|
||||
import intersectsSyntaxNode from '../util/isInSyntaxNode';
|
||||
|
||||
const startingSpaceRegex = /^(\s*)/;
|
||||
|
||||
@ -423,6 +424,35 @@ export const increaseIndent: Command = (view: EditorView): boolean => {
|
||||
return true;
|
||||
};
|
||||
|
||||
// Like `increaseIndent`, but may insert tabs, rather than
|
||||
// indenting, in some instances.
|
||||
export const insertOrIncreaseIndent: Command = (view: EditorView): boolean => {
|
||||
const selection = view.state.selection;
|
||||
const mainSelection = selection.main;
|
||||
if (selection.ranges.length !== 1 || !mainSelection.empty) {
|
||||
return increaseIndent(view);
|
||||
}
|
||||
|
||||
|
||||
if (intersectsSyntaxNode(view.state, mainSelection, 'ListItem')) {
|
||||
return increaseIndent(view);
|
||||
}
|
||||
|
||||
const indentUnit = indentString(view.state, getIndentUnit(view.state));
|
||||
view.dispatch(view.state.changeByRange(selection => {
|
||||
return {
|
||||
// Move the selection to after the inserted text
|
||||
range: EditorSelection.cursor(selection.from + indentUnit.length),
|
||||
changes: {
|
||||
from: selection.from,
|
||||
insert: indentUnit,
|
||||
},
|
||||
};
|
||||
}));
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export const decreaseIndent: Command = (view: EditorView): boolean => {
|
||||
const matchEmpty = true;
|
||||
const changes = toggleSelectedLinesStartWith(
|
||||
|
32
packages/editor/CodeMirror/util/isInSyntaxNode.ts
Normal file
32
packages/editor/CodeMirror/util/isInSyntaxNode.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { syntaxTree } from '@codemirror/language';
|
||||
import { EditorState } from '@codemirror/state';
|
||||
|
||||
interface Range {
|
||||
from: number;
|
||||
to: number;
|
||||
}
|
||||
|
||||
const intersectsSyntaxNode = (state: EditorState, range: Range, nodeName: string) => {
|
||||
let foundNode = false;
|
||||
|
||||
syntaxTree(state).iterate({
|
||||
from: range.from,
|
||||
to: range.to,
|
||||
enter: node => {
|
||||
if (node.name === nodeName) {
|
||||
foundNode = true;
|
||||
|
||||
// Skip children
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search children if we haven't found a matching node yet.
|
||||
return !foundNode;
|
||||
},
|
||||
});
|
||||
|
||||
return foundNode;
|
||||
};
|
||||
|
||||
export default intersectsSyntaxNode;
|
||||
|
Loading…
Reference in New Issue
Block a user