diff --git a/src/lsp/providers/hoverProvider.ts b/src/lsp/providers/hoverProvider.ts index a9010a3142cb4e9700f63e3bd06426a144b9afa0..7e27d9ac9833ec166a6332607b38562ec0b03f80 100644 --- a/src/lsp/providers/hoverProvider.ts +++ b/src/lsp/providers/hoverProvider.ts @@ -1,10 +1,17 @@ -import { State } from '../util/state' +import { State, DocumentClassName } from '../util/state' import { Hover, TextDocumentPositionParams } from 'vscode-languageserver' -import { getClassNameParts } from '../util/getClassNameAtPosition' +import { + getClassNameAtPosition, + getClassNameParts, +} from '../util/getClassNameAtPosition' import { stringifyCss, stringifyConfigValue } from '../util/stringify' const dlv = require('dlv') import { isCssContext } from '../util/css' +export function provideHover( +import { isCssContext } from '../util/css' import { findClassNameAtPosition } from '../util/find' +import { isWithinRange } from '../util/isWithinRange' +import { findClassNamesInRange } from '../util/find' export function provideHover( state: State, @@ -69,33 +76,80 @@ }, } } -function provideClassNameHover( +function provideClassAttributeHover( state: State, { textDocument, position }: TextDocumentPositionParams ): Hover { let doc = state.editor.documents.get(textDocument.uri) + if ( + !isHtmlContext(state, doc, position) && + !isJsContext(state, doc, position) +import { State } from '../util/state' const dlv = require('dlv') import { getClassNameParts } from '../util/getClassNameAtPosition' +import { State } from '../util/state' + + let hovered = getClassNameAtPosition(doc, position) - if (className === null) return null + if (!hovered) return null + + return classNameToHover(state, hovered) +} + + state: State, + { className, range }: DocumentClassName - const parts = getClassNameParts(state, className.className) +): Hover { + const parts = getClassNameParts(state, className) if (!parts) return null return { contents: { language: 'css', + value: stringifyCss(className, dlv(state.classNames.classNames, parts)), const dlv = require('dlv') -export function provideHover( +import { State } from '../util/state' + range, + } +import { State } from '../util/state' import { isCssContext } from '../util/css' + +function provideAtApplyHover( +import { State } from '../util/state' -import { isCssContext } from '../util/css' import { State } from '../util/state' + +): Hover { + let doc = state.editor.documents.get(textDocument.uri) + + if (!isCssContext(state, doc, position)) return null + + import { isCssContext } from '../util/css' + start: { line: Math.max(position.line - 10, 0), character: 0 }, + end: { line: position.line + 10, character: 0 }, import { Hover, TextDocumentPositionParams } from 'vscode-languageserver' +import { stringifyCss, stringifyConfigValue } from '../util/stringify' + + const className = classNames.find(({ range }) => + isWithinRange(position, range) +import { State } from '../util/state' const dlv = require('dlv') + +export function provideHover( import { State } from '../util/state' + + return classNameToHover(state, className) +import { State } from '../util/state' import { isCssContext } from '../util/css' + +function provideClassNameHover( + state: State, + params: TextDocumentPositionParams +): Hover { +import { State } from '../util/state' import { getClassNameParts } from '../util/getClassNameAtPosition' +export function provideHover( import { getClassNameParts } from '../util/getClassNameAtPosition' -import { Hover, TextDocumentPositionParams } from 'vscode-languageserver' + provideAtApplyHover(state, params) + ) } diff --git a/src/lsp/util/find.ts b/src/lsp/util/find.ts index 2fa38956102b75ea56c4e7330934c4c3f47d85e0..bd770aa37cce04fb856e76bf21b272c6c8c4f07f 100644 --- a/src/lsp/util/find.ts +++ b/src/lsp/util/find.ts @@ -1,11 +1,7 @@ import { TextDocument, Range, Position } from 'vscode-languageserver' -import { DocumentClassName, DocumentClassList, State } from './state' -import lineColumn from 'line-column' -import { isCssContext } from './css' -import { isHtmlContext } from './html' -import { isWithinRange } from './isWithinRange' +import { TextDocument, Range, Position } from 'vscode-languageserver' import { isJsContext } from './js' -import { getClassAttributeLexer } from './lexers' +import lineColumn from 'line-column' export function findAll(re: RegExp, str: string): RegExpMatchArray[] { let match: RegExpMatchArray @@ -26,11 +21,9 @@ } export function findClassNamesInRange( doc: TextDocument, - range: Range, -import { DocumentClassName, DocumentClassList, State } from './state' import { isWithinRange } from './isWithinRange' ): DocumentClassName[] { - const classLists = findClassListsInRange(doc, range, mode) + const classLists = findClassListsInRange(doc, range) return [].concat.apply( [], classLists.map(({ classList, range }) => { @@ -65,7 +57,7 @@ }) ) } -export function findClassListsInCssRange( +export function findClassListsInRange( doc: TextDocument, range: Range ): DocumentClassList[] { @@ -94,154 +86,13 @@ } }) } -export function findClassListsInHtmlRange( - doc: TextDocument, - range: Range -import { isWithinRange } from './isWithinRange' import { TextDocument, Range, Position } from 'vscode-languageserver' - const text = doc.getText(range) -import { getClassAttributeLexer } from './lexers' import { isCssContext } from './css' - const result: DocumentClassList[] = [] - - matches.forEach((match) => { -import { getClassAttributeLexer } from './lexers' import { isJsContext } from './js' - - let lexer = getClassAttributeLexer() - lexer.reset(subtext) - - let classLists: { value: string; offset: number }[] = [] - import { TextDocument, Range, Position } from 'vscode-languageserver' - let currentClassList: { value: string; offset: number } - - try { - import { isCssContext } from './css' - if (token.type === 'classlist') { - if (currentClassList) { - currentClassList.value += token.value - import { getClassAttributeLexer } from './lexers' - currentClassList = { import { TextDocument, Range, Position } from 'vscode-languageserver' - offset: token.offset, - } - } -export function findAll(re: RegExp, str: string): RegExpMatchArray[] { import { isCssContext } from './css' - if (currentClassList) { - classLists.push({ - value: currentClassList.value, - offset: currentClassList.offset, - }) - } - currentClassList = undefined - } - } - } catch (_) {} - - if (currentClassList) { - classLists.push({ - value: currentClassList.value, - offset: currentClassList.offset, - }) - } - - result.push( - ...classLists - .map(({ value, offset }) => { - if (value.trim() === '') { - return null - } - - const before = value.match(/^\s*/) - const beforeOffset = before === null ? 0 : before[0].length - const after = value.match(/\s*$/) - const afterOffset = after === null ? 0 : -after[0].length - - const start = indexToPosition( - text, - match.index + match[0].length - 1 + offset + beforeOffset - ) - const end = indexToPosition( - text, - match.index + - match[0].length - - 1 + - offset + - value.length + - afterOffset - ) - - return { - classList: value, - range: { - start: { - line: range.start.line + start.line, - character: range.start.character + start.character, - }, - end: { - line: range.start.line + end.line, - character: range.start.character + end.character, - }, - }, - } - }) - .filter((x) => x !== null) - ) - }) - - return result -} - -export function findClassListsInRange( - doc: TextDocument, - range: Range, - mode: 'html' | 'css' -): DocumentClassList[] { - if (mode === 'css') { - return findClassListsInCssRange(doc, range) - } - return findClassListsInHtmlRange(doc, range) -} - -function indexToPosition(str: string, index: number): Position { - const { line, col } = lineColumn(str + '\n', index) - return { line: line - 1, character: col - 1 } -} - -export function findClassNameAtPosition( - state: State, - doc: TextDocument, - position: Position -): DocumentClassName { - let classNames = [] - const searchRange = { - start: { line: Math.max(position.line - 10, 0), character: 0 }, - end: { line: position.line + 10, character: 0 }, - } - - if (isCssContext(state, doc, position)) { - classNames = findClassNamesInRange(doc, searchRange, 'css') - } else if ( - isHtmlContext(state, doc, position) || - isJsContext(state, doc, position) - ) { - classNames = findClassNamesInRange(doc, searchRange, 'html') - } - - if (classNames.length === 0) { - return null - } - - const className = classNames.find(({ range }) => - isWithinRange(position, range) - ) - - if (!className) return null - - return matches }