Skip to content

Commit 30aa472

Browse files
authored
Merge pull request #128 from vim-denops/add-modules
Refactoring and add `buffer` and `argument` modules
2 parents ea4b59f + f0fb8b7 commit 30aa472

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1831
-199
lines changed

denops_std/README.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ for a plugin.
1212
By using this module, developers can write Vim/Neovim denops plugins like:
1313

1414
```typescript
15-
import { Denops } from "https://deno.land/x/denops_std/mod.ts";
16-
import * as fn from "https://deno.land/x/denops_std/function/mod.ts";
17-
import * as vars from "https://deno.land/x/denops_std/variable/mod.ts";
18-
import * as helper from "https://deno.land/x/denops_std/helper/mod.ts";
15+
import { Denops } from "./mod.ts";
16+
import * as fn from "./function/mod.ts";
17+
import * as vars from "./variable/mod.ts";
18+
import * as helper from "./helper/mod.ts";
1919

2020
import { assertString } from "https://deno.land/x/unknownutil/mod.ts";
2121

@@ -54,14 +54,16 @@ for more details.
5454

5555
## Index
5656

57-
| Name | Description |
58-
| -------------------------- | ---------------------------------------------------------------- |
59-
| [`anonymous`](./anonymous) | A module to provide anonymous function |
60-
| [`autocmd`](./autocmd) | A module to provide helper functions to manage `autocmd` |
61-
| [`batch`](./batch) | A module to provide wrapper functions of `denops.batch()` |
62-
| [`bufname`](./bufname) | A module to provide helper functions to manage Vim's buffer name |
63-
| [`function`](./function) | A module to provide functions of Vim and Neovim native functions |
64-
| [`helper`](./helper) | A module to provide helper functions |
65-
| [`mapping`](./mapping) | A module to provide helper functions to manage mappings |
66-
| [`option`](./option) | A module to provide helper functions to manage options |
67-
| [`variable`](./variable) | A module to provide helper accessor functions to variables |
57+
| Name | Description |
58+
| -------------------------- | ---------------------------------------------------------------------- |
59+
| [`anonymous`](./anonymous) | A module to provide anonymous function |
60+
| [`argument`](./argument) | A module to provide helper functions to manage Vim's command arguments |
61+
| [`autocmd`](./autocmd) | A module to provide helper functions to manage `autocmd` |
62+
| [`batch`](./batch) | A module to provide wrapper functions of `denops.batch()` |
63+
| [`buffer`](./buffer) | A module to provide helper functions to manage buffers |
64+
| [`bufname`](./bufname) | A module to provide helper functions to manage Vim's buffer name |
65+
| [`function`](./function) | A module to provide functions of Vim and Neovim native functions |
66+
| [`helper`](./helper) | A module to provide helper functions |
67+
| [`mapping`](./mapping) | A module to provide helper functions to manage mappings |
68+
| [`option`](./option) | A module to provide helper functions to manage options |
69+
| [`variable`](./variable) | A module to provide helper accessor functions to variables |

denops_std/anonymous/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ Use `add()` to add new anonymous functions and use return value as unique IDs to
1313
call added functions later like:
1414

1515
```typescript
16-
import { Denops } from "https://deno.land/x/denops_std/mod.ts";
17-
import * as anonymous from "https://deno.land/x/denops_std/anonymous/mod.ts";
16+
import { Denops } from "../mod.ts";
17+
import * as anonymous from "./mod.ts";
1818

