add vue/svelte support

master
Brad Cornes 2020-04-11 23:34:03 +01:00
parent 072809d9b7
commit adadf06518
5 changed files with 81 additions and 17 deletions

View File

@ -10,8 +10,8 @@ import {
const dlv = require('dlv') const dlv = require('dlv')
import removeMeta from '../util/removeMeta' import removeMeta from '../util/removeMeta'
import { getColor, getColorFromString } from '../util/color' import { getColor, getColorFromString } from '../util/color'
import { isHtmlDoc } from '../util/html' import { isHtmlContext } from '../util/html'
import { isCssDoc } from '../util/css' import { isCssContext } from '../util/css'
import { findLast, findJsxStrings, arrFindLast } from '../util/find' import { findLast, findJsxStrings, arrFindLast } from '../util/find'
import { stringifyConfigValue } from '../util/stringify' import { stringifyConfigValue } from '../util/stringify'
import isObject from '../util/isObject' import isObject from '../util/isObject'
@ -171,11 +171,11 @@ function provideClassNameCompletions(
): CompletionList { ): CompletionList {
let doc = state.editor.documents.get(params.textDocument.uri) let doc = state.editor.documents.get(params.textDocument.uri)
if (isHtmlDoc(doc)) { if (isHtmlContext(doc, params.position)) {
return provideClassAttributeCompletions(state, params) return provideClassAttributeCompletions(state, params)
} }
if (isCssDoc(doc)) { if (isCssContext(doc, params.position)) {
return provideAtApplyCompletions(state, params) return provideAtApplyCompletions(state, params)
} }
@ -188,7 +188,7 @@ function provideCssHelperCompletions(
): CompletionList { ): CompletionList {
let doc = state.editor.documents.get(textDocument.uri) let doc = state.editor.documents.get(textDocument.uri)
if (!isCssDoc(doc)) { if (!isCssContext(doc, position)) {
return null return null
} }

View File

@ -1,4 +1,5 @@
import { TextDocument } from 'vscode-languageserver' import { TextDocument, Position } from 'vscode-languageserver'
import { isMixedDoc, isInsideTag } from './html'
export const CSS_LANGUAGES = [ export const CSS_LANGUAGES = [
'css', 'css',
@ -7,10 +8,25 @@ export const CSS_LANGUAGES = [
'sass', 'sass',
'scss', 'scss',
'stylus', 'stylus',
'svelte',
'vue'
] ]
export function isCssDoc(doc: TextDocument): boolean { function isCssDoc(doc: TextDocument): boolean {
return CSS_LANGUAGES.indexOf(doc.languageId) !== -1 return CSS_LANGUAGES.indexOf(doc.languageId) !== -1
} }
export function isCssContext(doc: TextDocument, position: Position): boolean {
if (isCssDoc(doc)) {
return true
}
if (isMixedDoc(doc)) {
let str = doc.getText({
start: { line: 0, character: 0 },
end: position,
})
return isInsideTag(str, ['style'])
}
return false
}

View File

@ -1,4 +1,4 @@
import { TextDocument } from 'vscode-languageserver' import { TextDocument, Position } from 'vscode-languageserver'
import { JS_LANGUAGES } from './js' import { JS_LANGUAGES } from './js'
export const HTML_LANGUAGES = [ export const HTML_LANGUAGES = [
@ -19,12 +19,61 @@ export const HTML_LANGUAGES = [
'php', 'php',
'razor', 'razor',
'slim', 'slim',
'svelte',
'twig', 'twig',
'vue', ...JS_LANGUAGES,
...JS_LANGUAGES
] ]
export function isHtmlDoc(doc: TextDocument): boolean { function isHtmlDoc(doc: TextDocument): boolean {
return HTML_LANGUAGES.indexOf(doc.languageId) !== -1 return HTML_LANGUAGES.indexOf(doc.languageId) !== -1
} }
function isVueDoc(doc: TextDocument): boolean {
return doc.languageId === 'vue'
}
function isSvelteDoc(doc: TextDocument): boolean {
return doc.languageId === 'svelte'
}
export function isMixedDoc(doc: TextDocument): boolean {
return isVueDoc(doc) || isSvelteDoc(doc)
}
export function isHtmlContext(doc: TextDocument, position: Position): boolean {
if (isHtmlDoc(doc)) {
return true
}
if (isMixedDoc(doc)) {
let str = doc.getText({
start: { line: 0, character: 0 },
end: position,
})
if (isVueDoc(doc)) {
return isInsideTag(str, ['template', 'script'])
}
if (isSvelteDoc(doc)) {
return !isInsideTag(str, ['style'])
}
}
return false
}
export function isInsideTag(str: string, tag: string | string[]): boolean {
let open = 0
let close = 0
let match: RegExpExecArray
let tags = Array.isArray(tag) ? tag : [tag]
let regex = new RegExp(`<(?<slash>/?)(?:${tags.join('|')})\\b`, 'ig')
while ((match = regex.exec(str)) !== null) {
if (match.groups.slash) {
close += 1
} else {
open += 1
}
}
return open > 0 && open > close
}

View File

@ -4,8 +4,7 @@ export const JS_LANGUAGES = [
'javascript', 'javascript',
'javascriptreact', 'javascriptreact',
'reason', 'reason',
'svelte', 'typescriptreact',
'typescriptreact'
] ]
export function isJsDoc(doc: TextDocument): boolean { export function isJsDoc(doc: TextDocument): boolean {

View File

@ -22,7 +22,7 @@ import {
let defaultClient: LanguageClient let defaultClient: LanguageClient
let clients: Map<string, LanguageClient> = new Map() let clients: Map<string, LanguageClient> = new Map()
const LANGS = ['css', 'javascript', 'html'] const LANGS = ['css', 'javascript', 'html', 'vue', 'svelte']
let _sortedWorkspaceFolders: string[] | undefined let _sortedWorkspaceFolders: string[] | undefined
function sortedWorkspaceFolders(): string[] { function sortedWorkspaceFolders(): string[] {