Skip to content

Commit

Permalink
feat: 支持了组件库中按需导入的组件提供代码提示
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon-He95 committed Nov 22, 2023
1 parent ceee862 commit f7c1d87
Show file tree
Hide file tree
Showing 25 changed files with 652 additions and 1,004 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@types/vscode": "^1.77.0",
"@typescript-eslint/typescript-estree": "^6.0.0",
"@vscode-use/createwebview": "^0.0.10",
"@vscode-use/utils": "^0.0.56",
"@vscode-use/utils": "^0.0.61",
"@vue/compiler-sfc": "^3.3.4",
"axios": "^1.6.0",
"bing-translate-api": "^2.9.2",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 16 additions & 4 deletions scripts/generateIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ const fg = require('fast-glob')
const fsp = require('node:fs/promises')

export async function run() {
const folder = 'src/ui/arcoDesignVue'
const name = 'arcoDesignVue2'
const folder = 'src/ui/antDesignVue'
const name = 'antDesignVue4'
const isHyphen = true /** 生成的模板中的使用是 true ? a-affix : AAfix */
const url = path.resolve(root, `${folder}/${name}`)
const entry = await fg(['**/*.json'], { dot: true, cwd: url })
const imports = entry.map((_url: string) => `import ${_url.split('.')[0]} from './${_url}'`)
let prefix = ''
debugger
const map = entry.map((_url: string) => {
return `[${_url.split('.')[0]}, "xx", "<${_url.split('.')[0]}></${_url.split('.')[0]}>"],`
let tagName = 'A'+_url.split('.')[0]
if (isHyphen) {
tagName = hyphenate(tagName)
prefix = '\'' + tagName.split('-')[0] + '\''
}
return `[${_url.split('.')[0]}, ${_url.split('.')[0]}.name, "<${tagName}></${tagName}>"],`
})
const template =
`import { componentsReducer, propsReducer } from '../../utils'
Expand All @@ -29,10 +36,15 @@ export function ${name}Components() {
const map = [
${map.join('\n ')}
]
return componentsReducer(map, ${isHyphen})
return componentsReducer(map, ${isHyphen}, ${prefix})
}
`
fsp.writeFile(path.resolve(root, `${folder}/${name}/index.ts`), template)
}

run()


function hyphenate(s: string): string {
return s.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')
}
60 changes: 56 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode'
import { addEventListener, copyText, createCompletionItem, getActiveTextEditorLanguageId, getSelection, message, openExternalUrl, registerCommand, registerCompletionItemProvider } from '@vscode-use/utils'
import { addEventListener, createCompletionItem, getActiveText, getActiveTextEditorLanguageId, getSelection, message, openExternalUrl, registerCommand, registerCompletionItemProvider, setCopyText } from '@vscode-use/utils'
import { CreateWebview } from '@vscode-use/createwebview'
import { findPkgUI, parser } from './utils'
import UI from './ui'
Expand Down Expand Up @@ -34,11 +34,12 @@ export function activate(context: vscode.ExtensionContext) {
findUI()
}))
context.subscriptions.push(registerCommand('intellisense.copyDemo', () => {
copyText(global.commonIntellisense.copyDom)
setCopyText(global.commonIntellisense.copyDom)
message.info('copy successfully')
}))

findUI()

context.subscriptions.push(registerCompletionItemProvider(filter, (document, position) => {
const { lineText } = getSelection()!
const p: any = position
Expand All @@ -57,6 +58,7 @@ export function activate(context: vscode.ExtensionContext) {

const lan = getActiveTextEditorLanguageId()
const isVue = lan === 'vue'
const deps = optionsComponents.prefix.length ? getImportDeps(getActiveText()!) : undefined
const { character } = position
const isPreEmpty = lineText[character - 1] === ' '
const isValue = result.isValue
Expand Down Expand Up @@ -94,7 +96,27 @@ export function activate(context: vscode.ExtensionContext) {
return UiCompletions.icons

const propName = result.propName
const { events, completions } = UiCompletions[name]
let target = UiCompletions[name]
if (!target) {
const prefix = optionsComponents.prefix
let flag = false
for (const d in deps) {
const n = deps[d]
for (const p of prefix) {
const t = UiCompletions[p.toUpperCase() + n]
if (t) {
target = t
flag = true
break
}
}
if (flag)
break
}
}
if (!target)
return
const { events, completions } = target
if (!completionsCallbacks.has(name)) {
const _events = events[0]()
eventCallbacks.set(name, _events)
Expand Down Expand Up @@ -188,10 +210,12 @@ export function activate(context: vscode.ExtensionContext) {
return optionsComponents.data
}
}, ['"', '\'', '-', ' ', '@', '.']))

const provider = new CreateWebview(context.extensionUri, {
viewColumn: vscode.ViewColumn.Beside,
scripts: ['main.js'],
})

context.subscriptions.push(registerCommand('intellisense.openDocument', (args) => {
// 注册全局的link点击时间
const url = args.link
Expand Down Expand Up @@ -224,13 +248,15 @@ export function activate(context: vscode.ExtensionContext) {
}
})
}))

context.subscriptions.push(registerCommand('intellisense.openDocumentExternal', (args) => {
// 注册全局的link点击时间
const url = args.link
if (!url)
return
openExternalUrl(url)
}))

const LANS = ['javascriptreact', 'typescript', 'typescriptreact', 'vue', 'svelte', 'solid', 'swan', 'react', 'js', 'ts', 'tsx', 'jsx']

context.subscriptions.push(vscode.languages.registerHoverProvider(LANS, {
Expand All @@ -243,7 +269,17 @@ export function activate(context: vscode.ExtensionContext) {
if (!optionsComponents.data.length || !word)
return new vscode.Hover('')

const target = UiCompletions[toCamel(word)[0].toUpperCase() + toCamel(word).slice(1)]
let target = UiCompletions[toCamel(word)[0].toUpperCase() + toCamel(word).slice(1)]
if (!target) {
const prefix = optionsComponents.prefix
for (const p of prefix) {
const t = UiCompletions[p.toUpperCase() + word]
if (t) {
target = t
break
}
}
}
if (!target)
return

Expand Down Expand Up @@ -323,3 +359,19 @@ function isSamePrefix(label: string, key: string) {
}
return labelName === key
}

const IMPORT_REG = /import\s+{([^\}]+)}\s+from\s+['"]([^"']+)['"]/g
function getImportDeps(text: string) {
const deps: Record<string, string[]> = {}
for (const match of text.matchAll(IMPORT_REG)) {
if (!match)
continue
const from = match[2]
if (/^[\.\/\@]/.test(from))
continue
if (!UINames.map((i: string) => i.replace(/[0-9]/g, '')).includes(toCamel(from)))
continue
deps[from] = match[1].replace(/\s/g, '').split(',')
}
return deps
}
Loading

0 comments on commit f7c1d87

Please sign in to comment.