Skip to content

Commit

Permalink
word based highlight for unsupported languages
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonlyu123 committed Jan 17, 2024
1 parent a6ce555 commit 27b5122
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {
DocumentHighlight,
DocumentHighlightKind,
Position,
Range
} from 'vscode-languageserver-types';
import { Document, TagInformation } from '../documents';

export function wordHighlightForTag(
document: Document,
position: Position,
tag: TagInformation | null,
wordPattern: RegExp
): DocumentHighlight[] | null {
if (!tag || tag.start === tag.end) {
return null;
}

const offset = document.offsetAt(position);

const text = document.getText();
if (
offset < tag.start ||
offset > tag.end ||
// empty before and after the cursor
!text.slice(offset - 1, offset + 1).trim()
) {
return null;
}

const word = wordAt(document, position, wordPattern);
if (!word) {
return null;
}

const searching = document.getText().slice(tag.start, tag.end);

const highlights: DocumentHighlight[] = [];

let index = 0;
while (index < searching.length) {
index = searching.indexOf(word, index);
if (index === -1) {
break;
}

const start = tag.start + index;
highlights.push({
range: {
start: document.positionAt(start),
end: document.positionAt(start + word.length)
},
kind: DocumentHighlightKind.Text
});

index += word.length;
}

return highlights;
}

function wordAt(document: Document, position: Position, wordPattern: RegExp): string | null {
const line = document
.getText(
Range.create(Position.create(position.line, 0), Position.create(position.line + 1, 0))
)
.trimEnd();

wordPattern.lastIndex = 0;

let start: number | undefined;
let end: number | undefined;
const matchEnd = Math.min(position.character, line.length);
while (wordPattern.lastIndex < matchEnd) {
const match = wordPattern.exec(line);
if (!match) {
break;
}

start = match.index;
end = match.index + match[0].length;
}

if (start === undefined || end === undefined || end < position.character) {
return null;
}

return line.slice(start, end);
}
16 changes: 8 additions & 8 deletions packages/language-server/src/plugins/css/CSSPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ import { StyleAttributeDocument } from './StyleAttributeDocument';
import { getDocumentContext } from '../documentContext';
import { FoldingRange, FoldingRangeKind } from 'vscode-languageserver-types';
import { indentBasedFoldingRangeForTag } from '../../lib/foldingRange/indentFolding';
import { wordHighlightForTag } from '../../lib/documentHighlight/wordHighlight';

// https://github.com/microsoft/vscode/blob/c6f507deeb99925e713271b1048f21dbaab4bd54/extensions/css/language-configuration.json#L34
const wordPattern = /(#?-?\d*\.\d\w*%?)|(::?[\w-]*(?=[^,{;]*[,{]))|(([@#.!])?[\w-?]+%?|[@#!.])/g;

export class CSSPlugin
implements
Expand Down Expand Up @@ -441,6 +445,10 @@ export class CSSPlugin
findDocumentHighlight(document: Document, position: Position): DocumentHighlight[] | null {
const cssDocument = this.getCSSDoc(document);
if (cssDocument.isInGenerated(position)) {
if (shouldExcludeDocumentHighlights(cssDocument)) {
return wordHighlightForTag(document, position, document.styleInfo, wordPattern);
}

return this.findDocumentHighlightInternal(cssDocument, position);
}

Expand All @@ -463,16 +471,8 @@ export class CSSPlugin
cssDocument: CSSDocumentBase,
position: Position
): DocumentHighlight[] | null {
if (!cssDocument.isInGenerated(position)) {
return null;
}

const kind = extractLanguage(cssDocument);

if (shouldExcludeDocumentHighlights(cssDocument)) {
return null;
}

const result = getLanguageService(this.cssLanguageServices, kind)
.findDocumentHighlights(
cssDocument,
Expand Down
15 changes: 15 additions & 0 deletions packages/language-server/src/plugins/html/HTMLPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ import { importPrettier } from '../../importPackage';
import path from 'path';
import { Logger } from '../../logger';
import { indentBasedFoldingRangeForTag } from '../../lib/foldingRange/indentFolding';
import { wordHighlightForTag } from '../../lib/documentHighlight/wordHighlight';

// https://github.com/microsoft/vscode/blob/c6f507deeb99925e713271b1048f21dbaab4bd54/extensions/html/language-configuration.json#L34
const wordPattern = /(-?\d*\.\d\w*)|([^`~!@$^&*()=+[{\]}\|;:'",.<>\/\s]+)/g;

export class HTMLPlugin
implements
Expand Down Expand Up @@ -412,6 +416,17 @@ export class HTMLPlugin
return null;
}

const templateResult = wordHighlightForTag(
document,
position,
document.templateInfo,
wordPattern
);

if (templateResult) {
return templateResult;
}

const node = html.findNodeAt(document.offsetAt(position));
if (possiblyComponent(node)) {
return null;
Expand Down
22 changes: 22 additions & 0 deletions packages/language-server/test/plugins/css/CSSPlugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,5 +558,27 @@ describe('CSS Plugin', () => {
}
]);
});

it('provide word highlight for unsupported languages', () => {
const { plugin, document } = setup('<style lang="postcss">.hi {}</style>');

const highlight = plugin.findDocumentHighlight(document, Position.create(0, 25));

assert.deepStrictEqual(highlight, <DocumentHighlight[]>[
{
range: {
start: {
line: 0,
character: 22
},
end: {
line: 0,
character: 25
}
},
kind: DocumentHighlightKind.Text
}
]);
});
});
});
22 changes: 22 additions & 0 deletions packages/language-server/test/plugins/html/HTMLPlugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,26 @@ describe('HTML Plugin', () => {
}
]);
});

it('provide word highlight for unsupported languages', () => {
const { plugin, document } = setup('<template lang="pug">\n div\n p</template>');

const highlight = plugin.findDocumentHighlight(document, Position.create(1, 5));

assert.deepStrictEqual(highlight, <DocumentHighlight[]>[
{
range: {
start: {
line: 1,
character: 2
},
end: {
line: 1,
character: 5
}
},
kind: DocumentHighlightKind.Text
}
]);
});
});

0 comments on commit 27b5122

Please sign in to comment.