1919
export async function main(denops: Denops): Promise<void> {
2020
// Add anonymous functions
@@ -46,8 +46,8 @@ export async function main(denops: Denops): Promise<void> {
4646
If you need one-time anonymous function, use `once()` instead like:
4747

4848
```typescript
49-
import { Denops } from "https://deno.land/x/denops_std/mod.ts";
50-
import * as anonymous from "https://deno.land/x/denops_std/anonymous/mod.ts";
49+
import { Denops } from "../mod.ts";
50+
import * as anonymous from "../anonymous/mod.ts";
5151

5252
export async function main(denops: Denops): Promise<void> {
5353
// Add anonymous functions
@@ -76,8 +76,8 @@ export async function main(denops: Denops): Promise<void> {
7676
When you need to remove callback, use `remove()` like:
7777

7878
```typescript
79-
import { Denops } from "https://deno.land/x/denops_std/mod.ts";
80-
import * as anonymous from "https://deno.land/x/denops_std/anonymous/mod.ts";
79+
import { Denops } from "../mod.ts";
80+
import * as anonymous from "../anonymous/mod.ts";
8181

8282
export async function main(denops: Denops): Promise<void> {
8383
// Add anonymous functions

denops_std/anonymous/mod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Denops } from "../deps.ts";
1+
import type { Denops } from "https://deno.land/x/denops_core@v3.0.1/mod.ts";
22

33
// https://github.com/microsoft/TypeScript/issues/26223#issuecomment-674500430
44
export type TupleOf<T, N extends number> = N extends N

denops_std/anonymous/mod_test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import { assertEquals, assertRejects } from "../deps_test.ts";
2-
import { test } from "../deps_test.ts";
1+
import {
2+
assertEquals,
3+
assertRejects,
4+
} from "https://deno.land/std@0.133.0/testing/asserts.ts";
5+
import { test } from "https://deno.land/x/denops_core@v3.0.1/test/mod.ts";
36
import * as anonymous from "./mod.ts";
47

58
test({

denops_std/argument/README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# argument
2+
3+
`argument` is a module to handle Vim's command arguments.
4+
5+
- [API documentation](https://doc.deno.land/https/deno.land/x/denops_std/argument/mod.ts)
6+
7+
## Usage
8+
9+
### parse/parseOpts/parseFlags
10+
11+
Use `parse()`, `parseOpts`, or `parseFlags` to parse Vim's command arguments
12+
like:
13+
14+
```typescript
15+
import { Denops } from "../mod.ts";
16+
import { parse, parseFlags, parseOpts } from "../argument/mod.ts";
17+
18+
export async function main(denops: Denops): Promise<void> {
19+
const args = [
20+
"++enc=sjis",
21+
"++ff=dos",
22+
"-f",
23+
"--foo=foo",
24+
"--bar=bar",
25+
"--bar=baz",
26+
"hello",
27+
"world",
28+
];
29+
const [opts, flags, residues] = parse(args);
30+
// Or use parseOpts/parseFlags instead
31+
//const [opts, residues] = parseOpts(args);
32+
//const [flags, residues] = parseFlags(args);
33+
34+
console.log(opts);
35+
// { "enc": "sjis", "ff": "dos" }
36+
37+
console.log(flags);
38+
// { "f": "", "foo": "foo", "bar": ["bar", "baz"] }
39+
40+
console.log(residues);
41+
// ["hello", "world"]
42+
}
43+
```
44+
45+
### validateOpts/validateFlags
46+
47+
Use `validateOpts` or `validateFlags` to validate if `opts` or `flags` has
48+
unknown attributes like:
49+
50+
```typescript
51+
import { Denops } from "../mod.ts";
52+
import {
53+
builtinOpts,
54+
parse,
55+
validateFlags,
56+
validateOpts,
57+
} from "../argument/mod.ts";
58+
59+
export async function main(denops: Denops): Promise<void> {
60+
const args = [
61+
"++enc=sjis",
62+
"++ff=dos",
63+
"-f",
64+
"--foo=foo",
65+
"--bar=bar",
66+
"--bar=baz",
67+
"hello",
68+
"world",
69+
];
70+
const [opts, flags, residues] = parse(args);
71+
72+
validateOpts(opts, ["enc", "ff"]);
73+
// Or use `builtinOpts` to validate Vim's builtin `++opts`
74+
//validateOpts(opts, builtinOpts);
75+
76+
validateFlags(flags, ["f", "foo", "bar"]);
77+
}
78+
```
79+
80+
### formatOpt/formatFlag
81+
82+
Use `formatOpt` or `formatFlag` to format `key` and `value` pair like:
83+
84+
```typescript
85+
import { Denops } from "../mod.ts";
86+
import { formatFlag, formatOpt } from "../argument/mod.ts";
87+
88+
export async function main(denops: Denops): Promise<void> {
89+
console.log(formatOpt("enc", "sjis"));
90+
// "++enc=sjis"
91+
92+
console.log(formatFlag("f", ""));
93+
// "-f"
94+
95+
console.log(formatFlag("foo", "value"));
96+
// "--foo=value"
97+
}
98+
```
99+
100+
### formatOpts/formatFlags
101+
102+
Use `formatOpts` or `formatFlags` to format `opts` or `flags` like:
103+
104+
```typescript
105+
import { Denops } from "../mod.ts";
106+
import { formatFlags, formatOpts, parse } from "../argument/mod.ts";
107+
108+
export async function main(denops: Denops): Promise<void> {
109+
const args = [
110+
"++enc=sjis",
111+
"++ff=dos",
112+
"-f",
113+
"--foo=foo",
114+
"--bar=bar",
115+
"--bar=baz",
116+
"hello",
117+
"world",
118+
];
119+
const [opts, flags, residues] = parse(args);
120+
121+
console.log(formatOpts(opts));
122+
// "++enc=sjis ++ff=dos"
123+
124+
console.log(formatFlags(flags));
125+
// "-f --foo=foo --bar=bar --bar=baz"
126+
}
127+
```

denops_std/argument/flags.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { parsePattern } from "./util.ts";
2+
3+
export type Flags = Record<string, string | string[] | undefined>;
4+
5+
const longPattern = /^--([a-zA-Z0-9-]+)(?:=(.*))?/;
6+
const shortPattern = /^-([a-zA-Z0-9])(.*)/;
7+
8+
/**
9+
* Parse string array to extract flags (-f/--flag).
10+
*/
11+
export function parseFlags(args: string[]): [Flags, string[]] {
12+
const patterns = [longPattern, shortPattern];
13+
const flags: Flags = {};
14+
const residue: string[] = [];
15+
loop:
16+
for (let i = 0; i < args.length; i++) {
17+
const arg = args[i];
18+
if (arg === "--") {
19+
residue.push(...args.slice(i));
20+
break;
21+
}
22+
for (const pattern of patterns) {
23+
const r = parsePattern(arg, pattern);
24+
if (r) {
25+
const [k, v] = r;
26+
const b = flags[k];
27+
if (b != undefined) {
28+
flags[k] = Array.isArray(b) ? [...b, v] : [b, v];
29+
} else {
30+
flags[k] = v;
31+
}
32+
continue loop;
33+
}
34+
}
35+
residue.push(arg);
36+
}
37+
return [flags, residue];
38+
}
39+
40+
/**
41+
* Validate if `flags` has unknown attributes.
42+
*/
43+
export function validateFlags(flags: Flags, knownAttributes: string[]): void {
44+
Object.keys(flags).forEach((v) => {
45+
if (!knownAttributes.includes(v)) {
46+
if (v.length === 1) {
47+
throw new Error(`Unknown flag '-${v}' is specified.`);
48+
} else {
49+
throw new Error(`Unknown flag '--${v}' is specified.`);
50+
}
51+
}
52+
});
53+
}
54+
55+
/**
56+
* Format `key` and `value` to construct string array.
57+
*/
58+
export function formatFlag(
59+
key: string,
60+
value: string | string[] | undefined,
61+
): string[] {
62+
if (value == undefined) {
63+
return [];
64+
}
65+
value = Array.isArray(value) ? value : [value];
66+
if (key.length === 1) {
67+
return value.map((v) => v ? `-${key}${v}` : `-${key}`);
68+
} else {
69+
return value.map((v) => v ? `--${key}=${v}` : `--${key}`);
70+
}
71+
}
72+
73+
/**
74+
* Format `flags` to construct string array.
75+
*/
76+
export function formatFlags(flags: Flags, includes?: string[]): string[] {
77+
let entries = Object.entries(flags);
78+
if (includes != undefined) {
79+
entries = entries.filter(([k, _]) => includes.includes(k));
80+
}
81+
return entries.map(([k, v]) => formatFlag(k, v)).flat();
82+
}

denops_std/argument/flags_test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { assertEquals } from "https://deno.land/std@0.133.0/testing/asserts.ts";
2+
import { parseFlags } from "./flags.ts";
3+
4+
Deno.test("parseFlags", () => {
5+
const [flags, residue] = parseFlags([
6+
"Gin",
7+
"++buffer",
8+
"status",
9+
"++ff=mac",
10+
"-unormal",
11+
"++enc=utf-8",
12+
"--ignore-submodules=all",
13+
"--ignore",
14+
"-v",
15+
"autoload/gin.vim",
16+
"--",
17+
"++buffer",
18+
"-v",
19+
"--ignore",
20+
"autoload/gin/debug.vim",
21+
]);
22+
assertEquals(flags, {
23+
u: "normal",
24+
"ignore-submodules": "all",
25+
ignore: "",
26+
v: "",
27+
});
28+
assertEquals(residue, [
29+
"Gin",
30+
"++buffer",
31+
"status",
32+
"++ff=mac",
33+
"++enc=utf-8",
34+
"autoload/gin.vim",
35+
"--",
36+
"++buffer",
37+
"-v",
38+
"--ignore",
39+
"autoload/gin/debug.vim",
40+
]);
41+
});

denops_std/argument/mod.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Opts, parseOpts } from "./opts.ts";
2+
import { Flags, parseFlags } from "./flags.ts";
3+
4+
export function parse(args: string[]): [Opts, Flags, string[]] {
5+
const [opts, intermediate] = parseOpts(args);
6+
const [flags, residue] = parseFlags(intermediate);
7+
return [opts, flags, residue];
8+
}
9+
10+
export * from "./opts.ts";
11+
export * from "./flags.ts";

0 commit comments

Comments
 (0)