Skip to content

Commit

Permalink
Add hooks_file feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Shougo committed Oct 23, 2023
1 parent 4202280 commit d9f10f0
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 66 deletions.
2 changes: 1 addition & 1 deletion autoload/dpp/util.vim
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ endfunction
function! dpp#util#_check_files() abort
const time = dpp#util#_get_runtime_path()->getftime()
const ret = !(g:dpp#_check_files->copy()
\ ->map({ _, val -> val->expand()->getftime() })
\ ->map({ _, val -> dpp#util#_expand(val)->getftime() })
\ ->filter({ _, val -> time < val })->empty())
if !ret
return 0
Expand Down
109 changes: 79 additions & 30 deletions denops/dpp/dpp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { Loader } from "./loader.ts";
import { defaultExtOptions } from "./base/ext.ts";
import { defaultProtocolOptions } from "./base/protocol.ts";
import { ConfigReturn } from "./base/config.ts";
import { errorException, isDirectory } from "./utils.ts";
import { errorException, isDirectory, parseHooksFile } from "./utils.ts";

export class Dpp {
private loader: Loader;
Expand Down Expand Up @@ -113,14 +113,32 @@ export class Dpp {
// Initialize plugins
const protocols = await this.getProtocols(denops, options);
const recordPlugins: Record<string, Plugin> = {};
for (const plugin of configReturn.plugins) {
recordPlugins[plugin.name] = initPlugin(
await detectPlugin(
denops,
options,
protocols,
for (let plugin of configReturn.plugins) {
plugin = await detectPlugin(
denops,
options,
protocols,
plugin,
);

if (plugin.hooks_file) {
const hooksFile = await denops.call(
"dpp#util#_expand",
plugin.hooks_file,
) as string;
const hooksFileLines = (await Deno.readTextFile(hooksFile)).split("\n");

plugin = Object.assign(
plugin,
),
parseHooksFile(
options.hooksFileMarker,
hooksFileLines,
),
);
}

recordPlugins[plugin.name] = initPlugin(
plugin,
basePath,
);
}
Expand Down Expand Up @@ -228,12 +246,45 @@ export class Dpp {
`let &runtimepath = '${newRuntimepath}'`,
];

for (const plugin of Object.values(recordPlugins)) {
if (!plugin.path || !await isDirectory(plugin.path) || !plugin.hook_add) {
continue;
// hooksFiles
if (configReturn.hooksFiles) {
for (
const hooksFile of await Promise.all(configReturn.hooksFiles.map(
async (hooksFile) =>
await denops.call("dpp#util#_expand", hooksFile) as string,
))
) {
const hooksFileLines = (await Deno.readTextFile(hooksFile)).split("\n");

const parsedHooksFile = parseHooksFile(
options.hooksFileMarker,
hooksFileLines,
);

// Use ftplugin only
if (parsedHooksFile.ftplugin && is.Record(parsedHooksFile.ftplugin)) {
if (!configReturn.ftplugins) {
configReturn.ftplugins = {};
}

// Merge ftplugins
for (const filetype of Object.keys(parsedHooksFile.ftplugin)) {
if (configReturn.ftplugins[filetype]) {
configReturn.ftplugins[filetype] += `\n${
parsedHooksFile.ftplugin[filetype]
}`;
} else {
configReturn.ftplugins[filetype] =
parsedHooksFile.ftplugin[filetype];
}
}
}
}
}

stateLines.push(plugin.hook_add);
let checkFiles = configReturn.checkFiles ?? [];
if (configReturn.hooksFiles) {
checkFiles = checkFiles.concat(configReturn.hooksFiles);
}

if (await vars.g.get(denops, "did_load_filetypes", false)) {
Expand All @@ -249,6 +300,20 @@ export class Dpp {
stateLines = stateLines.concat(configReturn.stateLines);
}

for (const plugin of Object.values(recordPlugins)) {
if (!plugin.path || !await isDirectory(plugin.path)) {
continue;
}

if (plugin.hooks_file) {
checkFiles.push(plugin.hooks_file);
}

if (plugin.hook_add) {
stateLines.push(plugin.hook_add);
}
}

const inlineVimrcs = await Promise.all(options.inlineVimrcs.map(
async (vimrc) => await denops.call("dpp#util#_expand", vimrc) as string,
));
Expand Down Expand Up @@ -279,7 +344,7 @@ export class Dpp {
recordPlugins,
{},
options,
configReturn.checkFiles ?? [],
checkFiles,
]),
];
//console.log(cacheFile);
Expand All @@ -292,7 +357,7 @@ export class Dpp {
await this.mergePlugins(denops, dppRuntimepath, recordPlugins);

// Generate ftplugin files
console.log(configReturn.ftplugins);
//console.log(configReturn.ftplugins);
if (configReturn.ftplugins) {
const generatedFtplugins = await denops.call(
"dpp#util#_generate_ftplugin",
Expand Down Expand Up @@ -666,22 +731,6 @@ async function detectPlugin(
return plugin;
}

async function parseHooksFile(
denops: Denops,
marker: string,
hooksFile: string[],
): Promise<Partial<Plugin>> {
const startMarker = marker.split(',')[0]
const endMarker = marker.split(',')[1]
const options: Partial<Plugin> = {};
let hookName = "";

for (const line of hooksFile) {
}

return options;
}

Deno.test("initPlugin", () => {
assertEquals(
initPlugin({
Expand Down
5 changes: 4 additions & 1 deletion denops/dpp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,18 @@ export type Plugin = {
augroup?: string;
build?: string;
depends?: string | string[];
dummy_commands?: string[];
dummy_mappings?: string[];
frozen?: boolean;
ftplugin?: Record<string, string>;
if?: boolean | string;
hook_add?: string;
hook_depends_update?: string;
hook_done_update?: string;
hook_post_source?: string;
hook_post_update?: string;
hook_source?: string;
hooks_file?: string;
if?: boolean | string;
lazy?: boolean;
local?: boolean;
lua_add?: string;
Expand Down
112 changes: 111 additions & 1 deletion denops/dpp/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Denops } from "./deps.ts";
import { assertEquals, Denops } from "./deps.ts";

export async function errorException(
denops: Denops,
Expand Down Expand Up @@ -61,3 +61,113 @@ export async function safeStat(path: string): Promise<Deno.FileInfo | null> {
}
return null;
}

export function parseHooksFile(
marker: string,
hooksFile: string[],
): Record<string, string | Record<string, string>> {
const startMarker = marker.split(",")[0];
const endMarker = marker.split(",")[1];
const options: Record<string, string | Record<string, string>> = {};
const ftplugin: Record<string, string> = {};
let dest:
| Record<string, string | Record<string, string>>
| Record<string, string>
| null = null;
let hookName = "";

for (const line of hooksFile) {
if (hookName.length === 0) {
const markerPos = line.lastIndexOf(startMarker);
if (markerPos < 0) {
continue;
}

dest = null;

// Get hookName
const match = line.slice(0, markerPos).match(
/\s+(?<hookName>[0-9a-zA-Z_-]+)\s*/,
);
if (!match || !match.groups) {
// Invalid marker
continue;
}

hookName = match.groups.hookName;
if (hookName.startsWith("hook_") || hookName.startsWith("lua_")) {
dest = options;
} else {
// Use ftplugin
dest = ftplugin;
}
} else {
if (line.endsWith(endMarker)) {
hookName = "";
continue;
}

if (!dest) {
continue;
}

if (dest[hookName]) {
dest[hookName] += "\n" + line;
} else {
dest[hookName] = line;
}
}
}

options["ftplugin"] = ftplugin;

return options;
}

Deno.test("parseHooksFile", () => {
assertEquals(
parseHooksFile("{{{,}}}", [
'" c {{{',
"hogera",
"}}}",
'" hook_source {{{',
"piyo",
"}}}",
]),
{
hook_source: "piyo",
ftplugin: {
c: "hogera",
},
},
);

// Invalid line
assertEquals(
parseHooksFile("{{{,}}}", [
'" {{{',
"hogera",
"}}}",
'" hook_source {{{',
"piyo",
"}}}",
]),
{
hook_source: "piyo",
ftplugin: {},
},
);

// Lua
assertEquals(
parseHooksFile("{{{,}}}", [
"-- lua_source {{{",
"piyo",
"-- }}}",
]),
{
lua_source: "piyo",
ftplugin: {},
},
);
});
36 changes: 3 additions & 33 deletions doc/dpp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -235,37 +235,6 @@ ftplugin (Dictionary)
NOTE: You need to call |dpp#clear_state()| after vimrc is
changed.

*dpp-plugin-option-hooks_file*
hooks_file (String) or (List)
Hooks file path. It must be valid path.
It is useful to define long hooks.

The file format is:

{hook_name} {start_marker}
...
{end_marker}

{start_marker} and {end_marker} are from
|dpp-option-hooksFileMarker|.
{hook_name} is "hook_xxx" or "lua_xxx" or
|dpp-plugin-options-ftplugin| filetype.

Example:
>
" hook_source {{{
let g:foo = 'bar'
" }}}
" cpp {{{
let g:bar = 'baz'
" }}}
" Use vim9script
" hook_update {{{
vim9script
g:bar = 'baz'
" }}}
<
*dpp-plugin-option-if*
if (Bool) or (String)
If set to |v:false|, dpp doesn't load the plugin.
If it is |String|, dpp will eval it.
Expand Down Expand Up @@ -440,9 +409,10 @@ hooks_file (String) or (List)
...
{end_marker}

{start_marker} and {end_marker} are from hooks_file_marker.
{start_marker} and {end_marker} are from
|dpp-option-hooksFileMarker|.
{hook_name} is "hook_xxx" or "lua_xxx" or
|dpp-plugin-option-ftplugin| filetype.
|dpp-plugin-options-ftplugin| filetype.

Example:
>
Expand Down

0 comments on commit d9f10f0

Please sign in to comment.