Highlight active indent guide (closes #14017)

This commit is contained in:
Alex Dima 2018-04-18 18:31:05 +02:00
parent 4686ca2e6e
commit 0100518547
16 changed files with 87 additions and 12 deletions

View File

@ -309,6 +309,7 @@
"editor.lineHighlightBackground": "#082050",
"editor.selectionBackground": "#770811",
"editorIndentGuide.background": "#002952",
"editorIndentGuide.activeBackground": "#204972",
"editorHoverWidget.background": "#000c38",
"editorHoverWidget.border": "#004c18",
"editorLineNumber.foreground": "#406385",

View File

@ -6,6 +6,7 @@
"editor.foreground": "#D4D4D4",
"editor.inactiveSelectionBackground": "#3A3D41",
"editorIndentGuide.background": "#404040",
"editorIndentGuide.activeBackground": "#707070",
"editor.selectionHighlightBackground": "#ADD6FF26",
"list.dropBackground": "#383B3D",
"activityBarBadge.background": "#007ACC",

View File

@ -5,6 +5,7 @@
"editor.background": "#000000",
"editor.foreground": "#FFFFFF",
"editorIndentGuide.background": "#FFFFFF",
"editorIndentGuide.activeBackground": "#FFFFFF",
"sideBarTitle.foreground": "#FFFFFF"
},
"settings": [

View File

@ -6,6 +6,7 @@
"editor.foreground": "#000000",
"editor.inactiveSelectionBackground": "#E5EBF1",
"editorIndentGuide.background": "#D3D3D3",
"editorIndentGuide.activeBackground": "#939393",
"editor.selectionHighlightBackground": "#ADD6FF4D",
"editorSuggestWidget.background": "#F3F3F3",
"activityBarBadge.background": "#007ACC",

View File

@ -19,6 +19,7 @@
"editorCursor.foreground": "#c07020",
"editorWhitespace.foreground": "#505037",
"editorIndentGuide.background": "#505037",
"editorIndentGuide.activeBackground": "#707057",
"editorGroupHeader.tabsBackground": "#282828",
"editorGroup.background": "#1e1e1e",
"tab.inactiveBackground": "#404040",

View File

@ -28,6 +28,7 @@
"editorCursor.foreground": "#f8f8f0",
"editorWhitespace.foreground": "#464741",
"editorIndentGuide.background": "#464741",
"editorIndentGuide.activeBackground": "#767771",
"editorGroupHeader.tabsBackground": "#1e1f1c",
"editorGroup.dropBackground": "#41433980",
"tab.inactiveBackground": "#414339",

View File

@ -357,7 +357,8 @@
"editor.lineHighlightBackground": "#073642",
"editorLineNumber.activeForeground": "#949494",
"editor.selectionBackground": "#073642",
// "editorIndentGuide.background": "",
"editorIndentGuide.background": "#93A1A180",
"editorIndentGuide.activeBackground": "#C3E1E180",
"editorHoverWidget.background": "#004052",
// "editorHoverWidget.border": "",
// "editorLineNumber.foreground": "",

View File

@ -352,7 +352,8 @@
"editorWhitespace.foreground": "#586E7580",
"editor.lineHighlightBackground": "#EEE8D5",
"editor.selectionBackground": "#EEE8D5",
// "editorIndentGuide.background": "",
"editorIndentGuide.background": "#586E7580",
"editorIndentGuide.activeBackground": "#081E2580",
"editorHoverWidget.background": "#CCC4B0",
"editorLineNumber.activeForeground": "#567983",
// "editorHoverWidget.border": "",

View File

@ -10,3 +10,6 @@
.monaco-editor .lines-content .cigr {
position: absolute;
}
.monaco-editor .lines-content .cigra {
position: absolute;
}

View File

@ -11,12 +11,13 @@ import { ViewContext } from 'vs/editor/common/view/viewContext';
import { RenderingContext } from 'vs/editor/common/view/renderingContext';
import * as viewEvents from 'vs/editor/common/view/viewEvents';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { editorIndentGuides } from 'vs/editor/common/view/editorColorRegistry';
import { editorIndentGuides, editorActiveIndentGuides } from 'vs/editor/common/view/editorColorRegistry';
import { Position } from 'vs/editor/common/core/position';
export class IndentGuidesOverlay extends DynamicViewOverlay {
private _context: ViewContext;
private _primaryLineNumber: number;
private _lineHeight: number;
private _spaceWidth: number;
private _renderResult: string[];
@ -25,6 +26,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
constructor(context: ViewContext) {
super();
this._context = context;
this._primaryLineNumber = 0;
this._lineHeight = this._context.configuration.editor.lineHeight;
this._spaceWidth = this._context.configuration.editor.fontInfo.spaceWidth;
this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides;
@ -54,6 +56,17 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
}
return true;
}
public onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
const selection = e.selections[0];
const newPrimaryLineNumber = selection.isEmpty() ? selection.positionLineNumber : 0;
if (this._primaryLineNumber !== newPrimaryLineNumber) {
this._primaryLineNumber = newPrimaryLineNumber;
return true;
}
return false;
}
public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean {
// true for inline decorations
return true;
@ -97,16 +110,28 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
const indents = this._context.model.getLinesIndentGuides(visibleStartLineNumber, visibleEndLineNumber);
let activeIndentStartLineNumber = 0;
let activeIndentEndLineNumber = 0;
let activeIndentLevel = 0;
if (this._primaryLineNumber) {
const activeIndentInfo = this._context.model.getActiveIndentGuide(this._primaryLineNumber);
activeIndentStartLineNumber = activeIndentInfo.startLineNumber;
activeIndentEndLineNumber = activeIndentInfo.endLineNumber;
activeIndentLevel = activeIndentInfo.indent;
}
let output: string[] = [];
for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) {
const containsActiveIndentGuide = (activeIndentStartLineNumber <= lineNumber && lineNumber <= activeIndentEndLineNumber);
const lineIndex = lineNumber - visibleStartLineNumber;
const indent = indents[lineIndex];
let result = '';
let leftMostVisiblePosition = ctx.visibleRangeForPosition(new Position(lineNumber, 1));
let left = leftMostVisiblePosition ? leftMostVisiblePosition.left : 0;
for (let i = 0; i < indent; i++) {
result += `<div class="cigr" style="left:${left}px;height:${lineHeight}px;width:${indentGuideWidth}px"></div>`;
for (let i = 1; i <= indent; i++) {
let className = (containsActiveIndentGuide && i === activeIndentLevel ? 'cigra' : 'cigr');
result += `<div class="${className}" style="left:${left}px;height:${lineHeight}px;width:${indentGuideWidth}px"></div>`;
left += tabWidth;
}
@ -128,8 +153,12 @@ export class IndentGuidesOverlay extends DynamicViewOverlay {
}
registerThemingParticipant((theme, collector) => {
let editorGuideColor = theme.getColor(editorIndentGuides);
if (editorGuideColor) {
collector.addRule(`.monaco-editor .lines-content .cigr { box-shadow: 1px 0 0 0 ${editorGuideColor} inset; }`);
let editorIndentGuidesColor = theme.getColor(editorIndentGuides);
if (editorIndentGuidesColor) {
collector.addRule(`.monaco-editor .lines-content .cigr { box-shadow: 1px 0 0 0 ${editorIndentGuidesColor} inset; }`);
}
let editorActiveIndentGuidesColor = theme.getColor(editorActiveIndentGuides) || editorIndentGuidesColor;
if (editorActiveIndentGuidesColor) {
collector.addRule(`.monaco-editor .lines-content .cigra { box-shadow: 1px 0 0 0 ${editorActiveIndentGuidesColor} inset; }`);
}
});

View File

@ -20,6 +20,7 @@ export const editorCursorForeground = registerColor('editorCursor.foreground', {
export const editorCursorBackground = registerColor('editorCursor.background', null, nls.localize('editorCursorBackground', 'The background color of the editor cursor. Allows customizing the color of a character overlapped by a block cursor.'));
export const editorWhitespaces = registerColor('editorWhitespace.foreground', { dark: '#e3e4e229', light: '#33333333', hc: '#e3e4e229' }, nls.localize('editorWhitespaces', 'Color of whitespace characters in the editor.'));
export const editorIndentGuides = registerColor('editorIndentGuide.background', { dark: editorWhitespaces, light: editorWhitespaces, hc: editorWhitespaces }, nls.localize('editorIndentGuides', 'Color of the editor indentation guides.'));
export const editorActiveIndentGuides = registerColor('editorIndentGuide.activeBackground', { dark: editorWhitespaces, light: editorWhitespaces, hc: editorWhitespaces }, nls.localize('editorActiveIndentGuide', 'Color of the active editor indentation guides.'));
export const editorLineNumbers = registerColor('editorLineNumber.foreground', { dark: '#5A5A5A', light: '#2B91AF', hc: Color.white }, nls.localize('editorLineNumbers', 'Color of editor line numbers.'));
const deprecatedEditorActiveLineNumber = registerColor('editorActiveLineNumber.foreground', { dark: null, light: null, hc: null }, nls.localize('editorActiveLineNumber', 'Color of editor active line number'), false, nls.localize('deprecatedEditorActiveLineNumber', 'Id is deprecated. Use \'editorLineNumber.activeForeground\' instead.'));

View File

@ -14,7 +14,7 @@ import { WrappingIndent } from 'vs/editor/common/config/editorOptions';
import { ModelDecorationOptions, ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModel';
import { ThemeColor, ITheme } from 'vs/platform/theme/common/themeService';
import { Color } from 'vs/base/common/color';
import { IModelDecoration, ITextModel, IModelDeltaDecoration, EndOfLinePreference } from 'vs/editor/common/model';
import { IModelDecoration, ITextModel, IModelDeltaDecoration, EndOfLinePreference, IActiveIndentGuideInfo } from 'vs/editor/common/model';
export class OutputPosition {
_outputPositionBrand: void;
@ -82,6 +82,7 @@ export interface IViewModelLinesCollection {
getViewLineCount(): number;
warmUpLookupCache(viewStartLineNumber: number, viewEndLineNumber: number): void;
getActiveIndentGuide(viewLineNumber: number): IActiveIndentGuideInfo;
getViewLinesIndentGuides(viewStartLineNumber: number, viewEndLineNumber: number): number[];
getViewLineContent(viewLineNumber: number): string;
getViewLineLength(viewLineNumber: number): number;
@ -504,6 +505,22 @@ export class SplitLinesCollection implements IViewModelLinesCollection {
this.prefixSumComputer.warmUpCache(viewStartLineNumber - 1, viewEndLineNumber - 1);
}
public getActiveIndentGuide(viewLineNumber: number): IActiveIndentGuideInfo {
this._ensureValidState();
viewLineNumber = this._toValidViewLineNumber(viewLineNumber);
const modelPosition = this.convertViewPositionToModelPosition(viewLineNumber, this.getViewLineMinColumn(viewLineNumber));
const result = this.model.getActiveIndentGuide(modelPosition.lineNumber);
const viewStartPosition = this.convertModelPositionToViewPosition(result.startLineNumber, 1);
const viewEndPosition = this.convertModelPositionToViewPosition(result.endLineNumber, 1);
return {
startLineNumber: viewStartPosition.lineNumber,
endLineNumber: viewEndPosition.lineNumber,
indent: result.indent
};
}
public getViewLinesIndentGuides(viewStartLineNumber: number, viewEndLineNumber: number): number[] {
this._ensureValidState();
viewStartLineNumber = this._toValidViewLineNumber(viewStartLineNumber);
@ -1241,6 +1258,14 @@ export class IdentityLinesCollection implements IViewModelLinesCollection {
public warmUpLookupCache(viewStartLineNumber: number, viewEndLineNumber: number): void {
}
public getActiveIndentGuide(viewLineNumber: number): IActiveIndentGuideInfo {
return {
startLineNumber: viewLineNumber,
endLineNumber: viewLineNumber,
indent: 0
};
}
public getViewLinesIndentGuides(viewStartLineNumber: number, viewEndLineNumber: number): number[] {
const viewLineCount = viewEndLineNumber - viewStartLineNumber + 1;
let result = new Array<number>(viewLineCount);

View File

@ -5,7 +5,7 @@
'use strict';
import { INewScrollPosition } from 'vs/editor/common/editorCommon';
import { EndOfLinePreference, IModelDecorationOptions } from 'vs/editor/common/model';
import { EndOfLinePreference, IModelDecorationOptions, IActiveIndentGuideInfo } from 'vs/editor/common/model';
import { IViewLineTokens } from 'vs/editor/common/core/lineTokens';
import { Position, IPosition } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
@ -132,6 +132,7 @@ export interface IViewModel {
getLineCount(): number;
getLineContent(lineNumber: number): string;
getLineLength(lineNumber: number): number;
getActiveIndentGuide(lineNumber: number): IActiveIndentGuideInfo;
getLinesIndentGuides(startLineNumber: number, endLineNumber: number): number[];
getLineMinColumn(lineNumber: number): number;
getLineMaxColumn(lineNumber: number): number;

View File

@ -23,7 +23,7 @@ import { Color } from 'vs/base/common/color';
import { IDisposable } from 'vs/base/common/lifecycle';
import { ITheme } from 'vs/platform/theme/common/themeService';
import { ModelDecorationOverviewRulerOptions } from 'vs/editor/common/model/textModel';
import { ITextModel, EndOfLinePreference, TrackedRangeStickiness } from 'vs/editor/common/model';
import { ITextModel, EndOfLinePreference, TrackedRangeStickiness, IActiveIndentGuideInfo } from 'vs/editor/common/model';
const USE_IDENTITY_LINES_COLLECTION = true;
@ -451,6 +451,10 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
this.viewportStartLineTop = this.viewLayout.getVerticalOffsetForLineNumber(startLineNumber);
}
public getActiveIndentGuide(lineNumber: number): IActiveIndentGuideInfo {
return this.lines.getActiveIndentGuide(lineNumber);
}
public getLinesIndentGuides(startLineNumber: number, endLineNumber: number): number[] {
return this.lines.getViewLinesIndentGuides(startLineNumber, endLineNumber);
}

View File

@ -7,7 +7,7 @@
import { IStandaloneThemeData } from 'vs/editor/standalone/common/standaloneThemeService';
import { editorBackground, editorForeground, editorSelectionHighlight, editorInactiveSelection } from 'vs/platform/theme/common/colorRegistry';
import { editorIndentGuides } from 'vs/editor/common/view/editorColorRegistry';
import { editorIndentGuides, editorActiveIndentGuides } from 'vs/editor/common/view/editorColorRegistry';
/* -------------------------------- Begin vs theme -------------------------------- */
export const vs: IStandaloneThemeData = {
@ -74,6 +74,7 @@ export const vs: IStandaloneThemeData = {
[editorForeground]: '#000000',
[editorInactiveSelection]: '#E5EBF1',
[editorIndentGuides]: '#D3D3D3',
[editorActiveIndentGuides]: '#939393',
[editorSelectionHighlight]: '#ADD6FF4D'
}
};
@ -144,6 +145,7 @@ export const vs_dark: IStandaloneThemeData = {
[editorForeground]: '#D4D4D4',
[editorInactiveSelection]: '#3A3D41',
[editorIndentGuides]: '#404040',
[editorActiveIndentGuides]: '#707070',
[editorSelectionHighlight]: '#ADD6FF26'
}
};
@ -205,6 +207,7 @@ export const hc_black: IStandaloneThemeData = {
[editorBackground]: '#000000',
[editorForeground]: '#FFFFFF',
[editorIndentGuides]: '#FFFFFF',
[editorActiveIndentGuides]: '#FFFFFF',
}
};
/* -------------------------------- End hc-black theme -------------------------------- */

View File

@ -66,6 +66,7 @@ addSettingMapping('rangeHighlight', editorColorRegistry.editorRangeHighlight);
addSettingMapping('caret', editorColorRegistry.editorCursorForeground);
addSettingMapping('invisibles', editorColorRegistry.editorWhitespaces);
addSettingMapping('guide', editorColorRegistry.editorIndentGuides);
addSettingMapping('activeGuide', editorColorRegistry.editorActiveIndentGuides);
const ansiColorMap = ['ansiBlack', 'ansiRed', 'ansiGreen', 'ansiYellow', 'ansiBlue', 'ansiMagenta', 'ansiCyan', 'ansiWhite',
'ansiBrightBlack', 'ansiBrightRed', 'ansiBrightGreen', 'ansiBrightYellow', 'ansiBrightBlue', 'ansiBrightMagenta', 'ansiBrightCyan', 'ansiBrightWhite'