1
0
Fork 0
mirror of synced 2024-06-25 18:21:11 -04:00
ultimate-vim/sources_non_forked/coc.nvim/src/core/funcs.ts
2022-07-20 13:20:15 +08:00

159 lines
4.3 KiB
TypeScript

'use strict'
import { Neovim } from '@chemzqm/neovim'
import minimatch from 'minimatch'
import os from 'os'
import path from 'path'
import semver from 'semver'
import { DocumentFilter, DocumentSelector } from 'vscode-languageserver-protocol'
import { URI } from 'vscode-uri'
import which from 'which'
import Configurations from '../configuration'
import Resolver from '../model/resolver'
import * as fs from '../util/fs'
import * as platform from '../util/platform'
let NAME_SPACE = 2000
const resolver = new Resolver()
const namespaceMap: Map<string, number> = new Map()
interface PartialEnv {
isVim: boolean
version: string
}
/**
* Like vim's has(), but for version check only.
* Check patch on neovim and check nvim on vim would return false.
*
* For example:
* - has('nvim-0.6.0')
* - has('patch-7.4.248')
*/
export function has(env: PartialEnv, feature: string): boolean {
if (!feature.startsWith('nvim-') && !feature.startsWith('patch-')) {
throw new Error('Feature param could only starts with nvim and patch')
}
if (!env.isVim && feature.startsWith('patch-')) {
return false
}
if (env.isVim && feature.startsWith('nvim-')) {
return false
}
if (env.isVim) {
let [_, major, minor, patch] = env.version.match(/^(\d)(\d{2})(\d+)$/)
let version = `${major}.${parseInt(minor, 10)}.${parseInt(patch, 10)}`
return semver.gte(version, feature.slice(6))
}
return semver.gte(env.version, feature.slice(5))
}
/*
* Create namespace id.
*
* @deprecated
*/
export function createNameSpace(name = ''): number {
if (namespaceMap.has(name)) return namespaceMap.get(name)
NAME_SPACE = NAME_SPACE + 1
namespaceMap.set(name, NAME_SPACE)
return NAME_SPACE
}
/**
* Resolve watchman path.
*/
export function getWatchmanPath(configurations: Configurations): string | null {
const preferences = configurations.getConfiguration('coc.preferences')
let watchmanPath = preferences.get<string>('watchmanPath', 'watchman')
try {
return which.sync(watchmanPath)
} catch (e) {
return null
}
}
export async function findUp(nvim: Neovim, cwd: string, filename: string | string[]): Promise<string | null> {
let filepath = await nvim.call('expand', '%:p') as string
filepath = path.normalize(filepath)
let isFile = filepath && path.isAbsolute(filepath)
if (isFile && !fs.isParentFolder(cwd, filepath, true)) {
// can't use cwd
return fs.findUp(filename, path.dirname(filepath))
}
let res = fs.findUp(filename, cwd)
if (res && res != os.homedir()) return res
if (isFile) return fs.findUp(filename, path.dirname(filepath))
return null
}
export function resolveModule(name: string): Promise<string> {
return resolver.resolveModule(name)
}
export function score(selector: DocumentSelector | DocumentFilter | string, uri: string, languageId: string): number {
if (Array.isArray(selector)) {
// array -> take max individual value
let ret = 0
for (const filter of selector) {
const value = score(filter, uri, languageId)
if (value === 10) {
return value // already at the highest
}
if (value > ret) {
ret = value
}
}
return ret
} else if (typeof selector === 'string') {
// short-hand notion, desugars to
// 'fooLang' -> { language: 'fooLang'}
// '*' -> { language: '*' }
if (selector === '*') {
return 5
} else if (selector === languageId) {
return 10
} else {
return 0
}
} else if (selector) {
let u = URI.parse(uri)
// filter -> select accordingly, use defaults for scheme
const { language, pattern, scheme } = selector
let ret = 0
if (scheme) {
if (scheme === u.scheme) {
ret = 5
} else if (scheme === '*') {
ret = 3
} else {
return 0
}
}
if (language) {
if (language === languageId) {
ret = 10
} else if (language === '*') {
ret = Math.max(ret, 5)
} else {
return 0
}
}
if (pattern) {
let caseInsensitive = platform.isWindows || platform.isMacintosh
let p = caseInsensitive ? pattern.toLowerCase() : pattern
let f = caseInsensitive ? u.fsPath.toLowerCase() : u.fsPath
if (p === f || minimatch(f, p, { dot: true })) {
ret = 5
} else {
return 0
}
}
return ret
} else {
return 0
}
}