-
Notifications
You must be signed in to change notification settings - Fork 97
/
asciidoc.provider.ts
113 lines (100 loc) · 3.5 KB
/
asciidoc.provider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import * as vscode from 'vscode'
import * as path from 'path'
import { createContext, Context } from './createContext'
import {
FileInfo,
getPathOfFolderToLookupFiles,
getChildrenOfPath,
sortFilesAndDirectories,
} from '../util/file'
export const AsciidocProvider = {
provideCompletionItems,
}
export async function provideCompletionItems (
document: vscode.TextDocument,
position: vscode.Position
): Promise<vscode.CompletionItem[]> {
const context = createContext(document, position)
return shouldProvide(context)
? provide(context)
: Promise.resolve([])
}
/**
* Checks if we should provide any CompletionItems
* @param context
*/
function shouldProvide (context: Context): boolean {
return /(include::|image::|image:)\S*/gi.test(context.textFullLine)
}
/**
* Provide Completion Items
*/
async function provide (
context: Context
): Promise<vscode.CompletionItem[]> {
const documentText = context.document.getText()
const pathExtractedFromIncludeString = context.textFullLine.replace('include::', '').replace('image::', '').replace('image:', '')
let entryDir = pathExtractedFromIncludeString.substr(0, pathExtractedFromIncludeString.lastIndexOf('/'))
// use path defined in a variable used
if (entryDir.startsWith('{')) {
const variableName = entryDir.replace('{', '').replace('}', '')
const match = documentText.match(new RegExp(`:${variableName}:.*`, 'g'))
if (match && match[0]) {
entryDir = match[0].replace(`:${variableName}: `, '')
}
}
const workspace = vscode.workspace.getWorkspaceFolder(context.document.uri)
const rootPath = workspace?.uri.fsPath
const searchPath = getPathOfFolderToLookupFiles(
context.document.uri.fsPath,
path.join(rootPath, entryDir)
)
const childrenOfPath = await getChildrenOfPath(searchPath)
const items = sortFilesAndDirectories(childrenOfPath)
const levelUpCompletionItem: vscode.CompletionItem = {
label: '..',
kind: vscode.CompletionItemKind.Folder,
sortText: '..',
}
const globalVariableDefinitions = documentText.match(/:\S+:.*/g)
let variablePathSubstitutions = []
// TODO: prevent editor.autoClosingBrackets at this point until finished inserting
const editorConfig = vscode.workspace.getConfiguration('editor')
const doAutoCloseBrackets = editorConfig.get('autoClosingBrackets') === 'always'
if (globalVariableDefinitions) {
variablePathSubstitutions = globalVariableDefinitions.map((variableDef) => {
const label = variableDef.match(/:\S+:/g)[0].replace(/:/g, '')
return {
label: `{${label}}`,
kind: vscode.CompletionItemKind.Variable,
sortText: `a_${label}`,
insertText: `{${label}${doAutoCloseBrackets ? '' : '}'}`, // } curly bracket will be closed automatically by default
}
})
}
return [
levelUpCompletionItem,
...variablePathSubstitutions,
...items.map((child) => {
const result = createPathCompletionItem(child)
result.insertText = result.kind === vscode.CompletionItemKind.File ? child.file + '[]' : child.file
if (result.kind === vscode.CompletionItemKind.Folder) {
result.command = {
command: 'default:type',
title: 'triggerSuggest',
arguments: [{ text: '/' }],
}
}
return result
}),
]
}
function createPathCompletionItem (
fileInfo: FileInfo
): vscode.CompletionItem {
return {
label: fileInfo.file,
kind: fileInfo.isFile ? vscode.CompletionItemKind.File : vscode.CompletionItemKind.Folder,
sortText: fileInfo.file,
}
}