Merge from vscode 91e99652cd5fcfc072387c64e151b435e39e8dcf (#6962)

This commit is contained in:
Anthony Dresser
2019-08-26 15:58:42 -07:00
committed by GitHub
parent edf470c8fa
commit 507bae90b7
103 changed files with 1743 additions and 1543 deletions

View File

@@ -132,7 +132,7 @@ class VisualEditorState {
this._zonesMap[String(zoneId)] = true;
if (newDecorations.zones[i].diff && viewZone.marginDomNode) {
this.inlineDiffMargins.push(new InlineDiffMargin(viewZone.marginDomNode, editor, newDecorations.zones[i].diff!, this._contextMenuService, this._clipboardService));
this.inlineDiffMargins.push(new InlineDiffMargin(zoneId, viewZone.marginDomNode, editor, newDecorations.zones[i].diff!, this._contextMenuService, this._clipboardService));
}
}
});

View File

@@ -9,6 +9,7 @@ import { Action } from 'vs/base/common/actions';
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
import { Range } from 'vs/editor/common/core/range';
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
@@ -21,10 +22,29 @@ export interface IDiffLinesChange {
}
export class InlineDiffMargin extends Disposable {
private readonly _lightBulb: HTMLElement;
private readonly _diffActions: HTMLElement;
private _visibility: boolean = false;
get visibility(): boolean {
return this._visibility;
}
set visibility(_visibility: boolean) {
if (this._visibility !== _visibility) {
this._visibility = _visibility;
if (_visibility) {
this._diffActions.style.visibility = 'visible';
} else {
this._diffActions.style.visibility = 'hidden';
}
}
}
constructor(
marginDomNode: HTMLElement,
private _viewZoneId: string,
private _marginDomNode: HTMLElement,
public editor: CodeEditorWidget,
public diff: IDiffLinesChange,
private _contextMenuService: IContextMenuService,
@@ -33,17 +53,18 @@ export class InlineDiffMargin extends Disposable {
super();
// make sure the diff margin shows above overlay.
marginDomNode.style.zIndex = '10';
this._marginDomNode.style.zIndex = '10';
this._lightBulb = document.createElement('div');
this._lightBulb.className = 'lightbulb-glyph';
this._lightBulb.style.position = 'absolute';
this._diffActions = document.createElement('div');
this._diffActions.className = 'lightbulb-glyph';
this._diffActions.style.position = 'absolute';
const lineHeight = editor.getConfiguration().lineHeight;
const lineFeed = editor.getModel()!.getEOL();
this._lightBulb.style.right = '0px';
this._lightBulb.style.visibility = 'hidden';
this._lightBulb.style.height = `${lineHeight}px`;
marginDomNode.appendChild(this._lightBulb);
this._diffActions.style.right = '0px';
this._diffActions.style.visibility = 'hidden';
this._diffActions.style.height = `${lineHeight}px`;
this._diffActions.style.lineHeight = `${lineHeight}px`;
this._marginDomNode.appendChild(this._diffActions);
const actions = [
new Action(
@@ -59,17 +80,21 @@ export class InlineDiffMargin extends Disposable {
let currentLineNumberOffset = 0;
const copyLineAction = new Action(
'diff.clipboard.copyDeletedLineContent',
nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line {0} content to clipboard", diff.originalStartLineNumber),
undefined,
true,
async () => {
await this._clipboardService.writeText(diff.originalContent[currentLineNumberOffset]);
}
);
let copyLineAction: Action | undefined = undefined;
actions.push(copyLineAction);
if (diff.originalEndLineNumber > diff.modifiedStartLineNumber) {
copyLineAction = new Action(
'diff.clipboard.copyDeletedLineContent',
nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line {0} content to clipboard", diff.originalStartLineNumber),
undefined,
true,
async () => {
await this._clipboardService.writeText(diff.originalContent[currentLineNumberOffset]);
}
);
actions.push(copyLineAction);
}
const readOnly = editor.getConfiguration().readOnly;
if (!readOnly) {
@@ -96,21 +121,8 @@ export class InlineDiffMargin extends Disposable {
}));
}
this._register(dom.addStandardDisposableListener(marginDomNode, 'mouseenter', e => {
this._lightBulb.style.visibility = 'visible';
currentLineNumberOffset = this._updateLightBulbPosition(marginDomNode, e.y, lineHeight);
}));
this._register(dom.addStandardDisposableListener(marginDomNode, 'mouseleave', e => {
this._lightBulb.style.visibility = 'hidden';
}));
this._register(dom.addStandardDisposableListener(marginDomNode, 'mousemove', e => {
currentLineNumberOffset = this._updateLightBulbPosition(marginDomNode, e.y, lineHeight);
}));
this._register(dom.addStandardDisposableListener(this._lightBulb, 'mousedown', e => {
const { top, height } = dom.getDomNodePagePosition(this._lightBulb);
this._register(dom.addStandardDisposableListener(this._diffActions, 'mousedown', e => {
const { top, height } = dom.getDomNodePagePosition(this._diffActions);
let pad = Math.floor(lineHeight / 3) + lineHeight;
this._contextMenuService.showContextMenu({
getAnchor: () => {
@@ -120,12 +132,29 @@ export class InlineDiffMargin extends Disposable {
};
},
getActions: () => {
copyLineAction.label = nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line {0} content to clipboard", diff.originalStartLineNumber + currentLineNumberOffset);
if (copyLineAction) {
copyLineAction.label = nls.localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line {0} content to clipboard", diff.originalStartLineNumber + currentLineNumberOffset);
}
return actions;
},
autoSelectFirstItem: true
});
}));
this._register(editor.onMouseMove((e: editorBrowser.IEditorMouseEvent) => {
if (e.target.type === editorBrowser.MouseTargetType.CONTENT_VIEW_ZONE || e.target.type === editorBrowser.MouseTargetType.GUTTER_VIEW_ZONE) {
const viewZoneId = e.target.detail.viewZoneId;
if (viewZoneId === this._viewZoneId) {
this.visibility = true;
currentLineNumberOffset = this._updateLightBulbPosition(this._marginDomNode, e.event.browserEvent.y, lineHeight);
} else {
this.visibility = false;
}
} else {
this.visibility = false;
}
}));
}
private _updateLightBulbPosition(marginDomNode: HTMLElement, y: number, lineHeight: number): number {
@@ -133,7 +162,7 @@ export class InlineDiffMargin extends Disposable {
const offset = y - top;
const lineNumberOffset = Math.floor(offset / lineHeight);
const newTop = lineNumberOffset * lineHeight;
this._lightBulb.style.top = `${newTop}px`;
this._diffActions.style.top = `${newTop}px`;
return lineNumberOffset;
}
}

View File

@@ -93,3 +93,16 @@
.monaco-editor .view-zones .view-lines .view-line span {
display: inline-block;
}
.monaco-editor .margin-view-zones .inline-deleted-margin-view-zone .lightbulb-glyph {
background: url('lightbulb-light.svg') center center no-repeat;
}
.monaco-editor.vs-dark .margin-view-zones .inline-deleted-margin-view-zone .lightbulb-glyph,
.monaco-editor.hc-dark .margin-view-zones .inline-deleted-margin-view-zone .lightbulb-glyph {
background: url('lightbulb-dark.svg') center center no-repeat;
}
.monaco-editor .margin-view-zones .lightbulb-glyph:hover {
cursor: pointer;
}

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6708 8.65806C11.3319 8.9916 11.0716 9.36278 10.8886 9.77172C10.7105 10.1792 10.621 10.6219 10.621 11.1009V12.7012C10.621 12.8807 10.5872 13.0503 10.5189 13.2091C10.4513 13.3661 10.3586 13.5038 10.2407 13.6213C10.1228 13.7388 9.98464 13.8311 9.82723 13.8984C9.66806 13.9663 9.49806 14 9.31823 14H7.71205C7.53223 14 7.36223 13.9663 7.20306 13.8984C7.04564 13.8311 6.90753 13.7388 6.78961 13.6213C6.67168 13.5038 6.57895 13.3661 6.51141 13.2091C6.44311 13.0503 6.40927 12.8807 6.40927 12.7012V11.1009C6.40927 10.622 6.31772 10.1795 6.13553 9.77209C5.95683 9.36336 5.69832 8.99156 5.35953 8.65806C4.92468 8.22903 4.58896 7.75003 4.35361 7.22134C4.11756 6.69107 4 6.11672 4 5.49953C4 5.08664 4.05342 4.68802 4.16048 4.30397C4.26728 3.92089 4.41907 3.56286 4.61595 3.23018C4.81257 2.89377 5.04777 2.58911 5.32146 2.31641C5.59503 2.04383 5.89858 1.80953 6.23195 1.61364C6.56979 1.41764 6.93146 1.2662 7.31578 1.15983C7.70106 1.0532 8.10094 1 8.51514 1C8.92934 1 9.32923 1.0532 9.71451 1.15983C10.0988 1.2662 10.458 1.41739 10.7918 1.61351C11.1294 1.80938 11.4351 2.0437 11.7088 2.31641C11.9825 2.5891 12.2177 2.89376 12.4143 3.23016C12.6112 3.56285 12.763 3.92088 12.8698 4.30397C12.9769 4.68802 13.0303 5.08664 13.0303 5.49953C13.0303 6.11672 12.9127 6.69107 12.6767 7.22134C12.4413 7.75003 12.1056 8.22903 11.6708 8.65806ZM9.62162 10.5H7.40867V12.7012C7.40867 12.7823 7.4372 12.8512 7.49888 12.9127C7.56058 12.9741 7.63007 13.0028 7.71205 13.0028H9.31823C9.40022 13.0028 9.46971 12.9741 9.5314 12.9127C9.59309 12.8512 9.62162 12.7823 9.62162 12.7012V10.5Z" fill="#C2C2C2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6708 8.65806C11.3319 8.9916 11.0716 9.36278 10.8886 9.77172C10.7105 10.1792 10.621 10.6219 10.621 11.1009V12.7012C10.621 12.8807 10.5872 13.0503 10.5189 13.2091C10.4513 13.3661 10.3586 13.5038 10.2407 13.6213C10.1228 13.7388 9.98464 13.8311 9.82723 13.8984C9.66806 13.9663 9.49806 14 9.31823 14H7.71205C7.53223 14 7.36223 13.9663 7.20306 13.8984C7.04564 13.8311 6.90753 13.7388 6.78961 13.6213C6.67168 13.5038 6.57895 13.3661 6.51141 13.2091C6.44311 13.0503 6.40927 12.8807 6.40927 12.7012V11.1009C6.40927 10.622 6.31772 10.1795 6.13553 9.77209C5.95683 9.36336 5.69832 8.99156 5.35953 8.65806C4.92468 8.22903 4.58896 7.75003 4.35361 7.22134C4.11756 6.69107 4 6.11672 4 5.49953C4 5.08664 4.05342 4.68802 4.16048 4.30397C4.26728 3.92089 4.41907 3.56286 4.61595 3.23018C4.81257 2.89377 5.04777 2.58911 5.32146 2.31641C5.59503 2.04383 5.89858 1.80953 6.23195 1.61364C6.56979 1.41764 6.93146 1.2662 7.31578 1.15983C7.70106 1.0532 8.10094 1 8.51514 1C8.92934 1 9.32923 1.0532 9.71451 1.15983C10.0988 1.2662 10.458 1.41739 10.7918 1.61351C11.1294 1.80938 11.4351 2.0437 11.7088 2.31641C11.9825 2.5891 12.2177 2.89376 12.4143 3.23016C12.6112 3.56285 12.763 3.92088 12.8698 4.30397C12.9769 4.68802 13.0303 5.08664 13.0303 5.49953C13.0303 6.11672 12.9127 6.69107 12.6767 7.22134C12.4413 7.75003 12.1056 8.22903 11.6708 8.65806ZM9.62162 10.5H7.40867V12.7012C7.40867 12.7823 7.4372 12.8512 7.49888 12.9127C7.56058 12.9741 7.63007 13.0028 7.71205 13.0028H9.31823C9.40022 13.0028 9.46971 12.9741 9.5314 12.9127C9.59309 12.8512 9.62162 12.7823 9.62162 12.7012V10.5Z" fill="#424242"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6708 8.65806C11.3319 8.9916 11.0716 9.36278 10.8886 9.77172C10.7105 10.1792 10.621 10.6219 10.621 11.1009V12.7012C10.621 12.8807 10.5872 13.0503 10.5189 13.2091C10.4513 13.3661 10.3586 13.5038 10.2407 13.6213C10.1228 13.7388 9.98464 13.8311 9.82723 13.8984C9.66806 13.9663 9.49806 14 9.31823 14H7.71205C7.53223 14 7.36223 13.9663 7.20306 13.8984C7.04564 13.8311 6.90753 13.7388 6.78961 13.6213C6.67168 13.5038 6.57895 13.3661 6.51141 13.2091C6.44311 13.0503 6.40927 12.8807 6.40927 12.7012V11.1009C6.40927 10.622 6.31772 10.1795 6.13553 9.77209C5.95683 9.36336 5.69832 8.99156 5.35953 8.65806C4.92468 8.22903 4.58896 7.75003 4.35361 7.22134C4.11756 6.69107 4 6.11672 4 5.49953C4 5.08664 4.05342 4.68802 4.16048 4.30397C4.26728 3.92089 4.41907 3.56286 4.61595 3.23018C4.81257 2.89377 5.04777 2.58911 5.32146 2.31641C5.59503 2.04383 5.89858 1.80953 6.23195 1.61364C6.56979 1.41764 6.93146 1.2662 7.31578 1.15983C7.70106 1.0532 8.10094 1 8.51514 1C8.92934 1 9.32923 1.0532 9.71451 1.15983C10.0988 1.2662 10.458 1.41739 10.7918 1.61351C11.1294 1.80938 11.4351 2.0437 11.7088 2.31641C11.9825 2.5891 12.2177 2.89376 12.4143 3.23016C12.6112 3.56285 12.763 3.92088 12.8698 4.30397C12.9769 4.68802 13.0303 5.08664 13.0303 5.49953C13.0303 6.11672 12.9127 6.69107 12.6767 7.22134C12.4413 7.75003 12.1056 8.22903 11.6708 8.65806ZM9.62162 10.5H7.40867V12.7012C7.40867 12.7823 7.4372 12.8512 7.49888 12.9127C7.56058 12.9741 7.63007 13.0028 7.71205 13.0028H9.31823C9.40022 13.0028 9.46971 12.9741 9.5314 12.9127C9.59309 12.8512 9.62162 12.7823 9.62162 12.7012V10.5Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -558,6 +558,17 @@ const editorConfiguration: IConfigurationNode = {
'default': EDITOR_DEFAULTS.autoClosingQuotes,
'description': nls.localize('autoClosingQuotes', "Controls whether the editor should automatically close quotes after the user adds an opening quote.")
},
'editor.autoClosingOvertype': {
type: 'string',
enum: ['always', 'auto', 'never'],
enumDescriptions: [
nls.localize('editor.autoClosingOvertype.always', "Always type over closing quotes or brackets."),
nls.localize('editor.autoClosingOvertype.auto', "Type over closing quotes or brackets only if they were automatically inserted."),
nls.localize('editor.autoClosingOvertype.never', "Never type over closing quotes or brackets."),
],
'default': EDITOR_DEFAULTS.autoClosingOvertype,
'description': nls.localize('autoClosingOvertype', "Controls whether the editor should type over closing quotes or brackets.")
},
'editor.autoSurround': {
type: 'string',
enum: ['languageDefined', 'brackets', 'quotes', 'never'],

View File

@@ -108,6 +108,11 @@ export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWh
*/
export type EditorAutoSurroundStrategy = 'languageDefined' | 'quotes' | 'brackets' | 'never';
/**
* Configuration options for typing over closing quotes or brackets
*/
export type EditorAutoClosingOvertypeStrategy = 'always' | 'auto' | 'never';
/**
* Configuration options for editor minimap
*/
@@ -544,6 +549,10 @@ export interface IEditorOptions {
* Defaults to language defined behavior.
*/
autoClosingQuotes?: EditorAutoClosingStrategy;
/**
* Options for typing over closing quotes or brackets.
*/
autoClosingOvertype?: EditorAutoClosingOvertypeStrategy;
/**
* Options for auto surrounding.
* Defaults to always allowing auto surrounding.
@@ -1079,6 +1088,7 @@ export interface IValidatedEditorOptions {
readonly wordWrapBreakObtrusiveCharacters: string;
readonly autoClosingBrackets: EditorAutoClosingStrategy;
readonly autoClosingQuotes: EditorAutoClosingStrategy;
readonly autoClosingOvertype: EditorAutoClosingOvertypeStrategy;
readonly autoSurround: EditorAutoSurroundStrategy;
readonly autoIndent: boolean;
readonly dragAndDrop: boolean;
@@ -1117,6 +1127,7 @@ export class InternalEditorOptions {
readonly wordSeparators: string;
readonly autoClosingBrackets: EditorAutoClosingStrategy;
readonly autoClosingQuotes: EditorAutoClosingStrategy;
readonly autoClosingOvertype: EditorAutoClosingOvertypeStrategy;
readonly autoSurround: EditorAutoSurroundStrategy;
readonly autoIndent: boolean;
readonly useTabStops: boolean;
@@ -1147,6 +1158,7 @@ export class InternalEditorOptions {
wordSeparators: string;
autoClosingBrackets: EditorAutoClosingStrategy;
autoClosingQuotes: EditorAutoClosingStrategy;
autoClosingOvertype: EditorAutoClosingOvertypeStrategy;
autoSurround: EditorAutoSurroundStrategy;
autoIndent: boolean;
useTabStops: boolean;
@@ -1172,6 +1184,7 @@ export class InternalEditorOptions {
this.wordSeparators = source.wordSeparators;
this.autoClosingBrackets = source.autoClosingBrackets;
this.autoClosingQuotes = source.autoClosingQuotes;
this.autoClosingOvertype = source.autoClosingOvertype;
this.autoSurround = source.autoSurround;
this.autoIndent = source.autoIndent;
this.useTabStops = source.useTabStops;
@@ -1203,6 +1216,7 @@ export class InternalEditorOptions {
&& this.wordSeparators === other.wordSeparators
&& this.autoClosingBrackets === other.autoClosingBrackets
&& this.autoClosingQuotes === other.autoClosingQuotes
&& this.autoClosingOvertype === other.autoClosingOvertype
&& this.autoSurround === other.autoSurround
&& this.autoIndent === other.autoIndent
&& this.useTabStops === other.useTabStops
@@ -1235,6 +1249,7 @@ export class InternalEditorOptions {
wordSeparators: (this.wordSeparators !== newOpts.wordSeparators),
autoClosingBrackets: (this.autoClosingBrackets !== newOpts.autoClosingBrackets),
autoClosingQuotes: (this.autoClosingQuotes !== newOpts.autoClosingQuotes),
autoClosingOvertype: (this.autoClosingOvertype !== newOpts.autoClosingOvertype),
autoSurround: (this.autoSurround !== newOpts.autoSurround),
autoIndent: (this.autoIndent !== newOpts.autoIndent),
useTabStops: (this.useTabStops !== newOpts.useTabStops),
@@ -1640,6 +1655,7 @@ export interface IConfigurationChangedEvent {
readonly wordSeparators: boolean;
readonly autoClosingBrackets: boolean;
readonly autoClosingQuotes: boolean;
readonly autoClosingOvertype: boolean;
readonly autoSurround: boolean;
readonly autoIndent: boolean;
readonly useTabStops: boolean;
@@ -1852,6 +1868,7 @@ export class EditorOptionsValidator {
wordWrapBreakObtrusiveCharacters: _string(opts.wordWrapBreakObtrusiveCharacters, defaults.wordWrapBreakObtrusiveCharacters),
autoClosingBrackets,
autoClosingQuotes,
autoClosingOvertype: _stringSet<EditorAutoClosingOvertypeStrategy>(opts.autoClosingOvertype, defaults.autoClosingOvertype, ['always', 'auto', 'never']),
autoSurround,
autoIndent: _boolean(opts.autoIndent, defaults.autoIndent),
dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop),
@@ -2148,7 +2165,6 @@ export class EditorOptionsValidator {
export class InternalEditorOptionsFactory {
private static _tweakValidatedOptions(opts: IValidatedEditorOptions, accessibilitySupport: AccessibilitySupport): IValidatedEditorOptions {
const accessibilityIsOn = (accessibilitySupport === AccessibilitySupport.Enabled);
const accessibilityIsOff = (accessibilitySupport === AccessibilitySupport.Disabled);
return {
inDiffEditor: opts.inDiffEditor,
@@ -2168,6 +2184,7 @@ export class InternalEditorOptionsFactory {
wordWrapBreakObtrusiveCharacters: opts.wordWrapBreakObtrusiveCharacters,
autoClosingBrackets: opts.autoClosingBrackets,
autoClosingQuotes: opts.autoClosingQuotes,
autoClosingOvertype: opts.autoClosingOvertype,
autoSurround: opts.autoSurround,
autoIndent: opts.autoIndent,
dragAndDrop: opts.dragAndDrop,
@@ -2244,7 +2261,7 @@ export class InternalEditorOptionsFactory {
selectionHighlight: opts.contribInfo.selectionHighlight,
occurrencesHighlight: opts.contribInfo.occurrencesHighlight,
codeLens: opts.contribInfo.codeLens,
folding: (accessibilityIsOn ? false : opts.contribInfo.folding), // DISABLED WHEN SCREEN READER IS ATTACHED
folding: opts.contribInfo.folding,
foldingStrategy: opts.contribInfo.foldingStrategy,
showFoldingControls: opts.contribInfo.showFoldingControls,
matchBrackets: opts.contribInfo.matchBrackets,
@@ -2396,6 +2413,7 @@ export class InternalEditorOptionsFactory {
wordSeparators: opts.wordSeparators,
autoClosingBrackets: opts.autoClosingBrackets,
autoClosingQuotes: opts.autoClosingQuotes,
autoClosingOvertype: opts.autoClosingOvertype,
autoSurround: opts.autoSurround,
autoIndent: opts.autoIndent,
useTabStops: opts.useTabStops,
@@ -2635,6 +2653,7 @@ export const EDITOR_DEFAULTS: IValidatedEditorOptions = {
wordWrapBreakObtrusiveCharacters: '.',
autoClosingBrackets: 'languageDefined',
autoClosingQuotes: 'languageDefined',
autoClosingOvertype: 'auto',
autoSurround: 'languageDefined',
autoIndent: true,
dragAndDrop: true,

View File

@@ -6,7 +6,7 @@
import { CharCode } from 'vs/base/common/charCode';
import { onUnexpectedError } from 'vs/base/common/errors';
import * as strings from 'vs/base/common/strings';
import { EditorAutoClosingStrategy, EditorAutoSurroundStrategy, IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions';
import { EditorAutoClosingStrategy, EditorAutoSurroundStrategy, IConfigurationChangedEvent, EditorAutoClosingOvertypeStrategy } from 'vs/editor/common/config/editorOptions';
import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
@@ -99,6 +99,7 @@ export class CursorConfiguration {
public readonly multiCursorMergeOverlapping: boolean;
public readonly autoClosingBrackets: EditorAutoClosingStrategy;
public readonly autoClosingQuotes: EditorAutoClosingStrategy;
public readonly autoClosingOvertype: EditorAutoClosingOvertypeStrategy;
public readonly autoSurround: EditorAutoSurroundStrategy;
public readonly autoIndent: boolean;
public readonly autoClosingPairsOpen2: Map<string, StandardAutoClosingPairConditional[]>;
@@ -117,6 +118,7 @@ export class CursorConfiguration {
|| e.multiCursorMergeOverlapping
|| e.autoClosingBrackets
|| e.autoClosingQuotes
|| e.autoClosingOvertype
|| e.autoSurround
|| e.useTabStops
|| e.lineHeight
@@ -146,6 +148,7 @@ export class CursorConfiguration {
this.multiCursorMergeOverlapping = c.multiCursorMergeOverlapping;
this.autoClosingBrackets = c.autoClosingBrackets;
this.autoClosingQuotes = c.autoClosingQuotes;
this.autoClosingOvertype = c.autoClosingOvertype;
this.autoSurround = c.autoSurround;
this.autoIndent = c.autoIndent;

View File

@@ -431,10 +431,8 @@ export class TypeOperations {
return null;
}
private static _isAutoClosingCloseCharType(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean {
const autoCloseConfig = isQuote(ch) ? config.autoClosingQuotes : config.autoClosingBrackets;
if (autoCloseConfig === 'never') {
private static _isAutoClosingOvertype(config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): boolean {
if (config.autoClosingOvertype === 'never') {
return false;
}
@@ -458,23 +456,25 @@ export class TypeOperations {
}
// Must over-type a closing character typed by the editor
let found = false;
for (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {
const autoClosedCharacter = autoClosedCharacters[j];
if (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {
found = true;
break;
if (config.autoClosingOvertype === 'auto') {
let found = false;
for (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {
const autoClosedCharacter = autoClosedCharacters[j];
if (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
if (!found) {
return false;
}
}
return true;
}
private static _runAutoClosingCloseCharType(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): EditOperationResult {
private static _runAutoClosingOvertype(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], ch: string): EditOperationResult {
let commands: ICommand[] = [];
for (let i = 0, len = selections.length; i < len; i++) {
const selection = selections[i];
@@ -765,7 +765,7 @@ export class TypeOperations {
return null;
}
if (this._isAutoClosingCloseCharType(config, model, selections, autoClosedCharacters, ch)) {
if (this._isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {
// Unfortunately, the close character is at this point "doubled", so we need to delete it...
const commands = selections.map(s => new ReplaceCommand(new Range(s.positionLineNumber, s.positionColumn, s.positionLineNumber, s.positionColumn + 1), '', false));
return new EditOperationResult(EditOperationType.Typing, commands, {
@@ -813,8 +813,8 @@ export class TypeOperations {
}
}
if (this._isAutoClosingCloseCharType(config, model, selections, autoClosedCharacters, ch)) {
return this._runAutoClosingCloseCharType(prevEditOperationType, config, model, selections, ch);
if (this._isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {
return this._runAutoClosingOvertype(prevEditOperationType, config, model, selections, ch);
}
const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, true);

View File

@@ -39,7 +39,8 @@ const enum WordType {
export const enum WordNavigationType {
WordStart = 0,
WordStartFast = 1,
WordEnd = 2
WordEnd = 2,
WordAccessibility = 3 // Respect chrome defintion of a word
}
export class WordOperations {
@@ -202,6 +203,18 @@ export class WordOperations {
return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
}
if (wordNavigationType === WordNavigationType.WordAccessibility) {
while (
prevWordOnLine
&& prevWordOnLine.wordType === WordType.Separator
) {
// Skip over words made up of only separators
prevWordOnLine = WordOperations._findPreviousWordOnLine(wordSeparators, model, new Position(lineNumber, prevWordOnLine.start + 1));
}
return new Position(lineNumber, prevWordOnLine ? prevWordOnLine.start + 1 : 1);
}
// We are stopping at the ending of words
if (prevWordOnLine && column <= prevWordOnLine.end + 1) {
@@ -270,6 +283,21 @@ export class WordOperations {
nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
}
}
if (nextWordOnLine) {
column = nextWordOnLine.end + 1;
} else {
column = model.getLineMaxColumn(lineNumber);
}
} else if (wordNavigationType === WordNavigationType.WordAccessibility) {
while (
nextWordOnLine
&& nextWordOnLine.wordType === WordType.Separator
) {
// Skip over a word made up of one single separator
nextWordOnLine = WordOperations._findNextWordOnLine(wordSeparators, model, new Position(lineNumber, nextWordOnLine.end + 1));
}
if (nextWordOnLine) {
column = nextWordOnLine.end + 1;
} else {
@@ -617,4 +645,4 @@ export class WordPartOperations extends WordOperations {
function enforceDefined<T>(arr: Array<T | undefined | null>): T[] {
return <T[]>arr.filter(el => Boolean(el));
}
}

View File

@@ -78,7 +78,7 @@ export function tokenizeLineToHTML(text: string, viewLineTokens: IViewLineTokens
break;
case CharCode.Space:
partContent += '&nbsp';
partContent += '&nbsp;';
break;
default:

View File

@@ -38,6 +38,7 @@
line-height: 19px;
transition: top 200ms linear;
padding: 0 4px;
box-sizing: border-box;
}
.monaco-editor .find-widget.hiddenEditor {

View File

@@ -57,7 +57,7 @@ const NLS_MATCHES_COUNT_LIMIT_TITLE = nls.localize('title.matchesCountLimit', "O
const NLS_MATCHES_LOCATION = nls.localize('label.matchesLocation', "{0} of {1}");
const NLS_NO_RESULTS = nls.localize('label.noResults', "No Results");
const FIND_WIDGET_INITIAL_WIDTH = 411;
const FIND_WIDGET_INITIAL_WIDTH = 419;
const PART_WIDTH = 275;
const FIND_INPUT_AREA_WIDTH = PART_WIDTH - 54;
@@ -1172,6 +1172,39 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
this._findInput.inputBox.layout();
this._tryUpdateHeight();
}));
this._register(this._resizeSash.onDidReset(() => {
// users double click on the sash
const currentWidth = dom.getTotalWidth(this._domNode);
if (currentWidth < FIND_WIDGET_INITIAL_WIDTH) {
// The editor is narrow and the width of the find widget is controlled fully by CSS.
return;
}
let width = FIND_WIDGET_INITIAL_WIDTH;
if (!this._resized || currentWidth === FIND_WIDGET_INITIAL_WIDTH) {
// 1. never resized before, double click should maximizes it
// 2. users resized it already but its width is the same as default
width = this._codeEditor.getConfiguration().layoutInfo.width - 28 - this._codeEditor.getConfiguration().layoutInfo.minimapWidth - 15;
this._resized = true;
} else {
/**
* no op, the find widget should be shrinked to its default size.
*/
}
const inputBoxWidth = width - FIND_ALL_CONTROLS_WIDTH;
this._domNode.style.width = `${width}px`;
this._findInput.inputBox.width = inputBoxWidth;
if (this._isReplaceVisible) {
this._replaceInput.width = dom.getTotalWidth(this._findInput.domNode);
}
this._findInput.inputBox.layout();
}));
}
private updateAccessibilitySupport(): void {

View File

@@ -7,7 +7,7 @@ import { alert } from 'vs/base/browser/ui/aria/aria';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { onUnexpectedError } from 'vs/base/common/errors';
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { dispose, IDisposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { dispose, IDisposable, DisposableStore, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorAction, EditorCommand, registerEditorAction, registerEditorCommand, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
import { EditOperation } from 'vs/editor/common/core/editOperation';
@@ -33,9 +33,49 @@ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerServ
import { IdleValue } from 'vs/base/common/async';
import { isObject } from 'vs/base/common/types';
import { CommitCharacterController } from './suggestCommitCharacters';
import { IPosition } from 'vs/editor/common/core/position';
import { TrackedRangeStickiness, ITextModel } from 'vs/editor/common/model';
const _sticky = false; // for development purposes only
class LineSuffix {
private readonly _marker: string[] | undefined;
constructor(private readonly _model: ITextModel, private readonly _position: IPosition) {
// spy on what's happening right of the cursor. two cases:
// 1. end of line -> check that it's still end of line
// 2. mid of line -> add a marker and compute the delta
const maxColumn = _model.getLineMaxColumn(_position.lineNumber);
if (maxColumn !== _position.column) {
const offset = _model.getOffsetAt(_position);
const end = _model.getPositionAt(offset + 1);
this._marker = _model.deltaDecorations([], [{
range: Range.fromPositions(_position, end),
options: { stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges }
}]);
}
}
dispose(): void {
if (this._marker) {
this._model.deltaDecorations(this._marker, []);
}
}
delta(position: IPosition): number {
if (this._position.lineNumber !== position.lineNumber) {
return 0;
} else if (this._marker) {
const range = this._model.getDecorationRange(this._marker[0]);
const end = this._model.getOffsetAt(range!.getStartPosition());
return end - this._model.getOffsetAt(position);
} else {
return this._model.getLineMaxColumn(position.lineNumber) - position.column;
}
}
}
export class SuggestController implements IEditorContribution {
private static readonly ID: string = 'editor.contrib.suggestController';
@@ -47,9 +87,9 @@ export class SuggestController implements IEditorContribution {
private readonly _model: SuggestModel;
private readonly _widget: IdleValue<SuggestWidget>;
private readonly _alternatives: IdleValue<SuggestAlternatives>;
private readonly _lineSuffix = new MutableDisposable<LineSuffix>();
private readonly _toDispose = new DisposableStore();
constructor(
private _editor: ICodeEditor,
@IEditorWorkerService editorWorker: IEditorWorkerService,
@@ -115,6 +155,7 @@ export class SuggestController implements IEditorContribution {
this._toDispose.add(this._model.onDidTrigger(e => {
this._widget.getValue().showTriggered(e.auto, e.shy ? 250 : 50);
this._lineSuffix.value = new LineSuffix(this._editor.getModel()!, e.position);
}));
this._toDispose.add(this._model.onDidSuggest(e => {
if (!e.shy) {
@@ -123,7 +164,7 @@ export class SuggestController implements IEditorContribution {
}
}));
this._toDispose.add(this._model.onDidCancel(e => {
if (this._widget && !e.retrigger) {
if (!e.retrigger) {
this._widget.getValue().hideWidget();
}
}));
@@ -154,6 +195,7 @@ export class SuggestController implements IEditorContribution {
this._toDispose.dispose();
this._widget.dispose();
this._model.dispose();
this._lineSuffix.dispose();
}
protected _insertSuggestion(event: ISelectedSuggestion | undefined, keepAlternativeSuggestions: boolean, undoStops: boolean): void {
@@ -193,10 +235,11 @@ export class SuggestController implements IEditorContribution {
const overwriteBefore = position.column - suggestion.range.startColumn;
const overwriteAfter = suggestion.range.endColumn - position.column;
const suffixDelta = this._lineSuffix.value ? this._lineSuffix.value.delta(this._editor.getPosition()) : 0;
SnippetController2.get(this._editor).insert(insertText, {
overwriteBefore: overwriteBefore + columnDelta,
overwriteAfter,
overwriteAfter: overwriteAfter + suffixDelta,
undoStopBefore: false,
undoStopAfter: false,
adjustWhitespace: !(suggestion.insertTextRules! & CompletionItemInsertTextRule.KeepWhitespace)

View File

@@ -10,7 +10,7 @@ import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable, dispose, DisposableStore, isDisposable } from 'vs/base/common/lifecycle';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { CursorChangeReason, ICursorSelectionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { Position } from 'vs/editor/common/core/position';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { ITextModel, IWordAtPosition } from 'vs/editor/common/model';
import { CompletionItemProvider, StandardTokenType, CompletionContext, CompletionProviderRegistry, CompletionTriggerKind, CompletionItemKind, completionKindFromString } from 'vs/editor/common/modes';
@@ -28,6 +28,7 @@ export interface ICancelEvent {
export interface ITriggerEvent {
readonly auto: boolean;
readonly shy: boolean;
readonly position: IPosition;
}
export interface ISuggestEvent {
@@ -365,7 +366,7 @@ export class SuggestModel implements IDisposable {
// Cancel previous requests, change state & update UI
this.cancel(retrigger);
this._state = auto ? State.Auto : State.Manual;
this._onDidTrigger.fire({ auto, shy: context.shy });
this._onDidTrigger.fire({ auto, shy: context.shy, position: this._editor.getPosition() });
// Capture context when request was sent
this._context = ctx;

View File

@@ -9,7 +9,7 @@ import { EditorCommand } from 'vs/editor/browser/editorExtensions';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { deserializePipePositions, serializePipePositions, testRepeatedActionAndExtractPositions } from 'vs/editor/contrib/wordOperations/test/wordTestUtils';
import { CursorWordEndLeft, CursorWordEndLeftSelect, CursorWordEndRight, CursorWordEndRightSelect, CursorWordLeft, CursorWordLeftSelect, CursorWordRight, CursorWordRightSelect, CursorWordStartLeft, CursorWordStartLeftSelect, CursorWordStartRight, CursorWordStartRightSelect, DeleteWordEndLeft, DeleteWordEndRight, DeleteWordLeft, DeleteWordRight, DeleteWordStartLeft, DeleteWordStartRight } from 'vs/editor/contrib/wordOperations/wordOperations';
import { CursorWordEndLeft, CursorWordEndLeftSelect, CursorWordEndRight, CursorWordEndRightSelect, CursorWordLeft, CursorWordLeftSelect, CursorWordRight, CursorWordRightSelect, CursorWordStartLeft, CursorWordStartLeftSelect, CursorWordStartRight, CursorWordStartRightSelect, DeleteWordEndLeft, DeleteWordEndRight, DeleteWordLeft, DeleteWordRight, DeleteWordStartLeft, DeleteWordStartRight, CursorWordAccessibilityLeft, CursorWordAccessibilityLeftSelect, CursorWordAccessibilityRight, CursorWordAccessibilityRightSelect } from 'vs/editor/contrib/wordOperations/wordOperations';
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
suite('WordOperations', () => {
@@ -26,6 +26,10 @@ suite('WordOperations', () => {
const _cursorWordStartRightSelect = new CursorWordStartRightSelect();
const _cursorWordEndRightSelect = new CursorWordEndRightSelect();
const _cursorWordRightSelect = new CursorWordRightSelect();
const _cursorWordAccessibilityLeft = new CursorWordAccessibilityLeft();
const _cursorWordAccessibilityLeftSelect = new CursorWordAccessibilityLeftSelect();
const _cursorWordAccessibilityRight = new CursorWordAccessibilityRight();
const _cursorWordAccessibilityRightSelect = new CursorWordAccessibilityRightSelect();
const _deleteWordLeft = new DeleteWordLeft();
const _deleteWordStartLeft = new DeleteWordStartLeft();
const _deleteWordEndLeft = new DeleteWordEndLeft();
@@ -39,6 +43,12 @@ suite('WordOperations', () => {
function cursorWordLeft(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordLeftSelect : _cursorWordLeft);
}
function cursorWordAccessibilityLeft(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordAccessibilityLeft : _cursorWordAccessibilityLeftSelect);
}
function cursorWordAccessibilityRight(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordAccessibilityRightSelect : _cursorWordAccessibilityRight);
}
function cursorWordStartLeft(editor: ICodeEditor, inSelectionMode: boolean = false): void {
runEditorCommand(editor, inSelectionMode ? _cursorWordStartLeftSelect : _cursorWordStartLeft);
}
@@ -326,6 +336,34 @@ suite('WordOperations', () => {
assert.deepEqual(actual, EXPECTED);
});
test('cursorWordAccessibilityLeft', () => {
const EXPECTED = ['| /* |Just |some |more |text |a+= |3 +|5-|3 + |7 */ '].join('\n');
const [text,] = deserializePipePositions(EXPECTED);
const actualStops = testRepeatedActionAndExtractPositions(
text,
new Position(1000, 1000),
ed => cursorWordAccessibilityLeft(ed),
ed => ed.getPosition()!,
ed => ed.getPosition()!.equals(new Position(1, 1))
);
const actual = serializePipePositions(text, actualStops);
assert.deepEqual(actual, EXPECTED);
});
test('cursorWordAccessibilityRight', () => {
const EXPECTED = [' /* Just| some| more| text| a|+= 3| +5|-3| + 7| */ |'].join('\n');
const [text,] = deserializePipePositions(EXPECTED);
const actualStops = testRepeatedActionAndExtractPositions(
text,
new Position(1, 1),
ed => cursorWordAccessibilityRight(ed),
ed => ed.getPosition()!,
ed => ed.getPosition()!.equals(new Position(1, 50))
);
const actual = serializePipePositions(text, actualStops);
assert.deepEqual(actual, EXPECTED);
});
test('deleteWordLeft for non-empty selection', () => {
withTestCodeEditor([
' \tMy First Line\t ',

View File

@@ -18,6 +18,9 @@ import { ScrollType } from 'vs/editor/common/editorCommon';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { ITextModel } from 'vs/editor/common/model';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { EDITOR_DEFAULTS } from 'vs/editor/common/config/editorOptions';
export interface MoveWordOptions extends ICommandOptions {
inSelectionMode: boolean;
@@ -170,6 +173,48 @@ export class CursorWordLeftSelect extends WordLeftCommand {
}
}
export class CursorWordAccessibilityLeft extends WordLeftCommand {
constructor() {
super({
inSelectionMode: false,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilityLeft',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyCode.LeftArrow,
mac: { primary: KeyMod.Alt | KeyCode.LeftArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}
export class CursorWordAccessibilityLeftSelect extends WordLeftCommand {
constructor() {
super({
inSelectionMode: true,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilitLeftSelecty',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow,
mac: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.LeftArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}
export class CursorWordStartRight extends WordRightCommand {
constructor() {
super({
@@ -248,6 +293,48 @@ export class CursorWordRightSelect extends WordRightCommand {
}
}
export class CursorWordAccessibilityRight extends WordRightCommand {
constructor() {
super({
inSelectionMode: false,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilityRight',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyCode.RightArrow,
mac: { primary: KeyMod.Alt | KeyCode.RightArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}
export class CursorWordAccessibilityRightSelect extends WordRightCommand {
constructor() {
super({
inSelectionMode: true,
wordNavigationType: WordNavigationType.WordAccessibility,
id: 'cursorWordAccessibilityRightSelect',
precondition: undefined,
kbOpts: {
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow,
mac: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.RightArrow },
weight: KeybindingWeight.EditorContrib + 1
}
});
}
protected _move(_: WordCharacterClassifier, model: ITextModel, position: Position, wordNavigationType: WordNavigationType): Position {
return super._move(getMapForWordSeparators(EDITOR_DEFAULTS.wordSeparators), model, position, wordNavigationType);
}
}
export interface DeleteWordOptions extends ICommandOptions {
whitespaceHeuristics: boolean;
wordNavigationType: WordNavigationType;
@@ -397,6 +484,10 @@ registerEditorCommand(new CursorWordRight());
registerEditorCommand(new CursorWordStartRightSelect());
registerEditorCommand(new CursorWordEndRightSelect());
registerEditorCommand(new CursorWordRightSelect());
registerEditorCommand(new CursorWordAccessibilityLeft());
registerEditorCommand(new CursorWordAccessibilityLeftSelect());
registerEditorCommand(new CursorWordAccessibilityRight());
registerEditorCommand(new CursorWordAccessibilityRightSelect());
registerEditorCommand(new DeleteWordStartLeft());
registerEditorCommand(new DeleteWordEndLeft());
registerEditorCommand(new DeleteWordLeft());

View File

@@ -4740,6 +4740,37 @@ suite('autoClosingPairs', () => {
mode.dispose();
});
test('issue #78833 - Add config to use old brackets/quotes overtyping', () => {
let mode = new AutoClosingMode();
usingCursor({
text: [
'',
'y=();'
],
languageIdentifier: mode.getLanguageIdentifier(),
editorOpts: {
autoClosingOvertype: 'always'
}
}, (model, cursor) => {
assertCursor(cursor, new Position(1, 1));
cursorCommand(cursor, H.Type, { text: 'x=(' }, 'keyboard');
assert.strictEqual(model.getLineContent(1), 'x=()');
cursorCommand(cursor, H.Type, { text: ')' }, 'keyboard');
assert.strictEqual(model.getLineContent(1), 'x=()');
cursor.setSelections('test', [new Selection(1, 4, 1, 4)]);
cursorCommand(cursor, H.Type, { text: ')' }, 'keyboard');
assert.strictEqual(model.getLineContent(1), 'x=()');
cursor.setSelections('test', [new Selection(2, 4, 2, 4)]);
cursorCommand(cursor, H.Type, { text: ')' }, 'keyboard');
assert.strictEqual(model.getLineContent(2), 'y=();');
});
mode.dispose();
});
test('issue #15825: accents on mac US intl keyboard', () => {
let mode = new AutoClosingMode();
usingCursor({

View File

@@ -109,9 +109,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
[
'<div>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #0000ff;text-decoration: underline;">world!</span>',
'</div>'
].join('')
@@ -122,9 +122,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
[
'<div>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #0000ff;text-decoration: underline;">w</span>',
'</div>'
].join('')
@@ -135,9 +135,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
[
'<div>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'</div>'
].join('')
);
@@ -147,9 +147,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
[
'<div>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">iao</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'</div>'
].join('')
);
@@ -158,9 +158,9 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
tokenizeLineToHTML(text, lineTokens, colorMap, 4, 11, 4),
[
'<div>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'</div>'
].join('')
);
@@ -170,7 +170,7 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
[
'<div>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'</div>'
].join('')
);
@@ -241,11 +241,11 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
tokenizeLineToHTML(text, lineTokens, colorMap, 0, 21, 4),
[
'<div>',
'<span style="color: #000000;">&nbsp&nbsp</span>',
'<span style="color: #000000;">&nbsp;&nbsp;</span>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
'<span style="color: #000000;">&nbsp&nbsp&nbsp</span>',
'<span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #0000ff;text-decoration: underline;">world!</span>',
'</div>'
].join('')
@@ -255,11 +255,11 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
tokenizeLineToHTML(text, lineTokens, colorMap, 0, 17, 4),
[
'<div>',
'<span style="color: #000000;">&nbsp&nbsp</span>',
'<span style="color: #000000;">&nbsp;&nbsp;</span>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">Ciao</span>',
'<span style="color: #000000;">&nbsp&nbsp&nbsp</span>',
'<span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span>',
'<span style="color: #00ff00;">hello</span>',
'<span style="color: #000000;">&nbsp</span>',
'<span style="color: #000000;">&nbsp;</span>',
'<span style="color: #0000ff;text-decoration: underline;">wo</span>',
'</div>'
].join('')
@@ -269,7 +269,7 @@ suite('Editor Modes - textToHtmlTokenizer', () => {
tokenizeLineToHTML(text, lineTokens, colorMap, 0, 3, 4),
[
'<div>',
'<span style="color: #000000;">&nbsp&nbsp</span>',
'<span style="color: #000000;">&nbsp;&nbsp;</span>',
'<span style="color: #ff0000;font-style: italic;font-weight: bold;">C</span>',
'</div>'
].join('')