Skip to content

Commit

Permalink
Merge #52 from justinmk/fixes
Browse files Browse the repository at this point in the history
fix: taglink special-cases |(| |{| …
  • Loading branch information
justinmk authored Oct 19, 2022
2 parents 30cd470 + 8c7b8ff commit 6ffd5e3
Show file tree
Hide file tree
Showing 7 changed files with 3,521 additions and 3,382 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ Known issues
`:help lcs-tab`.
- `url` doesn't handle _surrounding_ parens. E.g. `(https://example.com/#yay)` yields `word`
- `url` doesn't handle _nested_ parens. E.g. `(https://example.com/(foo)#yay)`
- `column_heading` currently only recognizes tilde "~" preceded by space (i.e.
"foo ~" not "foo~"). This covers 99% of :help files, but the grammar should
- `column_heading` currently only recognizes tilde `~` preceded by space (i.e.
`foo ~` not `foo~`). This covers 99% of :help files, but the grammar should
probably support "foo~" also.
- `column_heading` children should be plaintext. Currently its children are parsed as `$._atom`.

TODO
----
Expand Down
8 changes: 4 additions & 4 deletions corpus/arguments.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ EXTERNAL *netrw-externapp* {{{2
(help_file
(block
(line
(word)
(ERROR
(word))
(argument
(word))
(word)
(ERROR
(word)
(word)))
(word)
(codespan
(word))
Expand Down
28 changes: 13 additions & 15 deletions corpus/optionlink.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ world 'hello' world
(word))))

================================================================================
NOT optionlink: ' followed by whitespace
NOT optionlink: ' or 'x
================================================================================
'fillchars'
stl ' ' or '^' statusline
wbr ' ' windowbar
tricky: ' 'yes'
stl ' ' or '^' statusline
wbr ' ' windowbar
tricky: ' 'yes' 's foo


--------------------------------------------------------------------------------
Expand All @@ -60,12 +60,14 @@ NOT optionlink: ' followed by whitespace
(word)
(word)
(optionlink
(word)))))
(word))
(word)
(word))))

================================================================================
NOT optionlink #7 #14
================================================================================
Let's see if that works.
Let's see.
no! ','sqlKeyword'
single-char '-' 'g' '보'
non-ascii: '\"' '%)' '-bang' '.*\\.log' '.gitignore' '@{${\"foo\"}}'
Expand All @@ -80,9 +82,6 @@ number: '04' 'ISO-10646-1' 'python3'
(help_file
(block
(line
(word)
(word)
(word)
(word)
(word))
(line
Expand All @@ -107,11 +106,11 @@ number: '04' 'ISO-10646-1' 'python3'
(MISSING "*"))
(word)
(word)
(word)
(ERROR
(word))
(argument
(word))
(word)
(ERROR
(word)
(word)))
(word)
(word))
(line
Expand Down Expand Up @@ -155,8 +154,7 @@ x `after_codespan`'s
(word)
(codespan
(word))
(word)
(ERROR))))
(word))))

================================================================================
NOT optionlink 3
Expand Down
19 changes: 19 additions & 0 deletions corpus/taglink.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ taglink alone
================================================================================
taglink in text
================================================================================
|(|, |)|, |`|, |{|, |}|.

Hello |world| hello

|-+| +[num] line
Expand All @@ -26,6 +28,23 @@ Hello |world| hello
--------------------------------------------------------------------------------

(help_file
(block
(line
(taglink
(word))
(word)
(taglink
(word))
(word)
(taglink
(word))
(word)
(taglink
(word))
(word)
(taglink
(word))
(word)))
(block
(line
(word)
Expand Down
23 changes: 17 additions & 6 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ module.exports = grammar({

// Explicit special cases: these are plaintext, not errors.
_word_common: () => choice(
// NOT optionlink: single "'".
// NOT optionlink: '
"'",
// NOT optionlink: 'x
seq("'", token.immediate(/[^'\n\t ]/)),
// NOT optionlink: followed by non-lowercase char.
seq("'", token.immediate(/[a-z]*[^'a-z\n\t ][a-z]*/), optional(token.immediate("'"))),
// NOT optionlink: single char surrounded by "'".
Expand Down Expand Up @@ -199,7 +201,15 @@ module.exports = grammar({
// Link to option: 'foo'. Lowercase non-digit ASCII, minimum 2 chars. #14
optionlink: ($) => _word($, /[a-z][a-z]+/, "'", "'"),
// Link to tag: |foo|
taglink: ($) => _word($, /[^|\n\t ]+/, '|', '|'),
taglink: ($) => _word($, choice(
token.immediate(/[^|\n\t ]+/),
// Special cases: |(| |{| …
token.immediate('{'),
token.immediate('}'),
token.immediate('('),
token.immediate(')'),
token.immediate('`'),
), '|', '|'),
// Inline code (may contain whitespace!): `foo bar`
codespan: ($) => _word($, /[^``\n]+/, '`', '`'),
// Argument: {arg}
Expand All @@ -208,9 +218,10 @@ module.exports = grammar({
});

// Word delimited by special chars.
// The word_regex capture is aliased to "word" because they are semantically
// the same: atoms of captured plain text.
function _word($, word_regex, c1, c2, fname) {
// `rule` can be a rule function or regex. It is aliased to "word" because they are
// semantically the same: atoms of captured plain text.
function _word($, rule, c1, c2, fname) {
rule = rule.test !== undefined ? token.immediate(rule) : rule
fname = fname ?? 'text';
return seq(c1, field(fname, alias(token.immediate(word_regex), $.word)), token.immediate(c2));
return seq(c1, field(fname, alias(rule, $.word)), token.immediate(c2));
}
66 changes: 61 additions & 5 deletions src/grammar.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@
"type": "STRING",
"value": "'"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "'"
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^'\\n\\t ]"
}
}
]
},
{
"type": "SEQ",
"members": [
Expand Down Expand Up @@ -837,11 +853,51 @@
"content": {
"type": "ALIAS",
"content": {
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^|\\n\\t ]+"
}
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "PATTERN",
"value": "[^|\\n\\t ]+"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "{"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "}"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "("
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": ")"
}
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "`"
}
}
]
},
"named": true,
"value": "word"
Expand Down
Loading

0 comments on commit 6ffd5e3

Please sign in to comment.