import { CancellationToken , CompletionItem , CompletionItemKind , CompletionItemProvider , Position , Range , TextDocument , workspace } from 'vscode' ; import * as cssSchema from './schemas/cssSchema' ; import sassSchema from './schemas/sassSchema' ; param { String } currentWord return { Boolean } export function isClassOrId ( currentWord ) { return ( currentWord . startsWith ( '.' ) || currentWord . startsWith ( '#' ) || currentWord . startsWith ( '%' ) ) ; } export function isSelector ( currentWord ) { return currentWord === 'section' || currentWord === 'div' ; } param { String } currentWord return { Boolean } export function isAtRule ( currentWord ) { return currentWord . startsWith ( '@' ) ; } param { Object } cssSchema param { String } currentWord return { Boolean } export function isValue ( cssSchema , currentWord ) { const property = getPropertyName ( currentWord ) ; return property && Boolean ( findPropertySchema ( cssSchema , property ) ) ; } param { String } currentWord return { String } export function getPropertyName ( currentWord ) { return currentWord . trim ( ) . replace ( ':' , ' ' ) . split ( ' ' ) [ 0 ] ; } param { Object } cssSchema param { String } property return { Object } export function findPropertySchema ( cssSchema , property ) { return cssSchema . data . css . properties . find ( item => item . name === property ) ; } param { Object } cssSchema param { String } currentWord return { CompletionItem } export function getAtRules ( cssSchema , currentWord ) { if ( ! isAtRule ( currentWord ) ) { return [ ] ; } return cssSchema . data . css . atdirectives . map ( property => { const completionItem = new CompletionItem ( property . name ) ; completionItem . detail = property . desc ; completionItem . kind = CompletionItemKind . Keyword ; return completionItem ; } ) ; } param { Object } cssSchema param { String } currentWord return { CompletionItem } export function getProperties ( cssSchema , currentWord , useSeparator ) { if ( isClassOrId ( currentWord ) || isAtRule ( currentWord ) || isSelector ( currentWord ) ) { return [ ] ; } return cssSchema . data . css . properties . map ( property => { const completionItem = new CompletionItem ( property . name ) ; completionItem . insertText = property . name + ( useSeparator ? ': ' : ' ' ) ; completionItem . detail = property . desc ; completionItem . kind = CompletionItemKind . Property ; return completionItem ; } ) ; } param { Object } cssSchema param { String } currentWord return { CompletionItem } export function getValues ( cssSchema , currentWord ) { const property = getPropertyName ( currentWord ) ; const values = findPropertySchema ( cssSchema , property ) . values ; if ( ! values ) { return [ ] ; } return values . map ( property => { const completionItem = new CompletionItem ( property . name ) ; completionItem . detail = property . desc ; completionItem . kind = CompletionItemKind . Value ; return completionItem ; } ) ; } class SassCompletion implements CompletionItemProvider { provideCompletionItems ( document , position , token ) { const start = new Position ( position . line , 0 ) ; const range = new Range ( start , position ) ; const currentWord = document . getText ( range ) . trim ( ) ; const text = document . getText ( ) ; const value = isValue ( cssSchema , currentWord ) ; const config = workspace . getConfiguration ( 'sass-indented' ) ; let atRules = [ ] , properties = [ ] , values = [ ] ; if ( value ) { values = getValues ( cssSchema , currentWord ) ; } else { atRules = getAtRules ( cssSchema , currentWord ) ; properties = getProperties ( cssSchema , currentWord , config . get ( 'useSeparator' , true ) ) ; } const completions = [ ] . concat ( atRules , properties , values , sassSchema ) ; return completions ; } } export default SassCompletion ;