diff --git a/src/tests/editorOperationUtils/lockedCode.test.ts b/src/tests/editorOperationUtils/lockedCode.test.ts index 0dc187e..0c07e01 100644 --- a/src/tests/editorOperationUtils/lockedCode.test.ts +++ b/src/tests/editorOperationUtils/lockedCode.test.ts @@ -356,4 +356,50 @@ function findLargest(numbers: number[]): number { text: '' }) }) + + test('Handle all systems line break character', () => { + const model = createDefaultTestModel() + disposableStore.add(model) + const editor = monaco.editor.create(document.createElement('div'), { + model + }) + disposableStore.add(editor) + disposableStore.add(lockCodeRanges(editor, { + getLockedRanges () { + return createDefaultTestLockedCodeRanges(model) + } + })) + + const operationRange = createTestRange(model, 12, 22) + const operation = createTestOperation(operationRange, + '/* Ignore and do not change the code below */\n' + + '// toto\r\n' + + '/* Ignore and do not change the code above */\n' + + '\n' + + '// new comment\r\n' + + '// on two lines\r' + + '\n' + + '/* Ignore and do not change the code below */\r\n' + + '// toto\r' + + '/* Ignore and do not change the code above */\n' + + '\n' + + '// other comment\n' + ) + + const onDidChangeContent = jest.fn() + disposableStore.add(model.onDidChangeContent(onDidChangeContent)) + + editor.executeEdits(null, [operation]) + + expect(onDidChangeContent).toHaveBeenCalledTimes(1) + expect(onDidChangeContent.mock.calls[0]![0]).toMatchObject({ + changes: [{ + range: { startLineNumber: 21, startColumn: 1, endLineNumber: 22, endColumn: 24 }, + text: '\n// other comment\n' + }, { + range: { startLineNumber: 15, startColumn: 1, endLineNumber: 17, endColumn: 1 }, + text: '\n// new comment\n// on two lines' + }] + }) + }) }) diff --git a/src/tools.ts b/src/tools.ts index 9684c8a..17219a5 100644 --- a/src/tools.ts +++ b/src/tools.ts @@ -177,7 +177,7 @@ export function lockCodeRanges ( // Handle selection of the last line of an editable range disposableStore.add( editor.onDidChangeCursorSelection((e) => { - if (canEditRange(e.selection)) { + if (canEditRange(e.selection) || e.selection.isEmpty()) { return } const model = editor.getModel() diff --git a/src/tools/utils/editorOperationUtils.ts b/src/tools/utils/editorOperationUtils.ts index a3e4a6d..08f71c9 100644 --- a/src/tools/utils/editorOperationUtils.ts +++ b/src/tools/utils/editorOperationUtils.ts @@ -1,6 +1,7 @@ import * as monaco from 'monaco-editor' import { ValidAnnotatedEditOperation } from 'vscode/vscode/vs/editor/common/model' import { excludeRanges } from './rangeUtils' +import { normalizeStringLineBreaks } from './stringUtils' export class LockedCodeError extends Error {} @@ -50,7 +51,7 @@ function tryIgnoreLockedCodeTextForOperation ( const splitText: string[] = [] const uneditableRangesText = uneditableRangesInOperationRange.map(range => model.getValueInRange(range)) let currentRange: number = 0 - let remainingText: string = operationText + let remainingText: string = normalizeStringLineBreaks(operationText, model.getEOL()) while (remainingText.length > 0 && currentRange < uneditableRangesText.length) { const rangeText = uneditableRangesText[currentRange] if (rangeText != null && rangeText !== '') { diff --git a/src/tools/utils/stringUtils.ts b/src/tools/utils/stringUtils.ts new file mode 100644 index 0000000..ef235c2 --- /dev/null +++ b/src/tools/utils/stringUtils.ts @@ -0,0 +1,3 @@ +export function normalizeStringLineBreaks (str: string, lineBreakCharacter: string): string { + return str.replace(/\r\n|\r|\n/g, lineBreakCharacter) +}