Skip to content

Commit

Permalink
Use snippets for block completion (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
znck authored Oct 18, 2022
1 parent ea312c4 commit 9c20060
Show file tree
Hide file tree
Showing 13 changed files with 522 additions and 73 deletions.
29 changes: 29 additions & 0 deletions packages/shared/src/string.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
isPascalCase,
isCamelCase,
isKebabCase,
trimIndent,
} from './string'

describe('isString', () => {
Expand Down Expand Up @@ -141,3 +142,31 @@ describe('isKebabCase', () => {
expect(isKebabCase('_Prefix')).toBe(false)
})
})

describe('trimIndent', () => {
test('check', () => {
expect(trimIndent(' foo ')).toBe('foo \n')

expect(
trimIndent(`
foo
bar
baz
`),
).toBe('foo\n bar\nbaz\n')

expect(
trimIndent(`
foo
bar
`),
).toBe('foo\nbar \n')

expect(
trimIndent(`foo
bar
baz
`),
).toBe('foo\n bar\nbaz\n')
})
})
25 changes: 25 additions & 0 deletions packages/shared/src/string.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { first } from './array'

export function isString(value: any): value is string {
return typeof value === 'string'
}
Expand Down Expand Up @@ -65,3 +67,26 @@ export function ucfirst(str: string): string {
export function lcfirst(str: string): string {
return str.slice(0, 1).toLowerCase() + str.slice(1)
}

export function trimIndent(content: string): string {
const lines = content
.trimStart()
.replace(/\n\s*$/, '')
.split('\n')

const indent = lines.slice(1).reduce((min, line) => {
const match = line.match(/^\s+/)
const len = match?.[0] != null ? match[0].length : 0
return Math.min(min, len)
}, Infinity)
if (lines.length <= 1) return first(lines) + '\n'
return (
first(lines) +
'\n' +
lines
.slice(1)
.map((line) => line.slice(indent))
.join('\n') +
'\n'
)
}
15 changes: 1 addition & 14 deletions packages/transforms/test/tsTransformScriptSetup.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { transformScriptSetup } from '../src/tsTransformScriptSetup'
import * as typescript from 'typescript/lib/tsserverlibrary'
import { trimIndent } from '@vuedx/shared'

expect.addSnapshotSerializer({
test: () => true,
Expand Down Expand Up @@ -180,17 +181,3 @@ describe(transformScriptSetup, () => {
])
})
})

function trimIndent(str: string) {
const lines = str.trim().split('\n')
const size = lines
.slice(1)
.reduce(
(size, line) => Math.min(size, /^[ ]*/.exec(line)?.[0].length ?? 0),
Infinity,
)

return [lines[0], ...lines.slice(1).map((line) => line.slice(size))].join(
'\n',
)
}
48 changes: 46 additions & 2 deletions packages/vue-language-server/src/fs.node.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { FileSystemProvider, FileType } from '@vuedx/vue-languageservice'
import {
FilesystemHost,
FileSystemProvider,
FileType,
} from '@vuedx/vue-languageservice'
import FS from 'node:fs'
import { readdir, stat } from 'node:fs/promises'
import { posix } from 'node:path'
import { extname, posix } from 'node:path'

export function createFileSystemProvider(): FileSystemProvider {
return {
Expand Down Expand Up @@ -50,3 +55,42 @@ export function createFileSystemProvider(): FileSystemProvider {
},
}
}
export function createFilesystemHost(): FilesystemHost {
return {
fileExists(path) {
return FS.existsSync(path)
},

readFile(path) {
return FS.readFileSync(path, 'utf-8')
},

watchFile(_path, _callback) {
return {
close() {
// TODO
},
}
},

watchDirectory(_path, _callback) {
return {
close() {
// TODO
},
}
},

readDirectory(dir, extensions) {
return FS.readdirSync(dir, {
withFileTypes: true,
encoding: 'utf8',
})
.filter(
(dirent) =>
dirent.isFile() && extensions.includes(extname(dirent.name)),
)
.map((dirent) => dirent.name)
},
}
}
3 changes: 2 additions & 1 deletion packages/vue-language-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
TextDocuments,
TextDocumentSyncKind,
} from 'vscode-languageserver/node'
import { createFileSystemProvider } from './fs.node'
import { createFilesystemHost, createFileSystemProvider } from './fs.node'
import { createVueLanguageService } from './service'

