From 69e6bff65b9c9aaaecb7cbbc75970128bad7e5a7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Nov 2024 12:53:11 +0100 Subject: [PATCH 01/44] adding code in order to enable overtype --- .../widget/codeEditor/codeEditorWidget.ts | 2 + .../editor/common/commands/replaceCommand.ts | 28 +++ src/vs/editor/common/config/editorOptions.ts | 18 ++ src/vs/editor/common/cursor/cursor.ts | 11 +- .../common/cursor/cursorTypeEditOperations.ts | 13 +- .../common/cursor/cursorTypeOperations.ts | 9 +- .../common/standalone/standaloneEnums.ts | 177 ++++++++--------- .../editor/common/viewModel/viewModelImpl.ts | 12 +- src/vs/monaco.d.ts | 182 +++++++++--------- .../multicursor/notebookMulticursor.ts | 2 +- 10 files changed, 258 insertions(+), 196 deletions(-) diff --git a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts index 1f78e50887b1e..9b34b9922b73b 100644 --- a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts @@ -1805,6 +1805,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE paste: (text: string, pasteOnNewLine: boolean, multicursorText: string[] | null, mode: string | null) => { this._paste('keyboard', text, pasteOnNewLine, multicursorText, mode); }, + // type: (text: string) => { this._type('keyboard', text); }, @@ -1827,6 +1828,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE const payload: editorBrowser.PastePayload = { text, pasteOnNewLine, multicursorText, mode }; this._commandService.executeCommand(editorCommon.Handler.Paste, payload); }, + // type: (text: string) => { const payload: editorCommon.TypePayload = { text }; this._commandService.executeCommand(editorCommon.Handler.Type, payload); diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index f4beabe78a68b..e33e743411b84 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -31,6 +31,34 @@ export class ReplaceCommand implements ICommand { } } +export class ReplaceOvertypeCommand implements ICommand { + + private readonly _range: Range; + private readonly _text: string; + public readonly insertsAutoWhitespace: boolean; + + constructor(range: Range, text: string, insertsAutoWhitespace: boolean = false) { + this._range = range; + this._text = text; + this.insertsAutoWhitespace = insertsAutoWhitespace; + } + + public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { + const startPosition = this._range.getStartPosition(); + const endPosition = this._range.getEndPosition(); + const rangeEndOffset = model.getOffsetAt(endPosition); + const endOffset = rangeEndOffset + this._text.length; + const newRange = Range.fromPositions(startPosition, model.getPositionAt(endOffset)); + builder.addTrackedEditOperation(newRange, this._text); + } + + public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { + const inverseEditOperations = helper.getInverseEditOperations(); + const srcRange = inverseEditOperations[0].range; + return Selection.fromPositions(srcRange.getEndPosition()); + } +} + export class ReplaceCommandThatSelectsText implements ICommand { private readonly _range: Range; diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 107a4fde98f70..3c91c6997a08c 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -773,6 +773,11 @@ export interface IEditorOptions { * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. */ inlineCompletionsAccessibilityVerbose?: boolean; + + /** + * Controls the input type mode, whether it is insert or overtype + */ + inputType?: 'insert' | 'overtype'; } /** @@ -5389,6 +5394,7 @@ export const enum EditorOption { hover, inDiffEditor, inlineSuggest, + inputType, letterSpacing, lightbulb, lineDecorationsWidth, @@ -5843,6 +5849,18 @@ export const EditorOptions = { inDiffEditor: register(new EditorBooleanOption( EditorOption.inDiffEditor, 'inDiffEditor', false )), + inputType: register(new EditorStringEnumOption( + EditorOption.inputType, 'inputType', + 'insert' as 'insert' | 'overtype', + ['insert', 'overtype'] as const, + { + enumDescriptions: [ + nls.localize('inputType.insert', "Insert text at cursor position"), + nls.localize('inputType.overtype', "Replace text at cursor position") + ], + description: nls.localize('inputType', "Controls how text is inputted, whether it is inserted or it overwrites existing content.") + } + )), letterSpacing: register(new EditorFloatOption( EditorOption.letterSpacing, 'letterSpacing', EDITOR_FONT_DEFAULTS.letterSpacing, x => EditorFloatOption.clamp(x, -5, 20), diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index d68f60c56ed18..c791cc19e66bc 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -22,6 +22,7 @@ import { VerticalRevealType, ViewCursorStateChangedEvent, ViewRevealRangeRequest import { dispose, Disposable } from '../../../base/common/lifecycle.js'; import { ICoordinatesConverter } from '../viewModel.js'; import { CursorStateChangedEvent, ViewModelEventsCollector } from '../viewModelEventDispatcher.js'; +import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class CursorsController extends Disposable { @@ -550,8 +551,10 @@ export class CursorsController extends Disposable { }, eventsCollector, source); } - public type(eventsCollector: ViewModelEventsCollector, text: string, source?: string | null | undefined): void { + public type(eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration, text: string, source?: string | null | undefined): void { // this._executeEdit(() => { + console.log('source : ', source); + const inputType = editorConfiguration.getRawOptions().inputType; if (source === 'keyboard') { // If this event is coming straight from the keyboard, look for electric characters and enter @@ -562,18 +565,18 @@ export class CursorsController extends Disposable { const chr = text.substr(offset, charLength); // Here we must interpret each typed character individually - this._executeEditOperation(TypeOperations.typeWithInterceptors(!!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); + this._executeEditOperation(TypeOperations.typeWithInterceptors(inputType, !!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); offset += charLength; } } else { - this._executeEditOperation(TypeOperations.typeWithoutInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text)); + this._executeEditOperation(TypeOperations.typeWithoutInterceptors(inputType, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text)); } }, eventsCollector, source); } - public compositionType(eventsCollector: ViewModelEventsCollector, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { + public compositionType(eventsCollector: ViewModelEventsCollector, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { // if (text.length === 0 && replacePrevCharCnt === 0 && replaceNextCharCnt === 0) { // this edit is a no-op if (positionDelta !== 0) { diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 7b30480af2b55..f1f3a937b13a2 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -6,7 +6,7 @@ import { CharCode } from '../../../base/common/charCode.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import * as strings from '../../../base/common/strings.js'; -import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection } from '../commands/replaceCommand.js'; +import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand } from '../commands/replaceCommand.js'; import { ShiftCommand } from '../commands/shiftCommand.js'; import { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js'; import { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js'; @@ -483,13 +483,15 @@ export class InterceptorElectricCharOperation { export class SimpleCharacterTypeOperation { - public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { + public static getEdits(inputType: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // // A simple character type const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { - commands[i] = new ReplaceCommand(selections[i], ch); + const ChosenReplaceCommand = inputType === 'overtype' ? ReplaceOvertypeCommand : ReplaceCommand; + commands[i] = new ChosenReplaceCommand(selections[i], ch); } - + console.log('inputType : ', inputType); + console.log('SimpleCharacterTypeOperation.getEdits : ', commands); const opType = getTypingOperation(ch, prevEditOperationType); return new EditOperationResult(opType, commands, { shouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType), @@ -738,11 +740,12 @@ export class CompositionOperation { export class TypeWithoutInterceptorsOperation { - public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult { + public static getEdits(inputType: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult { // const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { commands[i] = new ReplaceCommand(selections[i], str); } + console.log('TypeWithoutInterceptorsOperation commands : ', commands); const opType = getTypingOperation(str, prevEditOperationType); return new EditOperationResult(opType, commands, { shouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType), diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index c518f3f97c44a..61487882def38 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,6 +12,7 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; +import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class TypeOperations { @@ -162,7 +163,7 @@ export class TypeOperations { return null; } - public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { + public static typeWithInterceptors(inputType: 'insert' | 'overtype' | undefined, isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { // const enterEdits = EnterOperation.getEdits(config, model, selections, ch, isDoingComposition); if (enterEdits !== undefined) { @@ -194,11 +195,11 @@ export class TypeOperations { return interceptorElectricCharOperation; } - return SimpleCharacterTypeOperation.getEdits(prevEditOperationType, selections, ch); + return SimpleCharacterTypeOperation.getEdits(inputType, prevEditOperationType, selections, ch); } - public static typeWithoutInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { - return TypeWithoutInterceptorsOperation.getEdits(prevEditOperationType, selections, str); + public static typeWithoutInterceptors(inputType: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { // + return TypeWithoutInterceptorsOperation.getEdits(inputType, prevEditOperationType, selections, str); } } diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 01607d8310bb2..d58a19b023598 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -238,94 +238,95 @@ export enum EditorOption { hover = 62, inDiffEditor = 63, inlineSuggest = 64, - letterSpacing = 65, - lightbulb = 66, - lineDecorationsWidth = 67, - lineHeight = 68, - lineNumbers = 69, - lineNumbersMinChars = 70, - linkedEditing = 71, - links = 72, - matchBrackets = 73, - minimap = 74, - mouseStyle = 75, - mouseWheelScrollSensitivity = 76, - mouseWheelZoom = 77, - multiCursorMergeOverlapping = 78, - multiCursorModifier = 79, - multiCursorPaste = 80, - multiCursorLimit = 81, - occurrencesHighlight = 82, - occurrencesHighlightDelay = 83, - overviewRulerBorder = 84, - overviewRulerLanes = 85, - padding = 86, - pasteAs = 87, - parameterHints = 88, - peekWidgetDefaultFocus = 89, - placeholder = 90, - definitionLinkOpensInPeek = 91, - quickSuggestions = 92, - quickSuggestionsDelay = 93, - readOnly = 94, - readOnlyMessage = 95, - renameOnType = 96, - renderControlCharacters = 97, - renderFinalNewline = 98, - renderLineHighlight = 99, - renderLineHighlightOnlyWhenFocus = 100, - renderValidationDecorations = 101, - renderWhitespace = 102, - revealHorizontalRightPadding = 103, - roundedSelection = 104, - rulers = 105, - scrollbar = 106, - scrollBeyondLastColumn = 107, - scrollBeyondLastLine = 108, - scrollPredominantAxis = 109, - selectionClipboard = 110, - selectionHighlight = 111, - selectOnLineNumbers = 112, - showFoldingControls = 113, - showUnused = 114, - snippetSuggestions = 115, - smartSelect = 116, - smoothScrolling = 117, - stickyScroll = 118, - stickyTabStops = 119, - stopRenderingLineAfter = 120, - suggest = 121, - suggestFontSize = 122, - suggestLineHeight = 123, - suggestOnTriggerCharacters = 124, - suggestSelection = 125, - tabCompletion = 126, - tabIndex = 127, - unicodeHighlighting = 128, - unusualLineTerminators = 129, - useShadowDOM = 130, - useTabStops = 131, - wordBreak = 132, - wordSegmenterLocales = 133, - wordSeparators = 134, - wordWrap = 135, - wordWrapBreakAfterCharacters = 136, - wordWrapBreakBeforeCharacters = 137, - wordWrapColumn = 138, - wordWrapOverride1 = 139, - wordWrapOverride2 = 140, - wrappingIndent = 141, - wrappingStrategy = 142, - showDeprecated = 143, - inlayHints = 144, - editorClassName = 145, - pixelRatio = 146, - tabFocusMode = 147, - layoutInfo = 148, - wrappingInfo = 149, - defaultColorDecorators = 150, - colorDecoratorsActivatedOn = 151, - inlineCompletionsAccessibilityVerbose = 152 + inputType = 65, + letterSpacing = 66, + lightbulb = 67, + lineDecorationsWidth = 68, + lineHeight = 69, + lineNumbers = 70, + lineNumbersMinChars = 71, + linkedEditing = 72, + links = 73, + matchBrackets = 74, + minimap = 75, + mouseStyle = 76, + mouseWheelScrollSensitivity = 77, + mouseWheelZoom = 78, + multiCursorMergeOverlapping = 79, + multiCursorModifier = 80, + multiCursorPaste = 81, + multiCursorLimit = 82, + occurrencesHighlight = 83, + occurrencesHighlightDelay = 84, + overviewRulerBorder = 85, + overviewRulerLanes = 86, + padding = 87, + pasteAs = 88, + parameterHints = 89, + peekWidgetDefaultFocus = 90, + placeholder = 91, + definitionLinkOpensInPeek = 92, + quickSuggestions = 93, + quickSuggestionsDelay = 94, + readOnly = 95, + readOnlyMessage = 96, + renameOnType = 97, + renderControlCharacters = 98, + renderFinalNewline = 99, + renderLineHighlight = 100, + renderLineHighlightOnlyWhenFocus = 101, + renderValidationDecorations = 102, + renderWhitespace = 103, + revealHorizontalRightPadding = 104, + roundedSelection = 105, + rulers = 106, + scrollbar = 107, + scrollBeyondLastColumn = 108, + scrollBeyondLastLine = 109, + scrollPredominantAxis = 110, + selectionClipboard = 111, + selectionHighlight = 112, + selectOnLineNumbers = 113, + showFoldingControls = 114, + showUnused = 115, + snippetSuggestions = 116, + smartSelect = 117, + smoothScrolling = 118, + stickyScroll = 119, + stickyTabStops = 120, + stopRenderingLineAfter = 121, + suggest = 122, + suggestFontSize = 123, + suggestLineHeight = 124, + suggestOnTriggerCharacters = 125, + suggestSelection = 126, + tabCompletion = 127, + tabIndex = 128, + unicodeHighlighting = 129, + unusualLineTerminators = 130, + useShadowDOM = 131, + useTabStops = 132, + wordBreak = 133, + wordSegmenterLocales = 134, + wordSeparators = 135, + wordWrap = 136, + wordWrapBreakAfterCharacters = 137, + wordWrapBreakBeforeCharacters = 138, + wordWrapColumn = 139, + wordWrapOverride1 = 140, + wordWrapOverride2 = 141, + wrappingIndent = 142, + wrappingStrategy = 143, + showDeprecated = 144, + inlayHints = 145, + editorClassName = 146, + pixelRatio = 147, + tabFocusMode = 148, + layoutInfo = 149, + wrappingInfo = 150, + defaultColorDecorators = 151, + colorDecoratorsActivatedOn = 152, + inlineCompletionsAccessibilityVerbose = 153 } /** diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 96043722d84c5..36aea0cea9353 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -1040,7 +1040,7 @@ export class ViewModel extends Disposable implements IViewModel { this._withViewEventsCollector(eventsCollector => this._cursor.restoreState(eventsCollector, states)); } - private _executeCursorEdit(callback: (eventsCollector: ViewModelEventsCollector) => void): void { + private _executeCursorEdit(callback: (eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration) => void): void { if (this._cursor.context.cursorConfig.readOnly) { // we cannot edit when read only... this._eventDispatcher.emitOutgoingEvent(new ReadOnlyEditAttemptEvent()); @@ -1057,10 +1057,10 @@ export class ViewModel extends Disposable implements IViewModel { public endComposition(source?: string | null | undefined): void { this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source)); } - public type(text: string, source?: string | null | undefined): void { - this._executeCursorEdit(eventsCollector => this._cursor.type(eventsCollector, text, source)); + public type(text: string, source?: string | null | undefined): void { // + this._executeCursorEdit((eventsCollector, editorConfiguration) => this._cursor.type(eventsCollector, editorConfiguration, text, source)); } - public compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { + public compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { // this._executeCursorEdit(eventsCollector => this._cursor.compositionType(eventsCollector, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta, source)); } public paste(text: string, pasteOnNewLine: boolean, multicursorText?: string[] | null | undefined, source?: string | null | undefined): void { @@ -1107,11 +1107,11 @@ export class ViewModel extends Disposable implements IViewModel { } //#endregion - private _withViewEventsCollector(callback: (eventsCollector: ViewModelEventsCollector) => T): T { + private _withViewEventsCollector(callback: (eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration) => T): T { return this._transactionalTarget.batchChanges(() => { try { const eventsCollector = this._eventDispatcher.beginEmitViewEvents(); - return callback(eventsCollector); + return callback(eventsCollector, this._configuration); } finally { this._eventDispatcher.endEmitViewEvents(); } diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 3143936013f25..ce3cb09a01457 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3810,6 +3810,10 @@ declare namespace monaco.editor { * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. */ inlineCompletionsAccessibilityVerbose?: boolean; + /** + * Controls the input type mode, whether it is insert or overtype + */ + inputType?: 'insert' | 'overtype'; } export interface IDiffEditorBaseOptions { @@ -4940,94 +4944,95 @@ declare namespace monaco.editor { hover = 62, inDiffEditor = 63, inlineSuggest = 64, - letterSpacing = 65, - lightbulb = 66, - lineDecorationsWidth = 67, - lineHeight = 68, - lineNumbers = 69, - lineNumbersMinChars = 70, - linkedEditing = 71, - links = 72, - matchBrackets = 73, - minimap = 74, - mouseStyle = 75, - mouseWheelScrollSensitivity = 76, - mouseWheelZoom = 77, - multiCursorMergeOverlapping = 78, - multiCursorModifier = 79, - multiCursorPaste = 80, - multiCursorLimit = 81, - occurrencesHighlight = 82, - occurrencesHighlightDelay = 83, - overviewRulerBorder = 84, - overviewRulerLanes = 85, - padding = 86, - pasteAs = 87, - parameterHints = 88, - peekWidgetDefaultFocus = 89, - placeholder = 90, - definitionLinkOpensInPeek = 91, - quickSuggestions = 92, - quickSuggestionsDelay = 93, - readOnly = 94, - readOnlyMessage = 95, - renameOnType = 96, - renderControlCharacters = 97, - renderFinalNewline = 98, - renderLineHighlight = 99, - renderLineHighlightOnlyWhenFocus = 100, - renderValidationDecorations = 101, - renderWhitespace = 102, - revealHorizontalRightPadding = 103, - roundedSelection = 104, - rulers = 105, - scrollbar = 106, - scrollBeyondLastColumn = 107, - scrollBeyondLastLine = 108, - scrollPredominantAxis = 109, - selectionClipboard = 110, - selectionHighlight = 111, - selectOnLineNumbers = 112, - showFoldingControls = 113, - showUnused = 114, - snippetSuggestions = 115, - smartSelect = 116, - smoothScrolling = 117, - stickyScroll = 118, - stickyTabStops = 119, - stopRenderingLineAfter = 120, - suggest = 121, - suggestFontSize = 122, - suggestLineHeight = 123, - suggestOnTriggerCharacters = 124, - suggestSelection = 125, - tabCompletion = 126, - tabIndex = 127, - unicodeHighlighting = 128, - unusualLineTerminators = 129, - useShadowDOM = 130, - useTabStops = 131, - wordBreak = 132, - wordSegmenterLocales = 133, - wordSeparators = 134, - wordWrap = 135, - wordWrapBreakAfterCharacters = 136, - wordWrapBreakBeforeCharacters = 137, - wordWrapColumn = 138, - wordWrapOverride1 = 139, - wordWrapOverride2 = 140, - wrappingIndent = 141, - wrappingStrategy = 142, - showDeprecated = 143, - inlayHints = 144, - editorClassName = 145, - pixelRatio = 146, - tabFocusMode = 147, - layoutInfo = 148, - wrappingInfo = 149, - defaultColorDecorators = 150, - colorDecoratorsActivatedOn = 151, - inlineCompletionsAccessibilityVerbose = 152 + inputType = 65, + letterSpacing = 66, + lightbulb = 67, + lineDecorationsWidth = 68, + lineHeight = 69, + lineNumbers = 70, + lineNumbersMinChars = 71, + linkedEditing = 72, + links = 73, + matchBrackets = 74, + minimap = 75, + mouseStyle = 76, + mouseWheelScrollSensitivity = 77, + mouseWheelZoom = 78, + multiCursorMergeOverlapping = 79, + multiCursorModifier = 80, + multiCursorPaste = 81, + multiCursorLimit = 82, + occurrencesHighlight = 83, + occurrencesHighlightDelay = 84, + overviewRulerBorder = 85, + overviewRulerLanes = 86, + padding = 87, + pasteAs = 88, + parameterHints = 89, + peekWidgetDefaultFocus = 90, + placeholder = 91, + definitionLinkOpensInPeek = 92, + quickSuggestions = 93, + quickSuggestionsDelay = 94, + readOnly = 95, + readOnlyMessage = 96, + renameOnType = 97, + renderControlCharacters = 98, + renderFinalNewline = 99, + renderLineHighlight = 100, + renderLineHighlightOnlyWhenFocus = 101, + renderValidationDecorations = 102, + renderWhitespace = 103, + revealHorizontalRightPadding = 104, + roundedSelection = 105, + rulers = 106, + scrollbar = 107, + scrollBeyondLastColumn = 108, + scrollBeyondLastLine = 109, + scrollPredominantAxis = 110, + selectionClipboard = 111, + selectionHighlight = 112, + selectOnLineNumbers = 113, + showFoldingControls = 114, + showUnused = 115, + snippetSuggestions = 116, + smartSelect = 117, + smoothScrolling = 118, + stickyScroll = 119, + stickyTabStops = 120, + stopRenderingLineAfter = 121, + suggest = 122, + suggestFontSize = 123, + suggestLineHeight = 124, + suggestOnTriggerCharacters = 125, + suggestSelection = 126, + tabCompletion = 127, + tabIndex = 128, + unicodeHighlighting = 129, + unusualLineTerminators = 130, + useShadowDOM = 131, + useTabStops = 132, + wordBreak = 133, + wordSegmenterLocales = 134, + wordSeparators = 135, + wordWrap = 136, + wordWrapBreakAfterCharacters = 137, + wordWrapBreakBeforeCharacters = 138, + wordWrapColumn = 139, + wordWrapOverride1 = 140, + wordWrapOverride2 = 141, + wrappingIndent = 142, + wrappingStrategy = 143, + showDeprecated = 144, + inlayHints = 145, + editorClassName = 146, + pixelRatio = 147, + tabFocusMode = 148, + layoutInfo = 149, + wrappingInfo = 150, + defaultColorDecorators = 151, + colorDecoratorsActivatedOn = 152, + inlineCompletionsAccessibilityVerbose = 153 } export const EditorOptions: { @@ -5098,6 +5103,7 @@ declare namespace monaco.editor { hideCursorInOverviewRuler: IEditorOption; hover: IEditorOption>>; inDiffEditor: IEditorOption; + inputType: IEditorOption; letterSpacing: IEditorOption; lightbulb: IEditorOption>>; lineDecorationsWidth: IEditorOption; diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts b/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts index 5eca9e4c247cb..b5dfdf6fe2dfb 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts @@ -235,7 +235,7 @@ export class NotebookMultiCursorController extends Disposable implements INotebo return; } if (match.cellViewModel.handle !== this.anchorCell?.[0].handle) { // don't relay to active cell, already has a controller for typing - controller.type(collector, input, 'keyboard'); + controller.type(collector, match.editorConfig, input, 'keyboard'); } }); })); From 5b951f7710a0f093ba26a0e36ca9968e52d235c0 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Nov 2024 13:14:35 +0100 Subject: [PATCH 02/44] adding a setting to determine the cursor style in overtype mode --- .../viewParts/viewCursors/viewCursor.ts | 6 +- .../viewParts/viewCursors/viewCursors.ts | 6 +- src/vs/editor/common/config/editorOptions.ts | 17 +- .../common/cursor/cursorTypeOperations.ts | 1 - .../common/standalone/standaloneEnums.ts | 251 ++++++++--------- src/vs/monaco.d.ts | 259 +++++++++--------- 6 files changed, 282 insertions(+), 258 deletions(-) diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index b69180772cc8c..42564febfc0bf 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -63,7 +63,8 @@ export class ViewCursor { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._cursorStyle = options.get(EditorOption.cursorStyle); + const typeMode = options.get(EditorOption.inputType); + this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -130,7 +131,8 @@ export class ViewCursor { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._cursorStyle = options.get(EditorOption.cursorStyle); + const typeMode = options.get(EditorOption.inputType); + this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index fc8695d3e1f01..98ebc1b4b8862 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -59,7 +59,8 @@ export class ViewCursors extends ViewPart { const options = this._context.configuration.options; this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - this._cursorStyle = options.get(EditorOption.cursorStyle); + const typeMode = options.get(EditorOption.inputType); + this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); this._selectionIsEmpty = true; @@ -114,7 +115,8 @@ export class ViewCursors extends ViewPart { this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - this._cursorStyle = options.get(EditorOption.cursorStyle); + const typeMode = options.get(EditorOption.inputType); + this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 3c91c6997a08c..48efb7bafaa02 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -238,10 +238,15 @@ export interface IEditorOptions { */ cursorSmoothCaretAnimation?: 'off' | 'explicit' | 'on'; /** - * Control the cursor style, either 'block' or 'line'. + * Control the cursor style in insert mode. * Defaults to 'line'. */ cursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; + /** + * Control the cursor style in overtype mode. + * Defaults to 'block'. + */ + overtypeCursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; /** * Control the width of the cursor when cursorStyle is set to 'line' */ @@ -5358,6 +5363,7 @@ export const enum EditorOption { cursorBlinking, cursorSmoothCaretAnimation, cursorStyle, + overtypeCursorStyle, cursorSurroundingLines, cursorSurroundingLinesStyle, cursorWidth, @@ -5700,7 +5706,14 @@ export const EditorOptions = { TextEditorCursorStyle.Line, 'line', ['line', 'block', 'underline', 'line-thin', 'block-outline', 'underline-thin'], cursorStyleFromString, - { description: nls.localize('cursorStyle', "Controls the cursor style.") } + { description: nls.localize('cursorStyle', "Controls the cursor style in insert input mode.") } + )), + overtypeCursorStyle: register(new EditorEnumOption( + EditorOption.overtypeCursorStyle, 'overtypeCursorStyle', + TextEditorCursorStyle.Block, 'block', + ['line', 'block', 'underline', 'line-thin', 'block-outline', 'underline-thin'], + cursorStyleFromString, + { description: nls.localize('overtypeCursorStyle', "Controls the cursor style in overtype input mode.") } )), cursorSurroundingLines: register(new EditorIntOption( EditorOption.cursorSurroundingLines, 'cursorSurroundingLines', diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 61487882def38..17b07736e61cd 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,7 +12,6 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; -import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class TypeOperations { diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index d58a19b023598..f634a4f8febb1 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -202,131 +202,132 @@ export enum EditorOption { cursorBlinking = 26, cursorSmoothCaretAnimation = 27, cursorStyle = 28, - cursorSurroundingLines = 29, - cursorSurroundingLinesStyle = 30, - cursorWidth = 31, - disableLayerHinting = 32, - disableMonospaceOptimizations = 33, - domReadOnly = 34, - dragAndDrop = 35, - dropIntoEditor = 36, - experimentalEditContextEnabled = 37, - emptySelectionClipboard = 38, - experimentalGpuAcceleration = 39, - experimentalWhitespaceRendering = 40, - extraEditorClassName = 41, - fastScrollSensitivity = 42, - find = 43, - fixedOverflowWidgets = 44, - folding = 45, - foldingStrategy = 46, - foldingHighlight = 47, - foldingImportsByDefault = 48, - foldingMaximumRegions = 49, - unfoldOnClickAfterEndOfLine = 50, - fontFamily = 51, - fontInfo = 52, - fontLigatures = 53, - fontSize = 54, - fontWeight = 55, - fontVariations = 56, - formatOnPaste = 57, - formatOnType = 58, - glyphMargin = 59, - gotoLocation = 60, - hideCursorInOverviewRuler = 61, - hover = 62, - inDiffEditor = 63, - inlineSuggest = 64, - inputType = 65, - letterSpacing = 66, - lightbulb = 67, - lineDecorationsWidth = 68, - lineHeight = 69, - lineNumbers = 70, - lineNumbersMinChars = 71, - linkedEditing = 72, - links = 73, - matchBrackets = 74, - minimap = 75, - mouseStyle = 76, - mouseWheelScrollSensitivity = 77, - mouseWheelZoom = 78, - multiCursorMergeOverlapping = 79, - multiCursorModifier = 80, - multiCursorPaste = 81, - multiCursorLimit = 82, - occurrencesHighlight = 83, - occurrencesHighlightDelay = 84, - overviewRulerBorder = 85, - overviewRulerLanes = 86, - padding = 87, - pasteAs = 88, - parameterHints = 89, - peekWidgetDefaultFocus = 90, - placeholder = 91, - definitionLinkOpensInPeek = 92, - quickSuggestions = 93, - quickSuggestionsDelay = 94, - readOnly = 95, - readOnlyMessage = 96, - renameOnType = 97, - renderControlCharacters = 98, - renderFinalNewline = 99, - renderLineHighlight = 100, - renderLineHighlightOnlyWhenFocus = 101, - renderValidationDecorations = 102, - renderWhitespace = 103, - revealHorizontalRightPadding = 104, - roundedSelection = 105, - rulers = 106, - scrollbar = 107, - scrollBeyondLastColumn = 108, - scrollBeyondLastLine = 109, - scrollPredominantAxis = 110, - selectionClipboard = 111, - selectionHighlight = 112, - selectOnLineNumbers = 113, - showFoldingControls = 114, - showUnused = 115, - snippetSuggestions = 116, - smartSelect = 117, - smoothScrolling = 118, - stickyScroll = 119, - stickyTabStops = 120, - stopRenderingLineAfter = 121, - suggest = 122, - suggestFontSize = 123, - suggestLineHeight = 124, - suggestOnTriggerCharacters = 125, - suggestSelection = 126, - tabCompletion = 127, - tabIndex = 128, - unicodeHighlighting = 129, - unusualLineTerminators = 130, - useShadowDOM = 131, - useTabStops = 132, - wordBreak = 133, - wordSegmenterLocales = 134, - wordSeparators = 135, - wordWrap = 136, - wordWrapBreakAfterCharacters = 137, - wordWrapBreakBeforeCharacters = 138, - wordWrapColumn = 139, - wordWrapOverride1 = 140, - wordWrapOverride2 = 141, - wrappingIndent = 142, - wrappingStrategy = 143, - showDeprecated = 144, - inlayHints = 145, - editorClassName = 146, - pixelRatio = 147, - tabFocusMode = 148, - layoutInfo = 149, - wrappingInfo = 150, - defaultColorDecorators = 151, - colorDecoratorsActivatedOn = 152, - inlineCompletionsAccessibilityVerbose = 153 + overtypeCursorStyle = 29, + cursorSurroundingLines = 30, + cursorSurroundingLinesStyle = 31, + cursorWidth = 32, + disableLayerHinting = 33, + disableMonospaceOptimizations = 34, + domReadOnly = 35, + dragAndDrop = 36, + dropIntoEditor = 37, + experimentalEditContextEnabled = 38, + emptySelectionClipboard = 39, + experimentalGpuAcceleration = 40, + experimentalWhitespaceRendering = 41, + extraEditorClassName = 42, + fastScrollSensitivity = 43, + find = 44, + fixedOverflowWidgets = 45, + folding = 46, + foldingStrategy = 47, + foldingHighlight = 48, + foldingImportsByDefault = 49, + foldingMaximumRegions = 50, + unfoldOnClickAfterEndOfLine = 51, + fontFamily = 52, + fontInfo = 53, + fontLigatures = 54, + fontSize = 55, + fontWeight = 56, + fontVariations = 57, + formatOnPaste = 58, + formatOnType = 59, + glyphMargin = 60, + gotoLocation = 61, + hideCursorInOverviewRuler = 62, + hover = 63, + inDiffEditor = 64, + inlineSuggest = 65, + inputType = 66, + letterSpacing = 67, + lightbulb = 68, + lineDecorationsWidth = 69, + lineHeight = 70, + lineNumbers = 71, + lineNumbersMinChars = 72, + linkedEditing = 73, + links = 74, + matchBrackets = 75, + minimap = 76, + mouseStyle = 77, + mouseWheelScrollSensitivity = 78, + mouseWheelZoom = 79, + multiCursorMergeOverlapping = 80, + multiCursorModifier = 81, + multiCursorPaste = 82, + multiCursorLimit = 83, + occurrencesHighlight = 84, + occurrencesHighlightDelay = 85, + overviewRulerBorder = 86, + overviewRulerLanes = 87, + padding = 88, + pasteAs = 89, + parameterHints = 90, + peekWidgetDefaultFocus = 91, + placeholder = 92, + definitionLinkOpensInPeek = 93, + quickSuggestions = 94, + quickSuggestionsDelay = 95, + readOnly = 96, + readOnlyMessage = 97, + renameOnType = 98, + renderControlCharacters = 99, + renderFinalNewline = 100, + renderLineHighlight = 101, + renderLineHighlightOnlyWhenFocus = 102, + renderValidationDecorations = 103, + renderWhitespace = 104, + revealHorizontalRightPadding = 105, + roundedSelection = 106, + rulers = 107, + scrollbar = 108, + scrollBeyondLastColumn = 109, + scrollBeyondLastLine = 110, + scrollPredominantAxis = 111, + selectionClipboard = 112, + selectionHighlight = 113, + selectOnLineNumbers = 114, + showFoldingControls = 115, + showUnused = 116, + snippetSuggestions = 117, + smartSelect = 118, + smoothScrolling = 119, + stickyScroll = 120, + stickyTabStops = 121, + stopRenderingLineAfter = 122, + suggest = 123, + suggestFontSize = 124, + suggestLineHeight = 125, + suggestOnTriggerCharacters = 126, + suggestSelection = 127, + tabCompletion = 128, + tabIndex = 129, + unicodeHighlighting = 130, + unusualLineTerminators = 131, + useShadowDOM = 132, + useTabStops = 133, + wordBreak = 134, + wordSegmenterLocales = 135, + wordSeparators = 136, + wordWrap = 137, + wordWrapBreakAfterCharacters = 138, + wordWrapBreakBeforeCharacters = 139, + wordWrapColumn = 140, + wordWrapOverride1 = 141, + wordWrapOverride2 = 142, + wrappingIndent = 143, + wrappingStrategy = 144, + showDeprecated = 145, + inlayHints = 146, + editorClassName = 147, + pixelRatio = 148, + tabFocusMode = 149, + layoutInfo = 150, + wrappingInfo = 151, + defaultColorDecorators = 152, + colorDecoratorsActivatedOn = 153, + inlineCompletionsAccessibilityVerbose = 154 } /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index ce3cb09a01457..986dc9d9f69de 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3284,10 +3284,15 @@ declare namespace monaco.editor { */ cursorSmoothCaretAnimation?: 'off' | 'explicit' | 'on'; /** - * Control the cursor style, either 'block' or 'line'. + * Control the cursor style in insert mode. * Defaults to 'line'. */ cursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; + /** + * Control the cursor style in overtype mode. + * Defaults to 'block'. + */ + overtypeCursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; /** * Control the width of the cursor when cursorStyle is set to 'line' */ @@ -4908,131 +4913,132 @@ declare namespace monaco.editor { cursorBlinking = 26, cursorSmoothCaretAnimation = 27, cursorStyle = 28, - cursorSurroundingLines = 29, - cursorSurroundingLinesStyle = 30, - cursorWidth = 31, - disableLayerHinting = 32, - disableMonospaceOptimizations = 33, - domReadOnly = 34, - dragAndDrop = 35, - dropIntoEditor = 36, - experimentalEditContextEnabled = 37, - emptySelectionClipboard = 38, - experimentalGpuAcceleration = 39, - experimentalWhitespaceRendering = 40, - extraEditorClassName = 41, - fastScrollSensitivity = 42, - find = 43, - fixedOverflowWidgets = 44, - folding = 45, - foldingStrategy = 46, - foldingHighlight = 47, - foldingImportsByDefault = 48, - foldingMaximumRegions = 49, - unfoldOnClickAfterEndOfLine = 50, - fontFamily = 51, - fontInfo = 52, - fontLigatures = 53, - fontSize = 54, - fontWeight = 55, - fontVariations = 56, - formatOnPaste = 57, - formatOnType = 58, - glyphMargin = 59, - gotoLocation = 60, - hideCursorInOverviewRuler = 61, - hover = 62, - inDiffEditor = 63, - inlineSuggest = 64, - inputType = 65, - letterSpacing = 66, - lightbulb = 67, - lineDecorationsWidth = 68, - lineHeight = 69, - lineNumbers = 70, - lineNumbersMinChars = 71, - linkedEditing = 72, - links = 73, - matchBrackets = 74, - minimap = 75, - mouseStyle = 76, - mouseWheelScrollSensitivity = 77, - mouseWheelZoom = 78, - multiCursorMergeOverlapping = 79, - multiCursorModifier = 80, - multiCursorPaste = 81, - multiCursorLimit = 82, - occurrencesHighlight = 83, - occurrencesHighlightDelay = 84, - overviewRulerBorder = 85, - overviewRulerLanes = 86, - padding = 87, - pasteAs = 88, - parameterHints = 89, - peekWidgetDefaultFocus = 90, - placeholder = 91, - definitionLinkOpensInPeek = 92, - quickSuggestions = 93, - quickSuggestionsDelay = 94, - readOnly = 95, - readOnlyMessage = 96, - renameOnType = 97, - renderControlCharacters = 98, - renderFinalNewline = 99, - renderLineHighlight = 100, - renderLineHighlightOnlyWhenFocus = 101, - renderValidationDecorations = 102, - renderWhitespace = 103, - revealHorizontalRightPadding = 104, - roundedSelection = 105, - rulers = 106, - scrollbar = 107, - scrollBeyondLastColumn = 108, - scrollBeyondLastLine = 109, - scrollPredominantAxis = 110, - selectionClipboard = 111, - selectionHighlight = 112, - selectOnLineNumbers = 113, - showFoldingControls = 114, - showUnused = 115, - snippetSuggestions = 116, - smartSelect = 117, - smoothScrolling = 118, - stickyScroll = 119, - stickyTabStops = 120, - stopRenderingLineAfter = 121, - suggest = 122, - suggestFontSize = 123, - suggestLineHeight = 124, - suggestOnTriggerCharacters = 125, - suggestSelection = 126, - tabCompletion = 127, - tabIndex = 128, - unicodeHighlighting = 129, - unusualLineTerminators = 130, - useShadowDOM = 131, - useTabStops = 132, - wordBreak = 133, - wordSegmenterLocales = 134, - wordSeparators = 135, - wordWrap = 136, - wordWrapBreakAfterCharacters = 137, - wordWrapBreakBeforeCharacters = 138, - wordWrapColumn = 139, - wordWrapOverride1 = 140, - wordWrapOverride2 = 141, - wrappingIndent = 142, - wrappingStrategy = 143, - showDeprecated = 144, - inlayHints = 145, - editorClassName = 146, - pixelRatio = 147, - tabFocusMode = 148, - layoutInfo = 149, - wrappingInfo = 150, - defaultColorDecorators = 151, - colorDecoratorsActivatedOn = 152, - inlineCompletionsAccessibilityVerbose = 153 + overtypeCursorStyle = 29, + cursorSurroundingLines = 30, + cursorSurroundingLinesStyle = 31, + cursorWidth = 32, + disableLayerHinting = 33, + disableMonospaceOptimizations = 34, + domReadOnly = 35, + dragAndDrop = 36, + dropIntoEditor = 37, + experimentalEditContextEnabled = 38, + emptySelectionClipboard = 39, + experimentalGpuAcceleration = 40, + experimentalWhitespaceRendering = 41, + extraEditorClassName = 42, + fastScrollSensitivity = 43, + find = 44, + fixedOverflowWidgets = 45, + folding = 46, + foldingStrategy = 47, + foldingHighlight = 48, + foldingImportsByDefault = 49, + foldingMaximumRegions = 50, + unfoldOnClickAfterEndOfLine = 51, + fontFamily = 52, + fontInfo = 53, + fontLigatures = 54, + fontSize = 55, + fontWeight = 56, + fontVariations = 57, + formatOnPaste = 58, + formatOnType = 59, + glyphMargin = 60, + gotoLocation = 61, + hideCursorInOverviewRuler = 62, + hover = 63, + inDiffEditor = 64, + inlineSuggest = 65, + inputType = 66, + letterSpacing = 67, + lightbulb = 68, + lineDecorationsWidth = 69, + lineHeight = 70, + lineNumbers = 71, + lineNumbersMinChars = 72, + linkedEditing = 73, + links = 74, + matchBrackets = 75, + minimap = 76, + mouseStyle = 77, + mouseWheelScrollSensitivity = 78, + mouseWheelZoom = 79, + multiCursorMergeOverlapping = 80, + multiCursorModifier = 81, + multiCursorPaste = 82, + multiCursorLimit = 83, + occurrencesHighlight = 84, + occurrencesHighlightDelay = 85, + overviewRulerBorder = 86, + overviewRulerLanes = 87, + padding = 88, + pasteAs = 89, + parameterHints = 90, + peekWidgetDefaultFocus = 91, + placeholder = 92, + definitionLinkOpensInPeek = 93, + quickSuggestions = 94, + quickSuggestionsDelay = 95, + readOnly = 96, + readOnlyMessage = 97, + renameOnType = 98, + renderControlCharacters = 99, + renderFinalNewline = 100, + renderLineHighlight = 101, + renderLineHighlightOnlyWhenFocus = 102, + renderValidationDecorations = 103, + renderWhitespace = 104, + revealHorizontalRightPadding = 105, + roundedSelection = 106, + rulers = 107, + scrollbar = 108, + scrollBeyondLastColumn = 109, + scrollBeyondLastLine = 110, + scrollPredominantAxis = 111, + selectionClipboard = 112, + selectionHighlight = 113, + selectOnLineNumbers = 114, + showFoldingControls = 115, + showUnused = 116, + snippetSuggestions = 117, + smartSelect = 118, + smoothScrolling = 119, + stickyScroll = 120, + stickyTabStops = 121, + stopRenderingLineAfter = 122, + suggest = 123, + suggestFontSize = 124, + suggestLineHeight = 125, + suggestOnTriggerCharacters = 126, + suggestSelection = 127, + tabCompletion = 128, + tabIndex = 129, + unicodeHighlighting = 130, + unusualLineTerminators = 131, + useShadowDOM = 132, + useTabStops = 133, + wordBreak = 134, + wordSegmenterLocales = 135, + wordSeparators = 136, + wordWrap = 137, + wordWrapBreakAfterCharacters = 138, + wordWrapBreakBeforeCharacters = 139, + wordWrapColumn = 140, + wordWrapOverride1 = 141, + wordWrapOverride2 = 142, + wrappingIndent = 143, + wrappingStrategy = 144, + showDeprecated = 145, + inlayHints = 146, + editorClassName = 147, + pixelRatio = 148, + tabFocusMode = 149, + layoutInfo = 150, + wrappingInfo = 151, + defaultColorDecorators = 152, + colorDecoratorsActivatedOn = 153, + inlineCompletionsAccessibilityVerbose = 154 } export const EditorOptions: { @@ -5067,6 +5073,7 @@ declare namespace monaco.editor { cursorBlinking: IEditorOption; cursorSmoothCaretAnimation: IEditorOption; cursorStyle: IEditorOption; + overtypeCursorStyle: IEditorOption; cursorSurroundingLines: IEditorOption; cursorSurroundingLinesStyle: IEditorOption; cursorWidth: IEditorOption; From b17acbe6b60af71cff93c71525dcf57acdae4905 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Nov 2024 13:27:44 +0100 Subject: [PATCH 03/44] adding action to toggle between overtype and insert mode --- .../parts/editor/editor.contribution.ts | 5 +++- .../browser/parts/editor/editorActions.ts | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 1c777faacaf8a..8c75858d98106 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -43,7 +43,8 @@ import { SplitEditorToFirstGroupAction, SplitEditorToLastGroupAction, SplitEditorToLeftGroupAction, SplitEditorToNextGroupAction, SplitEditorToPreviousGroupAction, SplitEditorToRightGroupAction, NavigateForwardInEditsAction, NavigateBackwardsInEditsAction, NavigateForwardInNavigationsAction, NavigateBackwardsInNavigationsAction, NavigatePreviousInNavigationsAction, NavigatePreviousInEditsAction, NavigateToLastNavigationLocationAction, MaximizeGroupHideSidebarAction, MoveEditorToNewWindowAction, CopyEditorToNewindowAction, RestoreEditorsToMainWindowAction, ToggleMaximizeEditorGroupAction, MinimizeOtherGroupsHideSidebarAction, CopyEditorGroupToNewWindowAction, - MoveEditorGroupToNewWindowAction, NewEmptyEditorWindowAction + MoveEditorGroupToNewWindowAction, NewEmptyEditorWindowAction, + ToggleOvertypeInsertMode } from './editorActions.js'; import { CLOSE_EDITORS_AND_GROUP_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITORS_TO_THE_RIGHT_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_EDITOR_GROUP_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID, @@ -171,6 +172,8 @@ quickAccessRegistry.registerQuickAccessProvider({ //#region Actions & Commands +registerAction2(ToggleOvertypeInsertMode); + registerAction2(ChangeLanguageAction); registerAction2(ChangeEOLAction); registerAction2(ChangeEncodingAction); diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 1b1a39b30cacc..4270a983b76ff 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2696,3 +2696,29 @@ export class NewEmptyEditorWindowAction extends Action2 { auxiliaryEditorPart.activeGroup.focus(); } } + +export class ToggleOvertypeInsertMode extends Action2 { + + constructor() { + super({ + id: 'editor.action.toggleOvertypeInsertMode', + title: { + ...localize2('toggleOvertypeInsertMode', "Toggle Overtype/Insert Mode"), + mnemonicTitle: localize({ key: 'mitoggleOvertypeInsertMode', comment: ['&& denotes a mnemonic'] }, "&&Toggle Overtype/Insert Mode"), + }, + metadata: { + description: localize2('toggleOvertypeMode.description', "Toggle between overtype and insert mode"), + }, + f1: true, + category: Categories.View + }); + } + + override async run(accessor: ServicesAccessor): Promise { + const configurationService = accessor.get(IConfigurationService); + const inputType = configurationService.getValue<'insert' | 'overtype' | undefined>('editor.inputType'); + const newInputType = inputType ? (inputType === 'insert' ? 'overtype' : 'insert') : 'insert'; + return configurationService.updateValue('editor.inputType', newInputType); + } +} + From 1fd450b2ac2bf315f29794ea66a25370e248385e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Nov 2024 16:13:33 +0100 Subject: [PATCH 04/44] adding a contribution which adds a statu bar icon --- .../contrib/codeEditor/browser/inputMode.ts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/vs/workbench/contrib/codeEditor/browser/inputMode.ts diff --git a/src/vs/workbench/contrib/codeEditor/browser/inputMode.ts b/src/vs/workbench/contrib/codeEditor/browser/inputMode.ts new file mode 100644 index 0000000000000..bcdd156edb044 --- /dev/null +++ b/src/vs/workbench/contrib/codeEditor/browser/inputMode.ts @@ -0,0 +1,64 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + +import { DisposableStore } from '../../../../base/common/lifecycle.js'; +import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; +import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; +import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from '../../../services/statusbar/browser/statusbar.js'; + +export class InputModeStatusContribution implements IWorkbenchContribution { + + public static ID: string = 'status.inputMode'; + + // private showInStatusBar!: boolean; + private readonly disposableStore: DisposableStore = new DisposableStore(); + private entryAccessor: IStatusbarEntryAccessor | undefined; + + constructor( + @IStatusbarService private readonly statusBarService: IStatusbarService, + @IConfigurationService private readonly _configurationService: IConfigurationService + ) { + this.disposableStore.add(this._configurationService.onDidChangeConfiguration(e => { + // if (e.affectsConfiguration('showInputModeInStatusBar')) { + // this._updateStatusBarEntry(); + // if (this.entryAccessor && !this.showInStatusBar) { + // this.entryAccessor.dispose(); + // this.entryAccessor = undefined; + // } + // } + if (e.affectsConfiguration('inputMode')) { + this.entryAccessor?.update(this.entry); + } + })); + this._updateStatusBarEntry(); + } + + private get entry(): IStatusbarEntry { + // const inputMode = this._configurationService.getValue(''); + return { + text: 'Insert', + name: 'Insert', + ariaLabel: 'Insert', + }; + } + + private _addStatusBarEntry = () => { + this.entryAccessor = this.statusBarService.addEntry(this.entry, 'status.inputMode', StatusbarAlignment.RIGHT, 5); + }; + + private _updateStatusBarEntry = () => { + // this.showInStatusBar = this._configurationService.getValue('showInputModeInStatusBar'); + if (!this.entryAccessor) { // this.showInStatusBar + this._addStatusBarEntry(); + } + }; + + public dispose(): void { + this.disposableStore.dispose(); + } +} + +registerWorkbenchContribution2(InputModeStatusContribution.ID, InputModeStatusContribution, WorkbenchPhase.Eventually); From c3b3496085e4a0eea6d72534c007943897970c22 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 11 Nov 2024 16:24:49 +0100 Subject: [PATCH 05/44] adding same as tab focus mode --- .../browser/config/editorConfiguration.ts | 2 + src/vs/editor/browser/config/inputMode.ts | 27 +++++++ .../viewParts/viewCursors/viewCursor.ts | 4 +- .../viewParts/viewCursors/viewCursors.ts | 4 +- .../widget/codeEditor/codeEditorWidget.ts | 2 - src/vs/editor/common/config/editorOptions.ts | 17 +++-- src/vs/editor/common/cursor/cursor.ts | 6 +- .../common/cursor/cursorTypeEditOperations.ts | 6 +- .../common/cursor/cursorTypeOperations.ts | 8 +- .../common/standalone/standaloneEnums.ts | 2 +- .../editor/common/viewModel/viewModelImpl.ts | 4 +- src/vs/monaco.d.ts | 8 +- .../browser/parts/editor/editorActions.ts | 9 +-- .../browser/parts/editor/editorStatus.ts | 74 +++++++++++++++++++ .../contrib/codeEditor/browser/inputMode.ts | 64 ---------------- 15 files changed, 137 insertions(+), 100 deletions(-) create mode 100644 src/vs/editor/browser/config/inputMode.ts delete mode 100644 src/vs/workbench/contrib/codeEditor/browser/inputMode.ts diff --git a/src/vs/editor/browser/config/editorConfiguration.ts b/src/vs/editor/browser/config/editorConfiguration.ts index d65d85cfe25f6..1527618f833cb 100644 --- a/src/vs/editor/browser/config/editorConfiguration.ts +++ b/src/vs/editor/browser/config/editorConfiguration.ts @@ -22,6 +22,7 @@ import { AccessibilitySupport, IAccessibilityService } from '../../../platform/a import { getWindow, getWindowById } from '../../../base/browser/dom.js'; import { PixelRatio } from '../../../base/browser/pixelRatio.js'; import { MenuId } from '../../../platform/actions/common/actions.js'; +import { InputMode } from './inputMode.js'; export interface IEditorConstructionOptions extends IEditorOptions { /** @@ -126,6 +127,7 @@ export class EditorConfiguration extends Disposable implements IEditorConfigurat emptySelectionClipboard: partialEnv.emptySelectionClipboard, pixelRatio: partialEnv.pixelRatio, tabFocusMode: TabFocus.getTabFocusMode(), + inputMode: InputMode.getInputMode(), accessibilitySupport: partialEnv.accessibilitySupport, glyphMarginDecorationLaneCount: this._glyphMarginDecorationLaneCount }; diff --git a/src/vs/editor/browser/config/inputMode.ts b/src/vs/editor/browser/config/inputMode.ts new file mode 100644 index 0000000000000..3a48239d36e98 --- /dev/null +++ b/src/vs/editor/browser/config/inputMode.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Emitter, Event } from '../../../base/common/event.js'; + +class InputModeImpl { + + private _inputMode: 'overtype' | 'insert' = 'insert'; + private readonly _onDidChangeInputMode = new Emitter<'overtype' | 'insert'>(); + public readonly onDidChangeInputMode: Event<'overtype' | 'insert'> = this._onDidChangeInputMode.event; + + public getInputMode(): 'overtype' | 'insert' { + return this._inputMode; + } + + public setInputMode(inputMode: 'overtype' | 'insert'): void { + this._inputMode = inputMode; + this._onDidChangeInputMode.fire(this._inputMode); + } +} + +/** + * Controls the type mode, whether insert or overtype + */ +export const InputMode = new InputModeImpl(); diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 42564febfc0bf..e88c2a5792604 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -63,7 +63,7 @@ export class ViewCursor { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - const typeMode = options.get(EditorOption.inputType); + const typeMode = options.get(EditorOption.inputMode); this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; @@ -131,7 +131,7 @@ export class ViewCursor { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - const typeMode = options.get(EditorOption.inputType); + const typeMode = options.get(EditorOption.inputMode); this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 98ebc1b4b8862..0f83d850f3f88 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -59,7 +59,7 @@ export class ViewCursors extends ViewPart { const options = this._context.configuration.options; this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - const typeMode = options.get(EditorOption.inputType); + const typeMode = options.get(EditorOption.inputMode); this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); @@ -115,7 +115,7 @@ export class ViewCursors extends ViewPart { this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - const typeMode = options.get(EditorOption.inputType); + const typeMode = options.get(EditorOption.inputMode); this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); diff --git a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts index 9b34b9922b73b..1f78e50887b1e 100644 --- a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts @@ -1805,7 +1805,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE paste: (text: string, pasteOnNewLine: boolean, multicursorText: string[] | null, mode: string | null) => { this._paste('keyboard', text, pasteOnNewLine, multicursorText, mode); }, - // type: (text: string) => { this._type('keyboard', text); }, @@ -1828,7 +1827,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE const payload: editorBrowser.PastePayload = { text, pasteOnNewLine, multicursorText, mode }; this._commandService.executeCommand(editorCommon.Handler.Paste, payload); }, - // type: (text: string) => { const payload: editorCommon.TypePayload = { text }; this._commandService.executeCommand(editorCommon.Handler.Type, payload); diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 48efb7bafaa02..ac7d2eee6f7e2 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -780,9 +780,9 @@ export interface IEditorOptions { inlineCompletionsAccessibilityVerbose?: boolean; /** - * Controls the input type mode, whether it is insert or overtype + * Controls the input mode, whether it is insert or overtype */ - inputType?: 'insert' | 'overtype'; + inputMode?: 'insert' | 'overtype'; } /** @@ -983,6 +983,7 @@ export interface IEnvironmentalOptions { readonly emptySelectionClipboard: boolean; readonly pixelRatio: number; readonly tabFocusMode: boolean; + readonly inputMode: 'insert' | 'overtype'; readonly accessibilitySupport: AccessibilitySupport; readonly glyphMarginDecorationLaneCount: number; } @@ -5400,7 +5401,7 @@ export const enum EditorOption { hover, inDiffEditor, inlineSuggest, - inputType, + inputMode, letterSpacing, lightbulb, lineDecorationsWidth, @@ -5862,16 +5863,16 @@ export const EditorOptions = { inDiffEditor: register(new EditorBooleanOption( EditorOption.inDiffEditor, 'inDiffEditor', false )), - inputType: register(new EditorStringEnumOption( - EditorOption.inputType, 'inputType', + inputMode: register(new EditorStringEnumOption( + EditorOption.inputMode, 'inputMode', 'insert' as 'insert' | 'overtype', ['insert', 'overtype'] as const, { enumDescriptions: [ - nls.localize('inputType.insert', "Insert text at cursor position"), - nls.localize('inputType.overtype', "Replace text at cursor position") + nls.localize('inputMode.insert', "Insert text at cursor position"), + nls.localize('inputMode.overtype', "Replace text at cursor position") ], - description: nls.localize('inputType', "Controls how text is inputted, whether it is inserted or it overwrites existing content.") + description: nls.localize('inputMode', "Controls how text is inputted, whether it is inserted or it overwrites existing content.") } )), letterSpacing: register(new EditorFloatOption( diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index c791cc19e66bc..b00431a33939e 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -554,7 +554,7 @@ export class CursorsController extends Disposable { public type(eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration, text: string, source?: string | null | undefined): void { // this._executeEdit(() => { console.log('source : ', source); - const inputType = editorConfiguration.getRawOptions().inputType; + const inputMode = editorConfiguration.getRawOptions().inputMode; if (source === 'keyboard') { // If this event is coming straight from the keyboard, look for electric characters and enter @@ -565,13 +565,13 @@ export class CursorsController extends Disposable { const chr = text.substr(offset, charLength); // Here we must interpret each typed character individually - this._executeEditOperation(TypeOperations.typeWithInterceptors(inputType, !!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); + this._executeEditOperation(TypeOperations.typeWithInterceptors(inputMode, !!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); offset += charLength; } } else { - this._executeEditOperation(TypeOperations.typeWithoutInterceptors(inputType, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text)); + this._executeEditOperation(TypeOperations.typeWithoutInterceptors(inputMode, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text)); } }, eventsCollector, source); } diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index f1f3a937b13a2..de5c4e2be9c16 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -483,14 +483,14 @@ export class InterceptorElectricCharOperation { export class SimpleCharacterTypeOperation { - public static getEdits(inputType: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // + public static getEdits(inputMode: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // // A simple character type const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { - const ChosenReplaceCommand = inputType === 'overtype' ? ReplaceOvertypeCommand : ReplaceCommand; + const ChosenReplaceCommand = inputMode === 'overtype' ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], ch); } - console.log('inputType : ', inputType); + console.log('inputType : ', inputMode); console.log('SimpleCharacterTypeOperation.getEdits : ', commands); const opType = getTypingOperation(ch, prevEditOperationType); return new EditOperationResult(opType, commands, { diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 17b07736e61cd..091918dc29035 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -162,7 +162,7 @@ export class TypeOperations { return null; } - public static typeWithInterceptors(inputType: 'insert' | 'overtype' | undefined, isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { // + public static typeWithInterceptors(inputMode: 'insert' | 'overtype' | undefined, isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { // const enterEdits = EnterOperation.getEdits(config, model, selections, ch, isDoingComposition); if (enterEdits !== undefined) { @@ -194,11 +194,11 @@ export class TypeOperations { return interceptorElectricCharOperation; } - return SimpleCharacterTypeOperation.getEdits(inputType, prevEditOperationType, selections, ch); + return SimpleCharacterTypeOperation.getEdits(inputMode, prevEditOperationType, selections, ch); } - public static typeWithoutInterceptors(inputType: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { // - return TypeWithoutInterceptorsOperation.getEdits(inputType, prevEditOperationType, selections, str); + public static typeWithoutInterceptors(inputMode: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { // + return TypeWithoutInterceptorsOperation.getEdits(inputMode, prevEditOperationType, selections, str); } } diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index f634a4f8febb1..189aae537e049 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -239,7 +239,7 @@ export enum EditorOption { hover = 63, inDiffEditor = 64, inlineSuggest = 65, - inputType = 66, + inputMode = 66, letterSpacing = 67, lightbulb = 68, lineDecorationsWidth = 69, diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 36aea0cea9353..2c3aab9119175 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -1057,10 +1057,10 @@ export class ViewModel extends Disposable implements IViewModel { public endComposition(source?: string | null | undefined): void { this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source)); } - public type(text: string, source?: string | null | undefined): void { // + public type(text: string, source?: string | null | undefined): void { this._executeCursorEdit((eventsCollector, editorConfiguration) => this._cursor.type(eventsCollector, editorConfiguration, text, source)); } - public compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { // + public compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { this._executeCursorEdit(eventsCollector => this._cursor.compositionType(eventsCollector, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta, source)); } public paste(text: string, pasteOnNewLine: boolean, multicursorText?: string[] | null | undefined, source?: string | null | undefined): void { diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 986dc9d9f69de..e804edf11ba16 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3816,9 +3816,9 @@ declare namespace monaco.editor { */ inlineCompletionsAccessibilityVerbose?: boolean; /** - * Controls the input type mode, whether it is insert or overtype + * Controls the input mode, whether it is insert or overtype */ - inputType?: 'insert' | 'overtype'; + inputMode?: 'insert' | 'overtype'; } export interface IDiffEditorBaseOptions { @@ -4950,7 +4950,7 @@ declare namespace monaco.editor { hover = 63, inDiffEditor = 64, inlineSuggest = 65, - inputType = 66, + inputMode = 66, letterSpacing = 67, lightbulb = 68, lineDecorationsWidth = 69, @@ -5110,7 +5110,7 @@ declare namespace monaco.editor { hideCursorInOverviewRuler: IEditorOption; hover: IEditorOption>>; inDiffEditor: IEditorOption; - inputType: IEditorOption; + inputMode: IEditorOption; letterSpacing: IEditorOption; lightbulb: IEditorOption>>; lineDecorationsWidth: IEditorOption; diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 4270a983b76ff..48abdc0814ebb 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -38,6 +38,7 @@ import { ICommandActionTitle } from '../../../../platform/action/common/action.j import { IProgressService, ProgressLocation } from '../../../../platform/progress/common/progress.js'; import { resolveCommandsContext } from './editorCommandsContext.js'; import { IListService } from '../../../../platform/list/browser/listService.js'; +import { InputMode } from '../../../../editor/browser/config/inputMode.js'; class ExecuteCommandAction extends Action2 { @@ -2715,10 +2716,8 @@ export class ToggleOvertypeInsertMode extends Action2 { } override async run(accessor: ServicesAccessor): Promise { - const configurationService = accessor.get(IConfigurationService); - const inputType = configurationService.getValue<'insert' | 'overtype' | undefined>('editor.inputType'); - const newInputType = inputType ? (inputType === 'insert' ? 'overtype' : 'insert') : 'insert'; - return configurationService.updateValue('editor.inputType', newInputType); + const oldInputMode = InputMode.getInputMode(); + const newInputMode = oldInputMode === 'insert' ? 'overtype' : 'insert'; + InputMode.setInputMode(newInputMode); } } - diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index acc013522c51f..b085db879ea94 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -56,6 +56,7 @@ import { KeybindingWeight } from '../../../../platform/keybinding/common/keybind import { KeyChord, KeyCode, KeyMod } from '../../../../base/common/keyCodes.js'; import { TabFocus } from '../../../../editor/browser/config/tabFocus.js'; import { IEditorGroupsService, IEditorPart } from '../../../services/editor/common/editorGroupsService.js'; +import { InputMode } from '../../../../editor/browser/config/inputMode.js'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private primary: IEncodingSupport, private secondary: IEncodingSupport) { } @@ -149,6 +150,7 @@ class StateChange { encoding: boolean = false; EOL: boolean = false; tabFocusMode: boolean = false; + inputMode: boolean = false; columnSelectionMode: boolean = false; metadata: boolean = false; @@ -160,6 +162,7 @@ class StateChange { this.encoding = this.encoding || other.encoding; this.EOL = this.EOL || other.EOL; this.tabFocusMode = this.tabFocusMode || other.tabFocusMode; + this.inputMode = this.inputMode || other.inputMode; this.columnSelectionMode = this.columnSelectionMode || other.columnSelectionMode; this.metadata = this.metadata || other.metadata; } @@ -172,6 +175,7 @@ class StateChange { || this.encoding || this.EOL || this.tabFocusMode + || this.inputMode || this.columnSelectionMode || this.metadata; } @@ -186,6 +190,7 @@ type StateDelta = ( | { type: 'tabFocusMode'; tabFocusMode: boolean } | { type: 'columnSelectionMode'; columnSelectionMode: boolean } | { type: 'metadata'; metadata: string | undefined } + | { type: 'inputMode'; inputMode: 'overtype' | 'insert' } ); class State { @@ -208,6 +213,9 @@ class State { private _tabFocusMode: boolean | undefined; get tabFocusMode(): boolean | undefined { return this._tabFocusMode; } + private _inputMode: 'overtype' | 'insert' | undefined; + get inputMode(): 'overtype' | 'insert' | undefined { return this._inputMode; } + private _columnSelectionMode: boolean | undefined; get columnSelectionMode(): boolean | undefined { return this._columnSelectionMode; } @@ -260,6 +268,13 @@ class State { } break; + case 'inputMode': + if (this._inputMode !== update.inputMode) { + this._inputMode = update.inputMode; + change.inputMode = true; + } + break; + case 'columnSelectionMode': if (this._columnSelectionMode !== update.columnSelectionMode) { this._columnSelectionMode = update.columnSelectionMode; @@ -307,6 +322,30 @@ class TabFocusMode extends Disposable { } } +class StatusInputMode extends Disposable { + + private readonly _onDidChange = this._register(new Emitter<'overtype' | 'insert'>()); + readonly onDidChange = this._onDidChange.event; + + constructor(@IConfigurationService private readonly configurationService: IConfigurationService) { + super(); + this.registerListeners(); + const inputMode = configurationService.getValue<'overtype' | 'insert'>('editor.inputMode'); + InputMode.setInputMode(inputMode); + } + + private registerListeners(): void { + this._register(InputMode.onDidChangeInputMode(inputMode => this._onDidChange.fire(inputMode))); + this._register(this.configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('editor.inputMode')) { + const inputMode = this.configurationService.getValue<'overtype' | 'insert'>('editor.inputMode'); + InputMode.setInputMode(inputMode); + this._onDidChange.fire(inputMode); + } + })); + } +} + const nlsSingleSelectionRange = localize('singleSelectionRange', "Ln {0}, Col {1} ({2} selected)"); const nlsSingleSelection = localize('singleSelection', "Ln {0}, Col {1}"); const nlsMultiSelectionRange = localize('multiSelectionRange', "{0} selections ({1} characters selected)"); @@ -317,6 +356,7 @@ const nlsEOLCRLF = localize('endOfLineCarriageReturnLineFeed', "CRLF"); class EditorStatus extends Disposable { private readonly tabFocusModeElement = this._register(new MutableDisposable()); + private readonly inputModeElement = this._register(new MutableDisposable()); private readonly columnSelectionModeElement = this._register(new MutableDisposable()); private readonly indentationElement = this._register(new MutableDisposable()); private readonly selectionElement = this._register(new MutableDisposable()); @@ -327,6 +367,7 @@ class EditorStatus extends Disposable { private readonly currentMarkerStatus = this._register(this.instantiationService.createInstance(ShowCurrentMarkerInStatusbarContribution)); private readonly tabFocusMode = this._register(this.instantiationService.createInstance(TabFocusMode)); + private readonly inputMode = this._register(this.instantiationService.createInstance(StatusInputMode)); private readonly state = new State(); private toRender: StateChange | undefined = undefined; @@ -361,6 +402,13 @@ class EditorStatus extends Disposable { this.onTabFocusModeChange(this.configurationService.getValue('editor.tabFocusMode')); } })); + this._register(Event.runAndSubscribe(this.inputMode.onDidChange, (inputMode) => { + if (inputMode !== undefined) { + this.onInputModeChange(inputMode); + } else { + this.onInputModeChange(this.configurationService.getValue('editor.inputMode')); + } + })); } private registerCommands(): void { @@ -422,6 +470,26 @@ class EditorStatus extends Disposable { } } + private updateInputModeElement(inputMode: 'overtype' | 'insert' | undefined): void { + if (!!inputMode) { + if (!this.inputModeElement.value) { + const text = inputMode === 'overtype' ? + localize('inputModeOvertype', 'OVR') + : localize('inputModeInsert', 'INS'); + this.inputModeElement.value = this.statusbarService.addEntry({ + name: localize('status.editor.inputMode', "Accessibility Mode"), + text, + ariaLabel: text, + tooltip: localize('Toggle Input Mode', "Toggle Input Mode"), + command: 'editor.action.toggleOvertypeInsertMode', + kind: 'prominent' + }, 'status.editor.inputMode', StatusbarAlignment.RIGHT, 100.6); + } + } else { + this.inputModeElement.clear(); + } + } + private updateColumnSelectionModeElement(visible: boolean): void { if (visible) { if (!this.columnSelectionModeElement.value) { @@ -586,6 +654,7 @@ class EditorStatus extends Disposable { private doRenderNow(): void { this.updateTabFocusModeElement(!!this.state.tabFocusMode); + this.updateInputModeElement(this.state.inputMode); this.updateColumnSelectionModeElement(!!this.state.columnSelectionMode); this.updateIndentationElement(this.state.indentation); this.updateSelectionElement(this.state.selectionStatus); @@ -872,6 +941,11 @@ class EditorStatus extends Disposable { this.updateState(info); } + private onInputModeChange(inputMode: 'insert' | 'overtype'): void { + const info: StateDelta = { type: 'inputMode', inputMode }; + this.updateState(info); + } + private isActiveEditor(control: IEditorPane): boolean { const activeEditorPane = this.editorService.activeEditorPane; diff --git a/src/vs/workbench/contrib/codeEditor/browser/inputMode.ts b/src/vs/workbench/contrib/codeEditor/browser/inputMode.ts deleted file mode 100644 index bcdd156edb044..0000000000000 --- a/src/vs/workbench/contrib/codeEditor/browser/inputMode.ts +++ /dev/null @@ -1,64 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - - -import { DisposableStore } from '../../../../base/common/lifecycle.js'; -import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; -import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; -import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from '../../../services/statusbar/browser/statusbar.js'; - -export class InputModeStatusContribution implements IWorkbenchContribution { - - public static ID: string = 'status.inputMode'; - - // private showInStatusBar!: boolean; - private readonly disposableStore: DisposableStore = new DisposableStore(); - private entryAccessor: IStatusbarEntryAccessor | undefined; - - constructor( - @IStatusbarService private readonly statusBarService: IStatusbarService, - @IConfigurationService private readonly _configurationService: IConfigurationService - ) { - this.disposableStore.add(this._configurationService.onDidChangeConfiguration(e => { - // if (e.affectsConfiguration('showInputModeInStatusBar')) { - // this._updateStatusBarEntry(); - // if (this.entryAccessor && !this.showInStatusBar) { - // this.entryAccessor.dispose(); - // this.entryAccessor = undefined; - // } - // } - if (e.affectsConfiguration('inputMode')) { - this.entryAccessor?.update(this.entry); - } - })); - this._updateStatusBarEntry(); - } - - private get entry(): IStatusbarEntry { - // const inputMode = this._configurationService.getValue(''); - return { - text: 'Insert', - name: 'Insert', - ariaLabel: 'Insert', - }; - } - - private _addStatusBarEntry = () => { - this.entryAccessor = this.statusBarService.addEntry(this.entry, 'status.inputMode', StatusbarAlignment.RIGHT, 5); - }; - - private _updateStatusBarEntry = () => { - // this.showInStatusBar = this._configurationService.getValue('showInputModeInStatusBar'); - if (!this.entryAccessor) { // this.showInStatusBar - this._addStatusBarEntry(); - } - }; - - public dispose(): void { - this.disposableStore.dispose(); - } -} - -registerWorkbenchContribution2(InputModeStatusContribution.ID, InputModeStatusContribution, WorkbenchPhase.Eventually); From f15cac5f9ea6aa2eab8928fe741efbef828890e7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 11 Nov 2024 17:27:39 +0100 Subject: [PATCH 06/44] polishing --- .../browser/config/editorConfiguration.ts | 2 -- .../viewParts/viewCursors/viewCursor.ts | 23 ++++++++++++----- .../viewParts/viewCursors/viewCursors.ts | 25 +++++++++++++------ src/vs/editor/common/config/editorOptions.ts | 1 - src/vs/editor/common/cursor/cursor.ts | 10 +++----- .../common/cursor/cursorTypeEditOperations.ts | 9 ++++--- .../common/cursor/cursorTypeOperations.ts | 9 ++++--- 7 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/vs/editor/browser/config/editorConfiguration.ts b/src/vs/editor/browser/config/editorConfiguration.ts index 1527618f833cb..d65d85cfe25f6 100644 --- a/src/vs/editor/browser/config/editorConfiguration.ts +++ b/src/vs/editor/browser/config/editorConfiguration.ts @@ -22,7 +22,6 @@ import { AccessibilitySupport, IAccessibilityService } from '../../../platform/a import { getWindow, getWindowById } from '../../../base/browser/dom.js'; import { PixelRatio } from '../../../base/browser/pixelRatio.js'; import { MenuId } from '../../../platform/actions/common/actions.js'; -import { InputMode } from './inputMode.js'; export interface IEditorConstructionOptions extends IEditorOptions { /** @@ -127,7 +126,6 @@ export class EditorConfiguration extends Disposable implements IEditorConfigurat emptySelectionClipboard: partialEnv.emptySelectionClipboard, pixelRatio: partialEnv.pixelRatio, tabFocusMode: TabFocus.getTabFocusMode(), - inputMode: InputMode.getInputMode(), accessibilitySupport: partialEnv.accessibilitySupport, glyphMarginDecorationLaneCount: this._glyphMarginDecorationLaneCount }; diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index e88c2a5792604..9d00cbd3c451c 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -14,6 +14,8 @@ import { RenderingContext, RestrictedRenderingContext } from '../../view/renderi import { ViewContext } from '../../../common/viewModel/viewContext.js'; import * as viewEvents from '../../../common/viewEvents.js'; import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from '../../../../base/browser/ui/mouseCursor/mouseCursor.js'; +import { InputMode } from '../../config/inputMode.js'; +import { Disposable } from '../../../../base/common/lifecycle.js'; export interface IViewCursorRenderData { domNode: HTMLElement; @@ -41,11 +43,11 @@ export enum CursorPlurality { MultiSecondary, } -export class ViewCursor { +export class ViewCursor extends Disposable { private readonly _context: ViewContext; private readonly _domNode: FastDomNode; - private _cursorStyle: TextEditorCursorStyle; + private _cursorStyle!: TextEditorCursorStyle; private _lineCursorWidth: number; private _lineHeight: number; private _typicalHalfwidthCharacterWidth: number; @@ -59,12 +61,12 @@ export class ViewCursor { private _renderData: ViewCursorRenderData | null; constructor(context: ViewContext, plurality: CursorPlurality) { + super(); this._context = context; const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - const typeMode = options.get(EditorOption.inputMode); - this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + this._setCursorStyle(); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -86,6 +88,10 @@ export class ViewCursor { this._lastRenderedContent = ''; this._renderData = null; + + this._register(InputMode.onDidChangeInputMode(() => { + this._setCursorStyle(); + })); } public getDomNode(): FastDomNode { @@ -131,8 +137,7 @@ export class ViewCursor { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - const typeMode = options.get(EditorOption.inputMode); - this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + this._setCursorStyle(); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -236,6 +241,12 @@ export class ViewCursor { return new ViewCursorRenderData(top, range.left, 0, width, height, textContent, textContentClassName); } + private _setCursorStyle(): void { + const options = this._context.configuration.options; + const inputMode = InputMode.getInputMode(); + this._cursorStyle = inputMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + } + private _getTokenClassName(position: Position): string { const lineData = this._context.viewModel.getViewLineData(position.lineNumber); const tokenIndex = lineData.tokens.findTokenIndexAtOffset(position.column - 1); diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 0f83d850f3f88..f38dd90dcb9c3 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -22,6 +22,7 @@ import { registerThemingParticipant } from '../../../../platform/theme/common/th import { isHighContrast } from '../../../../platform/theme/common/theme.js'; import { CursorChangeReason } from '../../../common/cursorEvents.js'; import { WindowIntervalTimer, getWindow } from '../../../../base/browser/dom.js'; +import { InputMode } from '../../config/inputMode.js'; /** * View cursors is a view part responsible for rendering the primary cursor and @@ -33,7 +34,7 @@ export class ViewCursors extends ViewPart { private _readOnly: boolean; private _cursorBlinking: TextEditorCursorBlinkingStyle; - private _cursorStyle: TextEditorCursorStyle; + private _cursorStyle!: TextEditorCursorStyle; private _cursorSmoothCaretAnimation: 'off' | 'explicit' | 'on'; private _experimentalEditContextEnabled: boolean; private _selectionIsEmpty: boolean; @@ -59,8 +60,7 @@ export class ViewCursors extends ViewPart { const options = this._context.configuration.options; this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - const typeMode = options.get(EditorOption.inputMode); - this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + this._setCursorStyle(); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); this._selectionIsEmpty = true; @@ -68,7 +68,7 @@ export class ViewCursors extends ViewPart { this._isVisible = false; - this._primaryCursor = new ViewCursor(this._context, CursorPlurality.Single); + this._primaryCursor = this._register(new ViewCursor(this._context, CursorPlurality.Single)); this._secondaryCursors = []; this._renderData = []; @@ -86,12 +86,17 @@ export class ViewCursors extends ViewPart { this._editorHasFocus = false; this._updateBlinking(); + + this._register(InputMode.onDidChangeInputMode(() => { + this._setCursorStyle(); + })); } public override dispose(): void { super.dispose(); this._startCursorBlinkAnimation.dispose(); this._cursorFlatBlinkInterval.dispose(); + this._secondaryCursors.forEach((cursor) => cursor.dispose()); } public getDomNode(): FastDomNode { @@ -115,13 +120,12 @@ export class ViewCursors extends ViewPart { this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - const typeMode = options.get(EditorOption.inputMode); - this._cursorStyle = typeMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); this._updateBlinking(); this._updateDomClassName(); + this._setCursorStyle(); this._primaryCursor.onConfigurationChanged(e); for (let i = 0, len = this._secondaryCursors.length; i < len; i++) { @@ -151,7 +155,8 @@ export class ViewCursors extends ViewPart { const removeCnt = this._secondaryCursors.length - secondaryPositions.length; for (let i = 0; i < removeCnt; i++) { this._domNode.removeChild(this._secondaryCursors[0].getDomNode()); - this._secondaryCursors.splice(0, 1); + const deletedCursors = this._secondaryCursors.splice(0, 1); + deletedCursors.forEach((deletedCursor) => deletedCursor.dispose()); } } @@ -341,6 +346,12 @@ export class ViewCursors extends ViewPart { return result; } + private _setCursorStyle(): void { + const options = this._context.configuration.options; + const inputMode = InputMode.getInputMode(); + this._cursorStyle = inputMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + } + private _show(): void { this._primaryCursor.show(); for (let i = 0, len = this._secondaryCursors.length; i < len; i++) { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index ac7d2eee6f7e2..5861eba3d4bcf 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -983,7 +983,6 @@ export interface IEnvironmentalOptions { readonly emptySelectionClipboard: boolean; readonly pixelRatio: number; readonly tabFocusMode: boolean; - readonly inputMode: 'insert' | 'overtype'; readonly accessibilitySupport: AccessibilitySupport; readonly glyphMarginDecorationLaneCount: number; } diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index b00431a33939e..c26124874c91e 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -551,10 +551,8 @@ export class CursorsController extends Disposable { }, eventsCollector, source); } - public type(eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration, text: string, source?: string | null | undefined): void { // + public type(eventsCollector: ViewModelEventsCollector, config: IEditorConfiguration, text: string, source?: string | null | undefined): void { // this._executeEdit(() => { - console.log('source : ', source); - const inputMode = editorConfiguration.getRawOptions().inputMode; if (source === 'keyboard') { // If this event is coming straight from the keyboard, look for electric characters and enter @@ -565,18 +563,18 @@ export class CursorsController extends Disposable { const chr = text.substr(offset, charLength); // Here we must interpret each typed character individually - this._executeEditOperation(TypeOperations.typeWithInterceptors(inputMode, !!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); + this._executeEditOperation(TypeOperations.typeWithInterceptors(config, !!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); offset += charLength; } } else { - this._executeEditOperation(TypeOperations.typeWithoutInterceptors(inputMode, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text)); + this._executeEditOperation(TypeOperations.typeWithoutInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text)); } }, eventsCollector, source); } - public compositionType(eventsCollector: ViewModelEventsCollector, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { // + public compositionType(eventsCollector: ViewModelEventsCollector, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { if (text.length === 0 && replacePrevCharCnt === 0 && replaceNextCharCnt === 0) { // this edit is a no-op if (positionDelta !== 0) { diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index de5c4e2be9c16..5fef566684541 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -19,10 +19,11 @@ import { ITextModel } from '../model.js'; import { EnterAction, IndentAction, StandardAutoClosingPairConditional } from '../languages/languageConfiguration.js'; import { getIndentationAtPosition } from '../languages/languageConfigurationRegistry.js'; import { IElectricAction } from '../languages/supports/electricCharacter.js'; -import { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/editorOptions.js'; +import { EditorAutoClosingStrategy, EditorAutoIndentStrategy, EditorOption } from '../config/editorOptions.js'; import { createScopedLineTokens } from '../languages/supports.js'; import { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js'; import { getEnterAction } from '../languages/enterAction.js'; +import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class AutoIndentOperation { @@ -483,7 +484,8 @@ export class InterceptorElectricCharOperation { export class SimpleCharacterTypeOperation { - public static getEdits(inputMode: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // + public static getEdits(editorConfig: IEditorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // + const inputMode = editorConfig.options.get(EditorOption.inputMode); // A simple character type const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { @@ -740,12 +742,11 @@ export class CompositionOperation { export class TypeWithoutInterceptorsOperation { - public static getEdits(inputType: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult { // + public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult { // const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { commands[i] = new ReplaceCommand(selections[i], str); } - console.log('TypeWithoutInterceptorsOperation commands : ', commands); const opType = getTypingOperation(str, prevEditOperationType); return new EditOperationResult(opType, commands, { shouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType), diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 091918dc29035..f5eaf9cfd5281 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,6 +12,7 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; +import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class TypeOperations { @@ -162,7 +163,7 @@ export class TypeOperations { return null; } - public static typeWithInterceptors(inputMode: 'insert' | 'overtype' | undefined, isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { // + public static typeWithInterceptors(editorConfig: IEditorConfiguration, isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { // const enterEdits = EnterOperation.getEdits(config, model, selections, ch, isDoingComposition); if (enterEdits !== undefined) { @@ -194,11 +195,11 @@ export class TypeOperations { return interceptorElectricCharOperation; } - return SimpleCharacterTypeOperation.getEdits(inputMode, prevEditOperationType, selections, ch); + return SimpleCharacterTypeOperation.getEdits(editorConfig, prevEditOperationType, selections, ch); } - public static typeWithoutInterceptors(inputMode: 'insert' | 'overtype' | undefined, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { // - return TypeWithoutInterceptorsOperation.getEdits(inputMode, prevEditOperationType, selections, str); + public static typeWithoutInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { // + return TypeWithoutInterceptorsOperation.getEdits(prevEditOperationType, selections, str); } } From e8fd730bbf772645050a7b44041c6bb381cd9f63 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 09:52:42 +0100 Subject: [PATCH 07/44] polish --- src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts | 4 ++-- src/vs/editor/common/cursor/cursorTypeEditOperations.ts | 5 ++--- src/vs/workbench/browser/parts/editor/editorStatus.ts | 7 +++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index f38dd90dcb9c3..7683b2f41f734 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -155,8 +155,8 @@ export class ViewCursors extends ViewPart { const removeCnt = this._secondaryCursors.length - secondaryPositions.length; for (let i = 0; i < removeCnt; i++) { this._domNode.removeChild(this._secondaryCursors[0].getDomNode()); - const deletedCursors = this._secondaryCursors.splice(0, 1); - deletedCursors.forEach((deletedCursor) => deletedCursor.dispose()); + const cursors = this._secondaryCursors.splice(0, 1); + cursors.forEach((cursor) => cursor.dispose()); } } diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 5fef566684541..745a954dca6c7 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -492,8 +492,7 @@ export class SimpleCharacterTypeOperation { const ChosenReplaceCommand = inputMode === 'overtype' ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], ch); } - console.log('inputType : ', inputMode); - console.log('SimpleCharacterTypeOperation.getEdits : ', commands); + const opType = getTypingOperation(ch, prevEditOperationType); return new EditOperationResult(opType, commands, { shouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, opType), @@ -742,7 +741,7 @@ export class CompositionOperation { export class TypeWithoutInterceptorsOperation { - public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult { // + public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], str: string): EditOperationResult { const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { commands[i] = new ReplaceCommand(selections[i], str); diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index b085db879ea94..5bd2e599c2da3 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -476,11 +476,14 @@ class EditorStatus extends Disposable { const text = inputMode === 'overtype' ? localize('inputModeOvertype', 'OVR') : localize('inputModeInsert', 'INS'); + const name = inputMode === 'overtype' ? + localize('status.editor.overtypeMode', "Toggle Overtype Mode") + : localize('status.editor.insertMode', "Toggle Insert Mode"); this.inputModeElement.value = this.statusbarService.addEntry({ - name: localize('status.editor.inputMode', "Accessibility Mode"), + name, text, ariaLabel: text, - tooltip: localize('Toggle Input Mode', "Toggle Input Mode"), + tooltip: name, command: 'editor.action.toggleOvertypeInsertMode', kind: 'prominent' }, 'status.editor.inputMode', StatusbarAlignment.RIGHT, 100.6); From 0d07ee03ae82c195fc30deb14393c710165406cf Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 10:20:35 +0100 Subject: [PATCH 08/44] updating by clicking on the status bar --- src/vs/workbench/browser/parts/editor/editorStatus.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 5bd2e599c2da3..e04222b974009 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -472,21 +472,26 @@ class EditorStatus extends Disposable { private updateInputModeElement(inputMode: 'overtype' | 'insert' | undefined): void { if (!!inputMode) { - if (!this.inputModeElement.value) { + const getStatusBarEntry = (inputMode: 'overtype' | 'insert'): IStatusbarEntry => { const text = inputMode === 'overtype' ? localize('inputModeOvertype', 'OVR') : localize('inputModeInsert', 'INS'); const name = inputMode === 'overtype' ? localize('status.editor.overtypeMode', "Toggle Overtype Mode") : localize('status.editor.insertMode', "Toggle Insert Mode"); - this.inputModeElement.value = this.statusbarService.addEntry({ + return { name, text, ariaLabel: text, tooltip: name, command: 'editor.action.toggleOvertypeInsertMode', kind: 'prominent' - }, 'status.editor.inputMode', StatusbarAlignment.RIGHT, 100.6); + }; + }; + if (!this.inputModeElement.value) { + this.inputModeElement.value = this.statusbarService.addEntry(getStatusBarEntry(inputMode), 'status.editor.inputMode', StatusbarAlignment.RIGHT, 100.6); + } else { + this.inputModeElement.value.update(getStatusBarEntry(inputMode)); } } else { this.inputModeElement.clear(); From 01de87e3bdaa513ccf6066862e4e08c0023dd87e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 10:42:01 +0100 Subject: [PATCH 09/44] polish --- .../{editor/browser/config => base/common}/inputMode.ts | 2 +- src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts | 2 +- .../editor/browser/viewParts/viewCursors/viewCursors.ts | 2 +- src/vs/editor/common/cursor/cursor.ts | 5 ++--- src/vs/editor/common/cursor/cursorTypeEditOperations.ts | 8 ++++---- src/vs/editor/common/cursor/cursorTypeOperations.ts | 7 +++---- src/vs/editor/common/viewModel/viewModelImpl.ts | 8 ++++---- src/vs/workbench/browser/parts/editor/editorActions.ts | 2 +- src/vs/workbench/browser/parts/editor/editorStatus.ts | 6 +++--- .../browser/contrib/multicursor/notebookMulticursor.ts | 2 +- 10 files changed, 21 insertions(+), 23 deletions(-) rename src/vs/{editor/browser/config => base/common}/inputMode.ts (93%) diff --git a/src/vs/editor/browser/config/inputMode.ts b/src/vs/base/common/inputMode.ts similarity index 93% rename from src/vs/editor/browser/config/inputMode.ts rename to src/vs/base/common/inputMode.ts index 3a48239d36e98..2c263b01991fb 100644 --- a/src/vs/editor/browser/config/inputMode.ts +++ b/src/vs/base/common/inputMode.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter, Event } from '../../../base/common/event.js'; +import { Emitter, Event } from './event.js'; class InputModeImpl { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 9d00cbd3c451c..3f05bb8010f51 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -14,7 +14,7 @@ import { RenderingContext, RestrictedRenderingContext } from '../../view/renderi import { ViewContext } from '../../../common/viewModel/viewContext.js'; import * as viewEvents from '../../../common/viewEvents.js'; import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from '../../../../base/browser/ui/mouseCursor/mouseCursor.js'; -import { InputMode } from '../../config/inputMode.js'; +import { InputMode } from '../../../../base/common/inputMode.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; export interface IViewCursorRenderData { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 7683b2f41f734..86fcf2aed964c 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -22,7 +22,7 @@ import { registerThemingParticipant } from '../../../../platform/theme/common/th import { isHighContrast } from '../../../../platform/theme/common/theme.js'; import { CursorChangeReason } from '../../../common/cursorEvents.js'; import { WindowIntervalTimer, getWindow } from '../../../../base/browser/dom.js'; -import { InputMode } from '../../config/inputMode.js'; +import { InputMode } from '../../../../base/common/inputMode.js'; /** * View cursors is a view part responsible for rendering the primary cursor and diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index c26124874c91e..d68f60c56ed18 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -22,7 +22,6 @@ import { VerticalRevealType, ViewCursorStateChangedEvent, ViewRevealRangeRequest import { dispose, Disposable } from '../../../base/common/lifecycle.js'; import { ICoordinatesConverter } from '../viewModel.js'; import { CursorStateChangedEvent, ViewModelEventsCollector } from '../viewModelEventDispatcher.js'; -import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class CursorsController extends Disposable { @@ -551,7 +550,7 @@ export class CursorsController extends Disposable { }, eventsCollector, source); } - public type(eventsCollector: ViewModelEventsCollector, config: IEditorConfiguration, text: string, source?: string | null | undefined): void { // + public type(eventsCollector: ViewModelEventsCollector, text: string, source?: string | null | undefined): void { this._executeEdit(() => { if (source === 'keyboard') { // If this event is coming straight from the keyboard, look for electric characters and enter @@ -563,7 +562,7 @@ export class CursorsController extends Disposable { const chr = text.substr(offset, charLength); // Here we must interpret each typed character individually - this._executeEditOperation(TypeOperations.typeWithInterceptors(config, !!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); + this._executeEditOperation(TypeOperations.typeWithInterceptors(!!this._compositionState, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr)); offset += charLength; } diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 745a954dca6c7..0033e2b2eeef0 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -19,11 +19,11 @@ import { ITextModel } from '../model.js'; import { EnterAction, IndentAction, StandardAutoClosingPairConditional } from '../languages/languageConfiguration.js'; import { getIndentationAtPosition } from '../languages/languageConfigurationRegistry.js'; import { IElectricAction } from '../languages/supports/electricCharacter.js'; -import { EditorAutoClosingStrategy, EditorAutoIndentStrategy, EditorOption } from '../config/editorOptions.js'; +import { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/editorOptions.js'; import { createScopedLineTokens } from '../languages/supports.js'; import { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js'; import { getEnterAction } from '../languages/enterAction.js'; -import { IEditorConfiguration } from '../config/editorConfiguration.js'; +import { InputMode } from '../../../base/common/inputMode.js'; export class AutoIndentOperation { @@ -484,11 +484,11 @@ export class InterceptorElectricCharOperation { export class SimpleCharacterTypeOperation { - public static getEdits(editorConfig: IEditorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // - const inputMode = editorConfig.options.get(EditorOption.inputMode); + public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { // A simple character type const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { + const inputMode = InputMode.getInputMode(); const ChosenReplaceCommand = inputMode === 'overtype' ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], ch); } diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index f5eaf9cfd5281..c518f3f97c44a 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,7 +12,6 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; -import { IEditorConfiguration } from '../config/editorConfiguration.js'; export class TypeOperations { @@ -163,7 +162,7 @@ export class TypeOperations { return null; } - public static typeWithInterceptors(editorConfig: IEditorConfiguration, isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { // + public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { const enterEdits = EnterOperation.getEdits(config, model, selections, ch, isDoingComposition); if (enterEdits !== undefined) { @@ -195,10 +194,10 @@ export class TypeOperations { return interceptorElectricCharOperation; } - return SimpleCharacterTypeOperation.getEdits(editorConfig, prevEditOperationType, selections, ch); + return SimpleCharacterTypeOperation.getEdits(prevEditOperationType, selections, ch); } - public static typeWithoutInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { // + public static typeWithoutInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { return TypeWithoutInterceptorsOperation.getEdits(prevEditOperationType, selections, str); } } diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 2c3aab9119175..96043722d84c5 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -1040,7 +1040,7 @@ export class ViewModel extends Disposable implements IViewModel { this._withViewEventsCollector(eventsCollector => this._cursor.restoreState(eventsCollector, states)); } - private _executeCursorEdit(callback: (eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration) => void): void { + private _executeCursorEdit(callback: (eventsCollector: ViewModelEventsCollector) => void): void { if (this._cursor.context.cursorConfig.readOnly) { // we cannot edit when read only... this._eventDispatcher.emitOutgoingEvent(new ReadOnlyEditAttemptEvent()); @@ -1058,7 +1058,7 @@ export class ViewModel extends Disposable implements IViewModel { this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source)); } public type(text: string, source?: string | null | undefined): void { - this._executeCursorEdit((eventsCollector, editorConfiguration) => this._cursor.type(eventsCollector, editorConfiguration, text, source)); + this._executeCursorEdit(eventsCollector => this._cursor.type(eventsCollector, text, source)); } public compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void { this._executeCursorEdit(eventsCollector => this._cursor.compositionType(eventsCollector, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta, source)); @@ -1107,11 +1107,11 @@ export class ViewModel extends Disposable implements IViewModel { } //#endregion - private _withViewEventsCollector(callback: (eventsCollector: ViewModelEventsCollector, editorConfiguration: IEditorConfiguration) => T): T { + private _withViewEventsCollector(callback: (eventsCollector: ViewModelEventsCollector) => T): T { return this._transactionalTarget.batchChanges(() => { try { const eventsCollector = this._eventDispatcher.beginEmitViewEvents(); - return callback(eventsCollector, this._configuration); + return callback(eventsCollector); } finally { this._eventDispatcher.endEmitViewEvents(); } diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 48abdc0814ebb..76b0208a719ae 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -38,7 +38,7 @@ import { ICommandActionTitle } from '../../../../platform/action/common/action.j import { IProgressService, ProgressLocation } from '../../../../platform/progress/common/progress.js'; import { resolveCommandsContext } from './editorCommandsContext.js'; import { IListService } from '../../../../platform/list/browser/listService.js'; -import { InputMode } from '../../../../editor/browser/config/inputMode.js'; +import { InputMode } from '../../../../base/common/inputMode.js'; class ExecuteCommandAction extends Action2 { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index e04222b974009..e14405d5d5e80 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -56,7 +56,7 @@ import { KeybindingWeight } from '../../../../platform/keybinding/common/keybind import { KeyChord, KeyCode, KeyMod } from '../../../../base/common/keyCodes.js'; import { TabFocus } from '../../../../editor/browser/config/tabFocus.js'; import { IEditorGroupsService, IEditorPart } from '../../../services/editor/common/editorGroupsService.js'; -import { InputMode } from '../../../../editor/browser/config/inputMode.js'; +import { InputMode } from '../../../../base/common/inputMode.js'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private primary: IEncodingSupport, private secondary: IEncodingSupport) { } @@ -477,8 +477,8 @@ class EditorStatus extends Disposable { localize('inputModeOvertype', 'OVR') : localize('inputModeInsert', 'INS'); const name = inputMode === 'overtype' ? - localize('status.editor.overtypeMode', "Toggle Overtype Mode") - : localize('status.editor.insertMode', "Toggle Insert Mode"); + localize('status.editor.insertMode', "Toggle Insert Mode") + : localize('status.editor.overtypeMode', "Toggle Overtype Mode"); return { name, text, diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts b/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts index b5dfdf6fe2dfb..5eca9e4c247cb 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/multicursor/notebookMulticursor.ts @@ -235,7 +235,7 @@ export class NotebookMultiCursorController extends Disposable implements INotebo return; } if (match.cellViewModel.handle !== this.anchorCell?.[0].handle) { // don't relay to active cell, already has a controller for typing - controller.type(collector, match.editorConfig, input, 'keyboard'); + controller.type(collector, input, 'keyboard'); } }); })); From 5048d0738e15cc3c35635434f5c616238f712230 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 10:47:49 +0100 Subject: [PATCH 10/44] changing the name of the status bar --- src/vs/workbench/browser/parts/editor/editorStatus.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index e14405d5d5e80..cb6c6644608ce 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -476,9 +476,7 @@ class EditorStatus extends Disposable { const text = inputMode === 'overtype' ? localize('inputModeOvertype', 'OVR') : localize('inputModeInsert', 'INS'); - const name = inputMode === 'overtype' ? - localize('status.editor.insertMode', "Toggle Insert Mode") - : localize('status.editor.overtypeMode', "Toggle Overtype Mode"); + const name = localize('status.editor.inputMode', "Toggle Input Mode"); return { name, text, From 4a2b843e38608e1265cc7dbc084351e96f0fd5d3 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 11:04:40 +0100 Subject: [PATCH 11/44] add some keybindings and make status bar less prominent --- src/vs/workbench/browser/parts/editor/editorActions.ts | 5 +++++ src/vs/workbench/browser/parts/editor/editorStatus.ts | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 76b0208a719ae..f9fef51339925 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2710,6 +2710,11 @@ export class ToggleOvertypeInsertMode extends Action2 { metadata: { description: localize2('toggleOvertypeMode.description', "Toggle between overtype and insert mode"), }, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyCode.Insert, + secondary: [KeyMod.Shift | KeyCode.Ctrl | KeyCode.KeyI], + }, f1: true, category: Categories.View }); diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index cb6c6644608ce..a31864e71aa2d 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -483,7 +483,6 @@ class EditorStatus extends Disposable { ariaLabel: text, tooltip: name, command: 'editor.action.toggleOvertypeInsertMode', - kind: 'prominent' }; }; if (!this.inputModeElement.value) { From 779035d7711b16534c04aab2345c83da72d604a6 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 12:23:49 +0100 Subject: [PATCH 12/44] polishing the replacement of text --- src/vs/editor/common/commands/replaceCommand.ts | 11 +++++++---- .../workbench/browser/parts/editor/editorActions.ts | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index e33e743411b84..1fbeaf89c717b 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -6,7 +6,7 @@ import { Range } from '../core/range.js'; import { Selection, SelectionDirection } from '../core/selection.js'; import { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js'; -import { ITextModel } from '../model.js'; +import { EndOfLineSequence, ITextModel } from '../model.js'; export class ReplaceCommand implements ICommand { @@ -47,9 +47,12 @@ export class ReplaceOvertypeCommand implements ICommand { const startPosition = this._range.getStartPosition(); const endPosition = this._range.getEndPosition(); const rangeEndOffset = model.getOffsetAt(endPosition); - const endOffset = rangeEndOffset + this._text.length; - const newRange = Range.fromPositions(startPosition, model.getPositionAt(endOffset)); - builder.addTrackedEditOperation(newRange, this._text); + const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); + const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); + const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; + const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; + const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); + builder.addTrackedEditOperation(replaceRange, this._text); } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index f9fef51339925..d500564db227f 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2713,7 +2713,7 @@ export class ToggleOvertypeInsertMode extends Action2 { keybinding: { weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.Insert, - secondary: [KeyMod.Shift | KeyCode.Ctrl | KeyCode.KeyI], + secondary: [KeyMod.Shift | KeyCode.Ctrl | KeyCode.KeyQ], }, f1: true, category: Categories.View From 900af97972806020f43637266747a4aec53e5e31 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 13:18:07 +0100 Subject: [PATCH 13/44] adding overtype on paste --- .../editor/common/commands/replaceCommand.ts | 14 +- src/vs/editor/common/config/editorOptions.ts | 9 ++ .../common/cursor/cursorTypeEditOperations.ts | 10 +- src/vs/editor/common/cursorCommon.ts | 3 + .../common/standalone/standaloneEnums.ts | 139 ++++++++--------- src/vs/monaco.d.ts | 144 +++++++++--------- 6 files changed, 177 insertions(+), 142 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 1fbeaf89c717b..0a9810928a640 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -46,11 +46,21 @@ export class ReplaceOvertypeCommand implements ICommand { public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { const startPosition = this._range.getStartPosition(); const endPosition = this._range.getEndPosition(); + const rangeStartOffset = model.getOffsetAt(startPosition); const rangeEndOffset = model.getOffsetAt(endPosition); const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); - const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; - const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; + let newEndOffset = endOffset; + for (let i = 0; i < endOffset - rangeStartOffset; i++) { + const characterStartPosition = model.getPositionAt(endOffset - i - 1); + const characterEndPosition = model.getPositionAt(endOffset - i); + const character = model.getValueInRange(Range.fromPositions(characterStartPosition, characterEndPosition)); + if (character === endOfLine) { + newEndOffset -= 1; + } else { + break; + } + } const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); builder.addTrackedEditOperation(replaceRange, this._text); } diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 5861eba3d4bcf..af632e6ad67e0 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -783,6 +783,11 @@ export interface IEditorOptions { * Controls the input mode, whether it is insert or overtype */ inputMode?: 'insert' | 'overtype'; + + /** + * Paste in overtype mode should overwrite. + */ + overtypeOnPaste?: boolean; } /** @@ -5420,6 +5425,7 @@ export const enum EditorOption { multiCursorLimit, occurrencesHighlight, occurrencesHighlightDelay, + overtypeOnPaste, overviewRulerBorder, overviewRulerLanes, padding, @@ -5982,6 +5988,9 @@ export const EditorOptions = { tags: ['preview'] } )), + overtypeOnPaste: register(new EditorBooleanOption( + EditorOption.overtypeOnPaste, 'overtypeOnPaste', true + )), overviewRulerBorder: register(new EditorBooleanOption( EditorOption.overviewRulerBorder, 'overviewRulerBorder', true, { description: nls.localize('overviewRulerBorder', "Controls whether a border should be drawn around the overview ruler.") } diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 0033e2b2eeef0..31e4327e3635a 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -639,7 +639,7 @@ export class EnterOperation { export class PasteOperation { - public static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) { + public static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) { // const distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText); if (distributedPaste) { selections = selections.sort(Range.compareRangesUsingStarts); @@ -678,6 +678,7 @@ export class PasteOperation { } private static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult { + console.log('_distributedPaste'); const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { commands[i] = new ReplaceCommand(selections[i], text[i]); @@ -689,6 +690,7 @@ export class PasteOperation { } private static _simplePaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean): EditOperationResult { + console.log('_simplePaste'); const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; @@ -699,12 +701,16 @@ export class PasteOperation { if (pasteOnNewLine && text.indexOf('\n') !== text.length - 1) { pasteOnNewLine = false; } + console.log('pasteOnNewLine : ', pasteOnNewLine); if (pasteOnNewLine) { // Paste entire line at the beginning of line const typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1); commands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true); } else { - commands[i] = new ReplaceCommand(selection, text); + const inputMode = InputMode.getInputMode(); + const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; + const ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand; + commands[i] = new ChosenReplaceCommand(selection, text); } } return new EditOperationResult(EditOperationType.Other, commands, { diff --git a/src/vs/editor/common/cursorCommon.ts b/src/vs/editor/common/cursorCommon.ts index 52f8673a32758..c74b923ef7a4e 100644 --- a/src/vs/editor/common/cursorCommon.ts +++ b/src/vs/editor/common/cursorCommon.ts @@ -77,6 +77,7 @@ export class CursorConfiguration { public readonly blockCommentStartToken: string | null; public readonly shouldAutoCloseBefore: { quote: (ch: string) => boolean; bracket: (ch: string) => boolean; comment: (ch: string) => boolean }; public readonly wordSegmenterLocales: string[]; + public readonly overtypeOnPaste: boolean; private readonly _languageId: string; private _electricChars: { [key: string]: boolean } | null; @@ -99,6 +100,7 @@ export class CursorConfiguration { || e.hasChanged(EditorOption.fontInfo) || e.hasChanged(EditorOption.readOnly) || e.hasChanged(EditorOption.wordSegmenterLocales) + || e.hasChanged(EditorOption.overtypeOnPaste) ); } @@ -137,6 +139,7 @@ export class CursorConfiguration { this.autoSurround = options.get(EditorOption.autoSurround); this.autoIndent = options.get(EditorOption.autoIndent); this.wordSegmenterLocales = options.get(EditorOption.wordSegmenterLocales); + this.overtypeOnPaste = options.get(EditorOption.overtypeOnPaste); this.surroundingPairs = {}; this._electricChars = null; diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 189aae537e049..f2df8468bcac0 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -259,75 +259,76 @@ export enum EditorOption { multiCursorLimit = 83, occurrencesHighlight = 84, occurrencesHighlightDelay = 85, - overviewRulerBorder = 86, - overviewRulerLanes = 87, - padding = 88, - pasteAs = 89, - parameterHints = 90, - peekWidgetDefaultFocus = 91, - placeholder = 92, - definitionLinkOpensInPeek = 93, - quickSuggestions = 94, - quickSuggestionsDelay = 95, - readOnly = 96, - readOnlyMessage = 97, - renameOnType = 98, - renderControlCharacters = 99, - renderFinalNewline = 100, - renderLineHighlight = 101, - renderLineHighlightOnlyWhenFocus = 102, - renderValidationDecorations = 103, - renderWhitespace = 104, - revealHorizontalRightPadding = 105, - roundedSelection = 106, - rulers = 107, - scrollbar = 108, - scrollBeyondLastColumn = 109, - scrollBeyondLastLine = 110, - scrollPredominantAxis = 111, - selectionClipboard = 112, - selectionHighlight = 113, - selectOnLineNumbers = 114, - showFoldingControls = 115, - showUnused = 116, - snippetSuggestions = 117, - smartSelect = 118, - smoothScrolling = 119, - stickyScroll = 120, - stickyTabStops = 121, - stopRenderingLineAfter = 122, - suggest = 123, - suggestFontSize = 124, - suggestLineHeight = 125, - suggestOnTriggerCharacters = 126, - suggestSelection = 127, - tabCompletion = 128, - tabIndex = 129, - unicodeHighlighting = 130, - unusualLineTerminators = 131, - useShadowDOM = 132, - useTabStops = 133, - wordBreak = 134, - wordSegmenterLocales = 135, - wordSeparators = 136, - wordWrap = 137, - wordWrapBreakAfterCharacters = 138, - wordWrapBreakBeforeCharacters = 139, - wordWrapColumn = 140, - wordWrapOverride1 = 141, - wordWrapOverride2 = 142, - wrappingIndent = 143, - wrappingStrategy = 144, - showDeprecated = 145, - inlayHints = 146, - editorClassName = 147, - pixelRatio = 148, - tabFocusMode = 149, - layoutInfo = 150, - wrappingInfo = 151, - defaultColorDecorators = 152, - colorDecoratorsActivatedOn = 153, - inlineCompletionsAccessibilityVerbose = 154 + overtypeOnPaste = 86, + overviewRulerBorder = 87, + overviewRulerLanes = 88, + padding = 89, + pasteAs = 90, + parameterHints = 91, + peekWidgetDefaultFocus = 92, + placeholder = 93, + definitionLinkOpensInPeek = 94, + quickSuggestions = 95, + quickSuggestionsDelay = 96, + readOnly = 97, + readOnlyMessage = 98, + renameOnType = 99, + renderControlCharacters = 100, + renderFinalNewline = 101, + renderLineHighlight = 102, + renderLineHighlightOnlyWhenFocus = 103, + renderValidationDecorations = 104, + renderWhitespace = 105, + revealHorizontalRightPadding = 106, + roundedSelection = 107, + rulers = 108, + scrollbar = 109, + scrollBeyondLastColumn = 110, + scrollBeyondLastLine = 111, + scrollPredominantAxis = 112, + selectionClipboard = 113, + selectionHighlight = 114, + selectOnLineNumbers = 115, + showFoldingControls = 116, + showUnused = 117, + snippetSuggestions = 118, + smartSelect = 119, + smoothScrolling = 120, + stickyScroll = 121, + stickyTabStops = 122, + stopRenderingLineAfter = 123, + suggest = 124, + suggestFontSize = 125, + suggestLineHeight = 126, + suggestOnTriggerCharacters = 127, + suggestSelection = 128, + tabCompletion = 129, + tabIndex = 130, + unicodeHighlighting = 131, + unusualLineTerminators = 132, + useShadowDOM = 133, + useTabStops = 134, + wordBreak = 135, + wordSegmenterLocales = 136, + wordSeparators = 137, + wordWrap = 138, + wordWrapBreakAfterCharacters = 139, + wordWrapBreakBeforeCharacters = 140, + wordWrapColumn = 141, + wordWrapOverride1 = 142, + wordWrapOverride2 = 143, + wrappingIndent = 144, + wrappingStrategy = 145, + showDeprecated = 146, + inlayHints = 147, + editorClassName = 148, + pixelRatio = 149, + tabFocusMode = 150, + layoutInfo = 151, + wrappingInfo = 152, + defaultColorDecorators = 153, + colorDecoratorsActivatedOn = 154, + inlineCompletionsAccessibilityVerbose = 155 } /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index e804edf11ba16..6bf895fd27bf8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3819,6 +3819,10 @@ declare namespace monaco.editor { * Controls the input mode, whether it is insert or overtype */ inputMode?: 'insert' | 'overtype'; + /** + * Paste in overtype mode should overwrite. + */ + overtypeOnPaste?: boolean; } export interface IDiffEditorBaseOptions { @@ -4970,75 +4974,76 @@ declare namespace monaco.editor { multiCursorLimit = 83, occurrencesHighlight = 84, occurrencesHighlightDelay = 85, - overviewRulerBorder = 86, - overviewRulerLanes = 87, - padding = 88, - pasteAs = 89, - parameterHints = 90, - peekWidgetDefaultFocus = 91, - placeholder = 92, - definitionLinkOpensInPeek = 93, - quickSuggestions = 94, - quickSuggestionsDelay = 95, - readOnly = 96, - readOnlyMessage = 97, - renameOnType = 98, - renderControlCharacters = 99, - renderFinalNewline = 100, - renderLineHighlight = 101, - renderLineHighlightOnlyWhenFocus = 102, - renderValidationDecorations = 103, - renderWhitespace = 104, - revealHorizontalRightPadding = 105, - roundedSelection = 106, - rulers = 107, - scrollbar = 108, - scrollBeyondLastColumn = 109, - scrollBeyondLastLine = 110, - scrollPredominantAxis = 111, - selectionClipboard = 112, - selectionHighlight = 113, - selectOnLineNumbers = 114, - showFoldingControls = 115, - showUnused = 116, - snippetSuggestions = 117, - smartSelect = 118, - smoothScrolling = 119, - stickyScroll = 120, - stickyTabStops = 121, - stopRenderingLineAfter = 122, - suggest = 123, - suggestFontSize = 124, - suggestLineHeight = 125, - suggestOnTriggerCharacters = 126, - suggestSelection = 127, - tabCompletion = 128, - tabIndex = 129, - unicodeHighlighting = 130, - unusualLineTerminators = 131, - useShadowDOM = 132, - useTabStops = 133, - wordBreak = 134, - wordSegmenterLocales = 135, - wordSeparators = 136, - wordWrap = 137, - wordWrapBreakAfterCharacters = 138, - wordWrapBreakBeforeCharacters = 139, - wordWrapColumn = 140, - wordWrapOverride1 = 141, - wordWrapOverride2 = 142, - wrappingIndent = 143, - wrappingStrategy = 144, - showDeprecated = 145, - inlayHints = 146, - editorClassName = 147, - pixelRatio = 148, - tabFocusMode = 149, - layoutInfo = 150, - wrappingInfo = 151, - defaultColorDecorators = 152, - colorDecoratorsActivatedOn = 153, - inlineCompletionsAccessibilityVerbose = 154 + overtypeOnPaste = 86, + overviewRulerBorder = 87, + overviewRulerLanes = 88, + padding = 89, + pasteAs = 90, + parameterHints = 91, + peekWidgetDefaultFocus = 92, + placeholder = 93, + definitionLinkOpensInPeek = 94, + quickSuggestions = 95, + quickSuggestionsDelay = 96, + readOnly = 97, + readOnlyMessage = 98, + renameOnType = 99, + renderControlCharacters = 100, + renderFinalNewline = 101, + renderLineHighlight = 102, + renderLineHighlightOnlyWhenFocus = 103, + renderValidationDecorations = 104, + renderWhitespace = 105, + revealHorizontalRightPadding = 106, + roundedSelection = 107, + rulers = 108, + scrollbar = 109, + scrollBeyondLastColumn = 110, + scrollBeyondLastLine = 111, + scrollPredominantAxis = 112, + selectionClipboard = 113, + selectionHighlight = 114, + selectOnLineNumbers = 115, + showFoldingControls = 116, + showUnused = 117, + snippetSuggestions = 118, + smartSelect = 119, + smoothScrolling = 120, + stickyScroll = 121, + stickyTabStops = 122, + stopRenderingLineAfter = 123, + suggest = 124, + suggestFontSize = 125, + suggestLineHeight = 126, + suggestOnTriggerCharacters = 127, + suggestSelection = 128, + tabCompletion = 129, + tabIndex = 130, + unicodeHighlighting = 131, + unusualLineTerminators = 132, + useShadowDOM = 133, + useTabStops = 134, + wordBreak = 135, + wordSegmenterLocales = 136, + wordSeparators = 137, + wordWrap = 138, + wordWrapBreakAfterCharacters = 139, + wordWrapBreakBeforeCharacters = 140, + wordWrapColumn = 141, + wordWrapOverride1 = 142, + wordWrapOverride2 = 143, + wrappingIndent = 144, + wrappingStrategy = 145, + showDeprecated = 146, + inlayHints = 147, + editorClassName = 148, + pixelRatio = 149, + tabFocusMode = 150, + layoutInfo = 151, + wrappingInfo = 152, + defaultColorDecorators = 153, + colorDecoratorsActivatedOn = 154, + inlineCompletionsAccessibilityVerbose = 155 } export const EditorOptions: { @@ -5130,6 +5135,7 @@ declare namespace monaco.editor { multiCursorLimit: IEditorOption; occurrencesHighlight: IEditorOption; occurrencesHighlightDelay: IEditorOption; + overtypeOnPaste: IEditorOption; overviewRulerBorder: IEditorOption; overviewRulerLanes: IEditorOption; padding: IEditorOption>>; From 09498472b2406aa751c3645c6332f6a1bb7fdefd Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 17:01:34 +0100 Subject: [PATCH 14/44] adding pasting support --- .../editor/common/commands/replaceCommand.ts | 51 ++++++++++++++----- .../common/cursor/cursorTypeEditOperations.ts | 4 +- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 0a9810928a640..4b7497205ada1 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Position } from '../core/position.js'; import { Range } from '../core/range.js'; import { Selection, SelectionDirection } from '../core/selection.js'; import { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js'; @@ -46,21 +47,11 @@ export class ReplaceOvertypeCommand implements ICommand { public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { const startPosition = this._range.getStartPosition(); const endPosition = this._range.getEndPosition(); - const rangeStartOffset = model.getOffsetAt(startPosition); const rangeEndOffset = model.getOffsetAt(endPosition); const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; - let newEndOffset = endOffset; - for (let i = 0; i < endOffset - rangeStartOffset; i++) { - const characterStartPosition = model.getPositionAt(endOffset - i - 1); - const characterEndPosition = model.getPositionAt(endOffset - i); - const character = model.getValueInRange(Range.fromPositions(characterStartPosition, characterEndPosition)); - if (character === endOfLine) { - newEndOffset -= 1; - } else { - break; - } - } + const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); + const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); builder.addTrackedEditOperation(replaceRange, this._text); } @@ -72,6 +63,42 @@ export class ReplaceOvertypeCommand implements ICommand { } } +export class OvertypePasteCommand implements ICommand { + + private readonly _range: Range; + private readonly _text: string; + public readonly insertsAutoWhitespace: boolean; + + constructor(range: Range, text: string, insertsAutoWhitespace: boolean = false) { + this._range = range; + this._text = text; + this.insertsAutoWhitespace = insertsAutoWhitespace; + } + + public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { + const startPosition = this._range.getStartPosition(); + const endPosition = this._range.getEndPosition(); + const endLine = endPosition.lineNumber; + const potentialEndOffset = model.getOffsetAt(endPosition) + this._text.length + (this._range.isEmpty() ? 0 : - 1); + const potentialEndPosition = model.getPositionAt(potentialEndOffset); + let newEndPosition: Position; + if (potentialEndPosition.lineNumber > endLine) { + const endLineMaxColumn = model.getLineMaxColumn(endLine); + newEndPosition = new Position(endLine, endLineMaxColumn); + } else { + newEndPosition = potentialEndPosition; + } + const range = Range.fromPositions(startPosition, newEndPosition); + builder.addTrackedEditOperation(range, this._text); + } + + public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { + const inverseEditOperations = helper.getInverseEditOperations(); + const srcRange = inverseEditOperations[0].range; + return Selection.fromPositions(srcRange.getEndPosition()); + } +} + export class ReplaceCommandThatSelectsText implements ICommand { private readonly _range: Range; diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 31e4327e3635a..7d51e8fe46795 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -6,7 +6,7 @@ import { CharCode } from '../../../base/common/charCode.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import * as strings from '../../../base/common/strings.js'; -import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand } from '../commands/replaceCommand.js'; +import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand } from '../commands/replaceCommand.js'; import { ShiftCommand } from '../commands/shiftCommand.js'; import { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js'; import { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js'; @@ -709,7 +709,7 @@ export class PasteOperation { } else { const inputMode = InputMode.getInputMode(); const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; - const ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand; + const ChosenReplaceCommand = shouldOvertypeOnPaste ? OvertypePasteCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selection, text); } } From 0968f6daa66751deeb3e21180aeb1c5d767f6f30 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 17:16:43 +0100 Subject: [PATCH 15/44] using paste on distributed cursors --- .../editor/common/cursor/cursorTypeEditOperations.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 7d51e8fe46795..635be4124c33c 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -639,7 +639,7 @@ export class EnterOperation { export class PasteOperation { - public static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) { // + public static getEdits(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean, multicursorText: string[]) { const distributedPaste = this._distributePasteToCursors(config, selections, text, pasteOnNewLine, multicursorText); if (distributedPaste) { selections = selections.sort(Range.compareRangesUsingStarts); @@ -678,10 +678,12 @@ export class PasteOperation { } private static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult { - console.log('_distributedPaste'); const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { - commands[i] = new ReplaceCommand(selections[i], text[i]); + const inputMode = InputMode.getInputMode(); + const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; + const ChosenReplaceCommand = shouldOvertypeOnPaste ? OvertypePasteCommand : ReplaceCommand; + commands[i] = new ChosenReplaceCommand(selections[i], text[i]); } return new EditOperationResult(EditOperationType.Other, commands, { shouldPushStackElementBefore: true, @@ -690,7 +692,6 @@ export class PasteOperation { } private static _simplePaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string, pasteOnNewLine: boolean): EditOperationResult { - console.log('_simplePaste'); const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { const selection = selections[i]; @@ -701,7 +702,6 @@ export class PasteOperation { if (pasteOnNewLine && text.indexOf('\n') !== text.length - 1) { pasteOnNewLine = false; } - console.log('pasteOnNewLine : ', pasteOnNewLine); if (pasteOnNewLine) { // Paste entire line at the beginning of line const typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1); From fb0434c318c1d78282335e43d8b736995f0e741f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Nov 2024 17:44:27 +0100 Subject: [PATCH 16/44] fix ReplaceOvertypeCommandWithOffsetCursorState --- .../editor/common/commands/replaceCommand.ts | 39 +++++++++++++++++++ .../common/cursor/cursorTypeEditOperations.ts | 12 ++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 4b7497205ada1..0f3766a579a4e 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -170,6 +170,45 @@ export class ReplaceCommandWithOffsetCursorState implements ICommand { } } +export class ReplaceOvertypeCommandWithOffsetCursorState implements ICommand { + + private readonly _range: Range; + private readonly _text: string; + private readonly _columnDeltaOffset: number; + private readonly _lineNumberDeltaOffset: number; + public readonly insertsAutoWhitespace: boolean; + + constructor(range: Range, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, insertsAutoWhitespace: boolean = false) { + this._range = range; + this._text = text; + this._columnDeltaOffset = columnDeltaOffset; + this._lineNumberDeltaOffset = lineNumberDeltaOffset; + this.insertsAutoWhitespace = insertsAutoWhitespace; + } + + public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { // TODO + const startPosition = this._range.getStartPosition(); + const endPosition = this._range.getEndPosition(); + const rangeEndOffset = model.getOffsetAt(endPosition); + const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); + const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; + const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); + const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; + const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); + console.log('ReplaceOvertypeCommandWithOffsetCursorState'); + console.log('this._range : ', this._range); + console.log('replaceRange : ', replaceRange); + console.log('this._text : ', this._text); + builder.addTrackedEditOperation(replaceRange, this._text); + } + + public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { + const inverseEditOperations = helper.getInverseEditOperations(); + const srcRange = inverseEditOperations[0].range; + return Selection.fromPositions(srcRange.getEndPosition().delta(this._lineNumberDeltaOffset, this._columnDeltaOffset)); + } +} + export class ReplaceCommandThatPreservesSelection implements ICommand { private readonly _range: Range; diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 635be4124c33c..17e00292e678a 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -6,7 +6,7 @@ import { CharCode } from '../../../base/common/charCode.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import * as strings from '../../../base/common/strings.js'; -import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand } from '../commands/replaceCommand.js'; +import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand, ReplaceOvertypeCommandWithOffsetCursorState } from '../commands/replaceCommand.js'; import { ShiftCommand } from '../commands/shiftCommand.js'; import { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js'; import { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js'; @@ -723,14 +723,14 @@ export class PasteOperation { export class CompositionOperation { public static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number) { - const commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta)); + const commands = selections.map(selection => this._compositionType(config, model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta)); return new EditOperationResult(EditOperationType.TypingOther, commands, { shouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther), shouldPushStackElementAfter: false }); } - private static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null { + private static _compositionType(config: CursorConfiguration, model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null { if (!selection.isEmpty()) { // looks like https://github.com/microsoft/vscode/issues/2773 // where a cursor operation occurred before a canceled composition @@ -741,7 +741,11 @@ export class CompositionOperation { const startColumn = Math.max(1, pos.column - replacePrevCharCnt); const endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt); const range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn); - return new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta); + + const inputMode = InputMode.getInputMode(); + const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; + const ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommandWithOffsetCursorState : ReplaceCommandWithOffsetCursorState; + return new ChosenReplaceCommand(range, text, 0, positionDelta); } } From 5706284f79e5e2c6742a5697caa33d1b5b608653 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 11:38:29 +0100 Subject: [PATCH 17/44] add code --- src/vs/editor/common/commands/replaceCommand.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 0f3766a579a4e..54ee4b6c13fdd 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -187,16 +187,25 @@ export class ReplaceOvertypeCommandWithOffsetCursorState implements ICommand { } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { // TODO + console.log('ReplaceOvertypeCommandWithOffsetCursorState'); + console.log('this._range : ', this._range); const startPosition = this._range.getStartPosition(); const endPosition = this._range.getEndPosition(); + const rangeStartOffset = model.getOffsetAt(startPosition); const rangeEndOffset = model.getOffsetAt(endPosition); - const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); + const rangeLength = rangeEndOffset - rangeStartOffset; + let endOffset = rangeEndOffset; + if (this._text.length > rangeLength) { + endOffset = rangeStartOffset + this._text.length; + } + console.log('rangeEndOffset : ', rangeEndOffset); + console.log('endOffset : ', endOffset); const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); + console.log('lastCharacter : ', lastCharacter); const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; + console.log('newEndOffset : ', newEndOffset); const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); - console.log('ReplaceOvertypeCommandWithOffsetCursorState'); - console.log('this._range : ', this._range); console.log('replaceRange : ', replaceRange); console.log('this._text : ', this._text); builder.addTrackedEditOperation(replaceRange, this._text); From 44c77dba6da1c35bd6db844a2f128960df78afa1 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 15:29:00 +0100 Subject: [PATCH 18/44] adding support for composition --- src/typings/editContext.d.ts | 4 +- .../editContext/native/nativeEditContext.ts | 6 ++- src/vs/editor/browser/view/viewController.ts | 7 +-- .../widget/codeEditor/codeEditorWidget.ts | 18 ++++---- .../editor/common/commands/replaceCommand.ts | 43 +++++-------------- src/vs/editor/common/cursor/cursor.ts | 4 +- .../common/cursor/cursorTypeEditOperations.ts | 12 ++---- .../common/cursor/cursorTypeOperations.ts | 26 +++++++++-- src/vs/editor/common/editorCommon.ts | 8 ++++ .../editor/common/viewModel/viewModelImpl.ts | 4 +- 10 files changed, 70 insertions(+), 62 deletions(-) diff --git a/src/typings/editContext.d.ts b/src/typings/editContext.d.ts index 5b5da0ac7e955..eb8fbe5fee13a 100644 --- a/src/typings/editContext.d.ts +++ b/src/typings/editContext.d.ts @@ -52,8 +52,8 @@ interface EditContextEventHandlersEventMap { textupdate: TextUpdateEvent; textformatupdate: TextFormatUpdateEvent; characterboundsupdate: CharacterBoundsUpdateEvent; - compositionstart: Event; - compositionend: Event; + compositionstart: CompositionEvent; + compositionend: CompositionEvent; } type EventHandler = (event: TEvent) => void; diff --git a/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts b/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts index f979b27ecd2e0..2623207d42ee8 100644 --- a/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts +++ b/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts @@ -118,19 +118,23 @@ export class NativeEditContext extends AbstractEditContext { this._register(editContextAddDisposableListener(this._editContext, 'textupdate', (e) => { this._emitTypeEvent(viewController, e); })); + let compositionStartPosition: Position | undefined; this._register(editContextAddDisposableListener(this._editContext, 'compositionstart', (e) => { // Utlimately fires onDidCompositionStart() on the editor to notify for example suggest model of composition state // Updates the composition state of the cursor controller which determines behavior of typing with interceptors viewController.compositionStart(); // Emits ViewCompositionStartEvent which can be depended on by ViewEventHandlers this._context.viewModel.onCompositionStart(); + compositionStartPosition = this._context.viewModel.getPrimaryCursorState().modelState.position; })); this._register(editContextAddDisposableListener(this._editContext, 'compositionend', (e) => { // Utlimately fires compositionEnd() on the editor to notify for example suggest model of composition state // Updates the composition state of the cursor controller which determines behavior of typing with interceptors - viewController.compositionEnd(); + const compositionRange = compositionStartPosition ? Range.fromPositions(compositionStartPosition, this._context.viewModel.getPrimaryCursorState().modelState.position) : undefined; + viewController.compositionEnd(compositionRange); // Emits ViewCompositionEndEvent which can be depended on by ViewEventHandlers this._context.viewModel.onCompositionEnd(); + compositionStartPosition = undefined; })); this._register(addDisposableListener(this.textArea.domNode, 'paste', (e) => { e.preventDefault(); diff --git a/src/vs/editor/browser/view/viewController.ts b/src/vs/editor/browser/view/viewController.ts index 5e53d12d2e442..6760c1b8f3045 100644 --- a/src/vs/editor/browser/view/viewController.ts +++ b/src/vs/editor/browser/view/viewController.ts @@ -9,6 +9,7 @@ import { IEditorMouseEvent, IPartialEditorMouseEvent } from '../editorBrowser.js import { ViewUserInputEvents } from './viewUserInputEvents.js'; import { Position } from '../../common/core/position.js'; import { Selection } from '../../common/core/selection.js'; +import { Range } from '../../common/core/range.js'; import { IEditorConfiguration } from '../../common/config/editorConfiguration.js'; import { IViewModel } from '../../common/viewModel.js'; import { IMouseWheelEvent } from '../../../base/browser/mouseEvent.js'; @@ -41,7 +42,7 @@ export interface ICommandDelegate { type(text: string): void; compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): void; startComposition(): void; - endComposition(): void; + endComposition(compositionRange: Range | undefined): void; cut(): void; } @@ -80,8 +81,8 @@ export class ViewController { this.commandDelegate.startComposition(); } - public compositionEnd(): void { - this.commandDelegate.endComposition(); + public compositionEnd(compositionRange: Range | undefined): void { + this.commandDelegate.endComposition(compositionRange); } public cut(): void { diff --git a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts index 1f78e50887b1e..6c9589daba48a 100644 --- a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts @@ -1060,9 +1060,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE case editorCommon.Handler.CompositionStart: this._startComposition(); return; - case editorCommon.Handler.CompositionEnd: - this._endComposition(source); + case editorCommon.Handler.CompositionEnd: { + const args = >payload; + this._endComposition(source, args.compositionRange); return; + } case editorCommon.Handler.Type: { const args = >payload; this._type(source, args.text || ''); @@ -1120,11 +1122,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._onDidCompositionStart.fire(); } - private _endComposition(source: string | null | undefined): void { + private _endComposition(source: string | null | undefined, compositionRange: Range | undefined): void { if (!this._modelData) { return; } - this._modelData.viewModel.endComposition(source); + this._modelData.viewModel.endComposition(source, compositionRange); this._onDidCompositionEnd.fire(); } @@ -1814,8 +1816,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE startComposition: () => { this._startComposition(); }, - endComposition: () => { - this._endComposition('keyboard'); + endComposition: (compositionRange: Range | undefined) => { + this._endComposition('keyboard', compositionRange); }, cut: () => { this._cut('keyboard'); @@ -1845,8 +1847,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE startComposition: () => { this._commandService.executeCommand(editorCommon.Handler.CompositionStart, {}); }, - endComposition: () => { - this._commandService.executeCommand(editorCommon.Handler.CompositionEnd, {}); + endComposition: (compositionRange: Range | undefined) => { + this._commandService.executeCommand(editorCommon.Handler.CompositionEnd, { compositionRange }); }, cut: () => { this._commandService.executeCommand(editorCommon.Handler.Cut, {}); diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 54ee4b6c13fdd..82cc4f4c88e9f 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -170,51 +170,30 @@ export class ReplaceCommandWithOffsetCursorState implements ICommand { } } -export class ReplaceOvertypeCommandWithOffsetCursorState implements ICommand { +export class ReplaceOvertypeCommandInComposition implements ICommand { private readonly _range: Range; - private readonly _text: string; - private readonly _columnDeltaOffset: number; - private readonly _lineNumberDeltaOffset: number; - public readonly insertsAutoWhitespace: boolean; - constructor(range: Range, text: string, lineNumberDeltaOffset: number, columnDeltaOffset: number, insertsAutoWhitespace: boolean = false) { + constructor(range: Range) { this._range = range; - this._text = text; - this._columnDeltaOffset = columnDeltaOffset; - this._lineNumberDeltaOffset = lineNumberDeltaOffset; - this.insertsAutoWhitespace = insertsAutoWhitespace; } - public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { // TODO - console.log('ReplaceOvertypeCommandWithOffsetCursorState'); - console.log('this._range : ', this._range); + public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { + const text = model.getValueInRange(this._range); const startPosition = this._range.getStartPosition(); - const endPosition = this._range.getEndPosition(); - const rangeStartOffset = model.getOffsetAt(startPosition); - const rangeEndOffset = model.getOffsetAt(endPosition); - const rangeLength = rangeEndOffset - rangeStartOffset; - let endOffset = rangeEndOffset; - if (this._text.length > rangeLength) { - endOffset = rangeStartOffset + this._text.length; + const endOffset = model.getOffsetAt(startPosition) + 2 * text.length; + let endPosition = model.getPositionAt(endOffset); + if (endPosition.lineNumber > this._range.endLineNumber) { + endPosition = new Position(this._range.endLineNumber, model.getLineMaxColumn(this._range.endLineNumber)); } - console.log('rangeEndOffset : ', rangeEndOffset); - console.log('endOffset : ', endOffset); - const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; - const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); - console.log('lastCharacter : ', lastCharacter); - const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; - console.log('newEndOffset : ', newEndOffset); - const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); - console.log('replaceRange : ', replaceRange); - console.log('this._text : ', this._text); - builder.addTrackedEditOperation(replaceRange, this._text); + const range = Range.fromPositions(startPosition, endPosition); + builder.addTrackedEditOperation(range, text); } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { const inverseEditOperations = helper.getInverseEditOperations(); const srcRange = inverseEditOperations[0].range; - return Selection.fromPositions(srcRange.getEndPosition().delta(this._lineNumberDeltaOffset, this._columnDeltaOffset)); + return Selection.fromPositions(srcRange.getEndPosition()); } } diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index d68f60c56ed18..20cba322b624f 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -538,14 +538,14 @@ export class CursorsController extends Disposable { this._compositionState = new CompositionState(this._model, this.getSelections()); } - public endComposition(eventsCollector: ViewModelEventsCollector, source?: string | null | undefined): void { + public endComposition(eventsCollector: ViewModelEventsCollector, source?: string | null | undefined, compositionRange?: Range | undefined): void { const compositionOutcome = this._compositionState ? this._compositionState.deduceOutcome(this._model, this.getSelections()) : null; this._compositionState = null; this._executeEdit(() => { if (source === 'keyboard') { // composition finishes, let's check if we need to auto complete if necessary. - this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, compositionOutcome, this.getSelections(), this.getAutoClosedCharacters())); + this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, compositionOutcome, this.getSelections(), this.getAutoClosedCharacters(), compositionRange)); } }, eventsCollector, source); } diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 17e00292e678a..a79d5b577939a 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -6,7 +6,7 @@ import { CharCode } from '../../../base/common/charCode.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import * as strings from '../../../base/common/strings.js'; -import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand, ReplaceOvertypeCommandWithOffsetCursorState } from '../commands/replaceCommand.js'; +import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand } from '../commands/replaceCommand.js'; import { ShiftCommand } from '../commands/shiftCommand.js'; import { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js'; import { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js'; @@ -484,12 +484,12 @@ export class InterceptorElectricCharOperation { export class SimpleCharacterTypeOperation { - public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], ch: string): EditOperationResult { + public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult { // A simple character type const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { const inputMode = InputMode.getInputMode(); - const ChosenReplaceCommand = inputMode === 'overtype' ? ReplaceOvertypeCommand : ReplaceCommand; + const ChosenReplaceCommand = inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], ch); } @@ -741,11 +741,7 @@ export class CompositionOperation { const startColumn = Math.max(1, pos.column - replacePrevCharCnt); const endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt); const range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn); - - const inputMode = InputMode.getInputMode(); - const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; - const ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommandWithOffsetCursorState : ReplaceCommandWithOffsetCursorState; - return new ChosenReplaceCommand(range, text, 0, positionDelta); + return new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta); } } diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index c518f3f97c44a..10091f1911761 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,6 +12,8 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; +import { InputMode } from '../../../base/common/inputMode.js'; +import { ReplaceOvertypeCommandInComposition } from '../commands/replaceCommand.js'; export class TypeOperations { @@ -72,7 +74,7 @@ export class TypeOperations { /** * This is very similar with typing, but the character is already in the text buffer! */ - public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, compositions: CompositionOutcome[] | null, selections: Selection[], autoClosedCharacters: Range[]): EditOperationResult | null { + public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, compositions: CompositionOutcome[] | null, selections: Selection[], autoClosedCharacters: Range[], compositionRange?: Range | undefined): EditOperationResult | null { if (!compositions) { // could not deduce what the composition did return null; @@ -90,7 +92,7 @@ export class TypeOperations { if (!insertedText || insertedText.length !== 1) { // we're only interested in the case where a single character was inserted - return null; + return this._overtypeEdits(compositionRange) ?? null; } const ch = insertedText; @@ -159,7 +161,23 @@ export class TypeOperations { return autoClosingOpenCharEdits; } - return null; + return this._overtypeEdits(compositionRange) ?? null; + } + + private static _overtypeEdits(compositionRange: Range | undefined): EditOperationResult | undefined { + if (!compositionRange) { + return undefined; + } + const inputMode = InputMode.getInputMode(); + const isOvertypeMode = inputMode === 'overtype'; + if (!isOvertypeMode) { + return undefined; + } + const commands = [new ReplaceOvertypeCommandInComposition(compositionRange)]; + return new EditOperationResult(EditOperationType.TypingOther, commands, { + shouldPushStackElementBefore: true, + shouldPushStackElementAfter: false + }); } public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { @@ -194,7 +212,7 @@ export class TypeOperations { return interceptorElectricCharOperation; } - return SimpleCharacterTypeOperation.getEdits(prevEditOperationType, selections, ch); + return SimpleCharacterTypeOperation.getEdits(prevEditOperationType, selections, ch, isDoingComposition); } public static typeWithoutInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index e25edb4fb50a5..578595929b9d6 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -762,6 +762,14 @@ export interface TypePayload { text: string; } +/** + * @internal + */ +export interface CompositionPayload { + compositionRange: Range; +} + + /** * @internal */ diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 96043722d84c5..b868280279286 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -1054,8 +1054,8 @@ export class ViewModel extends Disposable implements IViewModel { public startComposition(): void { this._executeCursorEdit(eventsCollector => this._cursor.startComposition(eventsCollector)); } - public endComposition(source?: string | null | undefined): void { - this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source)); + public endComposition(source?: string | null | undefined, compositionRange?: Range | undefined): void { + this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source, compositionRange)); } public type(text: string, source?: string | null | undefined): void { this._executeCursorEdit(eventsCollector => this._cursor.type(eventsCollector, text, source)); From 5f03a2983a155da2f5e14cbe992b1ec000998e1a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 15:35:31 +0100 Subject: [PATCH 19/44] undoing edit context changes --- src/typings/editContext.d.ts | 4 ++-- .../controller/editContext/textArea/textAreaEditContext.ts | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/typings/editContext.d.ts b/src/typings/editContext.d.ts index eb8fbe5fee13a..5b5da0ac7e955 100644 --- a/src/typings/editContext.d.ts +++ b/src/typings/editContext.d.ts @@ -52,8 +52,8 @@ interface EditContextEventHandlersEventMap { textupdate: TextUpdateEvent; textformatupdate: TextFormatUpdateEvent; characterboundsupdate: CharacterBoundsUpdateEvent; - compositionstart: CompositionEvent; - compositionend: CompositionEvent; + compositionstart: Event; + compositionend: Event; } type EventHandler = (event: TEvent) => void; diff --git a/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts b/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts index a3f8b75544bb0..474a93713ff70 100644 --- a/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts +++ b/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts @@ -342,6 +342,7 @@ export class TextAreaEditContext extends AbstractEditContext { this._viewController.setSelection(modelSelection); })); + let compositionStartPosition: Position | undefined; this._register(this._textAreaInput.onCompositionStart((e) => { // The textarea might contain some content when composition starts. @@ -365,6 +366,7 @@ export class TextAreaEditContext extends AbstractEditContext { const ta = this.textArea.domNode; const modelSelection = this._modelSelections[0]; + compositionStartPosition = modelSelection.getPosition(); const { distanceToModelLineStart, widthOfHiddenTextBefore } = (() => { // Find the text that is on the current line before the selection @@ -449,7 +451,9 @@ export class TextAreaEditContext extends AbstractEditContext { this._render(); this.textArea.setClassName(`inputarea ${MOUSE_CURSOR_TEXT_CSS_CLASS_NAME}`); - this._viewController.compositionEnd(); + const compositionRange = compositionStartPosition ? Range.fromPositions(compositionStartPosition, this._modelSelections[0].getPosition()) : undefined; + this._viewController.compositionEnd(compositionRange); + compositionStartPosition = undefined; this._context.viewModel.onCompositionEnd(); })); From 669ecc1ba8800324afc3ac74b50a466f6fcfd7aa Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 15:43:16 +0100 Subject: [PATCH 20/44] changing the status bar entry so it disappears when moving to insert mode --- .../browser/parts/editor/editorStatus.ts | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index a31864e71aa2d..f4b0120d0783d 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -471,24 +471,18 @@ class EditorStatus extends Disposable { } private updateInputModeElement(inputMode: 'overtype' | 'insert' | undefined): void { - if (!!inputMode) { - const getStatusBarEntry = (inputMode: 'overtype' | 'insert'): IStatusbarEntry => { - const text = inputMode === 'overtype' ? - localize('inputModeOvertype', 'OVR') - : localize('inputModeInsert', 'INS'); - const name = localize('status.editor.inputMode', "Toggle Input Mode"); - return { + if (!!inputMode && inputMode === 'overtype') { + if (!this.inputModeElement.value) { + const text = localize('inputModeOvertype', 'OVR'); + const name = localize('status.editor.enableInsertMode', "Enable Insert Mode"); + this.inputModeElement.value = this.statusbarService.addEntry({ name, text, ariaLabel: text, tooltip: name, command: 'editor.action.toggleOvertypeInsertMode', - }; - }; - if (!this.inputModeElement.value) { - this.inputModeElement.value = this.statusbarService.addEntry(getStatusBarEntry(inputMode), 'status.editor.inputMode', StatusbarAlignment.RIGHT, 100.6); - } else { - this.inputModeElement.value.update(getStatusBarEntry(inputMode)); + kind: 'prominent' + }, 'status.editor.inputMode', StatusbarAlignment.RIGHT, 100.6); } } else { this.inputModeElement.clear(); From d8483147e974fa9a6ef337307456fa802e8092f8 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 16:06:14 +0100 Subject: [PATCH 21/44] rerender the cursors --- src/vs/editor/browser/view.ts | 12 ++++++++++-- .../browser/viewParts/viewCursors/viewCursors.ts | 13 ++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index 1b6cd36a370c1..05229ed4848b9 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -38,7 +38,7 @@ import { OverviewRuler } from './viewParts/overviewRuler/overviewRuler.js'; import { Rulers } from './viewParts/rulers/rulers.js'; import { ScrollDecorationViewPart } from './viewParts/scrollDecoration/scrollDecoration.js'; import { SelectionsOverlay } from './viewParts/selections/selections.js'; -import { ViewCursors } from './viewParts/viewCursors/viewCursors.js'; +import { IViewCursorsHelper, ViewCursors } from './viewParts/viewCursors/viewCursors.js'; import { ViewZones } from './viewParts/viewZones/viewZones.js'; import { WhitespaceOverlay } from './viewParts/whitespace/whitespace.js'; import { IEditorConfiguration } from '../common/config/editorConfiguration.js'; @@ -209,7 +209,7 @@ export class View extends ViewEventHandler { this._contentWidgets = new ViewContentWidgets(this._context, this.domNode); this._viewParts.push(this._contentWidgets); - this._viewCursors = new ViewCursors(this._context); + this._viewCursors = new ViewCursors(this._context, this._createViewCursorsHelper()); this._viewParts.push(this._viewCursors); // Overlay widgets @@ -369,6 +369,14 @@ export class View extends ViewEventHandler { }; } + private _createViewCursorsHelper(): IViewCursorsHelper { + return { + renderNow: (): void => { + this.render(true, false); + } + }; + } + private _createTextAreaHandlerHelper(): IVisibleRangeProvider { return { visibleRangeForPosition: (position: Position) => { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 86fcf2aed964c..c8238e0e9d7fc 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -24,6 +24,10 @@ import { CursorChangeReason } from '../../../common/cursorEvents.js'; import { WindowIntervalTimer, getWindow } from '../../../../base/browser/dom.js'; import { InputMode } from '../../../../base/common/inputMode.js'; +export interface IViewCursorsHelper { + renderNow(): void; +} + /** * View cursors is a view part responsible for rendering the primary cursor and * any secondary cursors that are currently active. @@ -53,14 +57,15 @@ export class ViewCursors extends ViewPart { private readonly _primaryCursor: ViewCursor; private readonly _secondaryCursors: ViewCursor[]; private _renderData: IViewCursorRenderData[]; + private _viewHelper: IViewCursorsHelper; - constructor(context: ViewContext) { + constructor(context: ViewContext, viewHelper: IViewCursorsHelper) { super(context); const options = this._context.configuration.options; + this._viewHelper = viewHelper; this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); - this._setCursorStyle(); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); this._selectionIsEmpty = true; @@ -86,7 +91,7 @@ export class ViewCursors extends ViewPart { this._editorHasFocus = false; this._updateBlinking(); - + this._setCursorStyle(); this._register(InputMode.onDidChangeInputMode(() => { this._setCursorStyle(); })); @@ -350,6 +355,8 @@ export class ViewCursors extends ViewPart { const options = this._context.configuration.options; const inputMode = InputMode.getInputMode(); this._cursorStyle = inputMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + this.forceShouldRender(); + this._viewHelper.renderNow(); } private _show(): void { From 164c67d46fce30b1ddf4733e55e4c3f9bb3f10f4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 16:51:32 +0100 Subject: [PATCH 22/44] allowing composition over several lines --- .../editContext/native/nativeEditContext.ts | 6 +-- .../textArea/textAreaEditContext.ts | 6 +-- src/vs/editor/browser/view/viewController.ts | 7 ++-- .../widget/codeEditor/codeEditorWidget.ts | 18 ++++----- src/vs/editor/common/cursor/cursor.ts | 37 +++++++++++-------- .../common/cursor/cursorTypeOperations.ts | 15 ++++---- .../editor/common/viewModel/viewModelImpl.ts | 4 +- 7 files changed, 45 insertions(+), 48 deletions(-) diff --git a/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts b/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts index 2623207d42ee8..f979b27ecd2e0 100644 --- a/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts +++ b/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts @@ -118,23 +118,19 @@ export class NativeEditContext extends AbstractEditContext { this._register(editContextAddDisposableListener(this._editContext, 'textupdate', (e) => { this._emitTypeEvent(viewController, e); })); - let compositionStartPosition: Position | undefined; this._register(editContextAddDisposableListener(this._editContext, 'compositionstart', (e) => { // Utlimately fires onDidCompositionStart() on the editor to notify for example suggest model of composition state // Updates the composition state of the cursor controller which determines behavior of typing with interceptors viewController.compositionStart(); // Emits ViewCompositionStartEvent which can be depended on by ViewEventHandlers this._context.viewModel.onCompositionStart(); - compositionStartPosition = this._context.viewModel.getPrimaryCursorState().modelState.position; })); this._register(editContextAddDisposableListener(this._editContext, 'compositionend', (e) => { // Utlimately fires compositionEnd() on the editor to notify for example suggest model of composition state // Updates the composition state of the cursor controller which determines behavior of typing with interceptors - const compositionRange = compositionStartPosition ? Range.fromPositions(compositionStartPosition, this._context.viewModel.getPrimaryCursorState().modelState.position) : undefined; - viewController.compositionEnd(compositionRange); + viewController.compositionEnd(); // Emits ViewCompositionEndEvent which can be depended on by ViewEventHandlers this._context.viewModel.onCompositionEnd(); - compositionStartPosition = undefined; })); this._register(addDisposableListener(this.textArea.domNode, 'paste', (e) => { e.preventDefault(); diff --git a/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts b/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts index 474a93713ff70..a3f8b75544bb0 100644 --- a/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts +++ b/src/vs/editor/browser/controller/editContext/textArea/textAreaEditContext.ts @@ -342,7 +342,6 @@ export class TextAreaEditContext extends AbstractEditContext { this._viewController.setSelection(modelSelection); })); - let compositionStartPosition: Position | undefined; this._register(this._textAreaInput.onCompositionStart((e) => { // The textarea might contain some content when composition starts. @@ -366,7 +365,6 @@ export class TextAreaEditContext extends AbstractEditContext { const ta = this.textArea.domNode; const modelSelection = this._modelSelections[0]; - compositionStartPosition = modelSelection.getPosition(); const { distanceToModelLineStart, widthOfHiddenTextBefore } = (() => { // Find the text that is on the current line before the selection @@ -451,9 +449,7 @@ export class TextAreaEditContext extends AbstractEditContext { this._render(); this.textArea.setClassName(`inputarea ${MOUSE_CURSOR_TEXT_CSS_CLASS_NAME}`); - const compositionRange = compositionStartPosition ? Range.fromPositions(compositionStartPosition, this._modelSelections[0].getPosition()) : undefined; - this._viewController.compositionEnd(compositionRange); - compositionStartPosition = undefined; + this._viewController.compositionEnd(); this._context.viewModel.onCompositionEnd(); })); diff --git a/src/vs/editor/browser/view/viewController.ts b/src/vs/editor/browser/view/viewController.ts index 6760c1b8f3045..5e53d12d2e442 100644 --- a/src/vs/editor/browser/view/viewController.ts +++ b/src/vs/editor/browser/view/viewController.ts @@ -9,7 +9,6 @@ import { IEditorMouseEvent, IPartialEditorMouseEvent } from '../editorBrowser.js import { ViewUserInputEvents } from './viewUserInputEvents.js'; import { Position } from '../../common/core/position.js'; import { Selection } from '../../common/core/selection.js'; -import { Range } from '../../common/core/range.js'; import { IEditorConfiguration } from '../../common/config/editorConfiguration.js'; import { IViewModel } from '../../common/viewModel.js'; import { IMouseWheelEvent } from '../../../base/browser/mouseEvent.js'; @@ -42,7 +41,7 @@ export interface ICommandDelegate { type(text: string): void; compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): void; startComposition(): void; - endComposition(compositionRange: Range | undefined): void; + endComposition(): void; cut(): void; } @@ -81,8 +80,8 @@ export class ViewController { this.commandDelegate.startComposition(); } - public compositionEnd(compositionRange: Range | undefined): void { - this.commandDelegate.endComposition(compositionRange); + public compositionEnd(): void { + this.commandDelegate.endComposition(); } public cut(): void { diff --git a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts index 6c9589daba48a..1f78e50887b1e 100644 --- a/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditor/codeEditorWidget.ts @@ -1060,11 +1060,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE case editorCommon.Handler.CompositionStart: this._startComposition(); return; - case editorCommon.Handler.CompositionEnd: { - const args = >payload; - this._endComposition(source, args.compositionRange); + case editorCommon.Handler.CompositionEnd: + this._endComposition(source); return; - } case editorCommon.Handler.Type: { const args = >payload; this._type(source, args.text || ''); @@ -1122,11 +1120,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._onDidCompositionStart.fire(); } - private _endComposition(source: string | null | undefined, compositionRange: Range | undefined): void { + private _endComposition(source: string | null | undefined): void { if (!this._modelData) { return; } - this._modelData.viewModel.endComposition(source, compositionRange); + this._modelData.viewModel.endComposition(source); this._onDidCompositionEnd.fire(); } @@ -1816,8 +1814,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE startComposition: () => { this._startComposition(); }, - endComposition: (compositionRange: Range | undefined) => { - this._endComposition('keyboard', compositionRange); + endComposition: () => { + this._endComposition('keyboard'); }, cut: () => { this._cut('keyboard'); @@ -1847,8 +1845,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE startComposition: () => { this._commandService.executeCommand(editorCommon.Handler.CompositionStart, {}); }, - endComposition: (compositionRange: Range | undefined) => { - this._commandService.executeCommand(editorCommon.Handler.CompositionEnd, { compositionRange }); + endComposition: () => { + this._commandService.executeCommand(editorCommon.Handler.CompositionEnd, {}); }, cut: () => { this._commandService.executeCommand(editorCommon.Handler.Cut, {}); diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index 20cba322b624f..d171dc59735ad 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -538,14 +538,14 @@ export class CursorsController extends Disposable { this._compositionState = new CompositionState(this._model, this.getSelections()); } - public endComposition(eventsCollector: ViewModelEventsCollector, source?: string | null | undefined, compositionRange?: Range | undefined): void { + public endComposition(eventsCollector: ViewModelEventsCollector, source?: string | null | undefined): void { const compositionOutcome = this._compositionState ? this._compositionState.deduceOutcome(this._model, this.getSelections()) : null; this._compositionState = null; this._executeEdit(() => { if (source === 'keyboard') { // composition finishes, let's check if we need to auto complete if necessary. - this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, compositionOutcome, this.getSelections(), this.getAutoClosedCharacters(), compositionRange)); + this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, compositionOutcome, this.getSelections(), this.getAutoClosedCharacters())); } }, eventsCollector, source); } @@ -1020,8 +1020,9 @@ export class CommandExecutor { class CompositionLineState { constructor( public readonly text: string, - public readonly startSelection: number, - public readonly endSelection: number + public readonly startSelectionOffset: number, + public readonly endSelectionOffset: number, + public readonly lineNumber: number ) { } } @@ -1035,10 +1036,12 @@ class CompositionState { if (selection.startLineNumber !== selection.endLineNumber) { return null; } + const lineNumber = selection.startLineNumber; result.push(new CompositionLineState( - textModel.getLineContent(selection.startLineNumber), + textModel.getLineContent(lineNumber), selection.startColumn - 1, - selection.endColumn - 1 + selection.endColumn - 1, + lineNumber )); } return result; @@ -1072,24 +1075,28 @@ class CompositionState { private static _deduceOutcome(original: CompositionLineState, current: CompositionLineState): CompositionOutcome { const commonPrefix = Math.min( - original.startSelection, - current.startSelection, + original.startSelectionOffset, + current.startSelectionOffset, strings.commonPrefixLength(original.text, current.text) ); const commonSuffix = Math.min( - original.text.length - original.endSelection, - current.text.length - current.endSelection, + original.text.length - original.endSelectionOffset, + current.text.length - current.endSelectionOffset, strings.commonSuffixLength(original.text, current.text) ); const deletedText = original.text.substring(commonPrefix, original.text.length - commonSuffix); - const insertedText = current.text.substring(commonPrefix, current.text.length - commonSuffix); + const insertedTextStartOffset = commonPrefix; + const insertedTextEndOffset = current.text.length - commonSuffix; + const insertedText = current.text.substring(insertedTextStartOffset, insertedTextEndOffset); + const insertedTextRange = new Range(current.lineNumber, insertedTextStartOffset + 1, current.lineNumber, insertedTextEndOffset + 1); return new CompositionOutcome( deletedText, - original.startSelection - commonPrefix, - original.endSelection - commonPrefix, + original.startSelectionOffset - commonPrefix, + original.endSelectionOffset - commonPrefix, insertedText, - current.startSelection - commonPrefix, - current.endSelection - commonPrefix + current.startSelectionOffset - commonPrefix, + current.endSelectionOffset - commonPrefix, + insertedTextRange ); } } diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 10091f1911761..dd6df42878381 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -74,7 +74,7 @@ export class TypeOperations { /** * This is very similar with typing, but the character is already in the text buffer! */ - public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, compositions: CompositionOutcome[] | null, selections: Selection[], autoClosedCharacters: Range[], compositionRange?: Range | undefined): EditOperationResult | null { + public static compositionEndWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, compositions: CompositionOutcome[] | null, selections: Selection[], autoClosedCharacters: Range[]): EditOperationResult | null { if (!compositions) { // could not deduce what the composition did return null; @@ -92,7 +92,7 @@ export class TypeOperations { if (!insertedText || insertedText.length !== 1) { // we're only interested in the case where a single character was inserted - return this._overtypeEdits(compositionRange) ?? null; + return this._getOvertypeEdits(compositions) ?? null; } const ch = insertedText; @@ -160,12 +160,12 @@ export class TypeOperations { if (autoClosingOpenCharEdits !== undefined) { return autoClosingOpenCharEdits; } - - return this._overtypeEdits(compositionRange) ?? null; + return this._getOvertypeEdits(compositions) ?? null; } - private static _overtypeEdits(compositionRange: Range | undefined): EditOperationResult | undefined { - if (!compositionRange) { + private static _getOvertypeEdits(compositions: CompositionOutcome[] | null): EditOperationResult | undefined { + console.log('compositions', compositions); + if (!compositions) { return undefined; } const inputMode = InputMode.getInputMode(); @@ -173,7 +173,7 @@ export class TypeOperations { if (!isOvertypeMode) { return undefined; } - const commands = [new ReplaceOvertypeCommandInComposition(compositionRange)]; + const commands = compositions.map(composition => new ReplaceOvertypeCommandInComposition(composition.insertedTextRange)); return new EditOperationResult(EditOperationType.TypingOther, commands, { shouldPushStackElementBefore: true, shouldPushStackElementAfter: false @@ -228,5 +228,6 @@ export class CompositionOutcome { public readonly insertedText: string, public readonly insertedSelectionStart: number, public readonly insertedSelectionEnd: number, + public readonly insertedTextRange: Range, ) { } } diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index b868280279286..96043722d84c5 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -1054,8 +1054,8 @@ export class ViewModel extends Disposable implements IViewModel { public startComposition(): void { this._executeCursorEdit(eventsCollector => this._cursor.startComposition(eventsCollector)); } - public endComposition(source?: string | null | undefined, compositionRange?: Range | undefined): void { - this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source, compositionRange)); + public endComposition(source?: string | null | undefined): void { + this._executeCursorEdit(eventsCollector => this._cursor.endComposition(eventsCollector, source)); } public type(text: string, source?: string | null | undefined): void { this._executeCursorEdit(eventsCollector => this._cursor.type(eventsCollector, text, source)); From 6a6e9ae116da36b83403971ac9e056596279679b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 16:53:17 +0100 Subject: [PATCH 23/44] removing log --- src/vs/editor/common/cursor/cursorTypeOperations.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index dd6df42878381..68bb9972a0952 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -164,7 +164,6 @@ export class TypeOperations { } private static _getOvertypeEdits(compositions: CompositionOutcome[] | null): EditOperationResult | undefined { - console.log('compositions', compositions); if (!compositions) { return undefined; } From 24f1dabf2c993924f18720e15ac59de5c6ccd967 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 17:14:04 +0100 Subject: [PATCH 24/44] polishing the code --- .../viewParts/viewCursors/viewCursor.ts | 20 +++++++++++-------- .../viewParts/viewCursors/viewCursors.ts | 14 ++++++------- .../editor/common/commands/replaceCommand.ts | 18 ++++++++--------- src/vs/editor/common/config/editorOptions.ts | 4 ++-- .../common/cursor/cursorTypeEditOperations.ts | 4 ++-- src/vs/monaco.d.ts | 2 +- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 3f05bb8010f51..d910d8486b553 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -7,7 +7,7 @@ import * as dom from '../../../../base/browser/dom.js'; import { FastDomNode, createFastDomNode } from '../../../../base/browser/fastDomNode.js'; import * as strings from '../../../../base/common/strings.js'; import { applyFontInfo } from '../../config/domFontInfo.js'; -import { TextEditorCursorStyle, EditorOption } from '../../../common/config/editorOptions.js'; +import { TextEditorCursorStyle, EditorOption, IComputedEditorOptions } from '../../../common/config/editorOptions.js'; import { Position } from '../../../common/core/position.js'; import { Range } from '../../../common/core/range.js'; import { RenderingContext, RestrictedRenderingContext } from '../../view/renderingContext.js'; @@ -66,7 +66,6 @@ export class ViewCursor extends Disposable { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._setCursorStyle(); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -89,8 +88,9 @@ export class ViewCursor extends Disposable { this._lastRenderedContent = ''; this._renderData = null; + this._updateCursorStyle(); this._register(InputMode.onDidChangeInputMode(() => { - this._setCursorStyle(); + this._updateCursorStyle(); })); } @@ -137,7 +137,7 @@ export class ViewCursor extends Disposable { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._setCursorStyle(); + this._updateCursorStyle(); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -241,10 +241,8 @@ export class ViewCursor extends Disposable { return new ViewCursorRenderData(top, range.left, 0, width, height, textContent, textContentClassName); } - private _setCursorStyle(): void { - const options = this._context.configuration.options; - const inputMode = InputMode.getInputMode(); - this._cursorStyle = inputMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + private _updateCursorStyle(): void { + this._cursorStyle = getCursorStyle(this._context.configuration.options); } private _getTokenClassName(position: Position): string { @@ -287,3 +285,9 @@ export class ViewCursor extends Disposable { }; } } + +export function getCursorStyle(options: IComputedEditorOptions) { + return InputMode.getInputMode() === 'overtype' ? + options.get(EditorOption.overtypeCursorStyle) : + options.get(EditorOption.cursorStyle); +} diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index c8238e0e9d7fc..ff39210b60157 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -7,7 +7,7 @@ import './viewCursors.css'; import { FastDomNode, createFastDomNode } from '../../../../base/browser/fastDomNode.js'; import { IntervalTimer, TimeoutTimer } from '../../../../base/common/async.js'; import { ViewPart } from '../../view/viewPart.js'; -import { IViewCursorRenderData, ViewCursor, CursorPlurality } from './viewCursor.js'; +import { IViewCursorRenderData, ViewCursor, CursorPlurality, getCursorStyle } from './viewCursor.js'; import { TextEditorCursorBlinkingStyle, TextEditorCursorStyle, EditorOption } from '../../../common/config/editorOptions.js'; import { Position } from '../../../common/core/position.js'; import { @@ -91,9 +91,9 @@ export class ViewCursors extends ViewPart { this._editorHasFocus = false; this._updateBlinking(); - this._setCursorStyle(); + this._updateCursorStyle(); this._register(InputMode.onDidChangeInputMode(() => { - this._setCursorStyle(); + this._updateCursorStyle(); })); } @@ -130,7 +130,7 @@ export class ViewCursors extends ViewPart { this._updateBlinking(); this._updateDomClassName(); - this._setCursorStyle(); + this._updateCursorStyle(); this._primaryCursor.onConfigurationChanged(e); for (let i = 0, len = this._secondaryCursors.length; i < len; i++) { @@ -351,10 +351,8 @@ export class ViewCursors extends ViewPart { return result; } - private _setCursorStyle(): void { - const options = this._context.configuration.options; - const inputMode = InputMode.getInputMode(); - this._cursorStyle = inputMode === 'overtype' ? options.get(EditorOption.overtypeCursorStyle) : options.get(EditorOption.cursorStyle); + private _updateCursorStyle(): void { + this._cursorStyle = getCursorStyle(this._context.configuration.options); this.forceShouldRender(); this._viewHelper.renderNow(); } diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 82cc4f4c88e9f..7717b1133131a 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -50,7 +50,8 @@ export class ReplaceOvertypeCommand implements ICommand { const rangeEndOffset = model.getOffsetAt(endPosition); const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; - const lastCharacter = model.getValueInRange(Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset))); + const lastCharacterRange = Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset)); + const lastCharacter = model.getValueInRange(lastCharacterRange); const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); builder.addTrackedEditOperation(replaceRange, this._text); @@ -78,18 +79,17 @@ export class OvertypePasteCommand implements ICommand { public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { const startPosition = this._range.getStartPosition(); const endPosition = this._range.getEndPosition(); - const endLine = endPosition.lineNumber; + const endLineNumber = endPosition.lineNumber; const potentialEndOffset = model.getOffsetAt(endPosition) + this._text.length + (this._range.isEmpty() ? 0 : - 1); const potentialEndPosition = model.getPositionAt(potentialEndOffset); let newEndPosition: Position; - if (potentialEndPosition.lineNumber > endLine) { - const endLineMaxColumn = model.getLineMaxColumn(endLine); - newEndPosition = new Position(endLine, endLineMaxColumn); + if (potentialEndPosition.lineNumber > endLineNumber) { + newEndPosition = new Position(endLineNumber, model.getLineMaxColumn(endLineNumber)); } else { newEndPosition = potentialEndPosition; } - const range = Range.fromPositions(startPosition, newEndPosition); - builder.addTrackedEditOperation(range, this._text); + const replaceRange = Range.fromPositions(startPosition, newEndPosition); + builder.addTrackedEditOperation(replaceRange, this._text); } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { @@ -186,8 +186,8 @@ export class ReplaceOvertypeCommandInComposition implements ICommand { if (endPosition.lineNumber > this._range.endLineNumber) { endPosition = new Position(this._range.endLineNumber, model.getLineMaxColumn(this._range.endLineNumber)); } - const range = Range.fromPositions(startPosition, endPosition); - builder.addTrackedEditOperation(range, text); + const replaceRange = Range.fromPositions(startPosition, endPosition); + builder.addTrackedEditOperation(replaceRange, text); } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index af632e6ad67e0..7c3b6350c7549 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -785,7 +785,7 @@ export interface IEditorOptions { inputMode?: 'insert' | 'overtype'; /** - * Paste in overtype mode should overwrite. + * Controls whether paste in overtype mode should overwrite or insert. */ overtypeOnPaste?: boolean; } @@ -5877,7 +5877,7 @@ export const EditorOptions = { nls.localize('inputMode.insert', "Insert text at cursor position"), nls.localize('inputMode.overtype', "Replace text at cursor position") ], - description: nls.localize('inputMode', "Controls how text is inputted, whether it is inserted or it overwrites existing content.") + description: nls.localize('inputMode', "Controls whether new text is inserted or it replaces existing text, at the cursor position.") } )), letterSpacing: register(new EditorFloatOption( diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index a79d5b577939a..e641fecdb3510 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -723,14 +723,14 @@ export class PasteOperation { export class CompositionOperation { public static getEdits(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number) { - const commands = selections.map(selection => this._compositionType(config, model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta)); + const commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta)); return new EditOperationResult(EditOperationType.TypingOther, commands, { shouldPushStackElementBefore: shouldPushStackElementBetween(prevEditOperationType, EditOperationType.TypingOther), shouldPushStackElementAfter: false }); } - private static _compositionType(config: CursorConfiguration, model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null { + private static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null { if (!selection.isEmpty()) { // looks like https://github.com/microsoft/vscode/issues/2773 // where a cursor operation occurred before a canceled composition diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 6bf895fd27bf8..1d6945f5836c8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3820,7 +3820,7 @@ declare namespace monaco.editor { */ inputMode?: 'insert' | 'overtype'; /** - * Paste in overtype mode should overwrite. + * Controls whether paste in overtype mode should overwrite or insert. */ overtypeOnPaste?: boolean; } From 6a5daee176cf80ae3505bc6ea4e8e2089144272c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 13 Nov 2024 17:42:28 +0100 Subject: [PATCH 25/44] adding tests for overtype mode --- .../test/browser/controller/cursor.test.ts | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 2eb1303c28cc5..3f37cfef3eb81 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -28,6 +28,7 @@ import { OutgoingViewModelEventKind } from '../../../common/viewModelEventDispat import { ITestCodeEditor, TestCodeEditorInstantiationOptions, createCodeEditorServices, instantiateTestCodeEditor, withTestCodeEditor } from '../testCodeEditor.js'; import { IRelaxedTextModelCreationOptions, createTextModel, instantiateTextModel } from '../../common/testTextModel.js'; import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js'; +import { InputMode } from '../../../../base/common/inputMode.js'; // --------- utils @@ -6451,3 +6452,181 @@ suite('Undo stops', () => { model.dispose(); }); }); + +suite('Overtype Mode', () => { + + ensureNoDisposablesAreLeakedInTestSuite(); + + test('simple type', () => { + const model = createTextModel( + [ + '123456789', + '123456789', + ].join('\n'), + undefined, + { + insertSpaces: false, + } + ); + + withTestCodeEditor(model, {}, (editor, viewModel) => { + InputMode.setInputMode('overtype'); + viewModel.setSelections('test', [new Selection(1, 3, 1, 3)]); + viewModel.type('a', 'keyboard'); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '12a456789', + '123456789', + ].join('\n'), 'assert1'); + + viewModel.setSelections('test', [new Selection(1, 9, 1, 9)]); + viewModel.type('bbb', 'keyboard'); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '12a45678bbb', + '123456789', + ].join('\n'), 'assert2'); + }); + + model.dispose(); + }); + + test('multi-line selection type', () => { + const model = createTextModel( + [ + '123456789', + '123456789', + ].join('\n'), + undefined, + { + insertSpaces: false, + } + ); + + withTestCodeEditor(model, {}, (editor, viewModel) => { + InputMode.setInputMode('overtype'); + viewModel.setSelections('test', [new Selection(1, 5, 2, 3)]); + viewModel.type('cc', 'keyboard'); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234cc456789', + ].join('\n'), 'assert1'); + }); + + model.dispose(); + }); + + test('simple paste', () => { + const model = createTextModel( + [ + '123456789', + '123456789', + ].join('\n'), + undefined, + { + insertSpaces: false, + } + ); + + withTestCodeEditor(model, {}, (editor, viewModel) => { + InputMode.setInputMode('overtype'); + viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); + viewModel.paste('cc', false); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234cc789', + '123456789', + ].join('\n'), 'assert1'); + + viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); + viewModel.paste('dddddddd', false); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234dddddddd', + '123456789', + ].join('\n'), 'assert2'); + }); + + model.dispose(); + }); + + test('multi-line selection paste', () => { + const model = createTextModel( + [ + '123456789', + '123456789', + ].join('\n'), + undefined, + { + insertSpaces: false, + } + ); + + withTestCodeEditor(model, {}, (editor, viewModel) => { + InputMode.setInputMode('overtype'); + viewModel.setSelections('test', [new Selection(1, 5, 2, 3)]); + viewModel.paste('cc', false); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234cc456789', + ].join('\n'), 'assert1'); + }); + + model.dispose(); + }); + + test('paste multi-line text', () => { + const model = createTextModel( + [ + '123456789', + '123456789', + ].join('\n'), + undefined, + { + insertSpaces: false, + } + ); + + withTestCodeEditor(model, {}, (editor, viewModel) => { + InputMode.setInputMode('overtype'); + viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); + viewModel.paste([ + 'aaaaaaa', + 'bbbbbbb' + ].join('\n'), false); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234aaaaaaa', + 'bbbbbbb', + '123456789', + ].join('\n'), 'assert1'); + }); + + model.dispose(); + }); + + test('composition type', () => { + const model = createTextModel( + [ + '123456789', + '123456789', + ].join('\n'), + undefined, + { + insertSpaces: false, + } + ); + + withTestCodeEditor(model, {}, (editor, viewModel) => { + InputMode.setInputMode('overtype'); + viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); + viewModel.startComposition(); + viewModel.compositionType('ã‚»', 0, 0, 0, 'keyboard'); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234ã‚»56789', + '123456789', + ].join('\n'), 'assert1'); + + viewModel.endComposition('keyboard'); + assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ + '1234ã‚»6789', + '123456789', + ].join('\n'), 'assert1'); + }); + + model.dispose(); + }); +}); From d78453c583c3438863a304770bbbc19b41ce9db9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 14 Nov 2024 15:10:28 +0100 Subject: [PATCH 26/44] reset back the input mode to insert from ovetype on suite teardown --- .../editor/test/browser/controller/cursor.test.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index 3f37cfef3eb81..e98df235f013d 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -6455,6 +6455,14 @@ suite('Undo stops', () => { suite('Overtype Mode', () => { + setup(() => { + InputMode.setInputMode('overtype'); + }); + + teardown(() => { + InputMode.setInputMode('insert'); + }); + ensureNoDisposablesAreLeakedInTestSuite(); test('simple type', () => { @@ -6470,7 +6478,6 @@ suite('Overtype Mode', () => { ); withTestCodeEditor(model, {}, (editor, viewModel) => { - InputMode.setInputMode('overtype'); viewModel.setSelections('test', [new Selection(1, 3, 1, 3)]); viewModel.type('a', 'keyboard'); assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ @@ -6502,7 +6509,6 @@ suite('Overtype Mode', () => { ); withTestCodeEditor(model, {}, (editor, viewModel) => { - InputMode.setInputMode('overtype'); viewModel.setSelections('test', [new Selection(1, 5, 2, 3)]); viewModel.type('cc', 'keyboard'); assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ @@ -6526,7 +6532,6 @@ suite('Overtype Mode', () => { ); withTestCodeEditor(model, {}, (editor, viewModel) => { - InputMode.setInputMode('overtype'); viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); viewModel.paste('cc', false); assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ @@ -6558,7 +6563,6 @@ suite('Overtype Mode', () => { ); withTestCodeEditor(model, {}, (editor, viewModel) => { - InputMode.setInputMode('overtype'); viewModel.setSelections('test', [new Selection(1, 5, 2, 3)]); viewModel.paste('cc', false); assert.strictEqual(model.getValue(EndOfLinePreference.LF), [ @@ -6582,7 +6586,6 @@ suite('Overtype Mode', () => { ); withTestCodeEditor(model, {}, (editor, viewModel) => { - InputMode.setInputMode('overtype'); viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); viewModel.paste([ 'aaaaaaa', @@ -6611,7 +6614,6 @@ suite('Overtype Mode', () => { ); withTestCodeEditor(model, {}, (editor, viewModel) => { - InputMode.setInputMode('overtype'); viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]); viewModel.startComposition(); viewModel.compositionType('ã‚»', 0, 0, 0, 'keyboard'); From 539e18b5aa5d0f88c1629f76c4c3b83411bc2399 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 19 Nov 2024 11:57:45 +0100 Subject: [PATCH 27/44] moving inputMode class to the editor folder from the base folder --- src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts | 2 +- src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts | 2 +- src/vs/editor/common/cursor/cursorTypeEditOperations.ts | 2 +- src/vs/editor/common/cursor/cursorTypeOperations.ts | 2 +- src/vs/{base => editor}/common/inputMode.ts | 2 +- src/vs/editor/test/browser/controller/cursor.test.ts | 2 +- src/vs/workbench/browser/parts/editor/editorActions.ts | 2 +- src/vs/workbench/browser/parts/editor/editorStatus.ts | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) rename src/vs/{base => editor}/common/inputMode.ts (93%) diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index d910d8486b553..360404e0de101 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -14,7 +14,7 @@ import { RenderingContext, RestrictedRenderingContext } from '../../view/renderi import { ViewContext } from '../../../common/viewModel/viewContext.js'; import * as viewEvents from '../../../common/viewEvents.js'; import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from '../../../../base/browser/ui/mouseCursor/mouseCursor.js'; -import { InputMode } from '../../../../base/common/inputMode.js'; +import { InputMode } from '../../../common/inputMode.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; export interface IViewCursorRenderData { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index ff39210b60157..6d7fd83d8054f 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -22,7 +22,7 @@ import { registerThemingParticipant } from '../../../../platform/theme/common/th import { isHighContrast } from '../../../../platform/theme/common/theme.js'; import { CursorChangeReason } from '../../../common/cursorEvents.js'; import { WindowIntervalTimer, getWindow } from '../../../../base/browser/dom.js'; -import { InputMode } from '../../../../base/common/inputMode.js'; +import { InputMode } from '../../../common/inputMode.js'; export interface IViewCursorsHelper { renderNow(): void; diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index e641fecdb3510..b7face08b5a53 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -23,7 +23,7 @@ import { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/e import { createScopedLineTokens } from '../languages/supports.js'; import { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js'; import { getEnterAction } from '../languages/enterAction.js'; -import { InputMode } from '../../../base/common/inputMode.js'; +import { InputMode } from '../inputMode.js'; export class AutoIndentOperation { diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 68bb9972a0952..5860c7504e2e1 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,7 +12,7 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; -import { InputMode } from '../../../base/common/inputMode.js'; +import { InputMode } from '../inputMode.js'; import { ReplaceOvertypeCommandInComposition } from '../commands/replaceCommand.js'; export class TypeOperations { diff --git a/src/vs/base/common/inputMode.ts b/src/vs/editor/common/inputMode.ts similarity index 93% rename from src/vs/base/common/inputMode.ts rename to src/vs/editor/common/inputMode.ts index 2c263b01991fb..304ac1f140e9b 100644 --- a/src/vs/base/common/inputMode.ts +++ b/src/vs/editor/common/inputMode.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Emitter, Event } from './event.js'; +import { Emitter, Event } from '../../base/common/event.js'; class InputModeImpl { diff --git a/src/vs/editor/test/browser/controller/cursor.test.ts b/src/vs/editor/test/browser/controller/cursor.test.ts index e98df235f013d..fe7c5e59c46ec 100644 --- a/src/vs/editor/test/browser/controller/cursor.test.ts +++ b/src/vs/editor/test/browser/controller/cursor.test.ts @@ -28,7 +28,7 @@ import { OutgoingViewModelEventKind } from '../../../common/viewModelEventDispat import { ITestCodeEditor, TestCodeEditorInstantiationOptions, createCodeEditorServices, instantiateTestCodeEditor, withTestCodeEditor } from '../testCodeEditor.js'; import { IRelaxedTextModelCreationOptions, createTextModel, instantiateTextModel } from '../../common/testTextModel.js'; import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js'; -import { InputMode } from '../../../../base/common/inputMode.js'; +import { InputMode } from '../../../common/inputMode.js'; // --------- utils diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index d500564db227f..7621d54f3dae7 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -38,7 +38,7 @@ import { ICommandActionTitle } from '../../../../platform/action/common/action.j import { IProgressService, ProgressLocation } from '../../../../platform/progress/common/progress.js'; import { resolveCommandsContext } from './editorCommandsContext.js'; import { IListService } from '../../../../platform/list/browser/listService.js'; -import { InputMode } from '../../../../base/common/inputMode.js'; +import { InputMode } from '../../../../editor/common/inputMode.js'; class ExecuteCommandAction extends Action2 { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index f4b0120d0783d..58d8a76a01fb1 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -56,7 +56,7 @@ import { KeybindingWeight } from '../../../../platform/keybinding/common/keybind import { KeyChord, KeyCode, KeyMod } from '../../../../base/common/keyCodes.js'; import { TabFocus } from '../../../../editor/browser/config/tabFocus.js'; import { IEditorGroupsService, IEditorPart } from '../../../services/editor/common/editorGroupsService.js'; -import { InputMode } from '../../../../base/common/inputMode.js'; +import { InputMode } from '../../../../editor/common/inputMode.js'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private primary: IEncodingSupport, private secondary: IEncodingSupport) { } From 47e2c50dc2448c3792d82562aa832237e3ec733e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 19 Nov 2024 12:15:11 +0100 Subject: [PATCH 28/44] remove input mode default value --- src/vs/editor/common/config/editorOptions.ts | 18 -- .../common/standalone/standaloneEnums.ts | 179 +++++++++-------- src/vs/monaco.d.ts | 184 +++++++++--------- .../browser/parts/editor/editorStatus.ts | 3 +- 4 files changed, 179 insertions(+), 205 deletions(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 7c3b6350c7549..37afef8e33f3c 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -779,11 +779,6 @@ export interface IEditorOptions { */ inlineCompletionsAccessibilityVerbose?: boolean; - /** - * Controls the input mode, whether it is insert or overtype - */ - inputMode?: 'insert' | 'overtype'; - /** * Controls whether paste in overtype mode should overwrite or insert. */ @@ -5405,7 +5400,6 @@ export const enum EditorOption { hover, inDiffEditor, inlineSuggest, - inputMode, letterSpacing, lightbulb, lineDecorationsWidth, @@ -5868,18 +5862,6 @@ export const EditorOptions = { inDiffEditor: register(new EditorBooleanOption( EditorOption.inDiffEditor, 'inDiffEditor', false )), - inputMode: register(new EditorStringEnumOption( - EditorOption.inputMode, 'inputMode', - 'insert' as 'insert' | 'overtype', - ['insert', 'overtype'] as const, - { - enumDescriptions: [ - nls.localize('inputMode.insert', "Insert text at cursor position"), - nls.localize('inputMode.overtype', "Replace text at cursor position") - ], - description: nls.localize('inputMode', "Controls whether new text is inserted or it replaces existing text, at the cursor position.") - } - )), letterSpacing: register(new EditorFloatOption( EditorOption.letterSpacing, 'letterSpacing', EDITOR_FONT_DEFAULTS.letterSpacing, x => EditorFloatOption.clamp(x, -5, 20), diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index f2df8468bcac0..54f64789b6118 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -239,96 +239,95 @@ export enum EditorOption { hover = 63, inDiffEditor = 64, inlineSuggest = 65, - inputMode = 66, - letterSpacing = 67, - lightbulb = 68, - lineDecorationsWidth = 69, - lineHeight = 70, - lineNumbers = 71, - lineNumbersMinChars = 72, - linkedEditing = 73, - links = 74, - matchBrackets = 75, - minimap = 76, - mouseStyle = 77, - mouseWheelScrollSensitivity = 78, - mouseWheelZoom = 79, - multiCursorMergeOverlapping = 80, - multiCursorModifier = 81, - multiCursorPaste = 82, - multiCursorLimit = 83, - occurrencesHighlight = 84, - occurrencesHighlightDelay = 85, - overtypeOnPaste = 86, - overviewRulerBorder = 87, - overviewRulerLanes = 88, - padding = 89, - pasteAs = 90, - parameterHints = 91, - peekWidgetDefaultFocus = 92, - placeholder = 93, - definitionLinkOpensInPeek = 94, - quickSuggestions = 95, - quickSuggestionsDelay = 96, - readOnly = 97, - readOnlyMessage = 98, - renameOnType = 99, - renderControlCharacters = 100, - renderFinalNewline = 101, - renderLineHighlight = 102, - renderLineHighlightOnlyWhenFocus = 103, - renderValidationDecorations = 104, - renderWhitespace = 105, - revealHorizontalRightPadding = 106, - roundedSelection = 107, - rulers = 108, - scrollbar = 109, - scrollBeyondLastColumn = 110, - scrollBeyondLastLine = 111, - scrollPredominantAxis = 112, - selectionClipboard = 113, - selectionHighlight = 114, - selectOnLineNumbers = 115, - showFoldingControls = 116, - showUnused = 117, - snippetSuggestions = 118, - smartSelect = 119, - smoothScrolling = 120, - stickyScroll = 121, - stickyTabStops = 122, - stopRenderingLineAfter = 123, - suggest = 124, - suggestFontSize = 125, - suggestLineHeight = 126, - suggestOnTriggerCharacters = 127, - suggestSelection = 128, - tabCompletion = 129, - tabIndex = 130, - unicodeHighlighting = 131, - unusualLineTerminators = 132, - useShadowDOM = 133, - useTabStops = 134, - wordBreak = 135, - wordSegmenterLocales = 136, - wordSeparators = 137, - wordWrap = 138, - wordWrapBreakAfterCharacters = 139, - wordWrapBreakBeforeCharacters = 140, - wordWrapColumn = 141, - wordWrapOverride1 = 142, - wordWrapOverride2 = 143, - wrappingIndent = 144, - wrappingStrategy = 145, - showDeprecated = 146, - inlayHints = 147, - editorClassName = 148, - pixelRatio = 149, - tabFocusMode = 150, - layoutInfo = 151, - wrappingInfo = 152, - defaultColorDecorators = 153, - colorDecoratorsActivatedOn = 154, - inlineCompletionsAccessibilityVerbose = 155 + letterSpacing = 66, + lightbulb = 67, + lineDecorationsWidth = 68, + lineHeight = 69, + lineNumbers = 70, + lineNumbersMinChars = 71, + linkedEditing = 72, + links = 73, + matchBrackets = 74, + minimap = 75, + mouseStyle = 76, + mouseWheelScrollSensitivity = 77, + mouseWheelZoom = 78, + multiCursorMergeOverlapping = 79, + multiCursorModifier = 80, + multiCursorPaste = 81, + multiCursorLimit = 82, + occurrencesHighlight = 83, + occurrencesHighlightDelay = 84, + overtypeOnPaste = 85, + overviewRulerBorder = 86, + overviewRulerLanes = 87, + padding = 88, + pasteAs = 89, + parameterHints = 90, + peekWidgetDefaultFocus = 91, + placeholder = 92, + definitionLinkOpensInPeek = 93, + quickSuggestions = 94, + quickSuggestionsDelay = 95, + readOnly = 96, + readOnlyMessage = 97, + renameOnType = 98, + renderControlCharacters = 99, + renderFinalNewline = 100, + renderLineHighlight = 101, + renderLineHighlightOnlyWhenFocus = 102, + renderValidationDecorations = 103, + renderWhitespace = 104, + revealHorizontalRightPadding = 105, + roundedSelection = 106, + rulers = 107, + scrollbar = 108, + scrollBeyondLastColumn = 109, + scrollBeyondLastLine = 110, + scrollPredominantAxis = 111, + selectionClipboard = 112, + selectionHighlight = 113, + selectOnLineNumbers = 114, + showFoldingControls = 115, + showUnused = 116, + snippetSuggestions = 117, + smartSelect = 118, + smoothScrolling = 119, + stickyScroll = 120, + stickyTabStops = 121, + stopRenderingLineAfter = 122, + suggest = 123, + suggestFontSize = 124, + suggestLineHeight = 125, + suggestOnTriggerCharacters = 126, + suggestSelection = 127, + tabCompletion = 128, + tabIndex = 129, + unicodeHighlighting = 130, + unusualLineTerminators = 131, + useShadowDOM = 132, + useTabStops = 133, + wordBreak = 134, + wordSegmenterLocales = 135, + wordSeparators = 136, + wordWrap = 137, + wordWrapBreakAfterCharacters = 138, + wordWrapBreakBeforeCharacters = 139, + wordWrapColumn = 140, + wordWrapOverride1 = 141, + wordWrapOverride2 = 142, + wrappingIndent = 143, + wrappingStrategy = 144, + showDeprecated = 145, + inlayHints = 146, + editorClassName = 147, + pixelRatio = 148, + tabFocusMode = 149, + layoutInfo = 150, + wrappingInfo = 151, + defaultColorDecorators = 152, + colorDecoratorsActivatedOn = 153, + inlineCompletionsAccessibilityVerbose = 154 } /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 1d6945f5836c8..b07aff39cc519 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3815,10 +3815,6 @@ declare namespace monaco.editor { * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. */ inlineCompletionsAccessibilityVerbose?: boolean; - /** - * Controls the input mode, whether it is insert or overtype - */ - inputMode?: 'insert' | 'overtype'; /** * Controls whether paste in overtype mode should overwrite or insert. */ @@ -4954,96 +4950,95 @@ declare namespace monaco.editor { hover = 63, inDiffEditor = 64, inlineSuggest = 65, - inputMode = 66, - letterSpacing = 67, - lightbulb = 68, - lineDecorationsWidth = 69, - lineHeight = 70, - lineNumbers = 71, - lineNumbersMinChars = 72, - linkedEditing = 73, - links = 74, - matchBrackets = 75, - minimap = 76, - mouseStyle = 77, - mouseWheelScrollSensitivity = 78, - mouseWheelZoom = 79, - multiCursorMergeOverlapping = 80, - multiCursorModifier = 81, - multiCursorPaste = 82, - multiCursorLimit = 83, - occurrencesHighlight = 84, - occurrencesHighlightDelay = 85, - overtypeOnPaste = 86, - overviewRulerBorder = 87, - overviewRulerLanes = 88, - padding = 89, - pasteAs = 90, - parameterHints = 91, - peekWidgetDefaultFocus = 92, - placeholder = 93, - definitionLinkOpensInPeek = 94, - quickSuggestions = 95, - quickSuggestionsDelay = 96, - readOnly = 97, - readOnlyMessage = 98, - renameOnType = 99, - renderControlCharacters = 100, - renderFinalNewline = 101, - renderLineHighlight = 102, - renderLineHighlightOnlyWhenFocus = 103, - renderValidationDecorations = 104, - renderWhitespace = 105, - revealHorizontalRightPadding = 106, - roundedSelection = 107, - rulers = 108, - scrollbar = 109, - scrollBeyondLastColumn = 110, - scrollBeyondLastLine = 111, - scrollPredominantAxis = 112, - selectionClipboard = 113, - selectionHighlight = 114, - selectOnLineNumbers = 115, - showFoldingControls = 116, - showUnused = 117, - snippetSuggestions = 118, - smartSelect = 119, - smoothScrolling = 120, - stickyScroll = 121, - stickyTabStops = 122, - stopRenderingLineAfter = 123, - suggest = 124, - suggestFontSize = 125, - suggestLineHeight = 126, - suggestOnTriggerCharacters = 127, - suggestSelection = 128, - tabCompletion = 129, - tabIndex = 130, - unicodeHighlighting = 131, - unusualLineTerminators = 132, - useShadowDOM = 133, - useTabStops = 134, - wordBreak = 135, - wordSegmenterLocales = 136, - wordSeparators = 137, - wordWrap = 138, - wordWrapBreakAfterCharacters = 139, - wordWrapBreakBeforeCharacters = 140, - wordWrapColumn = 141, - wordWrapOverride1 = 142, - wordWrapOverride2 = 143, - wrappingIndent = 144, - wrappingStrategy = 145, - showDeprecated = 146, - inlayHints = 147, - editorClassName = 148, - pixelRatio = 149, - tabFocusMode = 150, - layoutInfo = 151, - wrappingInfo = 152, - defaultColorDecorators = 153, - colorDecoratorsActivatedOn = 154, - inlineCompletionsAccessibilityVerbose = 155 + letterSpacing = 66, + lightbulb = 67, + lineDecorationsWidth = 68, + lineHeight = 69, + lineNumbers = 70, + lineNumbersMinChars = 71, + linkedEditing = 72, + links = 73, + matchBrackets = 74, + minimap = 75, + mouseStyle = 76, + mouseWheelScrollSensitivity = 77, + mouseWheelZoom = 78, + multiCursorMergeOverlapping = 79, + multiCursorModifier = 80, + multiCursorPaste = 81, + multiCursorLimit = 82, + occurrencesHighlight = 83, + occurrencesHighlightDelay = 84, + overtypeOnPaste = 85, + overviewRulerBorder = 86, + overviewRulerLanes = 87, + padding = 88, + pasteAs = 89, + parameterHints = 90, + peekWidgetDefaultFocus = 91, + placeholder = 92, + definitionLinkOpensInPeek = 93, + quickSuggestions = 94, + quickSuggestionsDelay = 95, + readOnly = 96, + readOnlyMessage = 97, + renameOnType = 98, + renderControlCharacters = 99, + renderFinalNewline = 100, + renderLineHighlight = 101, + renderLineHighlightOnlyWhenFocus = 102, + renderValidationDecorations = 103, + renderWhitespace = 104, + revealHorizontalRightPadding = 105, + roundedSelection = 106, + rulers = 107, + scrollbar = 108, + scrollBeyondLastColumn = 109, + scrollBeyondLastLine = 110, + scrollPredominantAxis = 111, + selectionClipboard = 112, + selectionHighlight = 113, + selectOnLineNumbers = 114, + showFoldingControls = 115, + showUnused = 116, + snippetSuggestions = 117, + smartSelect = 118, + smoothScrolling = 119, + stickyScroll = 120, + stickyTabStops = 121, + stopRenderingLineAfter = 122, + suggest = 123, + suggestFontSize = 124, + suggestLineHeight = 125, + suggestOnTriggerCharacters = 126, + suggestSelection = 127, + tabCompletion = 128, + tabIndex = 129, + unicodeHighlighting = 130, + unusualLineTerminators = 131, + useShadowDOM = 132, + useTabStops = 133, + wordBreak = 134, + wordSegmenterLocales = 135, + wordSeparators = 136, + wordWrap = 137, + wordWrapBreakAfterCharacters = 138, + wordWrapBreakBeforeCharacters = 139, + wordWrapColumn = 140, + wordWrapOverride1 = 141, + wordWrapOverride2 = 142, + wrappingIndent = 143, + wrappingStrategy = 144, + showDeprecated = 145, + inlayHints = 146, + editorClassName = 147, + pixelRatio = 148, + tabFocusMode = 149, + layoutInfo = 150, + wrappingInfo = 151, + defaultColorDecorators = 152, + colorDecoratorsActivatedOn = 153, + inlineCompletionsAccessibilityVerbose = 154 } export const EditorOptions: { @@ -5115,7 +5110,6 @@ declare namespace monaco.editor { hideCursorInOverviewRuler: IEditorOption; hover: IEditorOption>>; inDiffEditor: IEditorOption; - inputMode: IEditorOption; letterSpacing: IEditorOption; lightbulb: IEditorOption>>; lineDecorationsWidth: IEditorOption; diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 58d8a76a01fb1..4bded406680dc 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -330,8 +330,7 @@ class StatusInputMode extends Disposable { constructor(@IConfigurationService private readonly configurationService: IConfigurationService) { super(); this.registerListeners(); - const inputMode = configurationService.getValue<'overtype' | 'insert'>('editor.inputMode'); - InputMode.setInputMode(inputMode); + InputMode.setInputMode('insert'); } private registerListeners(): void { From 09e30fba27e50d4f9ba487e18971bd805221b2d4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 19 Nov 2024 12:16:55 +0100 Subject: [PATCH 29/44] removing undefined check on input mode --- src/vs/workbench/browser/parts/editor/editorStatus.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 4bded406680dc..b3eaa334d7275 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -470,7 +470,7 @@ class EditorStatus extends Disposable { } private updateInputModeElement(inputMode: 'overtype' | 'insert' | undefined): void { - if (!!inputMode && inputMode === 'overtype') { + if (inputMode === 'overtype') { if (!this.inputModeElement.value) { const text = localize('inputModeOvertype', 'OVR'); const name = localize('status.editor.enableInsertMode', "Enable Insert Mode"); From 473deea53f8ec06dce1f2cb5ab198fa496142f88 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 19 Nov 2024 12:23:55 +0100 Subject: [PATCH 30/44] changing the keybindings for `alt+cmd+o` --- src/vs/workbench/browser/parts/editor/editorActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 7621d54f3dae7..ca811927d135a 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2713,7 +2713,7 @@ export class ToggleOvertypeInsertMode extends Action2 { keybinding: { weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.Insert, - secondary: [KeyMod.Shift | KeyCode.Ctrl | KeyCode.KeyQ], + secondary: [KeyMod.Alt | KeyCode.Ctrl | KeyCode.KeyO], }, f1: true, category: Categories.View From 619926f8f99ff9e775bf0c1822222debca374b04 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 20 Nov 2024 15:57:30 +0100 Subject: [PATCH 31/44] removing the composition payload --- src/vs/editor/common/editorCommon.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 578595929b9d6..e25edb4fb50a5 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -762,14 +762,6 @@ export interface TypePayload { text: string; } -/** - * @internal - */ -export interface CompositionPayload { - compositionRange: Range; -} - - /** * @internal */ From e0276c41c47c30bee1042f8eff3e5a2e991ffa74 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 20 Nov 2024 19:11:55 +0100 Subject: [PATCH 32/44] surfacing input mode through cursor configuration --- .../editor/common/cursor/cursorTypeEditOperations.ts | 12 ++++-------- src/vs/editor/common/cursor/cursorTypeOperations.ts | 12 +++++------- src/vs/editor/common/cursorCommon.ts | 5 +++++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index b7face08b5a53..f44fa8b722d02 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -23,7 +23,6 @@ import { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/e import { createScopedLineTokens } from '../languages/supports.js'; import { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js'; import { getEnterAction } from '../languages/enterAction.js'; -import { InputMode } from '../inputMode.js'; export class AutoIndentOperation { @@ -484,12 +483,11 @@ export class InterceptorElectricCharOperation { export class SimpleCharacterTypeOperation { - public static getEdits(prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult { + public static getEdits(config: CursorConfiguration, prevEditOperationType: EditOperationType, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult { // A simple character type const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { - const inputMode = InputMode.getInputMode(); - const ChosenReplaceCommand = inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand; + const ChosenReplaceCommand = config.inputMode === 'overtype' && !isDoingComposition ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], ch); } @@ -680,8 +678,7 @@ export class PasteOperation { private static _distributedPaste(config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], text: string[]): EditOperationResult { const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { - const inputMode = InputMode.getInputMode(); - const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; + const shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype'; const ChosenReplaceCommand = shouldOvertypeOnPaste ? OvertypePasteCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], text[i]); } @@ -707,8 +704,7 @@ export class PasteOperation { const typeSelection = new Range(position.lineNumber, 1, position.lineNumber, 1); commands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true); } else { - const inputMode = InputMode.getInputMode(); - const shouldOvertypeOnPaste = config.overtypeOnPaste && inputMode === 'overtype'; + const shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype'; const ChosenReplaceCommand = shouldOvertypeOnPaste ? OvertypePasteCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selection, text); } diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 5860c7504e2e1..111de14487861 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -12,7 +12,6 @@ import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; -import { InputMode } from '../inputMode.js'; import { ReplaceOvertypeCommandInComposition } from '../commands/replaceCommand.js'; export class TypeOperations { @@ -92,7 +91,7 @@ export class TypeOperations { if (!insertedText || insertedText.length !== 1) { // we're only interested in the case where a single character was inserted - return this._getOvertypeEdits(compositions) ?? null; + return this._getOvertypeEdits(config, compositions) ?? null; } const ch = insertedText; @@ -160,15 +159,14 @@ export class TypeOperations { if (autoClosingOpenCharEdits !== undefined) { return autoClosingOpenCharEdits; } - return this._getOvertypeEdits(compositions) ?? null; + return this._getOvertypeEdits(config, compositions) ?? null; } - private static _getOvertypeEdits(compositions: CompositionOutcome[] | null): EditOperationResult | undefined { + private static _getOvertypeEdits(config: CursorConfiguration, compositions: CompositionOutcome[] | null): EditOperationResult | undefined { if (!compositions) { return undefined; } - const inputMode = InputMode.getInputMode(); - const isOvertypeMode = inputMode === 'overtype'; + const isOvertypeMode = config.inputMode === 'overtype'; if (!isOvertypeMode) { return undefined; } @@ -211,7 +209,7 @@ export class TypeOperations { return interceptorElectricCharOperation; } - return SimpleCharacterTypeOperation.getEdits(prevEditOperationType, selections, ch, isDoingComposition); + return SimpleCharacterTypeOperation.getEdits(config, prevEditOperationType, selections, ch, isDoingComposition); } public static typeWithoutInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], str: string): EditOperationResult { diff --git a/src/vs/editor/common/cursorCommon.ts b/src/vs/editor/common/cursorCommon.ts index c74b923ef7a4e..2e1c78484fcb3 100644 --- a/src/vs/editor/common/cursorCommon.ts +++ b/src/vs/editor/common/cursorCommon.ts @@ -17,6 +17,7 @@ import { createScopedLineTokens } from './languages/supports.js'; import { IElectricAction } from './languages/supports/electricCharacter.js'; import { CursorColumns } from './core/cursorColumns.js'; import { normalizeIndentation } from './core/indentation.js'; +import { InputMode } from './inputMode.js'; export interface IColumnSelectData { isReal: boolean; @@ -176,6 +177,10 @@ export class CursorConfiguration { return this._electricChars; } + public get inputMode(): 'insert' | 'overtype' { + return InputMode.getInputMode(); + } + /** * Should return opening bracket type to match indentation with */ From 79744cf5ae577e8796de8b141b1887dc2e199ab7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 20 Nov 2024 19:26:46 +0100 Subject: [PATCH 33/44] removing disposableness on viewcursor --- .../viewParts/viewCursors/viewCursor.ts | 33 ++++++------------- .../viewParts/viewCursors/viewCursors.ts | 30 ++++++++++------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 360404e0de101..0c784a62594d2 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -7,15 +7,13 @@ import * as dom from '../../../../base/browser/dom.js'; import { FastDomNode, createFastDomNode } from '../../../../base/browser/fastDomNode.js'; import * as strings from '../../../../base/common/strings.js'; import { applyFontInfo } from '../../config/domFontInfo.js'; -import { TextEditorCursorStyle, EditorOption, IComputedEditorOptions } from '../../../common/config/editorOptions.js'; +import { TextEditorCursorStyle, EditorOption } from '../../../common/config/editorOptions.js'; import { Position } from '../../../common/core/position.js'; import { Range } from '../../../common/core/range.js'; import { RenderingContext, RestrictedRenderingContext } from '../../view/renderingContext.js'; import { ViewContext } from '../../../common/viewModel/viewContext.js'; import * as viewEvents from '../../../common/viewEvents.js'; import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from '../../../../base/browser/ui/mouseCursor/mouseCursor.js'; -import { InputMode } from '../../../common/inputMode.js'; -import { Disposable } from '../../../../base/common/lifecycle.js'; export interface IViewCursorRenderData { domNode: HTMLElement; @@ -43,11 +41,11 @@ export enum CursorPlurality { MultiSecondary, } -export class ViewCursor extends Disposable { +export class ViewCursor { private readonly _context: ViewContext; private readonly _domNode: FastDomNode; - private _cursorStyle!: TextEditorCursorStyle; + private _cursorStyle: TextEditorCursorStyle; private _lineCursorWidth: number; private _lineHeight: number; private _typicalHalfwidthCharacterWidth: number; @@ -60,12 +58,12 @@ export class ViewCursor extends Disposable { private _lastRenderedContent: string; private _renderData: ViewCursorRenderData | null; - constructor(context: ViewContext, plurality: CursorPlurality) { - super(); + constructor(context: ViewContext, plurality: CursorPlurality, cursorStyle: TextEditorCursorStyle) { this._context = context; const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); + this._cursorStyle = cursorStyle; this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -87,11 +85,6 @@ export class ViewCursor extends Disposable { this._lastRenderedContent = ''; this._renderData = null; - - this._updateCursorStyle(); - this._register(InputMode.onDidChangeInputMode(() => { - this._updateCursorStyle(); - })); } public getDomNode(): FastDomNode { @@ -137,7 +130,7 @@ export class ViewCursor extends Disposable { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._updateCursorStyle(); + this._cursorStyle = options.get(EditorOption.cursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -241,16 +234,16 @@ export class ViewCursor extends Disposable { return new ViewCursorRenderData(top, range.left, 0, width, height, textContent, textContentClassName); } - private _updateCursorStyle(): void { - this._cursorStyle = getCursorStyle(this._context.configuration.options); - } - private _getTokenClassName(position: Position): string { const lineData = this._context.viewModel.getViewLineData(position.lineNumber); const tokenIndex = lineData.tokens.findTokenIndexAtOffset(position.column - 1); return lineData.tokens.getClassName(tokenIndex); } + public updateCursorStyle(cursorStyle: TextEditorCursorStyle): void { + this._cursorStyle = cursorStyle; + } + public prepareRender(ctx: RenderingContext): void { this._renderData = this._prepareRender(ctx); } @@ -285,9 +278,3 @@ export class ViewCursor extends Disposable { }; } } - -export function getCursorStyle(options: IComputedEditorOptions) { - return InputMode.getInputMode() === 'overtype' ? - options.get(EditorOption.overtypeCursorStyle) : - options.get(EditorOption.cursorStyle); -} diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 6d7fd83d8054f..580e6a351e132 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -7,7 +7,7 @@ import './viewCursors.css'; import { FastDomNode, createFastDomNode } from '../../../../base/browser/fastDomNode.js'; import { IntervalTimer, TimeoutTimer } from '../../../../base/common/async.js'; import { ViewPart } from '../../view/viewPart.js'; -import { IViewCursorRenderData, ViewCursor, CursorPlurality, getCursorStyle } from './viewCursor.js'; +import { IViewCursorRenderData, ViewCursor, CursorPlurality } from './viewCursor.js'; import { TextEditorCursorBlinkingStyle, TextEditorCursorStyle, EditorOption } from '../../../common/config/editorOptions.js'; import { Position } from '../../../common/core/position.js'; import { @@ -73,7 +73,12 @@ export class ViewCursors extends ViewPart { this._isVisible = false; - this._primaryCursor = this._register(new ViewCursor(this._context, CursorPlurality.Single)); + this._updateCursorStyle(); + this._register(InputMode.onDidChangeInputMode(() => { + this._updateCursorStyle(); + })); + + this._primaryCursor = new ViewCursor(this._context, CursorPlurality.Single, this._cursorStyle); this._secondaryCursors = []; this._renderData = []; @@ -91,17 +96,12 @@ export class ViewCursors extends ViewPart { this._editorHasFocus = false; this._updateBlinking(); - this._updateCursorStyle(); - this._register(InputMode.onDidChangeInputMode(() => { - this._updateCursorStyle(); - })); } public override dispose(): void { super.dispose(); this._startCursorBlinkAnimation.dispose(); this._cursorFlatBlinkInterval.dispose(); - this._secondaryCursors.forEach((cursor) => cursor.dispose()); } public getDomNode(): FastDomNode { @@ -151,7 +151,7 @@ export class ViewCursors extends ViewPart { // Create new cursors const addCnt = secondaryPositions.length - this._secondaryCursors.length; for (let i = 0; i < addCnt; i++) { - const newCursor = new ViewCursor(this._context, CursorPlurality.MultiSecondary); + const newCursor = new ViewCursor(this._context, CursorPlurality.MultiSecondary, this._cursorStyle); this._domNode.domNode.insertBefore(newCursor.getDomNode().domNode, this._primaryCursor.getDomNode().domNode.nextSibling); this._secondaryCursors.push(newCursor); } @@ -160,8 +160,7 @@ export class ViewCursors extends ViewPart { const removeCnt = this._secondaryCursors.length - secondaryPositions.length; for (let i = 0; i < removeCnt; i++) { this._domNode.removeChild(this._secondaryCursors[0].getDomNode()); - const cursors = this._secondaryCursors.splice(0, 1); - cursors.forEach((cursor) => cursor.dispose()); + this._secondaryCursors.splice(0, 1); } } @@ -352,11 +351,20 @@ export class ViewCursors extends ViewPart { } private _updateCursorStyle(): void { - this._cursorStyle = getCursorStyle(this._context.configuration.options); + this._cursorStyle = this._getCursorStyle(); + this._primaryCursor.updateCursorStyle(this._cursorStyle); + this._secondaryCursors.forEach((cursor) => cursor.updateCursorStyle(this._cursorStyle)); this.forceShouldRender(); this._viewHelper.renderNow(); } + private _getCursorStyle() { + const options = this._context.configuration.options; + return InputMode.getInputMode() === 'overtype' ? + options.get(EditorOption.overtypeCursorStyle) : + options.get(EditorOption.cursorStyle); + } + private _show(): void { this._primaryCursor.show(); for (let i = 0, len = this._secondaryCursors.length; i < len; i++) { From 7b6a59fa66582460f1dd0acfed49fc1a92e57730 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 20 Nov 2024 20:27:23 +0100 Subject: [PATCH 34/44] adding effective cursor type --- .../browser/config/editorConfiguration.ts | 3 ++ src/vs/editor/browser/view.ts | 12 ++----- .../viewParts/viewCursors/viewCursor.ts | 6 +--- .../viewParts/viewCursors/viewCursors.ts | 33 ++----------------- src/vs/editor/common/config/editorOptions.ts | 20 +++++++++++ .../common/standalone/standaloneEnums.ts | 17 +++++----- src/vs/monaco.d.ts | 18 +++++----- 7 files changed, 48 insertions(+), 61 deletions(-) diff --git a/src/vs/editor/browser/config/editorConfiguration.ts b/src/vs/editor/browser/config/editorConfiguration.ts index d65d85cfe25f6..701c940c7367c 100644 --- a/src/vs/editor/browser/config/editorConfiguration.ts +++ b/src/vs/editor/browser/config/editorConfiguration.ts @@ -22,6 +22,7 @@ import { AccessibilitySupport, IAccessibilityService } from '../../../platform/a import { getWindow, getWindowById } from '../../../base/browser/dom.js'; import { PixelRatio } from '../../../base/browser/pixelRatio.js'; import { MenuId } from '../../../platform/actions/common/actions.js'; +import { InputMode } from '../../common/inputMode.js'; export interface IEditorConstructionOptions extends IEditorOptions { /** @@ -95,6 +96,7 @@ export class EditorConfiguration extends Disposable implements IEditorConfigurat this._register(FontMeasurements.onDidChange(() => this._recomputeOptions())); this._register(PixelRatio.getInstance(getWindow(container)).onDidChange(() => this._recomputeOptions())); this._register(this._accessibilityService.onDidChangeScreenReaderOptimized(() => this._recomputeOptions())); + this._register(InputMode.onDidChangeInputMode(() => this._recomputeOptions())); } private _recomputeOptions(): void { @@ -126,6 +128,7 @@ export class EditorConfiguration extends Disposable implements IEditorConfigurat emptySelectionClipboard: partialEnv.emptySelectionClipboard, pixelRatio: partialEnv.pixelRatio, tabFocusMode: TabFocus.getTabFocusMode(), + inputMode: InputMode.getInputMode(), accessibilitySupport: partialEnv.accessibilitySupport, glyphMarginDecorationLaneCount: this._glyphMarginDecorationLaneCount }; diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index 05229ed4848b9..1b6cd36a370c1 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -38,7 +38,7 @@ import { OverviewRuler } from './viewParts/overviewRuler/overviewRuler.js'; import { Rulers } from './viewParts/rulers/rulers.js'; import { ScrollDecorationViewPart } from './viewParts/scrollDecoration/scrollDecoration.js'; import { SelectionsOverlay } from './viewParts/selections/selections.js'; -import { IViewCursorsHelper, ViewCursors } from './viewParts/viewCursors/viewCursors.js'; +import { ViewCursors } from './viewParts/viewCursors/viewCursors.js'; import { ViewZones } from './viewParts/viewZones/viewZones.js'; import { WhitespaceOverlay } from './viewParts/whitespace/whitespace.js'; import { IEditorConfiguration } from '../common/config/editorConfiguration.js'; @@ -209,7 +209,7 @@ export class View extends ViewEventHandler { this._contentWidgets = new ViewContentWidgets(this._context, this.domNode); this._viewParts.push(this._contentWidgets); - this._viewCursors = new ViewCursors(this._context, this._createViewCursorsHelper()); + this._viewCursors = new ViewCursors(this._context); this._viewParts.push(this._viewCursors); // Overlay widgets @@ -369,14 +369,6 @@ export class View extends ViewEventHandler { }; } - private _createViewCursorsHelper(): IViewCursorsHelper { - return { - renderNow: (): void => { - this.render(true, false); - } - }; - } - private _createTextAreaHandlerHelper(): IVisibleRangeProvider { return { visibleRangeForPosition: (position: Position) => { diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 0c784a62594d2..99869ab822d38 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -130,7 +130,7 @@ export class ViewCursor { const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._cursorStyle = options.get(EditorOption.cursorStyle); + this._cursorStyle = options.get(EditorOption.effectiveCursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); @@ -240,10 +240,6 @@ export class ViewCursor { return lineData.tokens.getClassName(tokenIndex); } - public updateCursorStyle(cursorStyle: TextEditorCursorStyle): void { - this._cursorStyle = cursorStyle; - } - public prepareRender(ctx: RenderingContext): void { this._renderData = this._prepareRender(ctx); } diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 580e6a351e132..513ad641e2384 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -22,11 +22,6 @@ import { registerThemingParticipant } from '../../../../platform/theme/common/th import { isHighContrast } from '../../../../platform/theme/common/theme.js'; import { CursorChangeReason } from '../../../common/cursorEvents.js'; import { WindowIntervalTimer, getWindow } from '../../../../base/browser/dom.js'; -import { InputMode } from '../../../common/inputMode.js'; - -export interface IViewCursorsHelper { - renderNow(): void; -} /** * View cursors is a view part responsible for rendering the primary cursor and @@ -38,7 +33,7 @@ export class ViewCursors extends ViewPart { private _readOnly: boolean; private _cursorBlinking: TextEditorCursorBlinkingStyle; - private _cursorStyle!: TextEditorCursorStyle; + private _cursorStyle: TextEditorCursorStyle; private _cursorSmoothCaretAnimation: 'off' | 'explicit' | 'on'; private _experimentalEditContextEnabled: boolean; private _selectionIsEmpty: boolean; @@ -57,15 +52,14 @@ export class ViewCursors extends ViewPart { private readonly _primaryCursor: ViewCursor; private readonly _secondaryCursors: ViewCursor[]; private _renderData: IViewCursorRenderData[]; - private _viewHelper: IViewCursorsHelper; - constructor(context: ViewContext, viewHelper: IViewCursorsHelper) { + constructor(context: ViewContext) { super(context); const options = this._context.configuration.options; - this._viewHelper = viewHelper; this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); + this._cursorStyle = options.get(EditorOption.effectiveCursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); this._selectionIsEmpty = true; @@ -73,11 +67,6 @@ export class ViewCursors extends ViewPart { this._isVisible = false; - this._updateCursorStyle(); - this._register(InputMode.onDidChangeInputMode(() => { - this._updateCursorStyle(); - })); - this._primaryCursor = new ViewCursor(this._context, CursorPlurality.Single, this._cursorStyle); this._secondaryCursors = []; this._renderData = []; @@ -130,7 +119,6 @@ export class ViewCursors extends ViewPart { this._updateBlinking(); this._updateDomClassName(); - this._updateCursorStyle(); this._primaryCursor.onConfigurationChanged(e); for (let i = 0, len = this._secondaryCursors.length; i < len; i++) { @@ -350,21 +338,6 @@ export class ViewCursors extends ViewPart { return result; } - private _updateCursorStyle(): void { - this._cursorStyle = this._getCursorStyle(); - this._primaryCursor.updateCursorStyle(this._cursorStyle); - this._secondaryCursors.forEach((cursor) => cursor.updateCursorStyle(this._cursorStyle)); - this.forceShouldRender(); - this._viewHelper.renderNow(); - } - - private _getCursorStyle() { - const options = this._context.configuration.options; - return InputMode.getInputMode() === 'overtype' ? - options.get(EditorOption.overtypeCursorStyle) : - options.get(EditorOption.cursorStyle); - } - private _show(): void { this._primaryCursor.show(); for (let i = 0, len = this._secondaryCursors.length; i < len; i++) { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 37afef8e33f3c..555d4725b40a3 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -983,6 +983,7 @@ export interface IEnvironmentalOptions { readonly emptySelectionClipboard: boolean; readonly pixelRatio: number; readonly tabFocusMode: boolean; + readonly inputMode: 'insert' | 'overtype'; readonly accessibilitySupport: AccessibilitySupport; readonly glyphMarginDecorationLaneCount: number; } @@ -1883,6 +1884,23 @@ class EditorFontInfo extends ComputedEditorOption { + + constructor() { + super(EditorOption.effectiveCursorStyle); + } + + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: TextEditorCursorStyle): TextEditorCursorStyle { + return env.inputMode === 'overtype' ? + options.get(EditorOption.overtypeCursorStyle) : + options.get(EditorOption.cursorStyle); + } +} + +//#endregion + //#region fontSize class EditorFontSize extends SimpleEditorOption { @@ -5482,6 +5500,7 @@ export const enum EditorOption { showDeprecated, inlayHints, // Leave these at the end (because they have dependencies!) + effectiveCursorStyle, editorClassName, pixelRatio, tabFocusMode, @@ -6297,6 +6316,7 @@ export const EditorOptions = { )), // Leave these at the end (because they have dependencies!) + effectiveCursorStyle: register(new EffectiveCursorStyle()), editorClassName: register(new EditorClassName()), defaultColorDecorators: register(new EditorBooleanOption( EditorOption.defaultColorDecorators, 'defaultColorDecorators', true, diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 54f64789b6118..d83b9bd65eb75 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -320,14 +320,15 @@ export enum EditorOption { wrappingStrategy = 144, showDeprecated = 145, inlayHints = 146, - editorClassName = 147, - pixelRatio = 148, - tabFocusMode = 149, - layoutInfo = 150, - wrappingInfo = 151, - defaultColorDecorators = 152, - colorDecoratorsActivatedOn = 153, - inlineCompletionsAccessibilityVerbose = 154 + effectiveCursorStyle = 147, + editorClassName = 148, + pixelRatio = 149, + tabFocusMode = 150, + layoutInfo = 151, + wrappingInfo = 152, + defaultColorDecorators = 153, + colorDecoratorsActivatedOn = 154, + inlineCompletionsAccessibilityVerbose = 155 } /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index b07aff39cc519..2a3839c2a283d 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -5031,14 +5031,15 @@ declare namespace monaco.editor { wrappingStrategy = 144, showDeprecated = 145, inlayHints = 146, - editorClassName = 147, - pixelRatio = 148, - tabFocusMode = 149, - layoutInfo = 150, - wrappingInfo = 151, - defaultColorDecorators = 152, - colorDecoratorsActivatedOn = 153, - inlineCompletionsAccessibilityVerbose = 154 + effectiveCursorStyle = 147, + editorClassName = 148, + pixelRatio = 149, + tabFocusMode = 150, + layoutInfo = 151, + wrappingInfo = 152, + defaultColorDecorators = 153, + colorDecoratorsActivatedOn = 154, + inlineCompletionsAccessibilityVerbose = 155 } export const EditorOptions: { @@ -5189,6 +5190,7 @@ declare namespace monaco.editor { wordWrapColumn: IEditorOption; wordWrapOverride1: IEditorOption; wordWrapOverride2: IEditorOption; + effectiveCursorStyle: IEditorOption; editorClassName: IEditorOption; defaultColorDecorators: IEditorOption; pixelRatio: IEditorOption; From a53920705c1568cb6bafa574b64ad49d8c3e356e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 20 Nov 2024 21:08:26 +0100 Subject: [PATCH 35/44] removing the usage of the getOffsetAt --- .../editor/common/commands/replaceCommand.ts | 78 ++++++++++++++----- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 7717b1133131a..63138288f5ccf 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -45,15 +45,16 @@ export class ReplaceOvertypeCommand implements ICommand { } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - const startPosition = this._range.getStartPosition(); - const endPosition = this._range.getEndPosition(); - const rangeEndOffset = model.getOffsetAt(endPosition); - const endOffset = rangeEndOffset + this._text.length + (this._range.isEmpty() ? 0 : - 1); + const intialStartPosition = this._range.getStartPosition(); + const initialEndPosition = this._range.getEndPosition(); + const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : - 1); + const candidateEndPosition: Position = addPositiveDeltaToModelPosition(model, initialEndPosition, offsetDelta); + const candidateSecondToEndPosition = previousModelPosition(model, candidateEndPosition); const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; - const lastCharacterRange = Range.fromPositions(model.getPositionAt(endOffset - 1), model.getPositionAt(endOffset)); + const lastCharacterRange = Range.fromPositions(candidateSecondToEndPosition, candidateEndPosition); const lastCharacter = model.getValueInRange(lastCharacterRange); - const newEndOffset = lastCharacter === endOfLine ? endOffset - 1 : endOffset; - const replaceRange = Range.fromPositions(startPosition, model.getPositionAt(newEndOffset)); + const endPosition = lastCharacter === endOfLine ? candidateSecondToEndPosition : candidateEndPosition; + const replaceRange = Range.fromPositions(intialStartPosition, endPosition); builder.addTrackedEditOperation(replaceRange, this._text); } @@ -77,18 +78,18 @@ export class OvertypePasteCommand implements ICommand { } public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - const startPosition = this._range.getStartPosition(); - const endPosition = this._range.getEndPosition(); - const endLineNumber = endPosition.lineNumber; - const potentialEndOffset = model.getOffsetAt(endPosition) + this._text.length + (this._range.isEmpty() ? 0 : - 1); - const potentialEndPosition = model.getPositionAt(potentialEndOffset); - let newEndPosition: Position; - if (potentialEndPosition.lineNumber > endLineNumber) { - newEndPosition = new Position(endLineNumber, model.getLineMaxColumn(endLineNumber)); + const initialStartPosition = this._range.getStartPosition(); + const initialEndPosition = this._range.getEndPosition(); + const endLineNumber = initialEndPosition.lineNumber; + const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : - 1); + const candidateEndPosition = addPositiveDeltaToModelPosition(model, initialEndPosition, offsetDelta); + let endPosition: Position; + if (candidateEndPosition.lineNumber > endLineNumber) { + endPosition = new Position(endLineNumber, model.getLineMaxColumn(endLineNumber)); } else { - newEndPosition = potentialEndPosition; + endPosition = candidateEndPosition; } - const replaceRange = Range.fromPositions(startPosition, newEndPosition); + const replaceRange = Range.fromPositions(initialStartPosition, endPosition); builder.addTrackedEditOperation(replaceRange, this._text); } @@ -181,8 +182,7 @@ export class ReplaceOvertypeCommandInComposition implements ICommand { public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { const text = model.getValueInRange(this._range); const startPosition = this._range.getStartPosition(); - const endOffset = model.getOffsetAt(startPosition) + 2 * text.length; - let endPosition = model.getPositionAt(endOffset); + let endPosition = addPositiveDeltaToModelPosition(model, startPosition, 2 * text.length); if (endPosition.lineNumber > this._range.endLineNumber) { endPosition = new Position(this._range.endLineNumber, model.getLineMaxColumn(this._range.endLineNumber)); } @@ -222,3 +222,43 @@ export class ReplaceCommandThatPreservesSelection implements ICommand { return helper.getTrackedSelection(this._selectionId!); } } + +function addPositiveDeltaToModelPosition(model: ITextModel, position: Position, delta: number): Position { + if (delta < 0) { + throw new Error('Unexpected negative delta'); + } + const lineCount = model.getLineCount(); + let endPosition: Position | undefined; + for (let potentialEndLineNumber = position.lineNumber; potentialEndLineNumber <= lineCount; potentialEndLineNumber++) { + if (potentialEndLineNumber === position.lineNumber) { + const futureDelta = delta - model.getLineMaxColumn(position.lineNumber) - position.column; + if (futureDelta <= 0) { + endPosition = new Position(position.lineNumber, position.column + delta); + break; + } + delta = futureDelta; + } else { + const futureDelta = delta - model.getLineMaxColumn(potentialEndLineNumber); + if (futureDelta <= 0) { + endPosition = new Position(potentialEndLineNumber, delta); + break; + } + delta = futureDelta; + } + } + return endPosition ?? new Position(lineCount, model.getLineMaxColumn(lineCount)); +} + +function previousModelPosition(model: ITextModel, position: Position): Position { + let previousPosition: Position; + if (position.column > 1) { + previousPosition = new Position(position.lineNumber, position.column - 1); + } else { + if (position.lineNumber > 1) { + previousPosition = new Position(position.lineNumber - 1, model.getLineMaxColumn(position.lineNumber - 1)); + } else { + previousPosition = new Position(1, 1); + } + } + return previousPosition; +} From 6f706c059c1cd739efced36c637083175a8486ff Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 21 Nov 2024 12:14:47 +0100 Subject: [PATCH 36/44] polishing --- .../viewParts/viewCursors/viewCursor.ts | 4 ++-- .../viewParts/viewCursors/viewCursors.ts | 5 +++-- src/vs/editor/common/cursor/cursor.ts | 6 +++--- .../common/cursor/cursorTypeEditOperations.ts | 18 +++++++++++++++- .../common/cursor/cursorTypeOperations.ts | 21 +++---------------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index 99869ab822d38..b4380373c526a 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -58,12 +58,12 @@ export class ViewCursor { private _lastRenderedContent: string; private _renderData: ViewCursorRenderData | null; - constructor(context: ViewContext, plurality: CursorPlurality, cursorStyle: TextEditorCursorStyle) { + constructor(context: ViewContext, plurality: CursorPlurality) { this._context = context; const options = this._context.configuration.options; const fontInfo = options.get(EditorOption.fontInfo); - this._cursorStyle = cursorStyle; + this._cursorStyle = options.get(EditorOption.effectiveCursorStyle); this._lineHeight = options.get(EditorOption.lineHeight); this._typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this._lineCursorWidth = Math.min(options.get(EditorOption.cursorWidth), this._typicalHalfwidthCharacterWidth); diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts index 513ad641e2384..823a8e5c0a559 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts @@ -67,7 +67,7 @@ export class ViewCursors extends ViewPart { this._isVisible = false; - this._primaryCursor = new ViewCursor(this._context, CursorPlurality.Single, this._cursorStyle); + this._primaryCursor = new ViewCursor(this._context, CursorPlurality.Single); this._secondaryCursors = []; this._renderData = []; @@ -114,6 +114,7 @@ export class ViewCursors extends ViewPart { this._readOnly = options.get(EditorOption.readOnly); this._cursorBlinking = options.get(EditorOption.cursorBlinking); + this._cursorStyle = options.get(EditorOption.effectiveCursorStyle); this._cursorSmoothCaretAnimation = options.get(EditorOption.cursorSmoothCaretAnimation); this._experimentalEditContextEnabled = options.get(EditorOption.experimentalEditContextEnabled); @@ -139,7 +140,7 @@ export class ViewCursors extends ViewPart { // Create new cursors const addCnt = secondaryPositions.length - this._secondaryCursors.length; for (let i = 0; i < addCnt; i++) { - const newCursor = new ViewCursor(this._context, CursorPlurality.MultiSecondary, this._cursorStyle); + const newCursor = new ViewCursor(this._context, CursorPlurality.MultiSecondary); this._domNode.domNode.insertBefore(newCursor.getDomNode().domNode, this._primaryCursor.getDomNode().domNode.nextSibling); this._secondaryCursors.push(newCursor); } diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index d171dc59735ad..09825b6b9b42d 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -1020,9 +1020,9 @@ export class CommandExecutor { class CompositionLineState { constructor( public readonly text: string, + public readonly lineNumber: number, public readonly startSelectionOffset: number, - public readonly endSelectionOffset: number, - public readonly lineNumber: number + public readonly endSelectionOffset: number ) { } } @@ -1039,9 +1039,9 @@ class CompositionState { const lineNumber = selection.startLineNumber; result.push(new CompositionLineState( textModel.getLineContent(lineNumber), + lineNumber, selection.startColumn - 1, selection.endColumn - 1, - lineNumber )); } return result; diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index f44fa8b722d02..c19ea294e82d4 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -6,7 +6,7 @@ import { CharCode } from '../../../base/common/charCode.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import * as strings from '../../../base/common/strings.js'; -import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand } from '../commands/replaceCommand.js'; +import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand, ReplaceOvertypeCommandInComposition } from '../commands/replaceCommand.js'; import { ShiftCommand } from '../commands/shiftCommand.js'; import { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js'; import { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js'; @@ -23,6 +23,7 @@ import { EditorAutoClosingStrategy, EditorAutoIndentStrategy } from '../config/e import { createScopedLineTokens } from '../languages/supports.js'; import { getIndentActionForType, getIndentForEnter, getInheritIndentForLine } from '../languages/autoIndent.js'; import { getEnterAction } from '../languages/enterAction.js'; +import { CompositionOutcome } from './cursorTypeOperations.js'; export class AutoIndentOperation { @@ -354,6 +355,21 @@ export class AutoClosingOpenCharTypeOperation { } } +export class CompositionOvertypeOperation { + + public static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | undefined { + const isOvertypeMode = config.inputMode === 'overtype'; + if (!isOvertypeMode) { + return undefined; + } + const commands = compositions.map(composition => new ReplaceOvertypeCommandInComposition(composition.insertedTextRange)); + return new EditOperationResult(EditOperationType.TypingOther, commands, { + shouldPushStackElementBefore: true, + shouldPushStackElementAfter: false + }); + } +} + export class SurroundSelectionOperation { public static getEdits(config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string, isDoingComposition: boolean): EditOperationResult | undefined { diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 111de14487861..026d5bf437580 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -11,8 +11,7 @@ import { Selection } from '../core/selection.js'; import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; -import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; -import { ReplaceOvertypeCommandInComposition } from '../commands/replaceCommand.js'; +import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, CompositionOvertypeOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; export class TypeOperations { @@ -91,7 +90,7 @@ export class TypeOperations { if (!insertedText || insertedText.length !== 1) { // we're only interested in the case where a single character was inserted - return this._getOvertypeEdits(config, compositions) ?? null; + return CompositionOvertypeOperation.getEdits(config, compositions) ?? null; } const ch = insertedText; @@ -159,22 +158,8 @@ export class TypeOperations { if (autoClosingOpenCharEdits !== undefined) { return autoClosingOpenCharEdits; } - return this._getOvertypeEdits(config, compositions) ?? null; - } - private static _getOvertypeEdits(config: CursorConfiguration, compositions: CompositionOutcome[] | null): EditOperationResult | undefined { - if (!compositions) { - return undefined; - } - const isOvertypeMode = config.inputMode === 'overtype'; - if (!isOvertypeMode) { - return undefined; - } - const commands = compositions.map(composition => new ReplaceOvertypeCommandInComposition(composition.insertedTextRange)); - return new EditOperationResult(EditOperationType.TypingOther, commands, { - shouldPushStackElementBefore: true, - shouldPushStackElementAfter: false - }); + return CompositionOvertypeOperation.getEdits(config, compositions) ?? null; } public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { From 2ecbd609accf9333dd634858668f330e3e45c010 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 21 Nov 2024 13:19:32 +0100 Subject: [PATCH 37/44] polishing some more --- .../editor/common/commands/replaceCommand.ts | 13 +- src/vs/editor/common/config/editorOptions.ts | 14 +- .../common/standalone/standaloneEnums.ts | 112 ++++++++-------- src/vs/monaco.d.ts | 120 +++++++++--------- 4 files changed, 130 insertions(+), 129 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 63138288f5ccf..e1093fa497172 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -181,13 +181,14 @@ export class ReplaceOvertypeCommandInComposition implements ICommand { public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { const text = model.getValueInRange(this._range); - const startPosition = this._range.getStartPosition(); - let endPosition = addPositiveDeltaToModelPosition(model, startPosition, 2 * text.length); - if (endPosition.lineNumber > this._range.endLineNumber) { - endPosition = new Position(this._range.endLineNumber, model.getLineMaxColumn(this._range.endLineNumber)); + const initialEndPosition = this._range.getEndPosition(); + const initialEndLineNumber = initialEndPosition.lineNumber; + let endPosition = addPositiveDeltaToModelPosition(model, initialEndPosition, text.length); + if (endPosition.lineNumber > initialEndLineNumber) { + endPosition = new Position(initialEndLineNumber, model.getLineMaxColumn(initialEndLineNumber)); } - const replaceRange = Range.fromPositions(startPosition, endPosition); - builder.addTrackedEditOperation(replaceRange, text); + const replaceRange = Range.fromPositions(initialEndPosition, endPosition); + builder.addTrackedEditOperation(replaceRange, ''); } public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 555d4725b40a3..1fd04143c90fe 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -247,6 +247,10 @@ export interface IEditorOptions { * Defaults to 'block'. */ overtypeCursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; + /** + * Controls whether paste in overtype mode should overwrite or insert. + */ + overtypeOnPaste?: boolean; /** * Control the width of the cursor when cursorStyle is set to 'line' */ @@ -778,11 +782,6 @@ export interface IEditorOptions { * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. */ inlineCompletionsAccessibilityVerbose?: boolean; - - /** - * Controls whether paste in overtype mode should overwrite or insert. - */ - overtypeOnPaste?: boolean; } /** @@ -5381,7 +5380,6 @@ export const enum EditorOption { cursorBlinking, cursorSmoothCaretAnimation, cursorStyle, - overtypeCursorStyle, cursorSurroundingLines, cursorSurroundingLinesStyle, cursorWidth, @@ -5437,6 +5435,7 @@ export const enum EditorOption { multiCursorLimit, occurrencesHighlight, occurrencesHighlightDelay, + overtypeCursorStyle, overtypeOnPaste, overviewRulerBorder, overviewRulerLanes, @@ -5990,7 +5989,8 @@ export const EditorOptions = { } )), overtypeOnPaste: register(new EditorBooleanOption( - EditorOption.overtypeOnPaste, 'overtypeOnPaste', true + EditorOption.overtypeOnPaste, 'overtypeOnPaste', true, + { description: nls.localize('overtypeOnPaste', "Controls whether pasting should overtype.") } )), overviewRulerBorder: register(new EditorBooleanOption( EditorOption.overviewRulerBorder, 'overviewRulerBorder', true, diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index d83b9bd65eb75..db9a28f4fedd0 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -202,62 +202,62 @@ export enum EditorOption { cursorBlinking = 26, cursorSmoothCaretAnimation = 27, cursorStyle = 28, - overtypeCursorStyle = 29, - cursorSurroundingLines = 30, - cursorSurroundingLinesStyle = 31, - cursorWidth = 32, - disableLayerHinting = 33, - disableMonospaceOptimizations = 34, - domReadOnly = 35, - dragAndDrop = 36, - dropIntoEditor = 37, - experimentalEditContextEnabled = 38, - emptySelectionClipboard = 39, - experimentalGpuAcceleration = 40, - experimentalWhitespaceRendering = 41, - extraEditorClassName = 42, - fastScrollSensitivity = 43, - find = 44, - fixedOverflowWidgets = 45, - folding = 46, - foldingStrategy = 47, - foldingHighlight = 48, - foldingImportsByDefault = 49, - foldingMaximumRegions = 50, - unfoldOnClickAfterEndOfLine = 51, - fontFamily = 52, - fontInfo = 53, - fontLigatures = 54, - fontSize = 55, - fontWeight = 56, - fontVariations = 57, - formatOnPaste = 58, - formatOnType = 59, - glyphMargin = 60, - gotoLocation = 61, - hideCursorInOverviewRuler = 62, - hover = 63, - inDiffEditor = 64, - inlineSuggest = 65, - letterSpacing = 66, - lightbulb = 67, - lineDecorationsWidth = 68, - lineHeight = 69, - lineNumbers = 70, - lineNumbersMinChars = 71, - linkedEditing = 72, - links = 73, - matchBrackets = 74, - minimap = 75, - mouseStyle = 76, - mouseWheelScrollSensitivity = 77, - mouseWheelZoom = 78, - multiCursorMergeOverlapping = 79, - multiCursorModifier = 80, - multiCursorPaste = 81, - multiCursorLimit = 82, - occurrencesHighlight = 83, - occurrencesHighlightDelay = 84, + cursorSurroundingLines = 29, + cursorSurroundingLinesStyle = 30, + cursorWidth = 31, + disableLayerHinting = 32, + disableMonospaceOptimizations = 33, + domReadOnly = 34, + dragAndDrop = 35, + dropIntoEditor = 36, + experimentalEditContextEnabled = 37, + emptySelectionClipboard = 38, + experimentalGpuAcceleration = 39, + experimentalWhitespaceRendering = 40, + extraEditorClassName = 41, + fastScrollSensitivity = 42, + find = 43, + fixedOverflowWidgets = 44, + folding = 45, + foldingStrategy = 46, + foldingHighlight = 47, + foldingImportsByDefault = 48, + foldingMaximumRegions = 49, + unfoldOnClickAfterEndOfLine = 50, + fontFamily = 51, + fontInfo = 52, + fontLigatures = 53, + fontSize = 54, + fontWeight = 55, + fontVariations = 56, + formatOnPaste = 57, + formatOnType = 58, + glyphMargin = 59, + gotoLocation = 60, + hideCursorInOverviewRuler = 61, + hover = 62, + inDiffEditor = 63, + inlineSuggest = 64, + letterSpacing = 65, + lightbulb = 66, + lineDecorationsWidth = 67, + lineHeight = 68, + lineNumbers = 69, + lineNumbersMinChars = 70, + linkedEditing = 71, + links = 72, + matchBrackets = 73, + minimap = 74, + mouseStyle = 75, + mouseWheelScrollSensitivity = 76, + mouseWheelZoom = 77, + multiCursorMergeOverlapping = 78, + multiCursorModifier = 79, + multiCursorPaste = 80, + multiCursorLimit = 81, + occurrencesHighlight = 82, + occurrencesHighlightDelay = 83, + overtypeCursorStyle = 84, overtypeOnPaste = 85, overviewRulerBorder = 86, overviewRulerLanes = 87, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 2a3839c2a283d..83c6e1b89aaa7 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3293,6 +3293,10 @@ declare namespace monaco.editor { * Defaults to 'block'. */ overtypeCursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; + /** + * Controls whether paste in overtype mode should overwrite or insert. + */ + overtypeOnPaste?: boolean; /** * Control the width of the cursor when cursorStyle is set to 'line' */ @@ -3815,10 +3819,6 @@ declare namespace monaco.editor { * Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown. */ inlineCompletionsAccessibilityVerbose?: boolean; - /** - * Controls whether paste in overtype mode should overwrite or insert. - */ - overtypeOnPaste?: boolean; } export interface IDiffEditorBaseOptions { @@ -4913,62 +4913,62 @@ declare namespace monaco.editor { cursorBlinking = 26, cursorSmoothCaretAnimation = 27, cursorStyle = 28, - overtypeCursorStyle = 29, - cursorSurroundingLines = 30, - cursorSurroundingLinesStyle = 31, - cursorWidth = 32, - disableLayerHinting = 33, - disableMonospaceOptimizations = 34, - domReadOnly = 35, - dragAndDrop = 36, - dropIntoEditor = 37, - experimentalEditContextEnabled = 38, - emptySelectionClipboard = 39, - experimentalGpuAcceleration = 40, - experimentalWhitespaceRendering = 41, - extraEditorClassName = 42, - fastScrollSensitivity = 43, - find = 44, - fixedOverflowWidgets = 45, - folding = 46, - foldingStrategy = 47, - foldingHighlight = 48, - foldingImportsByDefault = 49, - foldingMaximumRegions = 50, - unfoldOnClickAfterEndOfLine = 51, - fontFamily = 52, - fontInfo = 53, - fontLigatures = 54, - fontSize = 55, - fontWeight = 56, - fontVariations = 57, - formatOnPaste = 58, - formatOnType = 59, - glyphMargin = 60, - gotoLocation = 61, - hideCursorInOverviewRuler = 62, - hover = 63, - inDiffEditor = 64, - inlineSuggest = 65, - letterSpacing = 66, - lightbulb = 67, - lineDecorationsWidth = 68, - lineHeight = 69, - lineNumbers = 70, - lineNumbersMinChars = 71, - linkedEditing = 72, - links = 73, - matchBrackets = 74, - minimap = 75, - mouseStyle = 76, - mouseWheelScrollSensitivity = 77, - mouseWheelZoom = 78, - multiCursorMergeOverlapping = 79, - multiCursorModifier = 80, - multiCursorPaste = 81, - multiCursorLimit = 82, - occurrencesHighlight = 83, - occurrencesHighlightDelay = 84, + cursorSurroundingLines = 29, + cursorSurroundingLinesStyle = 30, + cursorWidth = 31, + disableLayerHinting = 32, + disableMonospaceOptimizations = 33, + domReadOnly = 34, + dragAndDrop = 35, + dropIntoEditor = 36, + experimentalEditContextEnabled = 37, + emptySelectionClipboard = 38, + experimentalGpuAcceleration = 39, + experimentalWhitespaceRendering = 40, + extraEditorClassName = 41, + fastScrollSensitivity = 42, + find = 43, + fixedOverflowWidgets = 44, + folding = 45, + foldingStrategy = 46, + foldingHighlight = 47, + foldingImportsByDefault = 48, + foldingMaximumRegions = 49, + unfoldOnClickAfterEndOfLine = 50, + fontFamily = 51, + fontInfo = 52, + fontLigatures = 53, + fontSize = 54, + fontWeight = 55, + fontVariations = 56, + formatOnPaste = 57, + formatOnType = 58, + glyphMargin = 59, + gotoLocation = 60, + hideCursorInOverviewRuler = 61, + hover = 62, + inDiffEditor = 63, + inlineSuggest = 64, + letterSpacing = 65, + lightbulb = 66, + lineDecorationsWidth = 67, + lineHeight = 68, + lineNumbers = 69, + lineNumbersMinChars = 70, + linkedEditing = 71, + links = 72, + matchBrackets = 73, + minimap = 74, + mouseStyle = 75, + mouseWheelScrollSensitivity = 76, + mouseWheelZoom = 77, + multiCursorMergeOverlapping = 78, + multiCursorModifier = 79, + multiCursorPaste = 80, + multiCursorLimit = 81, + occurrencesHighlight = 82, + occurrencesHighlightDelay = 83, + overtypeCursorStyle = 84, overtypeOnPaste = 85, overviewRulerBorder = 86, overviewRulerLanes = 87, From 74aaf07b356a0b39e916cd107ae8e353e0a16906 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 21 Nov 2024 13:54:12 +0100 Subject: [PATCH 38/44] polishing the code --- .../editor/common/commands/replaceCommand.ts | 66 +++---------------- .../common/cursor/cursorTypeEditOperations.ts | 10 +-- .../common/cursor/cursorTypeOperations.ts | 6 +- 3 files changed, 16 insertions(+), 66 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index e1093fa497172..cdcd30a6821f8 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -7,7 +7,7 @@ import { Position } from '../core/position.js'; import { Range } from '../core/range.js'; import { Selection, SelectionDirection } from '../core/selection.js'; import { ICommand, ICursorStateComputerData, IEditOperationBuilder } from '../editorCommon.js'; -import { EndOfLineSequence, ITextModel } from '../model.js'; +import { ITextModel } from '../model.js'; export class ReplaceCommand implements ICommand { @@ -47,49 +47,13 @@ export class ReplaceOvertypeCommand implements ICommand { public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { const intialStartPosition = this._range.getStartPosition(); const initialEndPosition = this._range.getEndPosition(); - const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : - 1); - const candidateEndPosition: Position = addPositiveDeltaToModelPosition(model, initialEndPosition, offsetDelta); - const candidateSecondToEndPosition = previousModelPosition(model, candidateEndPosition); - const endOfLine = model.getEndOfLineSequence() === EndOfLineSequence.CRLF ? '\r\n' : '\n'; - const lastCharacterRange = Range.fromPositions(candidateSecondToEndPosition, candidateEndPosition); - const lastCharacter = model.getValueInRange(lastCharacterRange); - const endPosition = lastCharacter === endOfLine ? candidateSecondToEndPosition : candidateEndPosition; - const replaceRange = Range.fromPositions(intialStartPosition, endPosition); - builder.addTrackedEditOperation(replaceRange, this._text); - } - - public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection { - const inverseEditOperations = helper.getInverseEditOperations(); - const srcRange = inverseEditOperations[0].range; - return Selection.fromPositions(srcRange.getEndPosition()); - } -} - -export class OvertypePasteCommand implements ICommand { - - private readonly _range: Range; - private readonly _text: string; - public readonly insertsAutoWhitespace: boolean; - - constructor(range: Range, text: string, insertsAutoWhitespace: boolean = false) { - this._range = range; - this._text = text; - this.insertsAutoWhitespace = insertsAutoWhitespace; - } - - public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void { - const initialStartPosition = this._range.getStartPosition(); - const initialEndPosition = this._range.getEndPosition(); - const endLineNumber = initialEndPosition.lineNumber; - const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : - 1); - const candidateEndPosition = addPositiveDeltaToModelPosition(model, initialEndPosition, offsetDelta); - let endPosition: Position; - if (candidateEndPosition.lineNumber > endLineNumber) { - endPosition = new Position(endLineNumber, model.getLineMaxColumn(endLineNumber)); - } else { - endPosition = candidateEndPosition; + const initialEndLineNumber = initialEndPosition.lineNumber; + const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : -1); + let endPosition = addPositiveDeltaToModelPosition(model, initialEndPosition, offsetDelta); + if (endPosition.lineNumber > initialEndLineNumber) { + endPosition = new Position(initialEndLineNumber, model.getLineMaxColumn(initialEndLineNumber)); } - const replaceRange = Range.fromPositions(initialStartPosition, endPosition); + const replaceRange = Range.fromPositions(intialStartPosition, endPosition); builder.addTrackedEditOperation(replaceRange, this._text); } @@ -171,7 +135,7 @@ export class ReplaceCommandWithOffsetCursorState implements ICommand { } } -export class ReplaceOvertypeCommandInComposition implements ICommand { +export class ReplaceOvertypeCommandOnCompositionEnd implements ICommand { private readonly _range: Range; @@ -249,17 +213,3 @@ function addPositiveDeltaToModelPosition(model: ITextModel, position: Position, } return endPosition ?? new Position(lineCount, model.getLineMaxColumn(lineCount)); } - -function previousModelPosition(model: ITextModel, position: Position): Position { - let previousPosition: Position; - if (position.column > 1) { - previousPosition = new Position(position.lineNumber, position.column - 1); - } else { - if (position.lineNumber > 1) { - previousPosition = new Position(position.lineNumber - 1, model.getLineMaxColumn(position.lineNumber - 1)); - } else { - previousPosition = new Position(1, 1); - } - } - return previousPosition; -} diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index c19ea294e82d4..55192ff9c6c38 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -6,7 +6,7 @@ import { CharCode } from '../../../base/common/charCode.js'; import { onUnexpectedError } from '../../../base/common/errors.js'; import * as strings from '../../../base/common/strings.js'; -import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, OvertypePasteCommand, ReplaceOvertypeCommandInComposition } from '../commands/replaceCommand.js'; +import { ReplaceCommand, ReplaceCommandWithOffsetCursorState, ReplaceCommandWithoutChangingPosition, ReplaceCommandThatPreservesSelection, ReplaceOvertypeCommand, ReplaceOvertypeCommandOnCompositionEnd } from '../commands/replaceCommand.js'; import { ShiftCommand } from '../commands/shiftCommand.js'; import { SurroundSelectionCommand } from '../commands/surroundSelectionCommand.js'; import { CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from '../cursorCommon.js'; @@ -355,14 +355,14 @@ export class AutoClosingOpenCharTypeOperation { } } -export class CompositionOvertypeOperation { +export class CompositionEndOvertypeOperation { public static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | undefined { const isOvertypeMode = config.inputMode === 'overtype'; if (!isOvertypeMode) { return undefined; } - const commands = compositions.map(composition => new ReplaceOvertypeCommandInComposition(composition.insertedTextRange)); + const commands = compositions.map(composition => new ReplaceOvertypeCommandOnCompositionEnd(composition.insertedTextRange)); return new EditOperationResult(EditOperationType.TypingOther, commands, { shouldPushStackElementBefore: true, shouldPushStackElementAfter: false @@ -695,7 +695,7 @@ export class PasteOperation { const commands: ICommand[] = []; for (let i = 0, len = selections.length; i < len; i++) { const shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype'; - const ChosenReplaceCommand = shouldOvertypeOnPaste ? OvertypePasteCommand : ReplaceCommand; + const ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selections[i], text[i]); } return new EditOperationResult(EditOperationType.Other, commands, { @@ -721,7 +721,7 @@ export class PasteOperation { commands[i] = new ReplaceCommandThatPreservesSelection(typeSelection, text, selection, true); } else { const shouldOvertypeOnPaste = config.overtypeOnPaste && config.inputMode === 'overtype'; - const ChosenReplaceCommand = shouldOvertypeOnPaste ? OvertypePasteCommand : ReplaceCommand; + const ChosenReplaceCommand = shouldOvertypeOnPaste ? ReplaceOvertypeCommand : ReplaceCommand; commands[i] = new ChosenReplaceCommand(selection, text); } } diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index 026d5bf437580..bfc8dcf16954b 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -11,7 +11,7 @@ import { Selection } from '../core/selection.js'; import { Position } from '../core/position.js'; import { ICommand } from '../editorCommon.js'; import { ITextModel } from '../model.js'; -import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, CompositionOvertypeOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; +import { AutoClosingOpenCharTypeOperation, AutoClosingOvertypeOperation, AutoClosingOvertypeWithInterceptorsOperation, AutoIndentOperation, CompositionOperation, CompositionEndOvertypeOperation, EnterOperation, InterceptorElectricCharOperation, PasteOperation, shiftIndent, shouldSurroundChar, SimpleCharacterTypeOperation, SurroundSelectionOperation, TabOperation, TypeWithoutInterceptorsOperation, unshiftIndent } from './cursorTypeEditOperations.js'; export class TypeOperations { @@ -90,7 +90,7 @@ export class TypeOperations { if (!insertedText || insertedText.length !== 1) { // we're only interested in the case where a single character was inserted - return CompositionOvertypeOperation.getEdits(config, compositions) ?? null; + return CompositionEndOvertypeOperation.getEdits(config, compositions) ?? null; } const ch = insertedText; @@ -159,7 +159,7 @@ export class TypeOperations { return autoClosingOpenCharEdits; } - return CompositionOvertypeOperation.getEdits(config, compositions) ?? null; + return CompositionEndOvertypeOperation.getEdits(config, compositions) ?? null; } public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { From 83226c423c2e9ac26e117cb9ecd25044f4bcbe3c Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 21 Nov 2024 14:04:05 +0100 Subject: [PATCH 39/44] polishing --- .../editor/common/commands/replaceCommand.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index cdcd30a6821f8..0936f5d1c83a8 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -49,7 +49,7 @@ export class ReplaceOvertypeCommand implements ICommand { const initialEndPosition = this._range.getEndPosition(); const initialEndLineNumber = initialEndPosition.lineNumber; const offsetDelta = this._text.length + (this._range.isEmpty() ? 0 : -1); - let endPosition = addPositiveDeltaToModelPosition(model, initialEndPosition, offsetDelta); + let endPosition = addPositiveOffsetToModelPosition(model, initialEndPosition, offsetDelta); if (endPosition.lineNumber > initialEndLineNumber) { endPosition = new Position(initialEndLineNumber, model.getLineMaxColumn(initialEndLineNumber)); } @@ -147,7 +147,7 @@ export class ReplaceOvertypeCommandOnCompositionEnd implements ICommand { const text = model.getValueInRange(this._range); const initialEndPosition = this._range.getEndPosition(); const initialEndLineNumber = initialEndPosition.lineNumber; - let endPosition = addPositiveDeltaToModelPosition(model, initialEndPosition, text.length); + let endPosition = addPositiveOffsetToModelPosition(model, initialEndPosition, text.length); if (endPosition.lineNumber > initialEndLineNumber) { endPosition = new Position(initialEndLineNumber, model.getLineMaxColumn(initialEndLineNumber)); } @@ -188,27 +188,27 @@ export class ReplaceCommandThatPreservesSelection implements ICommand { } } -function addPositiveDeltaToModelPosition(model: ITextModel, position: Position, delta: number): Position { - if (delta < 0) { +function addPositiveOffsetToModelPosition(model: ITextModel, position: Position, offset: number): Position { + if (offset < 0) { throw new Error('Unexpected negative delta'); } const lineCount = model.getLineCount(); let endPosition: Position | undefined; - for (let potentialEndLineNumber = position.lineNumber; potentialEndLineNumber <= lineCount; potentialEndLineNumber++) { - if (potentialEndLineNumber === position.lineNumber) { - const futureDelta = delta - model.getLineMaxColumn(position.lineNumber) - position.column; + for (let lineNumber = position.lineNumber; lineNumber <= lineCount; lineNumber++) { + if (lineNumber === position.lineNumber) { + const futureDelta = offset - model.getLineMaxColumn(position.lineNumber) + position.column; if (futureDelta <= 0) { - endPosition = new Position(position.lineNumber, position.column + delta); + endPosition = new Position(position.lineNumber, position.column + offset); break; } - delta = futureDelta; + offset = futureDelta; } else { - const futureDelta = delta - model.getLineMaxColumn(potentialEndLineNumber); + const futureDelta = offset - model.getLineMaxColumn(lineNumber); if (futureDelta <= 0) { - endPosition = new Position(potentialEndLineNumber, delta); + endPosition = new Position(lineNumber, offset); break; } - delta = futureDelta; + offset = futureDelta; } } return endPosition ?? new Position(lineCount, model.getLineMaxColumn(lineCount)); From 368ae9cab142cdc48b99b4c2b9d99ba0b2cbe357 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 21 Nov 2024 15:36:45 +0100 Subject: [PATCH 40/44] polishing --- src/vs/editor/common/commands/replaceCommand.ts | 16 ++++++++-------- src/vs/editor/common/cursor/cursor.ts | 2 +- .../common/cursor/cursorTypeEditOperations.ts | 4 ++-- .../editor/common/cursor/cursorTypeOperations.ts | 4 ++-- .../browser/parts/editor/editorStatus.ts | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/common/commands/replaceCommand.ts b/src/vs/editor/common/commands/replaceCommand.ts index 0936f5d1c83a8..779dfd9a7b928 100644 --- a/src/vs/editor/common/commands/replaceCommand.ts +++ b/src/vs/editor/common/commands/replaceCommand.ts @@ -193,23 +193,23 @@ function addPositiveOffsetToModelPosition(model: ITextModel, position: Position, throw new Error('Unexpected negative delta'); } const lineCount = model.getLineCount(); - let endPosition: Position | undefined; + let endPosition = new Position(lineCount, model.getLineMaxColumn(lineCount)); for (let lineNumber = position.lineNumber; lineNumber <= lineCount; lineNumber++) { if (lineNumber === position.lineNumber) { - const futureDelta = offset - model.getLineMaxColumn(position.lineNumber) + position.column; - if (futureDelta <= 0) { + const futureOffset = offset - model.getLineMaxColumn(position.lineNumber) + position.column; + if (futureOffset <= 0) { endPosition = new Position(position.lineNumber, position.column + offset); break; } - offset = futureDelta; + offset = futureOffset; } else { - const futureDelta = offset - model.getLineMaxColumn(lineNumber); - if (futureDelta <= 0) { + const futureOffset = offset - model.getLineMaxColumn(lineNumber); + if (futureOffset <= 0) { endPosition = new Position(lineNumber, offset); break; } - offset = futureDelta; + offset = futureOffset; } } - return endPosition ?? new Position(lineCount, model.getLineMaxColumn(lineCount)); + return endPosition; } diff --git a/src/vs/editor/common/cursor/cursor.ts b/src/vs/editor/common/cursor/cursor.ts index 09825b6b9b42d..a276dfb354806 100644 --- a/src/vs/editor/common/cursor/cursor.ts +++ b/src/vs/editor/common/cursor/cursor.ts @@ -1041,7 +1041,7 @@ class CompositionState { textModel.getLineContent(lineNumber), lineNumber, selection.startColumn - 1, - selection.endColumn - 1, + selection.endColumn - 1 )); } return result; diff --git a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts index 55192ff9c6c38..e250bb744314f 100644 --- a/src/vs/editor/common/cursor/cursorTypeEditOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeEditOperations.ts @@ -357,10 +357,10 @@ export class AutoClosingOpenCharTypeOperation { export class CompositionEndOvertypeOperation { - public static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | undefined { + public static getEdits(config: CursorConfiguration, compositions: CompositionOutcome[]): EditOperationResult | null { const isOvertypeMode = config.inputMode === 'overtype'; if (!isOvertypeMode) { - return undefined; + return null; } const commands = compositions.map(composition => new ReplaceOvertypeCommandOnCompositionEnd(composition.insertedTextRange)); return new EditOperationResult(EditOperationType.TypingOther, commands, { diff --git a/src/vs/editor/common/cursor/cursorTypeOperations.ts b/src/vs/editor/common/cursor/cursorTypeOperations.ts index bfc8dcf16954b..b6d1a559cd087 100644 --- a/src/vs/editor/common/cursor/cursorTypeOperations.ts +++ b/src/vs/editor/common/cursor/cursorTypeOperations.ts @@ -90,7 +90,7 @@ export class TypeOperations { if (!insertedText || insertedText.length !== 1) { // we're only interested in the case where a single character was inserted - return CompositionEndOvertypeOperation.getEdits(config, compositions) ?? null; + return CompositionEndOvertypeOperation.getEdits(config, compositions); } const ch = insertedText; @@ -159,7 +159,7 @@ export class TypeOperations { return autoClosingOpenCharEdits; } - return CompositionEndOvertypeOperation.getEdits(config, compositions) ?? null; + return CompositionEndOvertypeOperation.getEdits(config, compositions); } public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult { diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index b3eaa334d7275..8f1023877973b 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -329,11 +329,11 @@ class StatusInputMode extends Disposable { constructor(@IConfigurationService private readonly configurationService: IConfigurationService) { super(); - this.registerListeners(); + this._registerListeners(); InputMode.setInputMode('insert'); } - private registerListeners(): void { + private _registerListeners(): void { this._register(InputMode.onDidChangeInputMode(inputMode => this._onDidChange.fire(inputMode))); this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('editor.inputMode')) { From 3cf08223feb76e76d990ea50ac61da19685f9ccf Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 27 Nov 2024 10:43:00 +0100 Subject: [PATCH 41/44] removing reading of config service --- .../workbench/browser/parts/editor/editorStatus.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 8f1023877973b..22d4a1cd095be 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -337,9 +337,9 @@ class StatusInputMode extends Disposable { this._register(InputMode.onDidChangeInputMode(inputMode => this._onDidChange.fire(inputMode))); this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('editor.inputMode')) { - const inputMode = this.configurationService.getValue<'overtype' | 'insert'>('editor.inputMode'); - InputMode.setInputMode(inputMode); - this._onDidChange.fire(inputMode); + const defaultInputMode = 'insert'; + InputMode.setInputMode(defaultInputMode); + this._onDidChange.fire(defaultInputMode); } })); } @@ -402,11 +402,7 @@ class EditorStatus extends Disposable { } })); this._register(Event.runAndSubscribe(this.inputMode.onDidChange, (inputMode) => { - if (inputMode !== undefined) { - this.onInputModeChange(inputMode); - } else { - this.onInputModeChange(this.configurationService.getValue('editor.inputMode')); - } + this.onInputModeChange(inputMode ?? 'insert'); })); } From 43a4c8e44bd23cb7eba8a89a057d078f06caa587 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 27 Nov 2024 10:46:27 +0100 Subject: [PATCH 42/44] changing the keybiding so it is only on max --- src/vs/workbench/browser/parts/editor/editorActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 2972d5bd23747..be79b3f0af2f8 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2713,7 +2713,7 @@ export class ToggleOvertypeInsertMode extends Action2 { keybinding: { weight: KeybindingWeight.WorkbenchContrib, primary: KeyCode.Insert, - secondary: [KeyMod.Alt | KeyCode.Ctrl | KeyCode.KeyO], + mac: { primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.KeyO }, }, f1: true, category: Categories.View From 24f6b1578920ba0501d6c047d416ac88223945df Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 27 Nov 2024 10:55:56 +0100 Subject: [PATCH 43/44] removing reading of config service --- src/vs/workbench/browser/parts/editor/editorStatus.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index 22d4a1cd095be..f1e002fc1fbf8 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -327,7 +327,7 @@ class StatusInputMode extends Disposable { private readonly _onDidChange = this._register(new Emitter<'overtype' | 'insert'>()); readonly onDidChange = this._onDidChange.event; - constructor(@IConfigurationService private readonly configurationService: IConfigurationService) { + constructor() { super(); this._registerListeners(); InputMode.setInputMode('insert'); @@ -335,13 +335,6 @@ class StatusInputMode extends Disposable { private _registerListeners(): void { this._register(InputMode.onDidChangeInputMode(inputMode => this._onDidChange.fire(inputMode))); - this._register(this.configurationService.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('editor.inputMode')) { - const defaultInputMode = 'insert'; - InputMode.setInputMode(defaultInputMode); - this._onDidChange.fire(defaultInputMode); - } - })); } } From 70cc13f6c1dd7d9a83e4c95293e62a911678f8fc Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 27 Nov 2024 11:11:09 +0100 Subject: [PATCH 44/44] polishing --- src/vs/workbench/browser/parts/editor/editorStatus.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index f1e002fc1fbf8..a1b9bd5215c2c 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -325,15 +325,11 @@ class TabFocusMode extends Disposable { class StatusInputMode extends Disposable { private readonly _onDidChange = this._register(new Emitter<'overtype' | 'insert'>()); - readonly onDidChange = this._onDidChange.event; + public readonly onDidChange = this._onDidChange.event; constructor() { super(); - this._registerListeners(); InputMode.setInputMode('insert'); - } - - private _registerListeners(): void { this._register(InputMode.onDidChangeInputMode(inputMode => this._onDidChange.fire(inputMode))); } } @@ -394,9 +390,7 @@ class EditorStatus extends Disposable { this.onTabFocusModeChange(this.configurationService.getValue('editor.tabFocusMode')); } })); - this._register(Event.runAndSubscribe(this.inputMode.onDidChange, (inputMode) => { - this.onInputModeChange(inputMode ?? 'insert'); - })); + this._register(Event.runAndSubscribe(this.inputMode.onDidChange, (inputMode) => this.onInputModeChange(inputMode ?? 'insert'))); } private registerCommands(): void {