Skip to content

Commit 89ed67b

Browse files
committed
Fix Perl 6 identifier matching & highligting
Backstory: * Perl 6 allows dashes in identifiers. * When I worked on syntax/perl6.vim in the past, I made heavy use of \k and \K (which are based on 'iskeyword') for convenience. At the time, 'iskeyword' in ftplugin/perl6.vim did not include a dash, which worked out fine for my needs. * As of f7f84ea, a dash is included in 'iskeyword', which is the right way to go as it makes various Vim keyword commands work on all Perl 6 identifiers. But this broke a lot of identifier-related highlighting. It's not simple to work around, since having a dash in \k and \K makes those classes useless for identifier-matching due to the rules about where a dash is allowed in identifiers. E.g. "$foo--bar" is illegal, and "$foo-5" is an expression. Since the regexes in the syntax file are getting rather unwieldy already, I don't want to simply replace all uses of \k and \K with new regexes. I would prefer to write them only once and refer to them later by name. The only way to do this in VimL is to concatenate and eval strings, which would makes the file even longer and less readable. So I opted for introducing a preprocessor instead. I'm adding syntax/perl6.vim.pre which will be the master source file, and leaving syntax/perl6.vim there as the preprocessed version. This way the syntax file still works out of the box when bundling this repository with pathogen or vundle or whatever. However, anyone who works on the Perl 6 syntax file should now edit syntax/perl6.vim.pre instead, and run "make preproc" (or just "make") before committing their changes. Additionally, I also added high-bit alphabetical characters to 'iskeyword', since Perl 6 allows them in identifiers. I also added a few syntax tests for Perl 6 which relate to idenfifiers. While converting the patterns to use the preprocessed ones I also fixed up some inconsistencies related to identifier. Most notably, dashes are now allowed in Pod identifiers. There are other cases in the syntax file where patterns are reused, so I will be moving more patterns into preprocessor macros to enhance maintainability. This is especially pertinent to the syntax regions, which have very long start/end patterns already.
1 parent bf618eb commit 89ed67b

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

preproc.pl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/end perl
2+
use strict;
3+
use warnings;
4+
5+
# This script is used to preprocess the perl6 syntax file to reduce
6+
# repetition of common patterns. VimL requires cumbersome string
7+
# concatenation and eval to reuse patterns, which makes for a lot of
8+
# boilerplate code and a less readable regexes. So instead we preprocess
9+
# the file to keep the original source more readable and easier to edit.
10+
#
11+
# A "macro" is defined by including lines in the source file which start
12+
# with the VimL comment character (") followed by an identifier name
13+
# surrounded by two sets of at-signs (@@FOO@@). This is followed by
14+
# whitespace and then a double or single-quoted string containing the
15+
# replacement text. Earlier macros can be interpolated into later macros.
16+
17+
my $preproc = '@@';
18+
my %replacements;
19+
while (my $line = <>) {
20+
my $check_line = $line;
21+
while ($check_line =~ /$preproc/) {
22+
$check_line = substr($check_line, $+[0]);
23+
if ($check_line !~ /^\w+$preproc/) {
24+
warn "Missing '$preproc' on line $.\n";
25+
}
26+
else {
27+
$check_line = substr($check_line, $+[0]);
28+
}
29+
}
30+
31+
if ($line =~ /^"\s*$preproc(\w+)$preproc\s+ (?:"(.+)"|'(.*)')\s*$/) {
32+
my ($name, $content) = ($1, $2);
33+
$content =~ s/$preproc(\w+)$preproc/
34+
die "Replacement for $preproc$1$preproc not found at line $.\n" if !$replacements{$1};
35+
$replacements{$1}
36+
/eg;
37+
$replacements{$name} = $content;
38+
}
39+
else {
40+
$line =~ s/$preproc(\w+)$preproc/
41+
die "Replacement for $preproc$1$preproc not found at line $.\n" if !$replacements{$1};
42+
$replacements{$1}
43+
/eg;
44+
}
45+
print $line;
46+
}

0 commit comments

Comments
 (0)