const connection = createConnection(ProposedFeatures.all)
Expand All @@ -27,6 +27,7 @@ connection.onInitialize((client) => {

const service = createVueLanguageService(
documents,
createFilesystemHost(),
createFileSystemProvider(),
client.capabilities.general?.markdown != null,
)
Expand Down
7 changes: 6 additions & 1 deletion packages/vue-language-server/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import {
LanguageModeVueHTML,
VueLanguageService,
VueTextDocument,
FilesystemHost,
VueProjectService,
} from '@vuedx/vue-languageservice'
import { TextDocuments } from 'vscode-languageserver'

export function createVueLanguageService(
documents: TextDocuments<VueTextDocument>,
host: FilesystemHost,
fs: FileSystemProvider,
supportsMarkdown: boolean = true,
): VueLanguageService {
Expand Down Expand Up @@ -48,7 +51,9 @@ export function createVueLanguageService(
})
})

service.registerLanguageMode(new LanguageModeVue(fs, supportsMarkdown))
service.registerLanguageMode(
new LanguageModeVue(new VueProjectService(host), fs, supportsMarkdown),
)

return service
}
1 change: 1 addition & 0 deletions packages/vue-languageservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@vuedx/shared": "workspace:*",
"@vuedx/template-ast-types": "workspace:*",
"@vuedx/compiler-sfc": "workspace:*",
"@vuedx/projectconfig": "workspace:*",
"vscode-languageserver-protocol": "^3.17.2",
"vscode-languageserver-types": "^3.17.2",
"vscode-languageserver-textdocument": "^1.0.7",
Expand Down
55 changes: 55 additions & 0 deletions packages/vue-languageservice/src/VueProjectService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { FilesystemHost, VueProject } from '@vuedx/projectconfig'
import { cache } from '@vuedx/shared'
import Path from 'path'

export type { FilesystemHost, VueProject }
export class VueProjectService {
#projects: Map<string, VueProject> = new Map()
#inferred: VueProject | undefined

constructor(private readonly fileSystemHost: FilesystemHost) {}

@cache()
public getProject(fileName: string): VueProject {
const find = findConfigFile.bind(
null,
(id) => this.fileSystemHost.fileExists(id),
fileName,
)

const configOrPackageFile = find('vueconfig.json') ?? find('package.json')
if (configOrPackageFile == null) {
if (this.#inferred == null) {
this.#inferred = VueProject.create(this.fileSystemHost, '/')
}

return this.#inferred
}

let project = this.#projects.get(configOrPackageFile)
if (project != null) return project

project = VueProject.create(
this.fileSystemHost,
Path.dirname(configOrPackageFile),
)

this.#projects.set(configOrPackageFile, project)

return project
}
}

function findConfigFile(
exists: (path: string) => boolean,
fileName: string,
configName: string,
): string | undefined {
const dir = Path.dirname(fileName)
if (exists(Path.join(dir, configName))) return dir

const parent = Path.posix.dirname(dir)
if (parent === dir) return

return findConfigFile(exists, parent, configName)
}
19 changes: 1 addition & 18 deletions packages/vue-languageservice/src/VueTextDocument.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { VueTextDocument } from './VueTextDocument'
import { trimIndent } from '@vuedx/shared'

describe(VueTextDocument, () => {
it('should return the correct block', () => {
Expand Down Expand Up @@ -120,21 +121,3 @@ describe(VueTextDocument, () => {
`)
})
})

function trimIndent(content: string): string {
const lines = content.trim().split('\n')
const indent = lines.slice(1).reduce((min, line) => {
const match = line.match(/^\s+/)
const len = match?.[0] != null ? match[0].length : 0
return Math.min(min, len)
}, Infinity)
return (
lines[0] +
'\n' +
lines
.slice(1)
.map((line) => line.slice(indent))
.join('\n') +
'\n'
)
}
2 changes: 2 additions & 0 deletions packages/vue-languageservice/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export {
export { LanguageModeVue, LanguageModeVueHTML } from './modes/LanguageModeHTML'
export { VueLanguageService } from './VueLanguageService'
export { VueTextDocument } from './VueTextDocument'
export { VueProjectService } from './VueProjectService'
export type { FilesystemHost, VueProject } from './VueProjectService'
Loading

0 comments on commit 9c20060

Please sign in to comment.