Skip to content

Commit cb6e72e

Browse files
committed
Custom word boundary matchers
The regexp engine and the shell grammar don't agree on what comprises a “word boundary”. This led to problems where a command or path ending in a shell keyword would be interpreted as that keyword. This change replaces `\b` word boundary matchers with lookahead/-behind matchers on whitespace, line breaks, and command separators (";" and "&"). Closes #22.
1 parent 98ded12 commit cb6e72e

File tree

1 file changed

+35
-35
lines changed

1 file changed

+35
-35
lines changed

Syntaxes/Shell-Unix-Bash.tmLanguage

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@
316316
<array>
317317
<dict>
318318
<key>begin</key>
319-
<string>\b(function)\s+([^\s\\]+)(?:\s*(\(\)))?</string>
319+
<string>(?&lt;=^|;|&amp;|\s)(function)\s+([^\s\\]+)(?:\s*(\(\)))?</string>
320320
<key>beginCaptures</key>
321321
<dict>
322322
<key>1</key>
@@ -357,7 +357,7 @@
357357
</dict>
358358
<dict>
359359
<key>begin</key>
360-
<string>\b([^\s\\=]+)\s*(\(\))</string>
360+
<string>(?&lt;=^|;|&amp;|\s)([^\s\\=]+)\s*(\(\))</string>
361361
<key>beginCaptures</key>
362362
<dict>
363363
<key>1</key>
@@ -424,7 +424,7 @@
424424
<key>contentName</key>
425425
<string>source.ruby.embedded.shell</string>
426426
<key>end</key>
427-
<string>^\t*(RUBY)\b</string>
427+
<string>^\t*(RUBY)(?=\s|;|&amp;|$)</string>
428428
<key>endCaptures</key>
429429
<dict>
430430
<key>1</key>
@@ -470,7 +470,7 @@
470470
<key>contentName</key>
471471
<string>source.ruby.embedded.shell</string>
472472
<key>end</key>
473-
<string>^(RUBY)\b</string>
473+
<string>^(RUBY)(?=\s|;|&amp;|$)</string>
474474
<key>endCaptures</key>
475475
<dict>
476476
<key>1</key>
@@ -516,7 +516,7 @@
516516
<key>contentName</key>
517517
<string>source.python.embedded.shell</string>
518518
<key>end</key>
519-
<string>^\t*(PYTHON)\b</string>
519+
<string>^\t*(PYTHON)(?=\s|;|&amp;|$)</string>
520520
<key>endCaptures</key>
521521
<dict>
522522
<key>1</key>
@@ -562,7 +562,7 @@
562562
<key>contentName</key>
563563
<string>source.python.embedded.shell</string>
564564
<key>end</key>
565-
<string>^(PYTHON)\b</string>
565+
<string>^(PYTHON)(?=\s|;|&amp;|$)</string>
566566
<key>endCaptures</key>
567567
<dict>
568568
<key>1</key>
@@ -608,7 +608,7 @@
608608
<key>contentName</key>
609609
<string>source.applescript.embedded.shell</string>
610610
<key>end</key>
611-
<string>^\t*(APPLESCRIPT)\b</string>
611+
<string>^\t*(APPLESCRIPT)(?=\s|;|&amp;|$)</string>
612612
<key>endCaptures</key>
613613
<dict>
614614
<key>1</key>
@@ -654,7 +654,7 @@
654654
<key>contentName</key>
655655
<string>source.applescript.embedded.shell</string>
656656
<key>end</key>
657-
<string>^(APPLESCRIPT)\b</string>
657+
<string>^(APPLESCRIPT)(?=\s|;|&amp;|$)</string>
658658
<key>endCaptures</key>
659659
<dict>
660660
<key>1</key>
@@ -700,7 +700,7 @@
700700
<key>contentName</key>
701701
<string>text.html.embedded.shell</string>
702702
<key>end</key>
703-
<string>^\t*(HTML)\b</string>
703+
<string>^\t*(HTML)(?=\s|;|&amp;|$)</string>
704704
<key>endCaptures</key>
705705
<dict>
706706
<key>1</key>
@@ -746,7 +746,7 @@
746746
<key>contentName</key>
747747
<string>text.html.embedded.shell</string>
748748
<key>end</key>
749-
<string>^(HTML)\b</string>
749+
<string>^(HTML)(?=\s|;|&amp;|$)</string>
750750
<key>endCaptures</key>
751751
<dict>
752752
<key>1</key>
@@ -792,7 +792,7 @@
792792
<key>contentName</key>
793793
<string>text.html.markdown.embedded.shell</string>
794794
<key>end</key>
795-
<string>^\t*(MARKDOWN)\b</string>
795+
<string>^\t*(MARKDOWN)(?=\s|;|&amp;|$)</string>
796796
<key>endCaptures</key>
797797
<dict>
798798
<key>1</key>
@@ -838,7 +838,7 @@
838838
<key>contentName</key>
839839
<string>text.html.markdown.embedded.shell</string>
840840
<key>end</key>
841-
<string>^(MARKDOWN)\b</string>
841+
<string>^(MARKDOWN)(?=\s|;|&amp;|$)</string>
842842
<key>endCaptures</key>
843843
<dict>
844844
<key>1</key>
@@ -884,7 +884,7 @@
884884
<key>contentName</key>
885885
<string>text.html.textile.embedded.shell</string>
886886
<key>end</key>
887-
<string>^\t*(TEXTILE)\b</string>
887+
<string>^\t*(TEXTILE)(?=\s|;|&amp;|$)</string>
888888
<key>endCaptures</key>
889889
<dict>
890890
<key>1</key>
@@ -930,7 +930,7 @@
930930
<key>contentName</key>
931931
<string>text.html.textile.embedded.shell</string>
932932
<key>end</key>
933-
<string>^(TEXTILE)\b</string>
933+
<string>^(TEXTILE)(?=\s|;|&amp;|$)</string>
934934
<key>endCaptures</key>
935935
<dict>
936936
<key>1</key>
@@ -974,7 +974,7 @@
974974
</dict>
975975
</dict>
976976
<key>end</key>
977-
<string>^\t*(\3)\b</string>
977+
<string>^\t*(\3)(?=\s|;|&amp;|$)</string>
978978
<key>endCaptures</key>
979979
<dict>
980980
<key>1</key>
@@ -1011,7 +1011,7 @@
10111011
</dict>
10121012
</dict>
10131013
<key>end</key>
1014-
<string>^(\3)\b</string>
1014+
<string>^(\3)(?=\s|;|&amp;|$)</string>
10151015
<key>endCaptures</key>
10161016
<dict>
10171017
<key>1</key>
@@ -1219,13 +1219,13 @@
12191219
<array>
12201220
<dict>
12211221
<key>match</key>
1222-
<string>\b(?:if|then|else|elif|fi|for|in|do|done|select|case|continue|esac|while|until|return)\b</string>
1222+
<string>(?&lt;=^|;|&amp;|\s)(?:if|then|else|elif|fi|for|in|do|done|select|case|continue|esac|while|until|return)(?=\s|;|&amp;|$)</string>
12231223
<key>name</key>
12241224
<string>keyword.control.shell</string>
12251225
</dict>
12261226
<dict>
12271227
<key>match</key>
1228-
<string>(?&lt;![-/])\b(?:export|declare|typeset|local|readonly)\b</string>
1228+
<string>(?&lt;=^|;|&amp;|\s)(?:export|declare|typeset|local|readonly)(?=\s|;|&amp;|$)</string>
12291229
<key>name</key>
12301230
<string>storage.modifier.shell</string>
12311231
</dict>
@@ -1269,7 +1269,7 @@
12691269
<array>
12701270
<dict>
12711271
<key>begin</key>
1272-
<string>\b(for)\s+(?=\({2})</string>
1272+
<string>(?&lt;=^|;|&amp;|\s)(for)\s+(?=\({2})</string>
12731273
<key>captures</key>
12741274
<dict>
12751275
<key>1</key>
@@ -1279,7 +1279,7 @@
12791279
</dict>
12801280
</dict>
12811281
<key>end</key>
1282-
<string>\b(done)\b</string>
1282+
<string>(?&lt;=^|;|&amp;|\s)(done)(?=\s|;|&amp;|$)</string>
12831283
<key>name</key>
12841284
<string>meta.scope.for-loop.shell</string>
12851285
<key>patterns</key>
@@ -1292,7 +1292,7 @@
12921292
</dict>
12931293
<dict>
12941294
<key>begin</key>
1295-
<string>\b(for)\s+((?:[^\s\\]|\\.)+)\b</string>
1295+
<string>(?&lt;=^|;|&amp;|\s)(for)\s+((?:[^\s\\]|\\.)+)(?=\s|;|&amp;|$)</string>
12961296
<key>beginCaptures</key>
12971297
<dict>
12981298
<key>1</key>
@@ -1307,7 +1307,7 @@
13071307
</dict>
13081308
</dict>
13091309
<key>end</key>
1310-
<string>\b(done)\b</string>
1310+
<string>(?&lt;=^|;|&amp;|\s)(done)(?=\s|;|&amp;|$)</string>
13111311
<key>endCaptures</key>
13121312
<dict>
13131313
<key>1</key>
@@ -1328,7 +1328,7 @@
13281328
</dict>
13291329
<dict>
13301330
<key>begin</key>
1331-
<string>\b(while|until)\b</string>
1331+
<string>(?&lt;=^|;|&amp;|\s)(while|until)(?=\s|;|&amp;|$)</string>
13321332
<key>captures</key>
13331333
<dict>
13341334
<key>1</key>
@@ -1338,7 +1338,7 @@
13381338
</dict>
13391339
</dict>
13401340
<key>end</key>
1341-
<string>\b(done)\b</string>
1341+
<string>(?&lt;=^|;|&amp;|\s)(done)(?=\s|;|&amp;|$)</string>
13421342
<key>name</key>
13431343
<string>meta.scope.while-loop.shell</string>
13441344
<key>patterns</key>
@@ -1351,7 +1351,7 @@
13511351
</dict>
13521352
<dict>
13531353
<key>begin</key>
1354-
<string>\b(select)\s+((?:[^\s\\]|\\.)+)\b</string>
1354+
<string>(?&lt;=^|;|&amp;|\s)(select)\s+((?:[^\s\\]|\\.)+)(?=\s|;|&amp;|$)</string>
13551355
<key>beginCaptures</key>
13561356
<dict>
13571357
<key>1</key>
@@ -1366,7 +1366,7 @@
13661366
</dict>
13671367
</dict>
13681368
<key>end</key>
1369-
<string>\b(done)\b</string>
1369+
<string>(?&lt;=^|;|&amp;|\s)(done)(?=\s|;|&amp;|$)</string>
13701370
<key>endCaptures</key>
13711371
<dict>
13721372
<key>1</key>
@@ -1387,7 +1387,7 @@
13871387
</dict>
13881388
<dict>
13891389
<key>begin</key>
1390-
<string>\b(case)\b</string>
1390+
<string>(?&lt;=^|;|&amp;|\s)(case)(?=\s|;|&amp;|$)</string>
13911391
<key>captures</key>
13921392
<dict>
13931393
<key>1</key>
@@ -1397,14 +1397,14 @@
13971397
</dict>
13981398
</dict>
13991399
<key>end</key>
1400-
<string>\b(esac)\b</string>
1400+
<string>(?&lt;=^|;|&amp;|\s)(esac)(?=\s|;|&amp;|$)</string>
14011401
<key>name</key>
14021402
<string>meta.scope.case-block.shell</string>
14031403
<key>patterns</key>
14041404
<array>
14051405
<dict>
14061406
<key>begin</key>
1407-
<string>\b(?:in)\b</string>
1407+
<string>(?&lt;=^|;|&amp;|\s)(?:in)(?=\s|;|&amp;|$)</string>
14081408
<key>beginCaptures</key>
14091409
<dict>
14101410
<key>1</key>
@@ -1414,7 +1414,7 @@
14141414
</dict>
14151415
</dict>
14161416
<key>end</key>
1417-
<string>(?=\b(?:esac)\b)</string>
1417+
<string>(?&lt;=^|;|&amp;|\s)(?=(?:esac)(?:\s|;|&amp;|$))</string>
14181418
<key>name</key>
14191419
<string>meta.scope.case-body.shell</string>
14201420
<key>patterns</key>
@@ -1441,7 +1441,7 @@
14411441
</dict>
14421442
<dict>
14431443
<key>begin</key>
1444-
<string>(^|(?&lt;=[&amp;;|]))\s*(if)\b</string>
1444+
<string>(^|(?&lt;=[&amp;;|]))\s*(if)(?=\s|;|&amp;|$)</string>
14451445
<key>beginCaptures</key>
14461446
<dict>
14471447
<key>2</key>
@@ -1453,7 +1453,7 @@
14531453
<key>comment</key>
14541454
<string>Restrict match to avoid matching in lines like `dd if=/dev/sda1 …`</string>
14551455
<key>end</key>
1456-
<string>\b(fi)\b</string>
1456+
<string>(?&lt;=^|;|&amp;|\s)(fi)(?=\s|;|&amp;|$)</string>
14571457
<key>endCaptures</key>
14581458
<dict>
14591459
<key>1</key>
@@ -1574,7 +1574,7 @@
15741574
<array>
15751575
<dict>
15761576
<key>match</key>
1577-
<string>\b(time)\b</string>
1577+
<string>(?&lt;=^|;|&amp;|\s)(time)(?=\s|;|&amp;|$)</string>
15781578
<key>name</key>
15791579
<string>keyword.other.shell</string>
15801580
</dict>
@@ -1765,13 +1765,13 @@
17651765
<array>
17661766
<dict>
17671767
<key>match</key>
1768-
<string>(?&lt;=^|\s)(?::|\.)(?=\s|;|&amp;|$)</string>
1768+
<string>(?&lt;=^|;|&amp;|\s)(?::|\.)(?=\s|;|&amp;|$)</string>
17691769
<key>name</key>
17701770
<string>support.function.builtin.shell</string>
17711771
</dict>
17721772
<dict>
17731773
<key>match</key>
1774-
<string>(?&lt;![-/])\b(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)\b</string>
1774+
<string>(?&lt;=^|;|&amp;|\s)(?:alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|read|readonly|set|shift|shopt|source|suspend|test|times|trap|true|type|ulimit|umask|unalias|unset|wait)(?=\s|;|&amp;|$)</string>
17751775
<key>name</key>
17761776
<string>support.function.builtin.shell</string>
17771777
</dict>

0 commit comments

Comments
 (0)