mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-09 01:32:34 -05:00
Merge VS Code 1.26.1 (#2394)
* Squash merge commits for 1.26 (#1) (#2323) * Polish tag search as per feedback (#55269) * Polish tag search as per feedback * Updated regex * Allow users to opt-out of features that send online requests in the background (#55097) * settings sweep #54690 * Minor css tweaks to enable eoverflow elipsis in more places (#55277) * fix an issue with titlebarheight when not scaling with zoom * Settings descriptions update #54690 * fixes #55209 * Settings editor - many padding fixes * More space above level 2 label * Fixing Cannot debug npm script using Yarn #55103 * Settings editor - show ellipsis when description overflows * Settings editor - ... fix measuring around links, relayout * Setting descriptions * Settings editor - fix ... for some short lines, fix select container width * Settings editor - overlay trees so scrollable shadow is full width * Fix #54133 - missing extension settings after reload * Settings color token description tweak * Settings editor - disable overflow indicator temporarily, needs to be faster * Added command to Run the selected npm script * fixes #54452 * fixes #54929 * fixes #55248 * prefix command with extension name * Contribute run selected to the context menu * node-debug@1.26.6 * Allow terminal rendererType to be swapped out at runtime Part of #53274 Fixes #55344 * Settings editor - fix not focusing search when restoring editor setInput must be actually async. Will be fixed naturally when we aren't using winJS promises... * Settings editor - TOC should only expand the section with a selected item * Bump node-debug2 * Settings editor - Tree focus outlines * Settings editor - don't blink the scrollbar when toc selection changes And hide TOC correctly when the editor is narrow * Settings editor - header rows should not be selectable * fixes #54877 * change debug assignee to isi * Settings sweep (#54690) * workaround for #55051 * Settings sweep (#54690) * settings sweep #54690 * Don't try closing tags when you type > after another > * Describe what implementation code lens does Fixes #55370 * fix javadoc formatter setting description * fixes #55325 * update to officical TS version * Settings editor - Even more padding, use semibold instead of bold * Fix #55357 - fix TOC twistie * fixes #55288 * explorer: refresh on di change file system provider registration fixes #53256 * Disable push to Linux repo to test standalone publisher * New env var to notify log level to extensions #54001 * Disable snippets in extension search (when not in suggest dropdown) (#55281) * Disable snippits in extension search (when not in suggest dropdown) * Add monaco input contributions * Fix bug preventing snippetSuggestions from taking effect in sub-editors * Latest emmet helper to fix #52366 * Fix comment updates for threads within same file * Allow extensions to log telemetry to log files #54001 * Pull latest css grammar * files.exclude control - use same style for "add" vs "edit" * files.exclude control - focus/keyboard behavior * don't show menubar too early * files.exclude - better styling * Place cursor at end of extensions search box on autofill (#55254) * Place cursor at end of extensions search box on autofill * Use position instead of selection * fix linux build issue (empty if block) * Settings editor - fix extension category prefixes * Settings editor - add simple ellipsis for first line that overflows, doesn't cover case when first line does not overflow but there is more text, TODO * File/Text search provider docs * Fixes #52655 * Include epoch (#55008) * Fixes #53385 * Fixes #49480 * VS Code Insiders (Users) not opening Fixes #55353 * Better handling of the case when the extension host fails to start * Fixes #53966 * Remove confusing Start from wordPartLeft commands ID * vscode-xterm@3.6.0-beta12 Fixes #55488 * Initial size is set to infinity!! Fixes #55461 * Polish embeddedEditorBackground * configuration service misses event * Fix #55224 - fix duplicate results in multiroot workspace from splitting the diskseach query * Select all not working in issue reporter on mac, fixes #55424 * Disable fuzzy matching for extensions autosuggest (#55498) * Fix clipping of extensions search border in some third party themes (#55504) * fixes #55538 * Fix bug causing an aria alert to not be shown the third time (and odd numbers thereafter) * Settings editor - work around rendering glitch with webkit-line-clamp * Settings editor - revert earlier '...' changes * Settings editor - move enumDescription to its own div, because it disturbs -webkit-line-clamp for some reason * Settings editor - better overflow indicator * Don't show existing filters in autocomplete (#55495) * Dont show existing filters in autocomplete * Simplify * Settings Editor: Add aria labels for input elements Fixes: #54836 (#55543) * fixes #55223 * Update vscode-css-languageservice to 3.0.10-next.1 * Fix #55509 - settings navigation * Fix #55519 * Fix #55520 * FIx #55524 * Fix #55556 - include wordSeparators in all search queries, so findTextInFiles can respect isWordMatch correctly * oss updates for endgame * Fix unit tests * fixes #55522 * Avoid missing manifest error from bubbling up #54757 * Settings format crawl * Search provider - Fix FileSearchProvider to return array, not progress * Fix #55598 * Settings editor - fix NPE rendering settings with no description * dont render inden guides in search box (#55600) * fixes #55454 * More settings crawl * Another change for #55598 - maxResults applies to FileSearch and TextSearch but not FileIndex * Fix FileSearchProvider unit tests for progress change * fixes #55561 * Settings description update for #54690 * Update setting descriptions for online services * Minor edits * fixes #55513 * fixes #55451 * Fix #55612 - fix findTextInFiles cancellation * fixes #55539 * More setting description tweaks * Setting to disable online experiments #54354 * fixes #55507 * fixes #55515 * Show online services action only in Insiders for now * Settings editor - change toc behavior default to 'filter' * Settings editor - nicer filter count style during search * Fix #55617 - search viewlet icons * Settings editor - better styling for element count indicator * SearchProvider - fix NPE when searching extraFileResources * Allow extends to work without json suffix Fixes #16905 * Remove accessability options logic entirely Follow up on #55451 * use latest version of DAP * fixes #55490 * fixes #55122 * fixes #52332 * Avoid assumptions about git: URIs (fixes #36236) * relative path for descriptions * resourece: get rid of isFile context key fixes #48275 * Register previous ids for compatibility (#53497) * more tuning for #48275 * no need to always re-read "files explorer" fixes #52003 * read out active composites properly fixes #51967 * Update link colors for hc theme to meet color contrast ratio, fixes #55651 Also updated link color for `textLinkActiveForeground` to be the same as `textLinkForeground` as it wasn't properly updated * detect 'winpty-agent.exe'; fixes #55672 * node-debug@1.26.7 * reset counter on new label * Settings editor - fix multiple setting links in one description * Settings editor - color code blocks in setting descriptions, fix #55532 * Settings editor - hover color in TOC * Settings editor - fix navigation NPE * Settings editor - fix text control width * Settings editor - maybe fix #55684 * Fix bug causing cursor to not move on paste * fixes #53582 * Use ctrlCmd instead of ctrl for go down from search box * fixes #55264 * fixes #55456 * filter for spcaes before triggering search (#55611) * Fix #55698 - don't lose filtered TOC counts when refreshing TOC * fixes #55421 * fixes #28979 * fixes #55576 * only add check for updates to windows/linux help * readonly files: append decoration to label fixes #53022 * debug: do not show toolbar while initialising fixes #55026 * Opening launch.json should not activate debug extensions fixes #55029 * fixes #55435 * fixes #55434 * fixes #55439 * trigger menu only on altkey up * Fix #50555 - fix settings editor memory leak * Fix #55712 - no need to focus 'a' anymore when restoring control focus after tree render * fixes #55335 * proper fix for readonly model fixes #53022 * improve FoldingRangeKind spec (for #55686) * Use class with static fields (fixes #55494) * Fixes #53671 * fixes #54630 * [html] should disable ionic suggestions by default. Currently forces deprecated Ionic v1 suggestions in .html files while typing. Fixes #53324 * cleanup deps * debug issues back to andre * update electron for smoketest * Fix #55757 - prevent settings tabs from overflowing * Fix #53897 - revert setting menu defaults to old editor * Add enum descriptions to `typescript.preferences.importModuleSpecifier` * Fix #55767 - leaking style elements from settings editor * Fix #55521 - prevent flashing when clicking in exclude control * Update Git modified color for contrast ratio, fixes #53140 * Revert "Merge branch 'master' of github.com:Microsoft/vscode" This reverts commit bf46b6bfbae0cab99c2863e1244a916181fa9fbc, reversing changes made to e275a424483dfb4ed33b428c97d5e2c441d6b917. * Revert "Revert "Merge branch 'master' of github.com:Microsoft/vscode"" This reverts commit 53949d963f39e40757557c6526332354a31d9154. * don't ask to install an incomplete menu * Fix NPE in terminal AccessibilityManager Fixes #55744 * don't display fallback menu unless we've closed the last window * fixes #55547 * Fix smoke tests for extension search box * Update OSSREADME.json for Electron 2.0.5 * Update distro Includes Chromium license changes * fix #55455 * fix #55865 * fixes #55893 * Fix bug causing workspace recommendations to go away upon ignoring a recommendation (#55805) * Fix bug causing workspace recommendations to go away upon ignoring a recommendation * ONly show on @recommended or @recommended:workspace * Make more consistant * Fix #55911 * Understand json activity (#55926) * Understand json file activity * Refactoring * adding composer.json * Distro update for experiments * use terminal.processId for auto-attach; fixes #55918 * Reject invalid URI with vscode.openFolder (for #55891) * improve win32 setup system vs user detection fixes #55840 fixes #55840 delay winreg import related to #55840 show notification earlier related to #55840 fix #55840 update inno setup message related to #55840 * Fix #55593 - this code only operates on local paths, so use fsPath and Uri.file instead * Bring back the old menu due to electron 2.0 issues (#55913) * add the old menu back for native menus * make menu labels match * `vscode.openFolder`: treat missing URI schema gracefully (for #55891) * delay EH reattach; fixes #55955 * Mark all json files under appSettingsHome as settings * Use localized strings for telemetry opt-out * Exception when saving file editor opened from remote file provider (fixes #55051) * Remove terminal menu from stable Fixes 56003 * VSCode Insiders crashes on open with TypeError: Cannot read property 'lastIndexOf' of undefined. Fixes #54933 * improve fix for #55891 * fix #55916 * Improve #55891 * increase EH debugging restart delay; fixes #55955 * Revert "Don't include non-resource entries in history quick pick" This reverts commit 37209a838e9f7e9abe6dc53ed73cdf1e03b72060. * Diff editor: horizontal scrollbar height is smaller (fixes #56062) * improve openFolder uri fix (correctly treat backslashes) * fixes #56116 repair ipc for native menubar keybindings * Fix #56240 - Open the JSON settings editor instead of the UI editor * Fix #55536 * uriDisplay: if no formatter is registered fall back to getPathlabel fixes #56104 * VSCode hangs when opening python file. Fixes #56377 * VS Code Hangs When Opening Specific PowerShell File. Fixes #56430 * Fix #56433 - search extraFileResources even when no folders open * Workaround #55649 * Fix in master #56371 * Fix tests #56371 * Fix in master #56317 * increase version to 1.26.1 * Fixes #56387: Handle SIGPIPE in extension host * fixes #56185 * Fix merge issues (part 1) * Fix build breaks (part 1) * Build breaks (part 2) * Build breaks (part 3) * More build breaks (part 4) * Fix build breaks (part 5) * WIP * Fix menus * Render query result and message panels (#2363) * Put back query editor hot exit changes * Fix grid changes that broke profiler (#2365) * Update APIs for saving query editor state * Fix restore view state for profiler and edit data * Updating custom default themes to support 4.5:1 contrast ratio * Test updates * Fix Extension Manager and Windows Setup * Update license headers * Add appveyor and travis files back * Fix hidden modal dropdown issue
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { EditorAction, EditorExtensionsRegistry, IEditorContributionCtor } from 'vs/editor/browser/editorExtensions';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export class CodeEditor extends CodeEditorWidget {
|
||||
|
||||
constructor(
|
||||
domElement: HTMLElement,
|
||||
options: IEditorOptions,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ICodeEditorService codeEditorService: ICodeEditorService,
|
||||
@ICommandService commandService: ICommandService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super(domElement, options, false, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService);
|
||||
}
|
||||
|
||||
protected _getContributions(): IEditorContributionCtor[] {
|
||||
return EditorExtensionsRegistry.getEditorContributions();
|
||||
}
|
||||
|
||||
protected _getActions(): EditorAction[] {
|
||||
return EditorExtensionsRegistry.getEditorActions();
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
@@ -16,19 +17,19 @@ import { registerEditorCommand, ICommandOptions, EditorCommand, Command } from '
|
||||
import { IColumnSelectResult, ColumnSelection } from 'vs/editor/common/controller/cursorColumnSelection';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import H = editorCommon.Handler;
|
||||
import { ICodeEditorService, getCodeEditor } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { IEditorService } from 'vs/platform/editor/common/editor';
|
||||
import { TypeOperations } from 'vs/editor/common/controller/cursorTypeOperations';
|
||||
import { DeleteOperations } from 'vs/editor/common/controller/cursorDeleteOperations';
|
||||
import { VerticalRevealType } from 'vs/editor/common/view/viewEvents';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
|
||||
const CORE_WEIGHT = KeybindingsRegistry.WEIGHT.editorCore();
|
||||
const CORE_WEIGHT = KeybindingWeight.EditorCore;
|
||||
|
||||
export abstract class CoreEditorCommand extends EditorCommand {
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void {
|
||||
@@ -704,10 +705,6 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newState: CursorState;
|
||||
if (args.wholeLine) {
|
||||
newState = CursorMoveCommands.line(context, cursors.getPrimaryCursor(), false, args.position, args.viewPosition);
|
||||
@@ -769,10 +766,6 @@ export namespace CoreNavigationCommands {
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastAddedCursorIndex = cursors.getLastAddedCursorIndex();
|
||||
|
||||
let newStates = cursors.getAll().slice(0);
|
||||
@@ -1251,9 +1244,6 @@ export namespace CoreNavigationCommands {
|
||||
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastAddedCursorIndex = cursors.getLastAddedCursorIndex();
|
||||
|
||||
@@ -1312,12 +1302,6 @@ export namespace CoreNavigationCommands {
|
||||
}
|
||||
|
||||
public runCoreEditorCommand(cursors: ICursors, args: any): void {
|
||||
const context = cursors.context;
|
||||
|
||||
if (context.config.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lastAddedCursorIndex = cursors.getLastAddedCursorIndex();
|
||||
|
||||
let newStates = cursors.getAll().slice(0);
|
||||
@@ -1637,14 +1621,8 @@ function findFocusedEditor(accessor: ServicesAccessor): ICodeEditor {
|
||||
return accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
}
|
||||
|
||||
function getWorkbenchActiveEditor(accessor: ServicesAccessor): ICodeEditor {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
let activeEditor = (<any>editorService).getActiveEditor && (<any>editorService).getActiveEditor();
|
||||
return getCodeEditor(activeEditor);
|
||||
}
|
||||
|
||||
function registerCommand(command: Command) {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule(command.toCommandAndKeybindingRule(CORE_WEIGHT));
|
||||
command.register();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1668,7 +1646,7 @@ class EditorOrNativeTextInputCommand extends Command {
|
||||
|
||||
let focusedEditor = findFocusedEditor(accessor);
|
||||
// Only if editor text focus (i.e. not if editor has widget focus).
|
||||
if (focusedEditor && focusedEditor.isFocused()) {
|
||||
if (focusedEditor && focusedEditor.hasTextFocus()) {
|
||||
return this._runEditorHandler(focusedEditor, args);
|
||||
}
|
||||
|
||||
@@ -1679,8 +1657,8 @@ class EditorOrNativeTextInputCommand extends Command {
|
||||
return;
|
||||
}
|
||||
|
||||
// Redirecting to last active editor
|
||||
let activeEditor = getWorkbenchActiveEditor(accessor);
|
||||
// Redirecting to active editor
|
||||
let activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
|
||||
if (activeEditor) {
|
||||
activeEditor.focus();
|
||||
return this._runEditorHandler(activeEditor, args);
|
||||
@@ -1728,11 +1706,17 @@ registerCommand(new EditorOrNativeTextInputCommand({
|
||||
editorHandler: CoreNavigationCommands.SelectAll,
|
||||
inputHandler: 'selectAll',
|
||||
id: 'editor.action.selectAll',
|
||||
precondition: null,
|
||||
precondition: EditorContextKeys.textInputFocus,
|
||||
kbOpts: {
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: null,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_A
|
||||
},
|
||||
menubarOpts: {
|
||||
menuId: MenuId.MenubarSelectionMenu,
|
||||
group: '1_basic',
|
||||
title: nls.localize({ key: 'miSelectAll', comment: ['&& denotes a mnemonic'] }, "&&Select All"),
|
||||
order: 1
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -1745,6 +1729,12 @@ registerCommand(new EditorOrNativeTextInputCommand({
|
||||
weight: CORE_WEIGHT,
|
||||
kbExpr: EditorContextKeys.textInputFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_Z
|
||||
},
|
||||
menubarOpts: {
|
||||
menuId: MenuId.MenubarEditMenu,
|
||||
group: '1_do',
|
||||
title: nls.localize({ key: 'miUndo', comment: ['&& denotes a mnemonic'] }, "&&Undo"),
|
||||
order: 1
|
||||
}
|
||||
}));
|
||||
registerCommand(new EditorHandlerCommand('default:' + H.Undo, H.Undo));
|
||||
@@ -1760,6 +1750,12 @@ registerCommand(new EditorOrNativeTextInputCommand({
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KEY_Y,
|
||||
secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z],
|
||||
mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z }
|
||||
},
|
||||
menubarOpts: {
|
||||
menuId: MenuId.MenubarEditMenu,
|
||||
group: '1_do',
|
||||
title: nls.localize({ key: 'miRedo', comment: ['&& denotes a mnemonic'] }, "&&Redo"),
|
||||
order: 2
|
||||
}
|
||||
}));
|
||||
registerCommand(new EditorHandlerCommand('default:' + H.Redo, H.Redo));
|
||||
|
||||
@@ -28,6 +28,7 @@ export interface IViewZoneData {
|
||||
|
||||
export interface IMarginData {
|
||||
isAfterLines: boolean;
|
||||
glyphMarginLeft: number;
|
||||
glyphMarginWidth: number;
|
||||
lineNumbersWidth: number;
|
||||
offsetX: number;
|
||||
@@ -602,6 +603,7 @@ export class MouseTargetFactory {
|
||||
let offset = Math.abs(request.pos.x - request.editorPos.x);
|
||||
const detail: IMarginData = {
|
||||
isAfterLines: res.isAfterLines,
|
||||
glyphMarginLeft: ctx.layoutInfo.glyphMarginLeft,
|
||||
glyphMarginWidth: ctx.layoutInfo.glyphMarginWidth,
|
||||
lineNumbersWidth: ctx.layoutInfo.lineNumbersWidth,
|
||||
offsetX: offset
|
||||
|
||||
@@ -126,7 +126,8 @@ export class TextAreaInput extends Disposable {
|
||||
this._nextCommand = ReadFromTextArea.Type;
|
||||
|
||||
this._register(dom.addStandardDisposableListener(textArea.domNode, 'keydown', (e: IKeyboardEvent) => {
|
||||
if (this._isDoingComposition && e.keyCode === KeyCode.KEY_IN_COMPOSITION) {
|
||||
if (this._isDoingComposition &&
|
||||
(e.keyCode === KeyCode.KEY_IN_COMPOSITION || e.keyCode === KeyCode.Backspace)) {
|
||||
// Stop propagation for keyDown events if the IME is processing key input
|
||||
e.stopPropagation();
|
||||
}
|
||||
@@ -204,15 +205,6 @@ export class TextAreaInput extends Disposable {
|
||||
this._register(dom.addDisposableListener(textArea.domNode, 'compositionupdate', (e: CompositionEvent) => {
|
||||
this._lastTextAreaEvent = TextAreaInputEventType.compositionupdate;
|
||||
|
||||
if (browser.isChromev56) {
|
||||
// See https://github.com/Microsoft/monaco-editor/issues/320
|
||||
// where compositionupdate .data is broken in Chrome v55 and v56
|
||||
// See https://bugs.chromium.org/p/chromium/issues/detail?id=677050#c9
|
||||
// The textArea doesn't get the composition update yet, the value of textarea is still obsolete
|
||||
// so we can't correct e at this moment.
|
||||
return;
|
||||
}
|
||||
|
||||
if (compositionDataInValid(e.locale)) {
|
||||
const [newState, typeInput] = deduceInputFromTextAreaValue(/*couldBeEmojiInput*/false, /*couldBeTypingAtOffset0*/false);
|
||||
this._textAreaState = newState;
|
||||
@@ -265,17 +257,6 @@ export class TextAreaInput extends Disposable {
|
||||
this._textArea.setIgnoreSelectionChangeTime('received input event');
|
||||
|
||||
if (this._isDoingComposition) {
|
||||
// See https://github.com/Microsoft/monaco-editor/issues/320
|
||||
if (browser.isChromev56) {
|
||||
const [newState, typeInput] = deduceComposition(this._textArea.getValue());
|
||||
this._textAreaState = newState;
|
||||
|
||||
this._onType.fire(typeInput);
|
||||
let e: ICompositionData = {
|
||||
data: typeInput.text
|
||||
};
|
||||
this._onCompositionUpdate.fire(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -286,7 +267,6 @@ export class TextAreaInput extends Disposable {
|
||||
}
|
||||
|
||||
this._textAreaState = newState;
|
||||
// console.log('==> DEDUCED INPUT: ' + JSON.stringify(typeInput));
|
||||
if (this._nextCommand === ReadFromTextArea.Type) {
|
||||
if (typeInput.text !== '') {
|
||||
this._onType.fire(typeInput);
|
||||
@@ -501,7 +481,7 @@ export class TextAreaInput extends Disposable {
|
||||
}
|
||||
|
||||
let copyHTML: string = null;
|
||||
if (!browser.isEdgeOrIE && (copyPlainText.length < 65536 || CopyOptions.forceCopyWithSyntaxHighlighting)) {
|
||||
if (browser.hasClipboardSupport() && (copyPlainText.length < 65536 || CopyOptions.forceCopyWithSyntaxHighlighting)) {
|
||||
copyHTML = this._host.getHTMLToCopy();
|
||||
}
|
||||
ClipboardEventUtils.setTextData(e, copyPlainText, copyHTML);
|
||||
|
||||
@@ -121,7 +121,7 @@ export class TextAreaState {
|
||||
// See https://github.com/Microsoft/vscode/issues/42251
|
||||
// where typing always happens at offset 0 in the textarea
|
||||
// when using a custom title area in OSX and moving the window
|
||||
if (strings.endsWith(currentValue, previousValue)) {
|
||||
if (!strings.startsWith(currentValue, previousValue) && strings.endsWith(currentValue, previousValue)) {
|
||||
// Looks like something was typed at offset 0
|
||||
// ==> pretend we placed the cursor at offset 0 to begin with...
|
||||
previousSelectionStart = 0;
|
||||
|
||||
@@ -53,6 +53,11 @@ export interface IViewZone {
|
||||
* If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen.
|
||||
*/
|
||||
heightInPx?: number;
|
||||
/**
|
||||
* The minimum width in px of the view zone.
|
||||
* If this is set, the editor will ensure that the scroll width is >= than this value.
|
||||
*/
|
||||
minWidthInPx?: number;
|
||||
/**
|
||||
* The dom node of the view zone
|
||||
*/
|
||||
@@ -360,12 +365,12 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
*/
|
||||
onDidChangeModelDecorations(listener: (e: IModelDecorationsChangedEvent) => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when the text inside this editor gained focus (i.e. cursor blinking).
|
||||
* An event emitted when the text inside this editor gained focus (i.e. cursor starts blinking).
|
||||
* @event
|
||||
*/
|
||||
onDidFocusEditorText(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when the text inside this editor lost focus.
|
||||
* An event emitted when the text inside this editor lost focus (i.e. cursor stops blinking).
|
||||
* @event
|
||||
*/
|
||||
onDidBlurEditorText(listener: () => void): IDisposable;
|
||||
@@ -373,12 +378,12 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* An event emitted when the text inside this editor or an editor widget gained focus.
|
||||
* @event
|
||||
*/
|
||||
onDidFocusEditor(listener: () => void): IDisposable;
|
||||
onDidFocusEditorWidget(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted when the text inside this editor or an editor widget lost focus.
|
||||
* @event
|
||||
*/
|
||||
onDidBlurEditor(listener: () => void): IDisposable;
|
||||
onDidBlurEditorWidget(listener: () => void): IDisposable;
|
||||
/**
|
||||
* An event emitted before interpreting typed characters (on the keyboard).
|
||||
* @event
|
||||
@@ -472,7 +477,7 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
restoreViewState(state: editorCommon.ICodeEditorViewState): void;
|
||||
|
||||
/**
|
||||
* Returns true if this editor or one of its widgets has keyboard focus.
|
||||
* Returns true if the text inside this editor or an editor widget has focus.
|
||||
*/
|
||||
hasWidgetFocus(): boolean;
|
||||
|
||||
@@ -573,9 +578,9 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
||||
* The edits will land on the undo-redo stack, but no "undo stop" will be pushed.
|
||||
* @param source The source of the call.
|
||||
* @param edits The edits to execute.
|
||||
* @param endCursoState Cursor state after the edits were applied.
|
||||
* @param endCursorState Cursor state after the edits were applied.
|
||||
*/
|
||||
executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursoState?: Selection[]): boolean;
|
||||
executeEdits(source: string, edits: IIdentifiedSingleEditOperation[], endCursorState?: Selection[]): boolean;
|
||||
|
||||
/**
|
||||
* Execute multiple (concommitent) commands on the editor.
|
||||
@@ -834,3 +839,18 @@ export function isDiffEditor(thing: any): thing is IDiffEditor {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*@internal
|
||||
*/
|
||||
export function getCodeEditor(thing: any): ICodeEditor {
|
||||
if (isCodeEditor(thing)) {
|
||||
return thing;
|
||||
}
|
||||
|
||||
if (isDiffEditor(thing)) {
|
||||
return thing.getModifiedEditor();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -14,13 +14,11 @@ import { GlobalMouseMoveMonitor } from 'vs/base/browser/globalMouseMoveMonitor';
|
||||
*/
|
||||
export class PageCoordinates {
|
||||
_pageCoordinatesBrand: void;
|
||||
public readonly x: number;
|
||||
public readonly y: number;
|
||||
|
||||
constructor(x: number, y: number) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
constructor(
|
||||
public readonly x: number,
|
||||
public readonly y: number
|
||||
) { }
|
||||
|
||||
public toClientCoordinates(): ClientCoordinates {
|
||||
return new ClientCoordinates(this.x - dom.StandardWindow.scrollX, this.y - dom.StandardWindow.scrollY);
|
||||
@@ -37,13 +35,10 @@ export class PageCoordinates {
|
||||
export class ClientCoordinates {
|
||||
_clientCoordinatesBrand: void;
|
||||
|
||||
public readonly clientX: number;
|
||||
public readonly clientY: number;
|
||||
|
||||
constructor(clientX: number, clientY: number) {
|
||||
this.clientX = clientX;
|
||||
this.clientY = clientY;
|
||||
}
|
||||
constructor(
|
||||
public readonly clientX: number,
|
||||
public readonly clientY: number
|
||||
) { }
|
||||
|
||||
public toPageCoordinates(): PageCoordinates {
|
||||
return new PageCoordinates(this.clientX + dom.StandardWindow.scrollX, this.clientY + dom.StandardWindow.scrollY);
|
||||
@@ -56,17 +51,12 @@ export class ClientCoordinates {
|
||||
export class EditorPagePosition {
|
||||
_editorPagePositionBrand: void;
|
||||
|
||||
public readonly x: number;
|
||||
public readonly y: number;
|
||||
public readonly width: number;
|
||||
public readonly height: number;
|
||||
|
||||
constructor(x: number, y: number, width: number, height: number) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
constructor(
|
||||
public readonly x: number,
|
||||
public readonly y: number,
|
||||
public readonly width: number,
|
||||
public readonly height: number
|
||||
) { }
|
||||
}
|
||||
|
||||
export function createEditorPagePosition(editorViewDomNode: HTMLElement): EditorPagePosition {
|
||||
|
||||
@@ -9,18 +9,18 @@ import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ServicesAccessor, IConstructorSignature1 } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
|
||||
import { KeybindingsRegistry, ICommandAndKeybindingRule, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeybindingsRegistry, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { MenuId, MenuRegistry, IMenuItem } from 'vs/platform/actions/common/actions';
|
||||
import { IEditorService } from 'vs/platform/editor/common/editor';
|
||||
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService, getCodeEditor } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
|
||||
export type ServicesAccessor = ServicesAccessor;
|
||||
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, editorCommon.IEditorContribution>;
|
||||
@@ -29,53 +29,83 @@ export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, editor
|
||||
|
||||
export interface ICommandKeybindingsOptions extends IKeybindings {
|
||||
kbExpr?: ContextKeyExpr;
|
||||
weight?: number;
|
||||
weight: number;
|
||||
}
|
||||
export interface ICommandMenubarOptions {
|
||||
menuId: MenuId;
|
||||
group: string;
|
||||
order: number;
|
||||
when?: ContextKeyExpr;
|
||||
title: string;
|
||||
}
|
||||
export interface ICommandOptions {
|
||||
id: string;
|
||||
precondition: ContextKeyExpr;
|
||||
kbOpts?: ICommandKeybindingsOptions;
|
||||
description?: ICommandHandlerDescription;
|
||||
menubarOpts?: ICommandMenubarOptions;
|
||||
}
|
||||
export abstract class Command {
|
||||
public readonly id: string;
|
||||
public readonly precondition: ContextKeyExpr;
|
||||
private readonly _kbOpts: ICommandKeybindingsOptions;
|
||||
private readonly _menubarOpts: ICommandMenubarOptions;
|
||||
private readonly _description: ICommandHandlerDescription;
|
||||
|
||||
constructor(opts: ICommandOptions) {
|
||||
this.id = opts.id;
|
||||
this.precondition = opts.precondition;
|
||||
this._kbOpts = opts.kbOpts;
|
||||
this._menubarOpts = opts.menubarOpts;
|
||||
this._description = opts.description;
|
||||
}
|
||||
|
||||
public toCommandAndKeybindingRule(defaultWeight: number): ICommandAndKeybindingRule {
|
||||
const kbOpts = this._kbOpts || { primary: 0 };
|
||||
public register(): void {
|
||||
|
||||
let kbWhen = kbOpts.kbExpr;
|
||||
if (this.precondition) {
|
||||
if (kbWhen) {
|
||||
kbWhen = ContextKeyExpr.and(kbWhen, this.precondition);
|
||||
} else {
|
||||
kbWhen = this.precondition;
|
||||
}
|
||||
if (this._menubarOpts) {
|
||||
MenuRegistry.appendMenuItem(this._menubarOpts.menuId, {
|
||||
group: this._menubarOpts.group,
|
||||
command: {
|
||||
id: this.id,
|
||||
title: this._menubarOpts.title,
|
||||
// precondition: this.precondition
|
||||
},
|
||||
when: this._menubarOpts.when,
|
||||
order: this._menubarOpts.order
|
||||
});
|
||||
}
|
||||
|
||||
const weight = (typeof kbOpts.weight === 'number' ? kbOpts.weight : defaultWeight);
|
||||
if (this._kbOpts) {
|
||||
let kbWhen = this._kbOpts.kbExpr;
|
||||
if (this.precondition) {
|
||||
if (kbWhen) {
|
||||
kbWhen = ContextKeyExpr.and(kbWhen, this.precondition);
|
||||
} else {
|
||||
kbWhen = this.precondition;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: this.id,
|
||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||
weight: weight,
|
||||
when: kbWhen,
|
||||
primary: kbOpts.primary,
|
||||
secondary: kbOpts.secondary,
|
||||
win: kbOpts.win,
|
||||
linux: kbOpts.linux,
|
||||
mac: kbOpts.mac,
|
||||
description: this._description
|
||||
};
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: this.id,
|
||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||
weight: this._kbOpts.weight,
|
||||
when: kbWhen,
|
||||
primary: this._kbOpts.primary,
|
||||
secondary: this._kbOpts.secondary,
|
||||
win: this._kbOpts.win,
|
||||
linux: this._kbOpts.linux,
|
||||
mac: this._kbOpts.mac,
|
||||
description: this._description
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: this.id,
|
||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||
description: this._description
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public abstract runCommand(accessor: ServicesAccessor, args: any): void | TPromise<void>;
|
||||
@@ -85,12 +115,6 @@ export abstract class Command {
|
||||
|
||||
//#region EditorCommand
|
||||
|
||||
function getWorkbenchActiveEditor(accessor: ServicesAccessor): ICodeEditor {
|
||||
const editorService = accessor.get(IEditorService);
|
||||
let activeEditor = (<any>editorService).getActiveEditor && (<any>editorService).getActiveEditor();
|
||||
return getCodeEditor(activeEditor);
|
||||
}
|
||||
|
||||
export interface IContributionCommandOptions<T> extends ICommandOptions {
|
||||
handler: (controller: T) => void;
|
||||
}
|
||||
@@ -124,14 +148,8 @@ export abstract class EditorCommand extends Command {
|
||||
public runCommand(accessor: ServicesAccessor, args: any): void | TPromise<void> {
|
||||
const codeEditorService = accessor.get(ICodeEditorService);
|
||||
|
||||
// Find the editor with text focus
|
||||
let editor = codeEditorService.getFocusedCodeEditor();
|
||||
|
||||
if (!editor) {
|
||||
// Fallback to use what the workbench considers the active editor
|
||||
editor = getWorkbenchActiveEditor(accessor);
|
||||
}
|
||||
|
||||
// Find the editor with text focus or active
|
||||
let editor = codeEditorService.getFocusedCodeEditor() || codeEditorService.getActiveCodeEditor();
|
||||
if (!editor) {
|
||||
// well, at least we tried...
|
||||
return;
|
||||
@@ -156,8 +174,8 @@ export abstract class EditorCommand extends Command {
|
||||
//#region EditorAction
|
||||
|
||||
export interface IEditorCommandMenuOptions {
|
||||
group?: string;
|
||||
order?: number;
|
||||
group: string;
|
||||
order: number;
|
||||
when?: ContextKeyExpr;
|
||||
}
|
||||
export interface IActionOptions extends ICommandOptions {
|
||||
@@ -178,20 +196,21 @@ export abstract class EditorAction extends EditorCommand {
|
||||
this.menuOpts = opts.menuOpts;
|
||||
}
|
||||
|
||||
public toMenuItem(): IMenuItem {
|
||||
if (!this.menuOpts) {
|
||||
return null;
|
||||
public register(): void {
|
||||
|
||||
if (this.menuOpts) {
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorContext, {
|
||||
command: {
|
||||
id: this.id,
|
||||
title: this.label
|
||||
},
|
||||
when: ContextKeyExpr.and(this.precondition, this.menuOpts.when),
|
||||
group: this.menuOpts.group,
|
||||
order: this.menuOpts.order
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
command: {
|
||||
id: this.id,
|
||||
title: this.label
|
||||
},
|
||||
when: ContextKeyExpr.and(this.precondition, this.menuOpts.when),
|
||||
group: this.menuOpts.group,
|
||||
order: this.menuOpts.order
|
||||
};
|
||||
super.register();
|
||||
}
|
||||
|
||||
public runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void | TPromise<void> {
|
||||
@@ -223,8 +242,14 @@ export function registerLanguageCommand(id: string, handler: (accessor: Services
|
||||
CommandsRegistry.registerCommand(id, (accessor, args) => handler(accessor, args || {}));
|
||||
}
|
||||
|
||||
export function registerDefaultLanguageCommand(id: string, handler: (model: ITextModel, position: Position, args: { [n: string]: any }) => any) {
|
||||
registerLanguageCommand(id, function (accessor, args) {
|
||||
interface IDefaultArgs {
|
||||
resource: URI;
|
||||
position: IPosition;
|
||||
[name: string]: any;
|
||||
}
|
||||
|
||||
export function registerDefaultLanguageCommand(id: string, handler: (model: ITextModel, position: Position, args: IDefaultArgs) => any) {
|
||||
registerLanguageCommand(id, function (accessor, args: IDefaultArgs) {
|
||||
|
||||
const { resource, position } = args;
|
||||
if (!(resource instanceof URI)) {
|
||||
@@ -301,14 +326,7 @@ class EditorContributionRegistry {
|
||||
}
|
||||
|
||||
public registerEditorAction(action: EditorAction) {
|
||||
|
||||
let menuItem = action.toMenuItem();
|
||||
if (menuItem) {
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorContext, menuItem);
|
||||
}
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule(action.toCommandAndKeybindingRule(KeybindingsRegistry.WEIGHT.editorContrib()));
|
||||
|
||||
action.register();
|
||||
this.editorActions.push(action);
|
||||
}
|
||||
|
||||
@@ -321,7 +339,7 @@ class EditorContributionRegistry {
|
||||
}
|
||||
|
||||
public registerEditorCommand(editorCommand: EditorCommand) {
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule(editorCommand.toCommandAndKeybindingRule(KeybindingsRegistry.WEIGHT.editorContrib()));
|
||||
editorCommand.register();
|
||||
this.editorCommands[editorCommand.id] = editorCommand;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
|
||||
@@ -84,7 +86,7 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
for (let i = 0; i < editors.length; i++) {
|
||||
let editor = editors[i];
|
||||
|
||||
if (editor.isFocused()) {
|
||||
if (editor.hasTextFocus()) {
|
||||
// bingo!
|
||||
return editor;
|
||||
}
|
||||
@@ -130,6 +132,9 @@ export abstract class AbstractCodeEditorService implements ICodeEditorService {
|
||||
_removeWatcher(w: ModelTransientSettingWatcher): void {
|
||||
delete this._transientWatchers[w.uri];
|
||||
}
|
||||
|
||||
abstract getActiveCodeEditor(): ICodeEditor;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): TPromise<ICodeEditor>;
|
||||
}
|
||||
|
||||
export class ModelTransientSettingWatcher {
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IDisposable, dispose, IReference } from 'vs/base/common/lifecycle';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
import { IFileService, FileChangeType } from 'vs/platform/files/common/files';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { IIdentifiedSingleEditOperation, ITextModel, EndOfLineSequence } from 'vs/editor/common/model';
|
||||
import { IProgressRunner, emptyProgressRunner, IProgress } from 'vs/platform/progress/common/progress';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ResourceTextEdit, ResourceFileEdit, isResourceFileEdit, isResourceTextEdit } from 'vs/editor/common/modes';
|
||||
import { getPathLabel } from 'vs/base/common/labels';
|
||||
|
||||
|
||||
abstract class IRecording {
|
||||
|
||||
static start(fileService: IFileService): IRecording {
|
||||
|
||||
const _changes = new Set<string>();
|
||||
let stop: IDisposable;
|
||||
|
||||
if (fileService) {
|
||||
// watch only when there is a fileservice available
|
||||
stop = fileService.onFileChanges(event => {
|
||||
for (const change of event.changes) {
|
||||
if (change.type === FileChangeType.UPDATED) {
|
||||
_changes.add(change.resource.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
stop() { return dispose(stop); },
|
||||
hasChanged(resource) { return _changes.has(resource.toString()); }
|
||||
};
|
||||
}
|
||||
|
||||
abstract stop(): void;
|
||||
abstract hasChanged(resource: URI): boolean;
|
||||
}
|
||||
|
||||
class EditTask implements IDisposable {
|
||||
|
||||
private _initialSelections: Selection[];
|
||||
private _endCursorSelection: Selection;
|
||||
private get _model(): ITextModel { return this._modelReference.object.textEditorModel; }
|
||||
private _modelReference: IReference<ITextEditorModel>;
|
||||
private _edits: IIdentifiedSingleEditOperation[];
|
||||
private _newEol: EndOfLineSequence;
|
||||
|
||||
constructor(modelReference: IReference<ITextEditorModel>) {
|
||||
this._endCursorSelection = null;
|
||||
this._modelReference = modelReference;
|
||||
this._edits = [];
|
||||
}
|
||||
|
||||
dispose() {
|
||||
if (this._model) {
|
||||
this._modelReference.dispose();
|
||||
this._modelReference = null;
|
||||
}
|
||||
}
|
||||
|
||||
addEdit(resourceEdit: ResourceTextEdit): void {
|
||||
|
||||
for (const edit of resourceEdit.edits) {
|
||||
if (typeof edit.eol === 'number') {
|
||||
// honor eol-change
|
||||
this._newEol = edit.eol;
|
||||
}
|
||||
if (edit.range || edit.text) {
|
||||
// create edit operation
|
||||
let range: Range;
|
||||
if (!edit.range) {
|
||||
range = this._model.getFullModelRange();
|
||||
} else {
|
||||
range = Range.lift(edit.range);
|
||||
}
|
||||
this._edits.push(EditOperation.replaceMove(range, edit.text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply(): void {
|
||||
if (this._edits.length > 0) {
|
||||
|
||||
this._edits = this._edits.map((value, index) => ({ value, index })).sort((a, b) => {
|
||||
let ret = Range.compareRangesUsingStarts(a.value.range, b.value.range);
|
||||
if (ret === 0) {
|
||||
ret = a.index - b.index;
|
||||
}
|
||||
return ret;
|
||||
}).map(element => element.value);
|
||||
|
||||
this._initialSelections = this._getInitialSelections();
|
||||
this._model.pushStackElement();
|
||||
this._model.pushEditOperations(this._initialSelections, this._edits, (edits) => this._getEndCursorSelections(edits));
|
||||
this._model.pushStackElement();
|
||||
}
|
||||
if (this._newEol !== undefined) {
|
||||
this._model.pushStackElement();
|
||||
this._model.setEOL(this._newEol);
|
||||
this._model.pushStackElement();
|
||||
}
|
||||
}
|
||||
|
||||
protected _getInitialSelections(): Selection[] {
|
||||
const firstRange = this._edits[0].range;
|
||||
const initialSelection = new Selection(
|
||||
firstRange.startLineNumber,
|
||||
firstRange.startColumn,
|
||||
firstRange.endLineNumber,
|
||||
firstRange.endColumn
|
||||
);
|
||||
return [initialSelection];
|
||||
}
|
||||
|
||||
private _getEndCursorSelections(inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] {
|
||||
let relevantEditIndex = 0;
|
||||
for (let i = 0; i < inverseEditOperations.length; i++) {
|
||||
const editRange = inverseEditOperations[i].range;
|
||||
for (let j = 0; j < this._initialSelections.length; j++) {
|
||||
const selectionRange = this._initialSelections[j];
|
||||
if (Range.areIntersectingOrTouching(editRange, selectionRange)) {
|
||||
relevantEditIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const srcRange = inverseEditOperations[relevantEditIndex].range;
|
||||
this._endCursorSelection = new Selection(
|
||||
srcRange.endLineNumber,
|
||||
srcRange.endColumn,
|
||||
srcRange.endLineNumber,
|
||||
srcRange.endColumn
|
||||
);
|
||||
return [this._endCursorSelection];
|
||||
}
|
||||
|
||||
getEndCursorSelection(): Selection {
|
||||
return this._endCursorSelection;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SourceModelEditTask extends EditTask {
|
||||
|
||||
private _knownInitialSelections: Selection[];
|
||||
|
||||
constructor(modelReference: IReference<ITextEditorModel>, initialSelections: Selection[]) {
|
||||
super(modelReference);
|
||||
this._knownInitialSelections = initialSelections;
|
||||
}
|
||||
|
||||
protected _getInitialSelections(): Selection[] {
|
||||
return this._knownInitialSelections;
|
||||
}
|
||||
}
|
||||
|
||||
class BulkEditModel implements IDisposable {
|
||||
|
||||
private _textModelResolverService: ITextModelService;
|
||||
private _edits = new Map<string, ResourceTextEdit[]>();
|
||||
private _tasks: EditTask[];
|
||||
private _sourceModel: URI;
|
||||
private _sourceSelections: Selection[];
|
||||
private _sourceModelTask: SourceModelEditTask;
|
||||
private _progress: IProgress<void>;
|
||||
|
||||
constructor(
|
||||
textModelResolverService: ITextModelService,
|
||||
editor: ICodeEditor,
|
||||
edits: ResourceTextEdit[],
|
||||
progress: IProgress<void>
|
||||
) {
|
||||
this._textModelResolverService = textModelResolverService;
|
||||
this._sourceModel = editor ? editor.getModel().uri : undefined;
|
||||
this._sourceSelections = editor ? editor.getSelections() : undefined;
|
||||
this._sourceModelTask = undefined;
|
||||
this._progress = progress;
|
||||
|
||||
edits.forEach(this.addEdit, this);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._tasks = dispose(this._tasks);
|
||||
}
|
||||
|
||||
addEdit(edit: ResourceTextEdit): void {
|
||||
let array = this._edits.get(edit.resource.toString());
|
||||
if (!array) {
|
||||
array = [];
|
||||
this._edits.set(edit.resource.toString(), array);
|
||||
}
|
||||
array.push(edit);
|
||||
}
|
||||
|
||||
async prepare(): TPromise<BulkEditModel> {
|
||||
|
||||
if (this._tasks) {
|
||||
throw new Error('illegal state - already prepared');
|
||||
}
|
||||
|
||||
this._tasks = [];
|
||||
const promises: TPromise<any>[] = [];
|
||||
|
||||
this._edits.forEach((value, key) => {
|
||||
const promise = this._textModelResolverService.createModelReference(URI.parse(key)).then(ref => {
|
||||
const model = ref.object;
|
||||
|
||||
if (!model || !model.textEditorModel) {
|
||||
throw new Error(`Cannot load file ${key}`);
|
||||
}
|
||||
|
||||
let task: EditTask;
|
||||
if (this._sourceModel && model.textEditorModel.uri.toString() === this._sourceModel.toString()) {
|
||||
this._sourceModelTask = new SourceModelEditTask(ref, this._sourceSelections);
|
||||
task = this._sourceModelTask;
|
||||
} else {
|
||||
task = new EditTask(ref);
|
||||
}
|
||||
|
||||
value.forEach(edit => task.addEdit(edit));
|
||||
this._tasks.push(task);
|
||||
this._progress.report(undefined);
|
||||
});
|
||||
promises.push(promise);
|
||||
});
|
||||
|
||||
await TPromise.join(promises);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
apply(): Selection {
|
||||
for (const task of this._tasks) {
|
||||
task.apply();
|
||||
this._progress.report(undefined);
|
||||
}
|
||||
return this._sourceModelTask
|
||||
? this._sourceModelTask.getEndCursorSelection()
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export type Edit = ResourceFileEdit | ResourceTextEdit;
|
||||
|
||||
export class BulkEdit {
|
||||
|
||||
static perform(edits: Edit[], textModelService: ITextModelService, fileService: IFileService, editor: ICodeEditor): TPromise<any> {
|
||||
const edit = new BulkEdit(editor, null, textModelService, fileService);
|
||||
edit.add(edits);
|
||||
return edit.perform();
|
||||
}
|
||||
|
||||
private _edits: Edit[] = [];
|
||||
private _editor: ICodeEditor;
|
||||
private _progress: IProgressRunner;
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
progress: IProgressRunner,
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
@optional(IFileService) private _fileService: IFileService
|
||||
) {
|
||||
this._editor = editor;
|
||||
this._progress = progress || emptyProgressRunner;
|
||||
}
|
||||
|
||||
add(edits: Edit[] | Edit): void {
|
||||
if (Array.isArray(edits)) {
|
||||
this._edits.push(...edits);
|
||||
} else {
|
||||
this._edits.push(edits);
|
||||
}
|
||||
}
|
||||
|
||||
ariaMessage(): string {
|
||||
const editCount = this._edits.reduce((prev, cur) => isResourceFileEdit(cur) ? prev : prev + cur.edits.length, 0);
|
||||
const resourceCount = this._edits.length;
|
||||
if (editCount === 0) {
|
||||
return nls.localize('summary.0', "Made no edits");
|
||||
} else if (editCount > 1 && resourceCount > 1) {
|
||||
return nls.localize('summary.nm', "Made {0} text edits in {1} files", editCount, resourceCount);
|
||||
} else {
|
||||
return nls.localize('summary.n0', "Made {0} text edits in one file", editCount, resourceCount);
|
||||
}
|
||||
}
|
||||
|
||||
async perform(): TPromise<Selection> {
|
||||
|
||||
let seen = new Set<string>();
|
||||
let total = 0;
|
||||
|
||||
const groups: Edit[][] = [];
|
||||
let group: Edit[];
|
||||
for (const edit of this._edits) {
|
||||
if (!group
|
||||
|| (isResourceFileEdit(group[0]) && !isResourceFileEdit(edit))
|
||||
|| (isResourceTextEdit(group[0]) && !isResourceTextEdit(edit))
|
||||
) {
|
||||
group = [];
|
||||
groups.push(group);
|
||||
}
|
||||
group.push(edit);
|
||||
|
||||
if (isResourceFileEdit(edit)) {
|
||||
total += 1;
|
||||
} else if (!seen.has(edit.resource.toString())) {
|
||||
seen.add(edit.resource.toString());
|
||||
total += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// define total work and progress callback
|
||||
// for child operations
|
||||
this._progress.total(total);
|
||||
let progress: IProgress<void> = { report: _ => this._progress.worked(1) };
|
||||
|
||||
// do it. return the last selection computed
|
||||
// by a text change (can be undefined then)
|
||||
let res: Selection = undefined;
|
||||
for (const group of groups) {
|
||||
if (isResourceFileEdit(group[0])) {
|
||||
await this._performFileEdits(<ResourceFileEdit[]>group, progress);
|
||||
} else {
|
||||
res = await this._performTextEdits(<ResourceTextEdit[]>group, progress) || res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private async _performFileEdits(edits: ResourceFileEdit[], progress: IProgress<void>) {
|
||||
for (const edit of edits) {
|
||||
|
||||
progress.report(undefined);
|
||||
|
||||
if (edit.newUri && edit.oldUri) {
|
||||
await this._fileService.moveFile(edit.oldUri, edit.newUri, false);
|
||||
} else if (!edit.newUri && edit.oldUri) {
|
||||
await this._fileService.del(edit.oldUri, true);
|
||||
} else if (edit.newUri && !edit.oldUri) {
|
||||
await this._fileService.createFile(edit.newUri, undefined, { overwrite: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _performTextEdits(edits: ResourceTextEdit[], progress: IProgress<void>): TPromise<Selection> {
|
||||
|
||||
const recording = IRecording.start(this._fileService);
|
||||
const model = new BulkEditModel(this._textModelService, this._editor, edits, progress);
|
||||
|
||||
await model.prepare();
|
||||
|
||||
const conflicts = edits
|
||||
.filter(edit => recording.hasChanged(edit.resource))
|
||||
.map(edit => getPathLabel(edit.resource));
|
||||
|
||||
recording.stop();
|
||||
|
||||
if (conflicts.length > 0) {
|
||||
model.dispose();
|
||||
throw new Error(nls.localize('conflict', "These files have changed in the meantime: {0}", conflicts.join(', ')));
|
||||
}
|
||||
|
||||
const selection = await model.apply();
|
||||
model.dispose();
|
||||
return selection;
|
||||
}
|
||||
}
|
||||
30
src/vs/editor/browser/services/bulkEditService.ts
Normal file
30
src/vs/editor/browser/services/bulkEditService.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { WorkspaceEdit } from 'vs/editor/common/modes';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ICodeEditor } from '../editorBrowser';
|
||||
import { IProgressRunner } from 'vs/platform/progress/common/progress';
|
||||
|
||||
export const IBulkEditService = createDecorator<IBulkEditService>('IWorkspaceEditService');
|
||||
|
||||
|
||||
export interface IBulkEditOptions {
|
||||
editor?: ICodeEditor;
|
||||
progress?: IProgressRunner;
|
||||
}
|
||||
|
||||
export interface IBulkEditResult {
|
||||
ariaSummary: string;
|
||||
}
|
||||
|
||||
export interface IBulkEditService {
|
||||
_serviceBrand: any;
|
||||
|
||||
apply(edit: WorkspaceEdit, options: IBulkEditOptions): TPromise<IBulkEditResult>;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ import { Event } from 'vs/base/common/event';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model';
|
||||
import { IEditor } from 'vs/platform/editor/common/editor';
|
||||
import { ICodeEditor, IDiffEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
|
||||
export const ICodeEditorService = createDecorator<ICodeEditorService>('codeEditorService');
|
||||
|
||||
@@ -41,40 +42,7 @@ export interface ICodeEditorService {
|
||||
|
||||
setTransientModelProperty(model: ITextModel, key: string, value: any): void;
|
||||
getTransientModelProperty(model: ITextModel, key: string): any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses `editor.getControl()` and returns either a `codeEditor` or a `diffEditor` or nothing.
|
||||
*/
|
||||
export function getCodeOrDiffEditor(editor: IEditor): { codeEditor: ICodeEditor; diffEditor: IDiffEditor } {
|
||||
if (editor) {
|
||||
let control = editor.getControl();
|
||||
if (control) {
|
||||
if (isCodeEditor(control)) {
|
||||
return {
|
||||
codeEditor: control,
|
||||
diffEditor: null
|
||||
};
|
||||
}
|
||||
if (isDiffEditor(control)) {
|
||||
return {
|
||||
codeEditor: null,
|
||||
diffEditor: control
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
codeEditor: null,
|
||||
diffEditor: null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses `editor.getControl()` and returns either the code editor, or the modified editor of a diff editor or nothing.
|
||||
*/
|
||||
export function getCodeEditor(editor: IEditor): ICodeEditor {
|
||||
let r = getCodeOrDiffEditor(editor);
|
||||
return r.codeEditor || (r.diffEditor && <ICodeEditor>r.diffEditor.getModifiedEditor()) || null;
|
||||
getActiveCodeEditor(): ICodeEditor;
|
||||
openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): TPromise<ICodeEditor>;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,11 @@ import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, Overview
|
||||
import { AbstractCodeEditorService } from 'vs/editor/browser/services/abstractCodeEditorService';
|
||||
import { IDisposable, dispose as disposeAll } from 'vs/base/common/lifecycle';
|
||||
import { IThemeService, ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
|
||||
export class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
|
||||
private _styleSheet: HTMLStyleElement;
|
||||
private _decorationOptionProviders: { [key: string]: IModelDecorationOptionsProvider };
|
||||
@@ -65,6 +68,8 @@ export class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
return provider.getOptions(this, writable);
|
||||
}
|
||||
|
||||
abstract getActiveCodeEditor(): ICodeEditor;
|
||||
abstract openCodeEditor(input: IResourceInput, source: ICodeEditor, sideBySide?: boolean): TPromise<ICodeEditor>;
|
||||
}
|
||||
|
||||
interface IModelDecorationOptionsProvider extends IDisposable {
|
||||
@@ -205,9 +210,9 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
|
||||
}
|
||||
|
||||
|
||||
const _CSS_MAP = {
|
||||
const _CSS_MAP: { [prop: string]: string; } = {
|
||||
color: 'color:{0} !important;',
|
||||
opacity: 'opacity:{0};',
|
||||
opacity: 'opacity:{0}; will-change: opacity;', // TODO@Ben: 'will-change: opacity' is a workaround for https://github.com/Microsoft/vscode/issues/52196
|
||||
backgroundColor: 'background-color:{0};',
|
||||
|
||||
outline: 'outline:{0};',
|
||||
|
||||
89
src/vs/editor/browser/services/openerService.ts
Normal file
89
src/vs/editor/browser/services/openerService.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { parse } from 'vs/base/common/marshalling';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { normalize } from 'vs/base/common/paths';
|
||||
import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { optional } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
|
||||
export class OpenerService implements IOpenerService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(
|
||||
@ICodeEditorService private readonly _editorService: ICodeEditorService,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@optional(ITelemetryService) private _telemetryService: ITelemetryService = NullTelemetryService
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
open(resource: URI, options?: { openToSide?: boolean }): TPromise<any> {
|
||||
|
||||
/* __GDPR__
|
||||
"openerService" : {
|
||||
"scheme" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this._telemetryService.publicLog('openerService', { scheme: resource.scheme });
|
||||
|
||||
const { scheme, path, query, fragment } = resource;
|
||||
let promise: TPromise<any> = TPromise.wrap(void 0);
|
||||
|
||||
if (scheme === Schemas.http || scheme === Schemas.https || scheme === Schemas.mailto) {
|
||||
// open http or default mail application
|
||||
dom.windowOpenNoOpener(resource.toString(true));
|
||||
} else if (scheme === 'command' && CommandsRegistry.getCommand(path)) {
|
||||
// execute as command
|
||||
let args: any = [];
|
||||
try {
|
||||
args = parse(query);
|
||||
if (!Array.isArray(args)) {
|
||||
args = [args];
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
promise = this._commandService.executeCommand(path, ...args);
|
||||
|
||||
} else {
|
||||
let selection: {
|
||||
startLineNumber: number;
|
||||
startColumn: number;
|
||||
};
|
||||
const match = /^L?(\d+)(?:,(\d+))?/.exec(fragment);
|
||||
if (match) {
|
||||
// support file:///some/file.js#73,84
|
||||
// support file:///some/file.js#L73
|
||||
selection = {
|
||||
startLineNumber: parseInt(match[1]),
|
||||
startColumn: match[2] ? parseInt(match[2]) : 1
|
||||
};
|
||||
// remove fragment
|
||||
resource = resource.with({ fragment: '' });
|
||||
}
|
||||
|
||||
if (!resource.scheme) {
|
||||
// we cannot handle those
|
||||
return TPromise.as(undefined);
|
||||
|
||||
} else if (resource.scheme === Schemas.file) {
|
||||
resource = resource.with({ path: normalize(resource.path) }); // workaround for non-normalized paths (https://github.com/Microsoft/vscode/issues/12954)
|
||||
}
|
||||
promise = this._editorService.openCodeEditor({ resource, options: { selection, } }, this._editorService.getFocusedCodeEditor(), options && options.openToSide);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { IEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ViewOutgoingEvents } from 'vs/editor/browser/view/viewOutgoingEvents';
|
||||
import { CoreNavigationCommands, CoreEditorCommand } from 'vs/editor/browser/controller/coreCommands';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
|
||||
export interface ExecCoreEditorCommandFunc {
|
||||
(editorCommand: CoreEditorCommand, args: any): void;
|
||||
@@ -47,14 +47,14 @@ export interface ICommandDelegate {
|
||||
|
||||
export class ViewController {
|
||||
|
||||
private readonly configuration: Configuration;
|
||||
private readonly configuration: IConfiguration;
|
||||
private readonly viewModel: IViewModel;
|
||||
private readonly _execCoreEditorCommandFunc: ExecCoreEditorCommandFunc;
|
||||
private readonly outgoingEvents: ViewOutgoingEvents;
|
||||
private readonly commandDelegate: ICommandDelegate;
|
||||
|
||||
constructor(
|
||||
configuration: Configuration,
|
||||
configuration: IConfiguration,
|
||||
viewModel: IViewModel,
|
||||
execCommandFunc: ExecCoreEditorCommandFunc,
|
||||
outgoingEvents: ViewOutgoingEvents,
|
||||
|
||||
@@ -10,7 +10,7 @@ import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { IConfiguration } from 'vs/editor/common/editorCommon';
|
||||
import { TextAreaHandler, ITextAreaHandlerHelper } from 'vs/editor/browser/controller/textAreaHandler';
|
||||
import { PointerHandler } from 'vs/editor/browser/controller/pointerHandler';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
@@ -93,7 +93,7 @@ export class View extends ViewEventHandler {
|
||||
|
||||
constructor(
|
||||
commandDelegate: ICommandDelegate,
|
||||
configuration: Configuration,
|
||||
configuration: IConfiguration,
|
||||
themeService: IThemeService,
|
||||
model: IViewModel,
|
||||
cursor: Cursor,
|
||||
|
||||
@@ -22,6 +22,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
private _spaceWidth: number;
|
||||
private _renderResult: string[];
|
||||
private _enabled: boolean;
|
||||
private _activeIndentEnabled: boolean;
|
||||
|
||||
constructor(context: ViewContext) {
|
||||
super();
|
||||
@@ -30,6 +31,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
this._lineHeight = this._context.configuration.editor.lineHeight;
|
||||
this._spaceWidth = this._context.configuration.editor.fontInfo.spaceWidth;
|
||||
this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides;
|
||||
this._activeIndentEnabled = this._context.configuration.editor.viewInfo.highlightActiveIndentGuide;
|
||||
this._renderResult = null;
|
||||
|
||||
this._context.addEventHandler(this);
|
||||
@@ -53,6 +55,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
}
|
||||
if (e.viewInfo) {
|
||||
this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides;
|
||||
this._activeIndentEnabled = this._context.configuration.editor.viewInfo.highlightActiveIndentGuide;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -105,6 +108,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
const visibleEndLineNumber = ctx.visibleRange.endLineNumber;
|
||||
const tabSize = this._context.model.getTabSize();
|
||||
const tabWidth = tabSize * this._spaceWidth;
|
||||
const scrollWidth = ctx.scrollWidth;
|
||||
const lineHeight = this._lineHeight;
|
||||
const indentGuideWidth = tabWidth;
|
||||
|
||||
@@ -113,7 +117,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
let activeIndentStartLineNumber = 0;
|
||||
let activeIndentEndLineNumber = 0;
|
||||
let activeIndentLevel = 0;
|
||||
if (this._primaryLineNumber) {
|
||||
if (this._activeIndentEnabled && this._primaryLineNumber) {
|
||||
const activeIndentInfo = this._context.model.getActiveIndentGuide(this._primaryLineNumber, visibleStartLineNumber, visibleEndLineNumber);
|
||||
activeIndentStartLineNumber = activeIndentInfo.startLineNumber;
|
||||
activeIndentEndLineNumber = activeIndentInfo.endLineNumber;
|
||||
@@ -133,6 +137,9 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
|
||||
let className = (containsActiveIndentGuide && i === activeIndentLevel ? 'cigra' : 'cigr');
|
||||
result += `<div class="${className}" style="left:${left}px;height:${lineHeight}px;width:${indentGuideWidth}px"></div>`;
|
||||
left += tabWidth;
|
||||
if (left > scrollWidth) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output[lineIndex] = result;
|
||||
|
||||
@@ -191,6 +191,7 @@ export class ViewLine implements IVisibleLine {
|
||||
let renderLineInput = new RenderLineInput(
|
||||
options.useMonospaceOptimizations,
|
||||
lineData.content,
|
||||
lineData.continuesWithWrappedLine,
|
||||
lineData.isBasicASCII,
|
||||
lineData.containsRTL,
|
||||
lineData.minColumn - 1,
|
||||
@@ -230,7 +231,7 @@ export class ViewLine implements IVisibleLine {
|
||||
// Another rounding error has been observed on Linux in VSCode, where <span> width
|
||||
// rounding errors add up to an observable large number...
|
||||
// ---
|
||||
// Also see another example of rounding errors on Windows in
|
||||
// Also see another example of rounding errors on Windows in
|
||||
// https://github.com/Microsoft/vscode/issues/33178
|
||||
renderedViewLine = new FastRenderedViewLine(
|
||||
this._renderedViewLine ? this._renderedViewLine.domNode : null,
|
||||
|
||||
@@ -271,6 +271,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
|
||||
return this._visibleLines.onTokensChanged(e);
|
||||
}
|
||||
public onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
|
||||
this._context.viewLayout.onMaxLineWidthChanged(this._maxLineWidth);
|
||||
return this._visibleLines.onZonesChanged(e);
|
||||
}
|
||||
public onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
|
||||
|
||||
@@ -913,6 +913,11 @@ export class Minimap extends ViewPart {
|
||||
minimapCharRenderer.x1BlockRenderChar(target, dx, dy, tokenColor, backgroundColor, useLighterFont);
|
||||
}
|
||||
dx += charWidth;
|
||||
|
||||
if (dx > maxDx) {
|
||||
// hit edge of minimap
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ export interface IMyViewZone {
|
||||
interface IComputedViewZoneProps {
|
||||
afterViewLineNumber: number;
|
||||
heightInPx: number;
|
||||
minWidthInPx: number;
|
||||
}
|
||||
|
||||
export class ViewZones extends ViewPart {
|
||||
@@ -138,7 +139,8 @@ export class ViewZones extends ViewPart {
|
||||
if (zone.afterLineNumber === 0) {
|
||||
return {
|
||||
afterViewLineNumber: 0,
|
||||
heightInPx: this._heightInPixels(zone)
|
||||
heightInPx: this._heightInPixels(zone),
|
||||
minWidthInPx: this._minWidthInPixels(zone)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -177,13 +179,14 @@ export class ViewZones extends ViewPart {
|
||||
let isVisible = this._context.model.coordinatesConverter.modelPositionIsVisible(zoneBeforeModelPosition);
|
||||
return {
|
||||
afterViewLineNumber: viewPosition.lineNumber,
|
||||
heightInPx: (isVisible ? this._heightInPixels(zone) : 0)
|
||||
heightInPx: (isVisible ? this._heightInPixels(zone) : 0),
|
||||
minWidthInPx: this._minWidthInPixels(zone)
|
||||
};
|
||||
}
|
||||
|
||||
public addZone(zone: IViewZone): number {
|
||||
let props = this._computeWhitespaceProps(zone);
|
||||
let whitespaceId = this._context.viewLayout.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx);
|
||||
let whitespaceId = this._context.viewLayout.addWhitespace(props.afterViewLineNumber, this._getZoneOrdinal(zone), props.heightInPx, props.minWidthInPx);
|
||||
|
||||
let myZone: IMyViewZone = {
|
||||
whitespaceId: whitespaceId,
|
||||
@@ -275,6 +278,13 @@ export class ViewZones extends ViewPart {
|
||||
return this._lineHeight;
|
||||
}
|
||||
|
||||
private _minWidthInPixels(zone: IViewZone): number {
|
||||
if (typeof zone.minWidthInPx === 'number') {
|
||||
return zone.minWidthInPx;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private _safeCallOnComputedHeight(zone: IViewZone, height: number): void {
|
||||
if (typeof zone.onComputedHeight === 'function') {
|
||||
try {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import { ISashEvent, IVerticalSashLayoutProvider, Sash } from 'vs/base/browser/ui/sash/sash';
|
||||
import { ISashEvent, IVerticalSashLayoutProvider, Sash, SashState } from 'vs/base/browser/ui/sash/sash';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
@@ -22,18 +22,16 @@ import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerServ
|
||||
import { LineDecoration } from 'vs/editor/common/viewLayout/lineDecorations';
|
||||
import { renderViewLine, RenderLineInput } from 'vs/editor/common/viewLayout/viewLineRenderer';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { CodeEditor } from 'vs/editor/browser/codeEditor';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { Configuration } from 'vs/editor/browser/config/configuration';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { Selection, ISelection } from 'vs/editor/common/core/selection';
|
||||
import { InlineDecoration, InlineDecorationType, ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { ColorId, MetadataConsts, FontStyle } from 'vs/editor/common/modes';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as editorOptions from 'vs/editor/common/config/editorOptions';
|
||||
import { registerThemingParticipant, IThemeService, ITheme, getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
|
||||
import { scrollbarShadow, diffInserted, diffRemoved, defaultInsertColor, defaultRemoveColor, diffInsertedOutline, diffRemovedOutline } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { scrollbarShadow, diffInserted, diffRemoved, defaultInsertColor, defaultRemoveColor, diffInsertedOutline, diffRemovedOutline, diffBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { OverviewRulerZone } from 'vs/editor/common/view/overviewZoneManager';
|
||||
import { IEditorWhitespace } from 'vs/editor/common/viewLayout/whitespaceComputer';
|
||||
@@ -87,7 +85,7 @@ class VisualEditorState {
|
||||
return allViewZones.filter((z) => !this._zonesMap[String(z.id)]);
|
||||
}
|
||||
|
||||
public clean(editor: CodeEditor): void {
|
||||
public clean(editor: CodeEditorWidget): void {
|
||||
// (1) View zones
|
||||
if (this._zones.length > 0) {
|
||||
editor.changeViewZones((viewChangeAccessor: editorBrowser.IViewZoneChangeAccessor) => {
|
||||
@@ -103,7 +101,7 @@ class VisualEditorState {
|
||||
this._decorations = editor.deltaDecorations(this._decorations, []);
|
||||
}
|
||||
|
||||
public apply(editor: CodeEditor, overviewRuler: editorBrowser.IOverviewRuler, newDecorations: IEditorDiffDecorationsWithZones, restoreScrollState: boolean): void {
|
||||
public apply(editor: CodeEditorWidget, overviewRuler: editorBrowser.IOverviewRuler, newDecorations: IEditorDiffDecorationsWithZones, restoreScrollState: boolean): void {
|
||||
|
||||
const scrollState = restoreScrollState ? StableEditorScrollState.capture(editor) : null;
|
||||
|
||||
@@ -162,12 +160,12 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
private _reviewHeight: number;
|
||||
private readonly _measureDomElementToken: number;
|
||||
|
||||
private originalEditor: CodeEditor;
|
||||
private originalEditor: CodeEditorWidget;
|
||||
private _originalDomNode: HTMLElement;
|
||||
private _originalEditorState: VisualEditorState;
|
||||
private _originalOverviewRuler: editorBrowser.IOverviewRuler;
|
||||
|
||||
private modifiedEditor: CodeEditor;
|
||||
private modifiedEditor: CodeEditorWidget;
|
||||
private _modifiedDomNode: HTMLElement;
|
||||
private _modifiedEditorState: VisualEditorState;
|
||||
private _modifiedOverviewRuler: editorBrowser.IOverviewRuler;
|
||||
@@ -470,8 +468,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
}));
|
||||
}
|
||||
|
||||
protected _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: editorOptions.IEditorOptions): CodeEditor {
|
||||
return instantiationService.createInstance(CodeEditor, container, options);
|
||||
protected _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: editorOptions.IEditorOptions): CodeEditorWidget {
|
||||
return instantiationService.createInstance(CodeEditorWidget, container, options, {});
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -486,10 +484,14 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
|
||||
this._cleanViewZonesAndDecorations();
|
||||
|
||||
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
|
||||
this._originalOverviewRuler.dispose();
|
||||
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
|
||||
this._modifiedOverviewRuler.dispose();
|
||||
if (this._originalOverviewRuler) {
|
||||
this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode());
|
||||
this._originalOverviewRuler.dispose();
|
||||
}
|
||||
if (this._modifiedOverviewRuler) {
|
||||
this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode());
|
||||
this._modifiedOverviewRuler.dispose();
|
||||
}
|
||||
this._overviewDomElement.removeChild(this._overviewViewportDomElement.domNode);
|
||||
this._containerDomElement.removeChild(this._overviewDomElement);
|
||||
|
||||
@@ -751,8 +753,8 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
|
||||
this.modifiedEditor.focus();
|
||||
}
|
||||
|
||||
public isFocused(): boolean {
|
||||
return this.originalEditor.isFocused() || this.modifiedEditor.isFocused();
|
||||
public hasTextFocus(): boolean {
|
||||
return this.originalEditor.hasTextFocus() || this.modifiedEditor.hasTextFocus();
|
||||
}
|
||||
|
||||
public onVisible(): void {
|
||||
@@ -1175,7 +1177,7 @@ interface IDataSource {
|
||||
getModifiedEditor(): editorBrowser.ICodeEditor;
|
||||
}
|
||||
|
||||
class DiffEditorWidgetStyle extends Disposable {
|
||||
abstract class DiffEditorWidgetStyle extends Disposable implements IDiffEditorWidgetStyle {
|
||||
|
||||
_dataSource: IDataSource;
|
||||
_insertColor: Color;
|
||||
@@ -1223,17 +1225,12 @@ class DiffEditorWidgetStyle extends Disposable {
|
||||
};
|
||||
}
|
||||
|
||||
_getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor, renderIndicators: boolean): IEditorsZones {
|
||||
return null;
|
||||
}
|
||||
protected abstract _getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor, renderIndicators: boolean): IEditorsZones;
|
||||
protected abstract _getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations;
|
||||
protected abstract _getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations;
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
return null;
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
return null;
|
||||
}
|
||||
public abstract setEnableSplitViewResizing(enableSplitViewResizing: boolean): void;
|
||||
public abstract layout(): number;
|
||||
}
|
||||
|
||||
interface IMyViewZone extends editorBrowser.IViewZone {
|
||||
@@ -1526,7 +1523,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
this._sash = this._register(new Sash(this._dataSource.getContainerDomNode(), this));
|
||||
|
||||
if (this._disableSash) {
|
||||
this._sash.disable();
|
||||
this._sash.state = SashState.Disabled;
|
||||
}
|
||||
|
||||
this._sash.onDidStart(() => this.onSashDragStart());
|
||||
@@ -1535,20 +1532,11 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
this._sash.onDidReset(() => this.onSashReset());
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public setEnableSplitViewResizing(enableSplitViewResizing: boolean): void {
|
||||
let newDisableSash = (enableSplitViewResizing === false);
|
||||
if (this._disableSash !== newDisableSash) {
|
||||
this._disableSash = newDisableSash;
|
||||
|
||||
if (this._disableSash) {
|
||||
this._sash.disable();
|
||||
} else {
|
||||
this._sash.enable();
|
||||
}
|
||||
this._sash.state = this._disableSash ? SashState.Disabled : SashState.Enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1617,12 +1605,12 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
return this._dataSource.getHeight();
|
||||
}
|
||||
|
||||
_getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorsZones {
|
||||
protected _getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorsZones {
|
||||
let c = new SideBySideViewZonesComputer(lineChanges, originalForeignVZ, modifiedForeignVZ);
|
||||
return c.getViewZones();
|
||||
}
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
protected _getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._removeColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
@@ -1682,7 +1670,7 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
|
||||
return result;
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
protected _getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._insertColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
@@ -1749,7 +1737,7 @@ class SideBySideViewZonesComputer extends ViewZonesComputer {
|
||||
super(lineChanges, originalForeignVZ, modifiedForeignVZ);
|
||||
}
|
||||
|
||||
_produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
if (lineChangeModifiedLength > lineChangeOriginalLength) {
|
||||
return {
|
||||
afterLineNumber: Math.max(lineChange.originalStartLineNumber, lineChange.originalEndLineNumber),
|
||||
@@ -1760,7 +1748,7 @@ class SideBySideViewZonesComputer extends ViewZonesComputer {
|
||||
return null;
|
||||
}
|
||||
|
||||
_produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
if (lineChangeOriginalLength > lineChangeModifiedLength) {
|
||||
return {
|
||||
afterLineNumber: Math.max(lineChange.modifiedStartLineNumber, lineChange.modifiedEndLineNumber),
|
||||
@@ -1789,20 +1777,16 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
}));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public setEnableSplitViewResizing(enableSplitViewResizing: boolean): void {
|
||||
// Nothing to do..
|
||||
}
|
||||
|
||||
_getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor, renderIndicators: boolean): IEditorsZones {
|
||||
protected _getViewZones(lineChanges: editorCommon.ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor, renderIndicators: boolean): IEditorsZones {
|
||||
let computer = new InlineViewZonesComputer(lineChanges, originalForeignVZ, modifiedForeignVZ, originalEditor, modifiedEditor, renderIndicators);
|
||||
return computer.getViewZones();
|
||||
}
|
||||
|
||||
_getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
protected _getOriginalEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._removeColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
@@ -1831,7 +1815,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor
|
||||
return result;
|
||||
}
|
||||
|
||||
_getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
protected _getModifiedEditorDecorations(lineChanges: editorCommon.ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor): IEditorDiffDecorations {
|
||||
const overviewZoneColor = this._insertColor.toString();
|
||||
|
||||
let result: IEditorDiffDecorations = {
|
||||
@@ -1913,7 +1897,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
this.renderIndicators = renderIndicators;
|
||||
}
|
||||
|
||||
_produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _produceOriginalFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
let marginDomNode = document.createElement('div');
|
||||
marginDomNode.className = 'inline-added-margin-view-zone';
|
||||
Configuration.applyFontInfoSlow(marginDomNode, this.modifiedEditorConfiguration.fontInfo);
|
||||
@@ -1926,7 +1910,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
};
|
||||
}
|
||||
|
||||
_produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
protected _produceModifiedFromDiff(lineChange: editorCommon.ILineChange, lineChangeOriginalLength: number, lineChangeModifiedLength: number): IMyViewZone {
|
||||
let decorations: InlineDecoration[] = [];
|
||||
if (lineChange.charChanges) {
|
||||
for (let j = 0, lengthJ = lineChange.charChanges.length; j < lengthJ; j++) {
|
||||
@@ -1945,8 +1929,10 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
let marginHTML: string[] = [];
|
||||
let lineDecorationsWidth = this.modifiedEditorConfiguration.layoutInfo.decorationsWidth;
|
||||
let lineHeight = this.modifiedEditorConfiguration.lineHeight;
|
||||
const typicalHalfwidthCharacterWidth = this.modifiedEditorConfiguration.fontInfo.typicalHalfwidthCharacterWidth;
|
||||
let maxCharsPerLine = 0;
|
||||
for (let lineNumber = lineChange.originalStartLineNumber; lineNumber <= lineChange.originalEndLineNumber; lineNumber++) {
|
||||
this.renderOriginalLine(lineNumber - lineChange.originalStartLineNumber, this.originalModel, this.modifiedEditorConfiguration, this.modifiedEditorTabSize, lineNumber, decorations, sb);
|
||||
maxCharsPerLine = Math.max(maxCharsPerLine, this._renderOriginalLine(lineNumber - lineChange.originalStartLineNumber, this.originalModel, this.modifiedEditorConfiguration, this.modifiedEditorTabSize, lineNumber, decorations, sb));
|
||||
|
||||
if (this.renderIndicators) {
|
||||
let index = lineNumber - lineChange.originalStartLineNumber;
|
||||
@@ -1955,6 +1941,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
]);
|
||||
}
|
||||
}
|
||||
maxCharsPerLine += this.modifiedEditorConfiguration.viewInfo.scrollBeyondLastColumn;
|
||||
|
||||
let domNode = document.createElement('div');
|
||||
domNode.className = 'view-lines line-delete';
|
||||
@@ -1970,27 +1957,17 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
shouldNotShrink: true,
|
||||
afterLineNumber: (lineChange.modifiedEndLineNumber === 0 ? lineChange.modifiedStartLineNumber : lineChange.modifiedStartLineNumber - 1),
|
||||
heightInLines: lineChangeOriginalLength,
|
||||
minWidthInPx: (maxCharsPerLine * typicalHalfwidthCharacterWidth),
|
||||
domNode: domNode,
|
||||
marginDomNode: marginDomNode
|
||||
};
|
||||
}
|
||||
|
||||
private renderOriginalLine(count: number, originalModel: ITextModel, config: editorOptions.InternalEditorOptions, tabSize: number, lineNumber: number, decorations: InlineDecoration[], sb: IStringBuilder): void {
|
||||
let lineContent = originalModel.getLineContent(lineNumber);
|
||||
private _renderOriginalLine(count: number, originalModel: ITextModel, config: editorOptions.InternalEditorOptions, tabSize: number, lineNumber: number, decorations: InlineDecoration[], sb: IStringBuilder): number {
|
||||
const lineTokens = originalModel.getLineTokens(lineNumber);
|
||||
const lineContent = lineTokens.getLineContent();
|
||||
|
||||
let actualDecorations = LineDecoration.filter(decorations, lineNumber, 1, lineContent.length + 1);
|
||||
|
||||
const defaultMetadata = (
|
||||
(FontStyle.None << MetadataConsts.FONT_STYLE_OFFSET)
|
||||
| (ColorId.DefaultForeground << MetadataConsts.FOREGROUND_OFFSET)
|
||||
| (ColorId.DefaultBackground << MetadataConsts.BACKGROUND_OFFSET)
|
||||
) >>> 0;
|
||||
|
||||
const tokens = new Uint32Array(2);
|
||||
tokens[0] = lineContent.length;
|
||||
tokens[1] = defaultMetadata;
|
||||
|
||||
const lineTokens = new LineTokens(tokens, lineContent);
|
||||
const actualDecorations = LineDecoration.filter(decorations, lineNumber, 1, lineContent.length + 1);
|
||||
|
||||
sb.appendASCIIString('<div class="view-line');
|
||||
if (decorations.length === 0) {
|
||||
@@ -2003,9 +1980,10 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
|
||||
const isBasicASCII = ViewLineRenderingData.isBasicASCII(lineContent, originalModel.mightContainNonBasicASCII());
|
||||
const containsRTL = ViewLineRenderingData.containsRTL(lineContent, isBasicASCII, originalModel.mightContainRTL());
|
||||
renderViewLine(new RenderLineInput(
|
||||
const output = renderViewLine(new RenderLineInput(
|
||||
(config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations),
|
||||
lineContent,
|
||||
false,
|
||||
isBasicASCII,
|
||||
containsRTL,
|
||||
0,
|
||||
@@ -2020,6 +1998,9 @@ class InlineViewZonesComputer extends ViewZonesComputer {
|
||||
), sb);
|
||||
|
||||
sb.appendASCIIString('</div>');
|
||||
|
||||
const absoluteOffsets = output.characterMapping.getAbsoluteOffsets();
|
||||
return absoluteOffsets.length > 0 ? absoluteOffsets[absoluteOffsets.length - 1] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2066,4 +2047,9 @@ registerThemingParticipant((theme, collector) => {
|
||||
if (shadow) {
|
||||
collector.addRule(`.monaco-diff-editor.side-by-side .editor.modified { box-shadow: -6px 0 5px -5px ${shadow}; }`);
|
||||
}
|
||||
|
||||
let border = theme.getColor(diffBorder);
|
||||
if (border) {
|
||||
collector.addRule(`.monaco-diff-editor.side-by-side .editor.modified { border-left: 1px solid ${border}; }`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -99,7 +99,7 @@ export class DiffNavigator {
|
||||
if (this._editor.getLineChanges() !== null) {
|
||||
this.revealFirst = false;
|
||||
this.nextIdx = -1;
|
||||
this.next();
|
||||
this.next(ScrollType.Immediate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,7 +167,7 @@ export class DiffNavigator {
|
||||
}
|
||||
}
|
||||
|
||||
private _move(fwd: boolean): void {
|
||||
private _move(fwd: boolean, scrollType: ScrollType): void {
|
||||
assert.ok(!this.disposed, 'Illegal State - diff navigator has been disposed');
|
||||
|
||||
if (!this.canNavigate()) {
|
||||
@@ -194,7 +194,7 @@ export class DiffNavigator {
|
||||
try {
|
||||
let pos = info.range.getStartPosition();
|
||||
this._editor.setPosition(pos);
|
||||
this._editor.revealPositionInCenter(pos, ScrollType.Smooth);
|
||||
this._editor.revealPositionInCenter(pos, scrollType);
|
||||
} finally {
|
||||
this.ignoreSelectionChange = false;
|
||||
}
|
||||
@@ -204,12 +204,12 @@ export class DiffNavigator {
|
||||
return this.ranges && this.ranges.length > 0;
|
||||
}
|
||||
|
||||
next(): void {
|
||||
this._move(true);
|
||||
next(scrollType: ScrollType = ScrollType.Smooth): void {
|
||||
this._move(true, scrollType);
|
||||
}
|
||||
|
||||
previous(): void {
|
||||
this._move(false);
|
||||
previous(scrollType: ScrollType = ScrollType.Smooth): void {
|
||||
this._move(false, scrollType);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -30,6 +30,7 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model';
|
||||
import { ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
|
||||
const DIFF_LINES_PADDING = 3;
|
||||
|
||||
@@ -124,12 +125,12 @@ export class DiffReview extends Disposable {
|
||||
}
|
||||
this._render();
|
||||
}));
|
||||
this._register(diffEditor.getOriginalEditor().onDidFocusEditor(() => {
|
||||
this._register(diffEditor.getOriginalEditor().onDidFocusEditorWidget(() => {
|
||||
if (this._isVisible) {
|
||||
this.hide();
|
||||
}
|
||||
}));
|
||||
this._register(diffEditor.getModifiedEditor().onDidFocusEditor(() => {
|
||||
this._register(diffEditor.getModifiedEditor().onDidFocusEditorWidget(() => {
|
||||
if (this._isVisible) {
|
||||
this.hide();
|
||||
}
|
||||
@@ -769,6 +770,7 @@ export class DiffReview extends Disposable {
|
||||
const r = renderViewLine(new RenderLineInput(
|
||||
(config.fontInfo.isMonospace && !config.viewInfo.disableMonospaceOptimizations),
|
||||
lineContent,
|
||||
false,
|
||||
isBasicASCII,
|
||||
containsRTL,
|
||||
0,
|
||||
@@ -809,7 +811,8 @@ class DiffReviewNext extends EditorAction {
|
||||
precondition: ContextKeyExpr.has('isInDiffEditor'),
|
||||
kbOpts: {
|
||||
kbExpr: null,
|
||||
primary: KeyCode.F7
|
||||
primary: KeyCode.F7,
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -831,7 +834,8 @@ class DiffReviewPrev extends EditorAction {
|
||||
precondition: ContextKeyExpr.has('isInDiffEditor'),
|
||||
kbOpts: {
|
||||
kbExpr: null,
|
||||
primary: KeyMod.Shift | KeyCode.F7
|
||||
primary: KeyMod.Shift | KeyCode.F7,
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { CodeEditor } from 'vs/editor/browser/codeEditor';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { IConfigurationChangedEvent, IEditorOptions, IDiffEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
export class EmbeddedCodeEditorWidget extends CodeEditor {
|
||||
export class EmbeddedCodeEditorWidget extends CodeEditorWidget {
|
||||
|
||||
private _parentEditor: ICodeEditor;
|
||||
private _overwriteOptions: IEditorOptions;
|
||||
@@ -33,7 +33,7 @@ export class EmbeddedCodeEditorWidget extends CodeEditor {
|
||||
@IThemeService themeService: IThemeService,
|
||||
@INotificationService notificationService: INotificationService
|
||||
) {
|
||||
super(domElement, parentEditor.getRawConfiguration(), instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService);
|
||||
super(domElement, parentEditor.getRawConfiguration(), {}, instantiationService, codeEditorService, commandService, contextKeyService, themeService, notificationService);
|
||||
|
||||
this._parentEditor = parentEditor;
|
||||
this._overwriteOptions = options;
|
||||
|
||||
Reference in New Issue
Block a user