diff --git a/autoload/ddc.vim b/autoload/ddc.vim index ea30950..79fd875 100644 --- a/autoload/ddc.vim +++ b/autoload/ddc.vim @@ -99,6 +99,10 @@ function ddc#update_items(name, items) abort call ddc#_notify('updateItems', [a:name, a:items]) endfunction +function ddc#set_static_import_path(path) abort + call ddc#_notify('setStaticImportPath', [a:path]) +endfunction + function ddc#on_event(event) abort " NOTE: If denops isn't running, stop if !ddc#_denops_running() diff --git a/denops/ddc/app.ts b/denops/ddc/app.ts index 6bfed3e..b987ed7 100644 --- a/denops/ddc/app.ts +++ b/denops/ddc/app.ts @@ -128,6 +128,10 @@ export function main(denops: Denops) { getCurrent(): Promise { return Promise.resolve(contextBuilder.getCurrent(denops)); }, + async setStaticImportPath(arg1: unknown): Promise { + await loader.initStaticImportPath(denops, arg1 as string); + return Promise.resolve(); + }, async getPreviewer(arg1: unknown, arg2: unknown): Promise { const [_skip, context, options] = await contextBuilder .createContext(denops, "Manual"); diff --git a/denops/ddc/base/source.ts b/denops/ddc/base/source.ts index 10b3448..a5cf656 100644 --- a/denops/ddc/base/source.ts +++ b/denops/ddc/base/source.ts @@ -10,7 +10,7 @@ import { SourceOptions, } from "../types.ts"; import { Denops } from "../deps.ts"; -import { convertKeywordPattern } from "../util.ts"; +import { convertKeywordPattern } from "../utils.ts"; import { Loader } from "../loader.ts"; export type BaseSourceParams = Record; diff --git a/denops/ddc/ddc.ts b/denops/ddc/ddc.ts index 7f44615..dfcf0f0 100644 --- a/denops/ddc/ddc.ts +++ b/denops/ddc/ddc.ts @@ -51,7 +51,7 @@ import { TimeoutError, vars, } from "./deps.ts"; -import { errorException } from "./util.ts"; +import { errorException } from "./utils.ts"; type DdcResult = { items: Item[]; diff --git a/denops/ddc/loader.ts b/denops/ddc/loader.ts index 3f1634b..bc5c2e2 100644 --- a/denops/ddc/loader.ts +++ b/denops/ddc/loader.ts @@ -11,6 +11,7 @@ import { UiName, } from "./types.ts"; import { basename, Denops, fn, Lock, op, parse, toFileUrl } from "./deps.ts"; +import { safeStat } from "./utils.ts"; export class Loader { private uis: Record> = {}; @@ -25,6 +26,22 @@ export class Loader { private registerLock = new Lock(0); private cachedPaths: Record = {}; private prevRuntimepath = ""; + private staticImportMod: Record = {}; + + async initStaticImportPath(denops: Denops, path: string) { + if (Object.values(this.staticImportMod).length !== 0) { + return; + } + + path = await fn.expand(denops, path) as string; + if (!await safeStat(path)) { + return; + } + + //const startTime = Date.now(); + this.staticImportMod = (await import(toFileUrl(path).href)).mods; + //console.log(`${Date.now() - startTime} ms`); + } async autoload( denops: Denops, @@ -82,7 +99,8 @@ export class Loader { const name = parse(path).name; - const mod = await import(toFileUrl(path).href); + const mod = this.staticImportMod[path] ?? + await import(toFileUrl(path).href); let add; switch (type) { diff --git a/denops/ddc/util.ts b/denops/ddc/utils.ts similarity index 81% rename from denops/ddc/util.ts rename to denops/ddc/utils.ts index b2535ce..255cf09 100644 --- a/denops/ddc/util.ts +++ b/denops/ddc/utils.ts @@ -84,6 +84,26 @@ export async function errorException( } } +export async function safeStat(path: string): Promise { + // NOTE: Deno.stat() may be failed + try { + const stat = await Deno.lstat(path); + if (stat.isSymlink) { + try { + const stat = await Deno.stat(path); + stat.isSymlink = true; + return stat; + } catch (_: unknown) { + // Ignore stat exception + } + } + return stat; + } catch (_: unknown) { + // Ignore stat exception + } + return null; +} + Deno.test("vimoption2ts", () => { assertEquals(vimoption2ts("@,48-57,_,\\"), "a-zA-Z0-9_\\\\"); assertEquals(vimoption2ts("@,-,48-57,_"), "a-zA-Z0-9_-"); diff --git a/doc/ddc.txt b/doc/ddc.txt index 3cd4e72..0bdb554 100644 --- a/doc/ddc.txt +++ b/doc/ddc.txt @@ -332,6 +332,7 @@ ddc#hide([{event}]) It must be list of |autocmd-events| string or "Manual" or "Initialize" or "Update". NOTE: It is used to cancel the completion. + NOTE: It does not restore inserted text. > inoremap call ddc#hide() < @@ -352,6 +353,12 @@ ddc#register({type}, {path}) {path} is ddc extension path. NOTE: {path} must be full path. + *ddc#set_static_import_path()* +ddc#set_static_import_path() + Set the path of staticImport file to optimize load ddc + extensions. + It is generated by "dpp.vim" |dpp-option-convertImportPaths|. + *ddc#skip_next_complete()* ddc#skip_next_complete() Skip the next auto completion. @@ -1622,6 +1629,9 @@ https://github.com/Shougo/ddc-ui-pum ============================================================================== COMPATIBILITY *ddc-compatibility* +2023.12.04 +* Rename "util.ts" to "utils.ts". + 2023.11.08 * Remove keywordPattern backward compatibility.