Skip to content

Commit f2f7186

Browse files
authored
Merge pull request #132 from vim-denops/fix-buffer-replace-on-vim
👍 Use `execute` instead of `load`
2 parents cf4494f + d6bb5b2 commit f2f7186

File tree

7 files changed

+224
-168
lines changed

7 files changed

+224
-168
lines changed

denops_std/buffer/buffer.ts

Lines changed: 102 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import type { Denops } from "https://deno.land/x/denops_core@v3.0.1/mod.ts";
22
import * as autocmd from "../autocmd/mod.ts";
33
import * as batch from "../batch/mod.ts";
44
import * as fn from "../function/mod.ts";
5-
import * as helper from "../helper/mod.ts";
5+
import * as vars from "../variable/mod.ts";
6+
import { execute } from "../helper/mod.ts";
67
import * as unknownutil from "https://deno.land/x/unknownutil@v2.0.0/mod.ts";
78
import {
89
assertFileFormat,
@@ -12,6 +13,81 @@ import {
1213
splitText,
1314
} from "./fileformat.ts";
1415
import { tryDecode } from "./fileencoding.ts";
16+
import { generateUniqueString } from "../util.ts";
17+
18+
const suffix = generateUniqueString();
19+
20+
async function ensurePrerequisites(denops: Denops): Promise<string> {
21+
if (await vars.g.get(denops, `loaded_denops_std_buffer_${suffix}`)) {
22+
return suffix;
23+
}
24+
const script = `
25+
let g:loaded_denops_std_buffer_${suffix} = 1
26+
27+
function! DenopsStdBufferReload_${suffix}(bufnr) abort
28+
if bufnr('%') is# a:bufnr
29+
edit
30+
return
31+
endif
32+
let winid_saved = win_getid()
33+
let winid = bufwinid(a:bufnr)
34+
if winid is# -1
35+
augroup denops_std_buffer_reload_${suffix}
36+
execute printf('autocmd! * <buffer=%d>', a:bufnr)
37+
execute printf('autocmd BufEnter <buffer=%d> ++nested ++once edit', a:bufnr)
38+
augroup END
39+
return
40+
endif
41+
keepjumps keepalt call win_gotoid(winid)
42+
try
43+
edit
44+
finally
45+
keepjumps keepalt call win_gotoid(winid_saved)
46+
endtry
47+
endfunction
48+
49+
function! DenopsStdBufferReplace_${suffix}(bufnr, repl, fileformat, fileencoding) abort
50+
let modified = getbufvar(a:bufnr, '&modified')
51+
let modifiable = getbufvar(a:bufnr, '&modifiable')
52+
let foldmethod = getbufvar(a:bufnr, '&foldmethod')
53+
call setbufvar(a:bufnr, '&modifiable', 1)
54+
call setbufvar(a:bufnr, '&foldmethod', 'manual')
55+
if a:fileformat isnot# v:null
56+
call setbufvar(a:bufnr, '&fileformat', a:fileformat)
57+
endif
58+
if a:fileencoding isnot# v:null
59+
call setbufvar(a:bufnr, '&fileencoding', a:fileencoding)
60+
endif
61+
call setbufline(a:bufnr, 1, a:repl)
62+
call deletebufline(a:bufnr, len(a:repl) + 1, '$')
63+
call setbufvar(a:bufnr, '&modified', modified)
64+
call setbufvar(a:bufnr, '&modifiable', modifiable)
65+
call setbufvar(a:bufnr, '&foldmethod', foldmethod)
66+
endfunction
67+
68+
function! DenopsStdBufferConcreteRestore_${suffix}() abort
69+
if !exists('b:denops_std_buffer_concrete_cache_${suffix}')
70+
return
71+
endif
72+
call DenopsStdBufferReplace_${suffix}(
73+
\\ bufnr('%'),
74+
\\ b:denops_std_buffer_concrete_cache_${suffix}.content,
75+
\\ v:null,
76+
\\ v:null,
77+
\\)
78+
let &filetype = b:denops_std_buffer_concrete_cache_${suffix}.filetype
79+
endfunction
80+
81+
function! DenopsStdBufferConcreteStore_${suffix}() abort
82+
let b:denops_std_buffer_concrete_cache_${suffix} = {
83+
\\ 'filetype': &filetype,
84+
\\ 'content': getline(1, '$'),
85+
\\}
86+
endfunction
87+
`;
88+
await execute(denops, script);
89+
return suffix;
90+
}
1591

1692
export type OpenOptions = {
1793
mods?: string;
@@ -35,25 +111,35 @@ export async function open(
35111
* Edit a buffer
36112
*/
37113
export async function reload(denops: Denops, bufnr: number): Promise<void> {
38-
await helper.load(denops, new URL("./buffer.vim", import.meta.url));
114+
const suffix = await ensurePrerequisites(denops);
39115
await denops.cmd(
40-
"call timer_start(0, { -> DenopsStdBufferV1Reload(bufnr) })",
41-
{
42-
bufnr,
43-
},
116+
`call timer_start(0, { -> DenopsStdBufferReload_${suffix}(bufnr) })`,
117+
{ bufnr },
44118
);
45119
}
46120

121+
export type ReplaceOptions = {
122+
fileformat?: string;
123+
fileencoding?: string;
124+
};
125+
47126
/**
48127
* Replace the buffer content
49128
*/
50129
export async function replace(
51130
denops: Denops,
52131
bufnr: number,
53132
repl: string[],
133+
options: ReplaceOptions = {},
54134
): Promise<void> {
55-
await helper.load(denops, new URL("./buffer.vim", import.meta.url));
56-
await denops.call("DenopsStdBufferV1Replace", bufnr, repl);
135+
const suffix = await ensurePrerequisites(denops);
136+
await denops.call(
137+
`DenopsStdBufferReplace_${suffix}`,
138+
bufnr,
139+
repl,
140+
options.fileformat ?? null,
141+
options.fileencoding ?? null,
142+
);
57143
}
58144

59145
export type AssignOptions = {
@@ -98,12 +184,9 @@ export async function assign(
98184
findFileFormat(text, fileformats) ?? fileformat;
99185
const preprocessor = options.preprocessor ?? ((v: string[]) => v);
100186
const repl = preprocessor(splitText(text, ff));
101-
await modifiable(denops, bufnr, async () => {
102-
await batch.batch(denops, async (denops) => {
103-
await fn.setbufvar(denops, bufnr, "&fileformat", ff);
104-
await fn.setbufvar(denops, bufnr, "&fileencoding", enc);
105-
await replace(denops, bufnr, repl);
106-
});
187+
await replace(denops, bufnr, repl, {
188+
fileformat: ff,
189+
fileencoding: enc,
107190
});
108191
}
109192

@@ -119,30 +202,30 @@ export async function concrete(
119202
denops: Denops,
120203
bufnr: number,
121204
): Promise<void> {
122-
await helper.load(denops, new URL("./buffer.vim", import.meta.url));
205+
const suffix = await ensurePrerequisites(denops);
123206
await batch.batch(denops, async (denops) => {
124207
await autocmd.group(
125208
denops,
126-
"denops_std_buffer_v1_concrete",
209+
`denops_std_buffer_concrete_${suffix}`,
127210
(helper) => {
128211
const pat = `<buffer=${bufnr}>`;
129212
helper.remove("*", pat);
130213
helper.define(
131214
"BufWriteCmd",
132215
pat,
133-
"call DenopsStdBufferV1ConcreteStore()",
216+
`call DenopsStdBufferConcreteStore_${suffix}()`,
134217
);
135218
helper.define(
136219
"BufReadCmd",
137220
pat,
138-
"call DenopsStdBufferV1ConcreteRestore()",
221+
`call DenopsStdBufferConcreteRestore_${suffix}()`,
139222
{
140223
nested: true,
141224
},
142225
);
143226
},
144227
);
145-
await denops.call("DenopsStdBufferV1ConcreteStore");
228+
await denops.call(`DenopsStdBufferConcreteStore_${suffix}`);
146229
});
147230
}
148231

denops_std/buffer/buffer.vim

Lines changed: 0 additions & 54 deletions
This file was deleted.

denops_std/helper/echo.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
import type { Denops } from "https://deno.land/x/denops_core@v3.0.1/mod.ts";
2+
import * as vars from "../variable/mod.ts";
3+
import { execute } from "./execute.ts";
24
import { batch } from "../batch/mod.ts";
3-
import { load } from "./load.ts";
5+
import { generateUniqueString } from "../util.ts";
6+
7+
const suffix = generateUniqueString();
8+
9+
async function ensurePrerequisites(denops: Denops): Promise<string> {
10+
if (await vars.g.get(denops, `loaded_denops_std_helper_echo_${suffix}`)) {
11+
return suffix;
12+
}
13+
const script = `
14+
let g:loaded_denops_std_helper_echo_${suffix} = 1
15+
16+
function! DenopsStdHelperEcho_${suffix}(message) abort
17+
call timer_start(0, { -> s:DenopsStdHelperEchoInternal_${suffix}(a:message) })
18+
endfunction
19+
20+
function! s:DenopsStdHelperEchoInternal_${suffix}(message) abort
21+
redraw | echo a:message
22+
endfunction
23+
`;
24+
await execute(denops, script);
25+
return suffix;
26+
}
427

528
/**
629
* Echo message as like `echo` on Vim script.
@@ -62,6 +85,6 @@ export async function friendlyCall(
6285
}
6386

6487
async function echoVim(denops: Denops, message: string): Promise<void> {
65-
await load(denops, new URL("./echo.vim", import.meta.url));
66-
await denops.call("DenopsStdHelperEchoV1", message);
88+
const suffix = await ensurePrerequisites(denops);
89+
await denops.call(`DenopsStdHelperEcho_${suffix}`, message);
6790
}

denops_std/helper/echo.vim

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)