diff --git a/assets/highlighting-tests/batch.bat b/assets/highlighting-tests/batch.bat index 962ef66007a..ed104aeaf0d 100644 --- a/assets/highlighting-tests/batch.bat +++ b/assets/highlighting-tests/batch.bat @@ -4,6 +4,7 @@ REM --- String, Variable, Label, Command, Operator, Number, Delimiter, Comment - :: Label :Start + :: Variable assignment and usage set "VAR1=Hello" set VAR2=World @@ -14,6 +15,9 @@ set "STR=Batch ^& CMD!" :: Arithmetic operation (number, operator) set /a SUM=5+10 +:: Arguments (variable, string) +echo Message from %0, referred to as "%~n0" + :: IF statement (keyword, operator, string, variable) if "%VAR1%"=="Hello" ( echo %VAR1%, %VAR2%! %STR% diff --git a/assets/highlighting-tests/markdown.md b/assets/highlighting-tests/markdown.md index 555b182f961..2572b607ecd 100644 --- a/assets/highlighting-tests/markdown.md +++ b/assets/highlighting-tests/markdown.md @@ -66,6 +66,16 @@ Reference: ![Logo][logo-ref] echo "Hello, world" | tr a-z A-Z ``` +```batch +@echo off + +if not "%~1"=="" ( + echo Hello %~1! +) else ( + echo Hi, I'm Batch, nice to meet you! +) +``` + ```javascript export function greet(name) { return `hello ${name}`; diff --git a/crates/lsh/definitions/batch.lsh b/crates/lsh/definitions/batch.lsh new file mode 100644 index 00000000000..1b65bf1d93d --- /dev/null +++ b/crates/lsh/definitions/batch.lsh @@ -0,0 +1,56 @@ +#[display_name = "Batch"] +#[path = "**/*.cmd"] +#[path = "**/*.bat"] +#[path = "**/*.btm"] + + +pub fn batch() { + until /$/ { + yield other; + + if /::.*/ { + yield comment; + } + else if /(?i:rem)\>\s*(.*)/ { + yield keyword.other; + yield $1 as comment; + } + else if /\^./ { // Escapes + yield markup.italic; + } + else if /%%~[fdpnxsatz]{0,6}[A-Za-z]?|%%[A-Za-z]|\%(?:[0-9]|[\w\s]+\%|\*|~[A-Za-z]*[0-9])|![\w\s]+!/ { // What even is a variable anymore + yield variable; + } + else if /:\w+/ { + yield method; // Most suiting out of the options that I could find that looked good + } + else if /"/ { + until /$/ { + yield string; + if /\^./ { + yield markup.italic; + } else if /%%~[fdpnxsatz]{0,6}[A-Za-z]?|%%[A-Za-z]|\%(?:[0-9]|[\w\s]+\%|\*|~[A-Za-z]*[0-9])|![\w\s]+!/ { + yield variable; + } else if /"/ { + yield string; + break; + } + } + } else if /(?i:for|if|else|call|goto|in|do|exist|not)\>/ { + yield keyword.control; + } else if /(?i:assoc|attrib|break|bcdedit|cacls|cd|chcp|chdir|chkdsk|chkntfs|choice|cls|cmd|color|comp|compact|convert|copy|date|del|dir|diskpart|doskey|driverquery|echo|endlocal|erase|exit|fc|find|findstr|format|fsutil|ftype|gpresult|help|icacls|label|md|mkdir|mklink|mode|more|move|openfiles|path|pause|popd|pushd|print|prompt|pushd|rd|recover|config|ren|rename|replace|rmdir|robocopy|set|setlocal|sc|schtasks|shift|shutdown|sort|start|subst|systeminfo|tasklist|taskkill|time|title|tree|type|ver|verify|vol|xcopy|wmic)\>/ { // Finally got the case insensitivity working properly! + yield keyword.other; + } + else if /(?i:-?(?:0x[\da-fA-F_]+|0b[01_]+|0o[0-7_]+|[\d_]+\.?[\d_]*|\.[\d_]+)(?:e[+-]?[\d_]+)?)n?/ { + if /\w+/ { + // Invalid numeric literal + } else { + yield constant.numeric; + } + } else if /\w+/ { + // Gobble word chars to align the next iteration on a word boundary. + } + + yield other; + } +} diff --git a/crates/lsh/definitions/markdown.lsh b/crates/lsh/definitions/markdown.lsh index 77a005fe925..396c1de1cb5 100644 --- a/crates/lsh/definitions/markdown.lsh +++ b/crates/lsh/definitions/markdown.lsh @@ -28,6 +28,16 @@ pub fn markdown() { if /.*/ {} } } + } else if /(?i:batch|bat)/ { + loop { + await input; + if /\s*```/ { + return; + } else { + batch(); + if /.*/ {} + } + } } else if /(?i:diff)/ { loop { await input;