Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
erasin authored and NTBBloodbath committed Apr 7, 2023
1 parent 2c6c445 commit 77bc7b2
Show file tree
Hide file tree
Showing 15 changed files with 3,305 additions and 3,430 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,26 @@ make build

Neovim loads parser in runtimepath order so to test the generated grammar,
prepend it to rtp with `set rtp^=/path/to/tree-sitter-http`.

# Tasks

- [ ] variable
- [x] comment
- [x] request
- [x] method
- [x] target_url
- [x] scheme
- [x] authority
- [x] host
- [x] path /
- [x] query ?
- [ ] fragment #
- [x] http-version
- [x] params
- [x] header
- [x] body
- [x] json
- [x] xml
- [x] file
- [ ] graphq
- [ ] cli
149 changes: 111 additions & 38 deletions grammar.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,118 @@
const json = require("tree-sitter-json/grammar");
const NL = token.immediate(/[\r\n]+/);

module.exports = grammar(json, {
const PREC = {
comment: 1,
request: 2,
header: 3,
param: 4,
body: 5,
var: 6,
}

module.exports = grammar({
name: "http",

extras: ($, original) => [
...original,
$.request,
$.header,
$.external_body,
$.comment,
],
extras: $ => [],
word: $ => $.identifier,
inline: $ => [],

rules: {
document: ($, original) => repeat(original),

request: ($) =>
seq(field("method", $.method), $._whitespace, field("url", $.url)),
method: (_) => /(GET|POST|PATCH|DELETE|PUT)/,
url: (_) =>
/((www|http:|https:)\/\/(?:w{1,3}\.)?[^\s.]+(?:\.[a-z]+)*(?::\d+)?|\{\{\w+\}\})([\w.,@?^=%&:\/~+#\{\}\u00C0-\u00FF-]*[\w@?^=%&\/~+#\u00C0-\u00FF-])?/,

header: ($) =>
seq(
field("name", seq($.name, ":")),
$._whitespace,
field("value", $.value)
),
name: (_) => /[A-Za-z-]+/,
value: (_) => /[^\n]+/,

external_body: ($) =>
seq(
token("<"),
$._whitespace,
field("json_file", $.json_file),
),
json_file: (_) => seq(/[A-Za-z-_./]+/, ".json"),


comment: ($) => token(seq("#", /.*/)),

_whitespace: (_) => repeat1(/[\t\v ]/),
document: $ => repeat(
choice(
$.variable_declaration,
$.variable,
$.comment,
$.request,
$.query_param,
$.header,
$.json_body,
$.xml_body,
$.external_body,
$.number,
NL,
)
),

request: $ => prec.left(PREC.request, seq(
$.method,
$._whitespace,
$.target_url,
optional(seq($._whitespace, $.http_version)),
NL),
),

method: $ => choice(/(OPTIONS|GET|HEAD|POST|PUT|DELETE|TRACE|CONNECT|PATCH)/, $.const_spec),

target_url: $ => seq(
optional(seq($.scheme, "://")),
optional($.authority),
$.host,
optional($.path),
optional(repeat1($.query_param)),
),

scheme: _ => /(about|acct|arcp|cap|cid|coap+tcp|coap+ws|coaps+tcp|coaps+ws|data|dns|example|file|ftp|geo|h323|http|https|im|info|ipp|mailto|mid|ni|nih|payto|pkcs11|pres|reload|secret-token|session|sms|tag|telnet|urn|ws|wss)/,

authority: $ => prec.left(PREC.request, seq(optional($.pair), "@")),
host: $ => prec.left(PREC.request, seq($.identifier, optional($.pair))),
path: $ => repeat1(choice("/", seq("/", $.identifier, optional("/")))),
http_version: _ => prec.right(/HTTP\/1.1|HTTP\/2/),

pair: $ => seq(
field("name", $.identifier),
":",
field("value", $.identifier),
),

query_param: $ => prec.left(PREC.param, seq(
choice("?", "&"),
field('key', alias($.identifier, $.key)),
'=',
field('value', alias($.identifier, $.value)),
optional(NL),
)),

header: $ => prec(PREC.header, seq(
field("name", alias($.identifier, $.name)),
":",
optional($._whitespace),
field("value", alias($._line, $.value)),
NL,
)),

json_body: $ => prec.left(PREC.body, seq(/\{\n/, repeat(seq($._line, NL)), /\}\n\n/)),
xml_body: $ => prec.left(PREC.body, seq(/<\?xml.*\?>/, NL, repeat(seq($._line, NL)), /<\/.*>\n\n/)),
graphql_body: $ => prec(PREC.body, seq("query", $._whitespace, "(", repeat(seq($._line, NL)), /\}\n\n/)),

external_body: $ => seq(
"<",
optional(seq("@", $.identifier)),
$._whitespace,
field("file_path", alias($._line, $.path))
),

variable: $ => prec.left(PREC.var, seq("{{", $.identifier, "}}")),

variable_declaration: $ => prec.left(PREC.var, seq(
"@",
field("identifier", $.identifier),
optional(seq(
optional($._whitespace),
"=",
optional($._whitespace),
field("value", $._line),
))
)),

const_spec: _ => /[A-Z][A-Z\\d_]+/,
identifier: _ => /[A-Za-z_.\d\u00A1-\uFFFF-]+/,
comment: _ => prec.left(PREC.comment, token(seq("#", /.*/, NL))),
_whitespace: _ => repeat1(/[\t\v ]/),
_newline: _ => repeat1(/[\n]/),
_line: _ => /[^\n]+/,
string: _ => /"[^"]*"/,
number: _ => /[0-9]+/,
boolean: _ => choice('true', 'false'),
null: _ => 'null',
},
});
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
},
"homepage": "https://github.com/rest-nvim/tree-sitter-http#readme",
"dependencies": {
"nan": "^2.14.2",
"tree-sitter-json": "^0.19.0"
"nan": "^2.14.2"
},
"devDependencies": {
"tree-sitter-cli": "^0.20.0"
Expand All @@ -44,4 +43,4 @@
}
}
]
}
}
32 changes: 29 additions & 3 deletions queries/highlights.scm
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
; inherits: json

; Display errors
(ERROR) @error

; Comments
(comment) @comment

(method) @keyword
(target_url) @text.uri
(host) @text.uri
(path) @text.uri
(scheme) @keyword

(request
method: (method) @keyword
url: (url) @text.uri)

(pair
name: (_) @attribute
value: (_) @string)


(query_param
key: (key) @attribute
value: (value) @string)

(header
name: (name) @constant
value: (value))

; rest.nvim Neovim plugin specific features
(external_body
json_file: (json_file) @text.uri) @keyword
file_path: (file_path) @text.uri) @keyword

(number) @number
(string) @string
(variable) @variable
(variable_declaration
identifier: (identifier) @variable
value: (value) @string)

[
"@"
":"
"="
] @operator
4 changes: 4 additions & 0 deletions queries/injections.scm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(comment) @comment

(json_body) @json
(xml_body) @xml
Loading

0 comments on commit 77bc7b2

Please sign in to comment.