JavaScriptgrammar.js -rw-r--r-- 1.5 KiB
1const NEWLINE = /\r?\n/;
2const WHITE_SPACE = /[\t\f\v ]+/;
3const ANYTHING = /[^\r\n]+/;
4
5module.exports = grammar({
6 name: "gitdiff",
7
8 extras: ($) => [WHITE_SPACE],
9
10 rules: {
11 source: ($) => repeat(seq($._line, NEWLINE)),
12
13 _line: ($) =>
14 choice(
15 $.command,
16 $.file_change,
17 $.binary_change,
18 $.index,
19 $.similarity,
20 $.file,
21 $.location,
22 $.addition,
23 $.deletion,
24 $.context
25 ),
26
27 command: ($) => iseq("diff", "--git", $.filename),
28
29 file_change: ($) =>
30 iseq(
31 field("kind", choice("new", "deleted", "rename")),
32 choice(
33 seq("file", "mode", $.mode),
34 seq(choice("from", "to"), $.filename)
35 )
36 ),
37
38 binary_change: ($) =>
39 iseq("Binary", "files", $.filename, "and", $.filename, "differ"),
40
41 index: ($) => iseq("index", $.commit, "..", $.commit, optional($.mode)),
42
43 similarity: ($) => iseq("similarity", "index", field("score", /\d+/), "%"),
44
45 file: ($) => iseq(field("kind", choice("---", "+++")), $.filename),
46
47 location: ($) => iseq("@@", $.linerange, $.linerange, "@@", ANYTHING),
48
49 addition: ($) => iseq("+", optional(ANYTHING)),
50
51 deletion: ($) => iseq("-", optional(ANYTHING)),
52
53 context: ($) => token(prec(-1, ANYTHING)),
54
55 linerange: ($) => /[-\+]\d+,\d+/,
56 filename: ($) => repeat1(/\S+/),
57 commit: ($) => /[a-f0-9]{7,40}/,
58 mode: ($) => /\d+/,
59 },
60});
61
62function iseq(start_token, ...tokens) {
63 return seq(token.immediate(start_token), ...tokens);
64}