mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-18 17:25:54 -05:00
Adds new recent changes annotations
This commit is contained in:
@@ -3,19 +3,29 @@ import { Functions, Objects } from '../system';
|
||||
import { DecorationRenderOptions, Disposable, Event, EventEmitter, ExtensionContext, OverviewRulerLane, TextDocument, TextDocumentChangeEvent, TextEditor, TextEditorDecorationType, TextEditorViewColumnChangeEvent, window, workspace } from 'vscode';
|
||||
import { AnnotationProviderBase } from './annotationProvider';
|
||||
import { TextDocumentComparer, TextEditorComparer } from '../comparers';
|
||||
import { BlameLineHighlightLocations, ExtensionKey, FileAnnotationType, IConfig, themeDefaults } from '../configuration';
|
||||
import { ExtensionKey, IConfig, LineHighlightLocations, themeDefaults } from '../configuration';
|
||||
import { BlameabilityChangeEvent, GitContextTracker, GitService, GitUri } from '../gitService';
|
||||
import { GutterBlameAnnotationProvider } from './gutterBlameAnnotationProvider';
|
||||
import { HoverBlameAnnotationProvider } from './hoverBlameAnnotationProvider';
|
||||
import { Logger } from '../logger';
|
||||
import { RecentChangesAnnotationProvider } from './recentChangesAnnotationProvider';
|
||||
import { WhitespaceController } from './whitespaceController';
|
||||
|
||||
export type FileAnnotationType = 'gutter' | 'hover' | 'recentChanges';
|
||||
export const FileAnnotationType = {
|
||||
Gutter: 'gutter' as FileAnnotationType,
|
||||
Hover: 'hover' as FileAnnotationType,
|
||||
RecentChanges: 'recentChanges' as FileAnnotationType
|
||||
};
|
||||
|
||||
export const Decorations = {
|
||||
annotation: window.createTextEditorDecorationType({
|
||||
blameAnnotation: window.createTextEditorDecorationType({
|
||||
isWholeLine: true,
|
||||
textDecoration: 'none'
|
||||
} as DecorationRenderOptions),
|
||||
highlight: undefined as TextEditorDecorationType | undefined
|
||||
blameHighlight: undefined as TextEditorDecorationType | undefined,
|
||||
recentChangesAnnotation: undefined as TextEditorDecorationType | undefined,
|
||||
recentChangesHighlight: undefined as TextEditorDecorationType | undefined
|
||||
};
|
||||
|
||||
export class AnnotationController extends Disposable {
|
||||
@@ -46,8 +56,8 @@ export class AnnotationController extends Disposable {
|
||||
dispose() {
|
||||
this._annotationProviders.forEach(async (p, i) => await this.clear(i));
|
||||
|
||||
Decorations.annotation && Decorations.annotation.dispose();
|
||||
Decorations.highlight && Decorations.highlight.dispose();
|
||||
Decorations.blameAnnotation && Decorations.blameAnnotation.dispose();
|
||||
Decorations.blameHighlight && Decorations.blameHighlight.dispose();
|
||||
|
||||
this._annotationsDisposable && this._annotationsDisposable.dispose();
|
||||
this._whitespaceController && this._whitespaceController.dispose();
|
||||
@@ -82,50 +92,83 @@ export class AnnotationController extends Disposable {
|
||||
}
|
||||
|
||||
const cfg = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
const cfgHighlight = cfg.blame.file.lineHighlight;
|
||||
const cfgBlameHighlight = cfg.blame.file.lineHighlight;
|
||||
const cfgChangesHighlight = cfg.recentChanges.file.lineHighlight;
|
||||
const cfgTheme = cfg.theme.lineHighlight;
|
||||
|
||||
if (!Objects.areEquivalent(cfgHighlight, this._config && this._config.blame.file.lineHighlight) ||
|
||||
if (!Objects.areEquivalent(cfgBlameHighlight, this._config && this._config.blame.file.lineHighlight) ||
|
||||
!Objects.areEquivalent(cfgChangesHighlight, this._config && this._config.recentChanges.file.lineHighlight) ||
|
||||
!Objects.areEquivalent(cfgTheme, this._config && this._config.theme.lineHighlight)) {
|
||||
changed = true;
|
||||
|
||||
Decorations.highlight && Decorations.highlight.dispose();
|
||||
Decorations.blameHighlight && Decorations.blameHighlight.dispose();
|
||||
|
||||
if (cfgHighlight.enabled) {
|
||||
Decorations.highlight = window.createTextEditorDecorationType({
|
||||
if (cfgBlameHighlight.enabled) {
|
||||
Decorations.blameHighlight = window.createTextEditorDecorationType({
|
||||
gutterIconSize: 'contain',
|
||||
isWholeLine: true,
|
||||
overviewRulerLane: OverviewRulerLane.Right,
|
||||
dark: {
|
||||
backgroundColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.Line)
|
||||
backgroundColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.Line)
|
||||
? cfgTheme.dark.backgroundColor || themeDefaults.lineHighlight.dark.backgroundColor
|
||||
: undefined,
|
||||
gutterIconPath: cfgHighlight.locations.includes(BlameLineHighlightLocations.Gutter)
|
||||
gutterIconPath: cfgBlameHighlight.locations.includes(LineHighlightLocations.Gutter)
|
||||
? this.context.asAbsolutePath('images/blame-dark.svg')
|
||||
: undefined,
|
||||
overviewRulerColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.OverviewRuler)
|
||||
overviewRulerColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
|
||||
? cfgTheme.dark.overviewRulerColor || themeDefaults.lineHighlight.dark.overviewRulerColor
|
||||
: undefined
|
||||
},
|
||||
light: {
|
||||
backgroundColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.Line)
|
||||
backgroundColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.Line)
|
||||
? cfgTheme.light.backgroundColor || themeDefaults.lineHighlight.light.backgroundColor
|
||||
: undefined,
|
||||
gutterIconPath: cfgHighlight.locations.includes(BlameLineHighlightLocations.Gutter)
|
||||
gutterIconPath: cfgBlameHighlight.locations.includes(LineHighlightLocations.Gutter)
|
||||
? this.context.asAbsolutePath('images/blame-light.svg')
|
||||
: undefined,
|
||||
overviewRulerColor: cfgHighlight.locations.includes(BlameLineHighlightLocations.OverviewRuler)
|
||||
overviewRulerColor: cfgBlameHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
|
||||
? cfgTheme.light.overviewRulerColor || themeDefaults.lineHighlight.light.overviewRulerColor
|
||||
: undefined
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
Decorations.highlight = undefined;
|
||||
Decorations.blameHighlight = undefined;
|
||||
}
|
||||
|
||||
Decorations.recentChangesHighlight && Decorations.recentChangesHighlight.dispose();
|
||||
|
||||
Decorations.recentChangesHighlight = window.createTextEditorDecorationType({
|
||||
gutterIconSize: 'contain',
|
||||
isWholeLine: true,
|
||||
overviewRulerLane: OverviewRulerLane.Right,
|
||||
dark: {
|
||||
backgroundColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.Line)
|
||||
? cfgTheme.dark.backgroundColor || themeDefaults.lineHighlight.dark.backgroundColor
|
||||
: undefined,
|
||||
gutterIconPath: cfgChangesHighlight.locations.includes(LineHighlightLocations.Gutter)
|
||||
? this.context.asAbsolutePath('images/blame-dark.svg')
|
||||
: undefined,
|
||||
overviewRulerColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
|
||||
? cfgTheme.dark.overviewRulerColor || themeDefaults.lineHighlight.dark.overviewRulerColor
|
||||
: undefined
|
||||
},
|
||||
light: {
|
||||
backgroundColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.Line)
|
||||
? cfgTheme.light.backgroundColor || themeDefaults.lineHighlight.light.backgroundColor
|
||||
: undefined,
|
||||
gutterIconPath: cfgChangesHighlight.locations.includes(LineHighlightLocations.Gutter)
|
||||
? this.context.asAbsolutePath('images/blame-light.svg')
|
||||
: undefined,
|
||||
overviewRulerColor: cfgChangesHighlight.locations.includes(LineHighlightLocations.OverviewRuler)
|
||||
? cfgTheme.light.overviewRulerColor || themeDefaults.lineHighlight.light.overviewRulerColor
|
||||
: undefined
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!Objects.areEquivalent(cfg.blame.file, this._config && this._config.blame.file) ||
|
||||
!Objects.areEquivalent(cfg.recentChanges.file, this._config && this._config.recentChanges.file) ||
|
||||
!Objects.areEquivalent(cfg.annotations, this._config && this._config.annotations) ||
|
||||
!Objects.areEquivalent(cfg.theme.annotations, this._config && this._config.theme.annotations)) {
|
||||
changed = true;
|
||||
@@ -138,7 +181,12 @@ export class AnnotationController extends Disposable {
|
||||
for (const provider of this._annotationProviders.values()) {
|
||||
if (provider === undefined) continue;
|
||||
|
||||
provider.reset(this._whitespaceController);
|
||||
if (provider.annotationType === FileAnnotationType.RecentChanges) {
|
||||
provider.reset(Decorations.recentChangesAnnotation, Decorations.recentChangesHighlight);
|
||||
}
|
||||
else {
|
||||
provider.reset(Decorations.blameAnnotation, Decorations.blameHighlight, this._whitespaceController);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,10 +232,15 @@ export class AnnotationController extends Disposable {
|
||||
let provider: AnnotationProviderBase | undefined = undefined;
|
||||
switch (type) {
|
||||
case FileAnnotationType.Gutter:
|
||||
provider = new GutterBlameAnnotationProvider(this.context, editor, Decorations.annotation, Decorations.highlight, this._whitespaceController, this.git, gitUri);
|
||||
provider = new GutterBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, Decorations.blameHighlight, this._whitespaceController, this.git, gitUri);
|
||||
break;
|
||||
|
||||
case FileAnnotationType.Hover:
|
||||
provider = new HoverBlameAnnotationProvider(this.context, editor, Decorations.annotation, Decorations.highlight, this._whitespaceController, this.git, gitUri);
|
||||
provider = new HoverBlameAnnotationProvider(this.context, editor, Decorations.blameAnnotation, Decorations.blameHighlight, this._whitespaceController, this.git, gitUri);
|
||||
break;
|
||||
|
||||
case FileAnnotationType.RecentChanges:
|
||||
provider = new RecentChangesAnnotationProvider(this.context, editor, undefined, Decorations.recentChangesHighlight!, this.git, gitUri);
|
||||
break;
|
||||
}
|
||||
if (provider === undefined || !(await provider.validate())) return false;
|
||||
@@ -219,13 +272,17 @@ export class AnnotationController extends Disposable {
|
||||
}
|
||||
|
||||
async toggleAnnotations(editor: TextEditor, type: FileAnnotationType, shaOrLine?: string | number): Promise<boolean> {
|
||||
if (!editor || !editor.document || !this.git.isEditorBlameable(editor)) return false;
|
||||
if (!editor || !editor.document || type === FileAnnotationType.RecentChanges ? !this.git.isTrackable(editor.document.uri) : !this.git.isEditorBlameable(editor)) return false;
|
||||
|
||||
const provider = this._annotationProviders.get(editor.viewColumn || -1);
|
||||
if (provider === undefined) return this.showAnnotations(editor, type, shaOrLine);
|
||||
|
||||
const reopen = provider.annotationType !== type;
|
||||
await this.clear(provider.editor.viewColumn || -1);
|
||||
return false;
|
||||
|
||||
if (!reopen) return false;
|
||||
|
||||
return this.showAnnotations(editor, type, shaOrLine);
|
||||
}
|
||||
|
||||
private _onBlameabilityChanged(e: BlameabilityChangeEvent) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
import { Functions } from '../system';
|
||||
import { Disposable, ExtensionContext, TextDocument, TextEditor, TextEditorDecorationType, TextEditorSelectionChangeEvent, window, workspace } from 'vscode';
|
||||
import { FileAnnotationType } from '../annotations/annotationController';
|
||||
import { TextDocumentComparer } from '../comparers';
|
||||
import { ExtensionKey, FileAnnotationType, IConfig } from '../configuration';
|
||||
import { ExtensionKey, IConfig } from '../configuration';
|
||||
import { WhitespaceController } from './whitespaceController';
|
||||
|
||||
export abstract class AnnotationProviderBase extends Disposable {
|
||||
@@ -13,7 +14,7 @@ import { WhitespaceController } from './whitespaceController';
|
||||
protected _config: IConfig;
|
||||
protected _disposable: Disposable;
|
||||
|
||||
constructor(context: ExtensionContext, public editor: TextEditor, protected decoration: TextEditorDecorationType, protected highlightDecoration: TextEditorDecorationType | undefined, protected whitespaceController: WhitespaceController | undefined) {
|
||||
constructor(context: ExtensionContext, public editor: TextEditor, protected decoration: TextEditorDecorationType | undefined, protected highlightDecoration: TextEditorDecorationType | undefined, protected whitespaceController: WhitespaceController | undefined) {
|
||||
super(() => this.dispose());
|
||||
|
||||
this.document = this.editor.document;
|
||||
@@ -42,10 +43,14 @@ import { WhitespaceController } from './whitespaceController';
|
||||
async clear() {
|
||||
if (this.editor !== undefined) {
|
||||
try {
|
||||
this.editor.setDecorations(this.decoration, []);
|
||||
this.highlightDecoration && this.editor.setDecorations(this.highlightDecoration, []);
|
||||
// I have no idea why the decorators sometimes don't get removed, but if they don't try again with a tiny delay
|
||||
if (this.decoration !== undefined) {
|
||||
this.editor.setDecorations(this.decoration, []);
|
||||
}
|
||||
|
||||
if (this.highlightDecoration !== undefined) {
|
||||
this.editor.setDecorations(this.highlightDecoration, []);
|
||||
|
||||
// I have no idea why the decorators sometimes don't get removed, but if they don't try again with a tiny delay
|
||||
await Functions.wait(1);
|
||||
|
||||
if (this.highlightDecoration === undefined) return;
|
||||
@@ -60,10 +65,12 @@ import { WhitespaceController } from './whitespaceController';
|
||||
this.whitespaceController && await this.whitespaceController.restore();
|
||||
}
|
||||
|
||||
async reset(whitespaceController: WhitespaceController | undefined) {
|
||||
async reset(decoration: TextEditorDecorationType | undefined, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController?: WhitespaceController) {
|
||||
await this.clear();
|
||||
|
||||
this._config = workspace.getConfiguration().get<IConfig>(ExtensionKey)!;
|
||||
this.decoration = decoration;
|
||||
this.highlightDecoration = highlightDecoration;
|
||||
this.whitespaceController = whitespaceController;
|
||||
|
||||
await this.provideAnnotation(this.editor === undefined ? undefined : this.editor.selection.active.line);
|
||||
|
||||
@@ -9,7 +9,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
|
||||
|
||||
protected _blame: Promise<GitBlame>;
|
||||
|
||||
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController: WhitespaceController | undefined, protected git: GitService, protected uri: GitUri) {
|
||||
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType | undefined, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController: WhitespaceController | undefined, protected git: GitService, protected uri: GitUri) {
|
||||
super(context, editor, decoration, highlightDecoration, whitespaceController);
|
||||
|
||||
this._blame = this.git.getBlameForFile(this.uri);
|
||||
@@ -56,7 +56,6 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
|
||||
const blame = await this._blame;
|
||||
return blame !== undefined && blame.lines.length !== 0;
|
||||
}
|
||||
|
||||
protected async getBlame(requiresWhitespaceHack: boolean): Promise<GitBlame | undefined> {
|
||||
let whitespacePromise: Promise<void> | undefined;
|
||||
// HACK: Until https://github.com/Microsoft/vscode/issues/11485 is fixed -- override whitespace (turn off)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
'use strict';
|
||||
import { DecorationOptions, ExtensionContext, Position, Range, TextEditor, TextEditorDecorationType } from 'vscode';
|
||||
import { AnnotationProviderBase } from './annotationProvider';
|
||||
import { GitService, GitUri } from '../gitService';
|
||||
import { WhitespaceController } from './whitespaceController';
|
||||
|
||||
export class DiffAnnotationProvider extends AnnotationProviderBase {
|
||||
|
||||
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType, highlightDecoration: TextEditorDecorationType | undefined, whitespaceController: WhitespaceController | undefined, private git: GitService, private uri: GitUri) {
|
||||
super(context, editor, decoration, highlightDecoration, whitespaceController);
|
||||
}
|
||||
|
||||
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
|
||||
// let sha1: string | undefined = undefined;
|
||||
// let sha2: string | undefined = undefined;
|
||||
// if (shaOrLine === undefined) {
|
||||
// const commit = await this.git.getLogCommit(this.uri.repoPath, this.uri.fsPath, { previous: true });
|
||||
// if (commit === undefined) return false;
|
||||
|
||||
// sha1 = commit.previousSha;
|
||||
// }
|
||||
// else if (typeof shaOrLine === 'string') {
|
||||
// sha1 = shaOrLine;
|
||||
// }
|
||||
// else {
|
||||
// const blame = await this.git.getBlameForLine(this.uri, shaOrLine);
|
||||
// if (blame === undefined) return false;
|
||||
|
||||
// sha1 = blame.commit.previousSha;
|
||||
// sha2 = blame.commit.sha;
|
||||
// }
|
||||
|
||||
// if (sha1 === undefined) return false;
|
||||
|
||||
const commit = await this.git.getLogCommit(this.uri.repoPath, this.uri.fsPath, { previous: true });
|
||||
if (commit === undefined) return false;
|
||||
|
||||
const diff = await this.git.getDiffForFile(this.uri, commit.previousSha);
|
||||
if (diff === undefined) return false;
|
||||
|
||||
const decorators: DecorationOptions[] = [];
|
||||
|
||||
for (const chunk of diff.chunks) {
|
||||
let count = chunk.currentPosition.start - 2;
|
||||
for (const change of chunk.current) {
|
||||
if (change === undefined) continue;
|
||||
|
||||
count++;
|
||||
|
||||
if (change.state === 'unchanged') continue;
|
||||
|
||||
decorators.push({
|
||||
range: new Range(new Position(count, 0), new Position(count, 0))
|
||||
} as DecorationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
this.editor.setDecorations(this.decoration, decorators);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async selection(shaOrLine?: string | number): Promise<void> {
|
||||
}
|
||||
|
||||
async validate(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
import { Strings } from '../system';
|
||||
import { DecorationOptions, Range } from 'vscode';
|
||||
import { FileAnnotationType } from './annotationController';
|
||||
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
|
||||
import { Annotations, endOfLineIndex } from './annotations';
|
||||
import { FileAnnotationType } from '../configuration';
|
||||
import { ICommitFormatOptions } from '../gitService';
|
||||
import * as moment from 'moment';
|
||||
|
||||
@@ -67,7 +67,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase {
|
||||
}
|
||||
|
||||
if (decorations.length) {
|
||||
this.editor.setDecorations(this.decoration, decorations);
|
||||
this.editor.setDecorations(this.decoration!, decorations);
|
||||
}
|
||||
|
||||
this.selection(shaOrLine, blame);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
import { DecorationOptions, Range } from 'vscode';
|
||||
import { FileAnnotationType } from './annotationController';
|
||||
import { BlameAnnotationProviderBase } from './blameAnnotationProvider';
|
||||
import { Annotations, endOfLineIndex } from './annotations';
|
||||
import { FileAnnotationType } from '../configuration';
|
||||
import * as moment from 'moment';
|
||||
|
||||
export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
|
||||
@@ -40,7 +40,7 @@ export class HoverBlameAnnotationProvider extends BlameAnnotationProviderBase {
|
||||
}
|
||||
|
||||
if (decorations.length) {
|
||||
this.editor.setDecorations(this.decoration, decorations);
|
||||
this.editor.setDecorations(this.decoration!, decorations);
|
||||
}
|
||||
|
||||
this.selection(shaOrLine, blame);
|
||||
|
||||
61
src/annotations/recentChangesAnnotationProvider.ts
Normal file
61
src/annotations/recentChangesAnnotationProvider.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
'use strict';
|
||||
import { DecorationOptions, ExtensionContext, Position, Range, TextEditor, TextEditorDecorationType } from 'vscode';
|
||||
import { endOfLineIndex } from './annotations';
|
||||
import { FileAnnotationType } from './annotationController';
|
||||
import { AnnotationProviderBase } from './annotationProvider';
|
||||
import { CommitFormatter, GitService, GitUri } from '../gitService';
|
||||
|
||||
export class RecentChangesAnnotationProvider extends AnnotationProviderBase {
|
||||
|
||||
constructor(context: ExtensionContext, editor: TextEditor, decoration: TextEditorDecorationType | undefined, highlightDecoration: TextEditorDecorationType | undefined, private git: GitService, private uri: GitUri) {
|
||||
super(context, editor, decoration, highlightDecoration, undefined);
|
||||
}
|
||||
|
||||
async provideAnnotation(shaOrLine?: string | number): Promise<boolean> {
|
||||
this.annotationType = FileAnnotationType.RecentChanges;
|
||||
|
||||
const commit = await this.git.getLogCommit(this.uri.repoPath, this.uri.fsPath, { previous: true });
|
||||
if (commit === undefined) return false;
|
||||
|
||||
const diff = await this.git.getDiffForFile(this.uri, commit.previousSha);
|
||||
if (diff === undefined) return false;
|
||||
|
||||
const cfg = this._config.annotations.file.recentChanges;
|
||||
|
||||
const decorators: DecorationOptions[] = [];
|
||||
|
||||
for (const chunk of diff.chunks) {
|
||||
let count = chunk.currentPosition.start - 2;
|
||||
for (const change of chunk.current) {
|
||||
if (change === undefined) continue;
|
||||
|
||||
count++;
|
||||
|
||||
if (change.state === 'unchanged') continue;
|
||||
|
||||
let endingIndex = 0;
|
||||
let message: string | undefined = undefined;
|
||||
if (cfg.hover.changes) {
|
||||
message = CommitFormatter.toHoverDiff(commit, chunk.previous[count], change);
|
||||
endingIndex = cfg.hover.wholeLine ? endOfLineIndex : this.editor.document.lineAt(count).firstNonWhitespaceCharacterIndex;
|
||||
}
|
||||
|
||||
decorators.push({
|
||||
hoverMessage: message,
|
||||
range: this.editor.document.validateRange(new Range(new Position(count, 0), new Position(count, endingIndex)))
|
||||
} as DecorationOptions);
|
||||
}
|
||||
}
|
||||
|
||||
this.editor.setDecorations(this.highlightDecoration!, decorators);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async selection(shaOrLine?: string | number): Promise<void> {
|
||||
}
|
||||
|
||||
async validate(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user