Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement configurable cursor style #1586

Closed
wants to merge 8 commits into from
2 changes: 1 addition & 1 deletion extensions/node-debug/node-debug.azure.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"account": "monacobuild",
"container": "debuggers",
"zip": "5c4669d/node-debug.zip",
"zip": "69132db/node-debug.zip",
"output": ""
}
42 changes: 42 additions & 0 deletions src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ import DomUtils = require('vs/base/browser/dom');
import EditorBrowser = require('vs/editor/browser/editorBrowser');
import EditorCommon = require('vs/editor/common/editorCommon');

export enum CursorStyle {
line,
block
}

const CursorStyleNames = ((e:any) => {
let i = 0, items = [];
while (true) {
if (e[i]) {
items.push(e[i]);
} else {
return items;
}
i++;
}
})(CursorStyle);

const CursorClassNames = CursorStyleNames.map(n => 'cursor-' + n);

export class ViewCursor {
private _context:EditorBrowser.IViewContext;
private _position: EditorCommon.IPosition;
Expand All @@ -18,13 +37,15 @@ export class ViewCursor {
private _isInEditableRange:boolean;
private _isVisible:boolean;
private _isInViewport:boolean;
private _cursorStyle:CursorStyle;

constructor(context:EditorBrowser.IViewContext, isSecondary:boolean) {
this._context = context;

this._isInEditableRange = true;

this._domNode = this._createCursorDomNode(isSecondary);
this.setStyle(CursorStyle[context.configuration.editor.cursorStyle || 'line'] || CursorStyle.line);
this._isVisible = true;
DomUtils.StyleMutator.setDisplay(this._domNode, 'none');
this.updatePosition({
Expand Down Expand Up @@ -120,6 +141,27 @@ export class ViewCursor {
}
}

public setStyle(style:CursorStyle): void {
if (this._cursorStyle === style) {
return;
}
this._cursorStyle = style;

let newStyleClass = 'cursor-' + CursorStyle[style];
if (this._domNode.classList.contains(newStyleClass)) {
return;
}

this._domNode.classList.remove(...CursorClassNames);
this._domNode.classList.add('cursor-' + CursorStyle[style]);
}

private removeCursorClass(c:string) {
if (this._domNode.classList.contains(c)) {
this._domNode.classList.remove(c);
}
}

private updatePosition(newPosition:EditorCommon.IPosition): void {
this._position = newPosition;
this._domNode.setAttribute('lineNumber', this._position.lineNumber.toString());
Expand Down
11 changes: 11 additions & 0 deletions src/vs/editor/browser/viewParts/viewCursors/viewCursors.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@
}

.monaco-editor .cursors-layer > .cursor {
position: absolute;
cursor: text;
}

.monaco-editor .cursors-layer > .cursor-line {
position: absolute;
width: 2px;
cursor: text;
}

.monaco-editor .cursors-layer > .cursor-block {
position: absolute;
width: 1ch;
cursor: text;
}

.monaco-editor .cursors-layer > .cursor.secondary {
width: 1px;
opacity: 0.6;
Expand Down
15 changes: 14 additions & 1 deletion src/vs/editor/browser/viewParts/viewCursors/viewCursors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import 'vs/css!./viewCursors';
import Browser = require('vs/base/browser/browser');

import {ViewCursor} from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
import {ViewCursor, CursorStyle} from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
import {ViewPart} from 'vs/editor/browser/view/viewPart';
import EditorBrowser = require('vs/editor/browser/editorBrowser');
import EditorCommon = require('vs/editor/common/editorCommon');
Expand Down Expand Up @@ -52,6 +52,7 @@ export class ViewCursors extends ViewPart {

this._editorHasFocus = false;
this._updateBlinking();
this._updateCursorStyle();
}

public dispose(): void {
Expand Down Expand Up @@ -107,6 +108,7 @@ export class ViewCursors extends ViewPart {
public onCursorPositionChanged(e:EditorCommon.IViewCursorPositionChangedEvent): boolean {
this._primaryCursor.onCursorPositionChanged(e.position, e.isInEditableRange);
this._updateBlinking();
this._updateCursorStyle();

if (this._secondaryCursors.length < e.secondaryPositions.length) {
// Create new cursors
Expand Down Expand Up @@ -137,6 +139,7 @@ export class ViewCursors extends ViewPart {
public onConfigurationChanged(e:EditorCommon.IConfigurationChangedEvent): boolean {
this._primaryCursor.onConfigurationChanged(e);
this._updateBlinking();
this._updateCursorStyle();
for (var i = 0, len = this._secondaryCursors.length; i < len; i++) {
this._secondaryCursors[i].onConfigurationChanged(e);
}
Expand All @@ -160,6 +163,7 @@ export class ViewCursors extends ViewPart {
public onViewFocusChanged(isFocused:boolean): boolean {
this._editorHasFocus = isFocused;
this._updateBlinking();
this._updateCursorStyle();
return false;
}
// --- end event handlers
Expand Down Expand Up @@ -209,6 +213,15 @@ export class ViewCursors extends ViewPart {
}
// --- end blinking logic

private _getCursorStyle(): CursorStyle {
return CursorStyle[this._context.configuration.editor.cursorStyle || 'line'] || CursorStyle.line;
}

private _updateCursorStyle(): void {
this._primaryCursor.setStyle(this._getCursorStyle());
}


private _blink(): void {
if (this._isVisible) {
this._hide();
Expand Down
8 changes: 8 additions & 0 deletions src/vs/editor/common/config/commonEditorConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class InternalEditorOptionsHelper {
scrollbar: scrollbar,
overviewRulerLanes: toInteger(opts.overviewRulerLanes, 0, 3),
cursorBlinking: opts.cursorBlinking,
cursorStyle: opts.cursorStyle,
hideCursorInOverviewRuler: toBoolean(opts.hideCursorInOverviewRuler),
scrollBeyondLastLine: toBoolean(opts.scrollBeyondLastLine),
wrappingIndent: opts.wrappingIndent,
Expand Down Expand Up @@ -238,6 +239,7 @@ class InternalEditorOptionsHelper {
scrollbar: (!this._scrollbarOptsEqual(prevOpts.scrollbar, newOpts.scrollbar)),
overviewRulerLanes: (prevOpts.overviewRulerLanes !== newOpts.overviewRulerLanes),
cursorBlinking: (prevOpts.cursorBlinking !== newOpts.cursorBlinking),
cursorStyle: (prevOpts.cursorStyle !== newOpts.cursorStyle),
hideCursorInOverviewRuler: (prevOpts.hideCursorInOverviewRuler !== newOpts.hideCursorInOverviewRuler),
scrollBeyondLastLine: (prevOpts.scrollBeyondLastLine !== newOpts.scrollBeyondLastLine),
wrappingIndent: (prevOpts.wrappingIndent !== newOpts.wrappingIndent),
Expand Down Expand Up @@ -802,6 +804,12 @@ configurationRegistry.registerConfiguration({
'default': DefaultConfig.editor.cursorBlinking,
'description': nls.localize('cursorBlinking', "Controls the cursor blinking animation, accepted values are 'blink', 'visible', and 'hidden'")
},
'editor.cursorStyle' : {
'type': 'string',
'enum': ['block', 'line'],
'default': DefaultConfig.editor.cursorStyle,
'description': nls.localize('cursorStyle', "Controls the cursor style, accepted values are 'block' and 'line'")
},
'editor.hideCursorInOverviewRuler' : {
'type': 'boolean',
'default': DefaultConfig.editor.hideCursorInOverviewRuler,
Expand Down
1 change: 1 addition & 0 deletions src/vs/editor/common/config/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ConfigClass implements IConfiguration {
},
overviewRulerLanes: 2,
cursorBlinking: 'blink',
cursorStyle: 'line',
hideCursorInOverviewRuler: false,
scrollBeyondLastLine: true,
automaticLayout: false,
Expand Down
7 changes: 7 additions & 0 deletions src/vs/editor/common/editorCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ export interface ICommonEditorOptions {
* Defaults to 'blink'.
*/
cursorBlinking?:string;
/**
* Control the cursor style, either 'block' or 'line'.
* Defaults to 'line'.
*/
cursorStyle?:string;
/**
* Should the cursor be hidden in the overview ruler.
* Defaults to false.
Expand Down Expand Up @@ -585,6 +590,7 @@ export interface IInternalEditorOptions {
scrollbar:IInternalEditorScrollbarOptions;
overviewRulerLanes:number;
cursorBlinking:string;
cursorStyle:string;
hideCursorInOverviewRuler:boolean;
scrollBeyondLastLine:boolean;
wrappingIndent: string;
Expand Down Expand Up @@ -676,6 +682,7 @@ export interface IConfigurationChangedEvent {
scrollbar:boolean;
overviewRulerLanes:boolean;
cursorBlinking:boolean;
cursorStyle:boolean;
hideCursorInOverviewRuler:boolean;
scrollBeyondLastLine:boolean;
wrappingIndent:boolean;
Expand Down
6 changes: 4 additions & 2 deletions src/vs/vscode.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2362,8 +2362,9 @@ declare namespace vscode {
* Reveal this channel in the UI.
*
* @param column The column in which to show the channel, default in [one](#ViewColumn.One).
* @param preserveFocus When `true` the channel will not take focus.
*/
show(column?: ViewColumn): void;
show(column?: ViewColumn, preserveFocus?: boolean): void;

/**
* Hide this channel from the UI.
Expand Down Expand Up @@ -2708,9 +2709,10 @@ declare namespace vscode {
* @param document A text document to be shown.
* @param column A view column in which the editor should be shown. The default is the [one](#ViewColumn.One), other values
* are adjusted to be __Min(column, columnCount + 1)__.
* @param preserveFocus When `true` the editor will not take focus.
* @return A promise that resolves to an [editor](#TextEditor).
*/
export function showTextDocument(document: TextDocument, column?: ViewColumn): Thenable<TextEditor>;
export function showTextDocument(document: TextDocument, column?: ViewColumn, preserveFocus?: boolean): Thenable<TextEditor>;

/**
* Create a TextEditorDecorationType that can be used to add decorations to text editors.
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/api/common/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ export class ExtHostAPIImplementation {
get visibleTextEditors() {
return pluginHostEditors.getVisibleTextEditors();
},
showTextDocument(document: vscode.TextDocument, column: vscode.ViewColumn): TPromise<vscode.TextEditor> {
return pluginHostEditors.showTextDocument(document, column);
showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean): TPromise<vscode.TextEditor> {
return pluginHostEditors.showTextDocument(document, column, preserveFocus);
},
createTextEditorDecorationType(options:vscode.DecorationRenderOptions): vscode.TextEditorDecorationType {
return pluginHostEditors.createTextEditorDecorationType(options);
Expand Down
8 changes: 4 additions & 4 deletions src/vs/workbench/api/common/extHostEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export class ExtHostEditors {
return this._onDidChangeActiveTextEditor && this._onDidChangeActiveTextEditor.event;
}

showTextDocument(document: TextDocument, column: ViewColumn): TPromise<vscode.TextEditor> {
return this._proxy._tryShowTextDocument(<URI> document.uri, TypeConverters.fromViewColumn(column)).then(id => {
showTextDocument(document: TextDocument, column: ViewColumn, preserveFocus: boolean): TPromise<vscode.TextEditor> {
return this._proxy._tryShowTextDocument(<URI> document.uri, TypeConverters.fromViewColumn(column), preserveFocus).then(id => {
let editor = this._editors[id];
if (editor) {
return editor;
Expand Down Expand Up @@ -525,12 +525,12 @@ export class MainThreadEditors {

// --- from plugin host process

_tryShowTextDocument(resource: URI, position: EditorPosition): TPromise<string> {
_tryShowTextDocument(resource: URI, position: EditorPosition, preserveFocus: boolean): TPromise<string> {

// the input we want to open
let input = {
resource,
options: { preserveFocus: false }
options: { preserveFocus }
};

return this._workbenchEditorService.openEditor(input, position).then(editor => {
Expand Down
8 changes: 4 additions & 4 deletions src/vs/workbench/api/common/extHostOutputService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export class ExtHostOutputChannel implements vscode.OutputChannel {
this._proxy.clear(this._name);
}

show(column?: vscode.ViewColumn): void {
this._proxy.reveal(this._name, TypeConverters.fromViewColumn(column));
show(column?: vscode.ViewColumn, preserveFocus?: boolean): void {
this._proxy.reveal(this._name, TypeConverters.fromViewColumn(column), preserveFocus);
}

hide(): void {
Expand Down Expand Up @@ -95,8 +95,8 @@ export class MainThreadOutputService {
return undefined;
}

public reveal(channel: string, position: Position): TPromise<void> {
this._outputService.showOutput(channel, position);
public reveal(channel: string, position: Position, preserveFocus: boolean): TPromise<void> {
this._outputService.showOutput(channel, position, preserveFocus);
return undefined;
}

Expand Down
2 changes: 2 additions & 0 deletions src/vs/workbench/parts/debug/common/debugProtocol.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ declare module DebugProtocol {
path?: string;
/** If sourceReference > 0 the contents of the source can be retrieved through the SourceRequest. A sourceReference is only valid for a session, so it must not be used to persist a source. */
sourceReference?: number;
/** The (optional) origin of this source: possible values "internal module", "inlined content from source map" */
origin?: string;
}

/** A Stackframe contains the source location. */
Expand Down