Skip to content

Commit 44ff26b

Browse files
committed
Add import-map support in config
1 parent 0002129 commit 44ff26b

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed

denops/ddc/app.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {
1414
UserOptions,
1515
} from "./types.ts";
1616
import { Loader } from "./loader.ts";
17-
import { isDenoCacheIssueError } from "./utils.ts";
17+
import { importPlugin, isDenoCacheIssueError } from "./utils.ts";
1818
import { createCallbackContext } from "./callback.ts";
1919
import { getFilter, getPreviewer, onCompleteDone, onEvent } from "./ext.ts";
2020
import type { BaseUi } from "./base/ui.ts";
@@ -27,7 +27,6 @@ import * as vars from "@denops/std/variable";
2727
import { ensure } from "@core/unknownutil/ensure";
2828
import { is } from "@core/unknownutil/is";
2929
import { Lock } from "@core/asyncutil/lock";
30-
import { toFileUrl } from "@std/path/to-file-url";
3130

3231
export const main: Entrypoint = (denops: Denops) => {
3332
const loader = new Loader();
@@ -193,12 +192,9 @@ export const main: Entrypoint = (denops: Denops) => {
193192
await lock.lock(async () => {
194193
const path = ensure(arg1, is.String) as string;
195194
try {
196-
// NOTE: Import module with fragment so that reload works properly.
197-
// https://github.com/vim-denops/denops.vim/issues/227
198-
const mod = await import(
199-
`${toFileUrl(path).href}#${performance.now()}`
200-
);
201-
const obj = new mod.Config();
195+
const mod = await importPlugin(path);
196+
// deno-lint-ignore no-explicit-any
197+
const obj = new (mod as any).Config();
202198
await obj.config({ denops, contextBuilder, setAlias });
203199
} catch (e) {
204200
if (isDenoCacheIssueError(e)) {

denops/ddc/deno.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
"@core/asyncutil": "jsr:@core/asyncutil@~1.2.0",
44
"@core/unknownutil": "jsr:@core/unknownutil@~4.3.0",
55
"@denops/std": "jsr:@denops/std@~7.6.0",
6-
"@std/async": "jsr:@std/async@~1.0.7",
6+
"@lambdalisue/import-map-importer": "jsr:@lambdalisue/import-map-importer@~0.3.1",
77
"@std/assert": "jsr:@std/assert@~1.0.7",
8+
"@std/async": "jsr:@std/async@~1.0.7",
89
"@std/path": "jsr:@std/path@~1.1.0",
910
"@std/testing": "jsr:@std/testing@~1.0.0"
1011
}

denops/ddc/utils.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
import type { Callback } from "./types.ts";
22

3-
import type { Denops } from "@denops/std";
4-
import * as op from "@denops/std/option";
5-
3+
import {
4+
type ImportMap,
5+
ImportMapImporter,
6+
loadImportMap,
7+
} from "@lambdalisue/import-map-importer";
68
import { is } from "@core/unknownutil/is";
79
import { assertEquals } from "@std/assert/equals";
10+
import { toFileUrl } from "@std/path/to-file-url";
11+
import { fromFileUrl } from "@std/path/from-file-url";
12+
import { join } from "@std/path/join";
13+
import { dirname } from "@std/path/dirname";
14+
15+
import type { Denops } from "@denops/std";
16+
import * as op from "@denops/std/option";
817

918
export async function convertKeywordPattern(
1019
denops: Denops,
@@ -134,6 +143,51 @@ export async function callCallback(
134143
}
135144
}
136145

146+
export async function tryLoadImportMap(
147+
script: string,
148+
): Promise<ImportMap | undefined> {
149+
if (script.startsWith("http://") || script.startsWith("https://")) {
150+
// We cannot load import maps for remote scripts
151+
return undefined;
152+
}
153+
const PATTERNS = [
154+
"deno.json",
155+
"deno.jsonc",
156+
"import_map.json",
157+
"import_map.jsonc",
158+
];
159+
// Convert file URL to path for file operations
160+
const scriptPath = script.startsWith("file://")
161+
? fromFileUrl(new URL(script))
162+
: script;
163+
const parentDir = dirname(scriptPath);
164+
for (const pattern of PATTERNS) {
165+
const importMapPath = join(parentDir, pattern);
166+
try {
167+
return await loadImportMap(importMapPath);
168+
} catch (err: unknown) {
169+
if (err instanceof Deno.errors.NotFound) {
170+
// Ignore NotFound errors and try the next pattern
171+
continue;
172+
}
173+
throw err; // Rethrow other errors
174+
}
175+
}
176+
return undefined;
177+
}
178+
179+
export async function importPlugin(path: string): Promise<unknown> {
180+
const suffix = performance.now();
181+
const url = toFileUrl(path).href;
182+
const importMap = await tryLoadImportMap(path);
183+
if (importMap) {
184+
const importer = new ImportMapImporter(importMap);
185+
return await importer.import(`${url}#${suffix}`);
186+
} else {
187+
return await import(`${url}#${suffix}`);
188+
}
189+
}
190+
137191
Deno.test("vimoption2ts", () => {
138192
assertEquals(vimoption2ts("@,48-57,_,\\"), "a-zA-Z0-9_\\\\");
139193
assertEquals(vimoption2ts("@,-,48-57,_"), "a-zA-Z0-9_-");

doc/ddc.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,8 @@ ddc#custom#load_config({path})
460460
Load TypeScript configuration from {path} file.
461461
NOTE: {path} must be full path.
462462
NOTE: The loading is asynchronous.
463+
NOTE: The "deno.json[c]" and "import_map.json[c]" files in the
464+
same directory will also be loaded.
463465

464466
*ddc#custom#patch_buffer()*
465467
ddc#custom#patch_buffer({option-name}, {value})

0 commit comments

Comments
 (0)