Skip to content

Commit 400d69d

Browse files
committed
lsh: add Bash, Zsh, Python and JavaScript highlighting
1 parent 35b863f commit 400d69d

9 files changed

Lines changed: 465 additions & 1 deletion

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Single-line comment
2+
/* Multi-line
3+
comment */
4+
5+
const single = 'single quoted string';
6+
const double = "double quoted string";
7+
const template = `template string with ${single}`;
8+
9+
const decimal = 42;
10+
const negative = -3.14e+2;
11+
const hex = 0x2a;
12+
const binary = 0b101010;
13+
const octal = 0o52;
14+
15+
const truthy = true;
16+
const falsy = false;
17+
const empty = null;
18+
const missing = undefined;
19+
const notANumber = NaN;
20+
const infinite = Infinity;
21+
22+
export async function greet(name) {
23+
if (name instanceof String) {
24+
return;
25+
} else if (name in { user: "ok" }) {
26+
throw new Error("unexpected");
27+
}
28+
29+
for (let i = 0; i < 3; i++) {
30+
while (false) {
31+
break;
32+
}
33+
}
34+
35+
try {
36+
return console.log(template, name);
37+
} catch (error) {
38+
return void error;
39+
} finally {
40+
delete globalThis.temp;
41+
}
42+
}
43+
44+
class Person extends Object {
45+
constructor(name) {
46+
super();
47+
this.name = name;
48+
}
49+
}
50+
51+
const result = greet("world");
52+
switch (result) {
53+
case true:
54+
break;
55+
default:
56+
continueLabel: do {
57+
break continueLabel;
58+
} while (false);
59+
}

assets/highlighting-tests/markdown.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,21 @@ Reference: ![Logo][logo-ref]
6666
echo "Hello, world" | tr a-z A-Z
6767
```
6868

69+
```javascript
70+
export function greet(name) {
71+
return `hello ${name}`;
72+
}
73+
```
74+
6975
```json
7076
{
7177
"name": "gfm-kitchen-sink",
7278
"private": true,
7379
"scripts": { "test": "echo ok" }
7480
}
7581
```
82+
83+
```python
84+
def greet(name: str) -> str:
85+
return f"hello {name}"
86+
```
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Single-line comment
2+
'''Triple single quoted string'''
3+
"""Triple double quoted string"""
4+
5+
single = 'single quoted string'
6+
double = "double quoted string"
7+
8+
decimal = 42
9+
negative = -3.14e+2
10+
hex_value = 0x2A
11+
binary_value = 0b101010
12+
octal_value = 0o52
13+
complex_value = 1.5j
14+
15+
truthy = True
16+
falsy = False
17+
nothing = None
18+
19+
@decorator
20+
async def greet(name: str) -> None:
21+
value = f"Hello, {name}"
22+
23+
if value and name is not None:
24+
print(value)
25+
elif value in {"hello", "world"}:
26+
raise ValueError("unexpected")
27+
else:
28+
return None
29+
30+
for item in [single, double]:
31+
while False:
32+
break
33+
34+
try:
35+
assert item
36+
except Exception as exc:
37+
yield exc
38+
finally:
39+
pass
40+
41+
42+
class Person:
43+
def __init__(self, name):
44+
self.name = name
45+
46+
47+
result = greet("world")
48+
lambda_value = lambda x: x + 1

assets/highlighting-tests/zsh.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env zsh
2+
# zsh-style shell sample
3+
4+
setopt autocd extendedglob
5+
6+
typeset -g POWERLEVEL="lean"
7+
readonly ZSH_THEME="agnoster"
8+
9+
plugins=(git docker fzf)
10+
11+
alias ll='ls -lah'
12+
alias gs='git status'
13+
14+
path=("$HOME/bin" $path)
15+
export EDITOR="nvim"
16+
17+
function mkcd() {
18+
local dir="$1"
19+
mkdir -p "$dir" && cd "$dir"
20+
}
21+
22+
if [[ -n "$HOME" ]]; then
23+
echo "home is $HOME"
24+
elif [[ -z "$HOME" ]]; then
25+
echo "missing home"
26+
else
27+
echo "unexpected"
28+
fi
29+
30+
for plugin in $plugins; do
31+
echo "$plugin"
32+
done
33+
34+
case "$ZSH_THEME" in
35+
agnoster) echo "theme selected" ;;
36+
*) echo "default theme" ;;
37+
esac
38+
39+
source "$HOME/.zsh_aliases"
40+
mkcd "${HOME}/tmp"

crates/lsh/definitions/bash.lsh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#[display_name = "Bash"]
2+
#[path = "**/*.bash"]
3+
#[path = "**/*.sh"]
4+
#[path = "**/.bash_profile"]
5+
#[path = "**/.bashrc"]
6+
#[path = "**/.profile"]
7+
pub fn bash() {
8+
until /$/ {
9+
yield other;
10+
11+
if /#.*/ {
12+
yield comment;
13+
} else if /'/ {
14+
until /$/ {
15+
yield string;
16+
if /'/ { yield string; break; }
17+
await input;
18+
}
19+
} else if /"/ {
20+
until /$/ {
21+
yield string;
22+
if /\\./ {}
23+
else if /"/ { yield string; break; }
24+
await input;
25+
}
26+
} else if /`/ {
27+
until /$/ {
28+
yield string;
29+
if /\\./ {}
30+
else if /`/ { yield string; break; }
31+
await input;
32+
}
33+
} else if /\$\{[^}]+\}|\$[A-Za-z_]\w*|\$\d+|\$[#?*!@$-]/ {
34+
yield variable;
35+
} else if /(?:if|then|elif|else|fi|for|while|until|do|done|case|esac|in|select)\>/ {
36+
if /\w+/ {
37+
yield other;
38+
} else {
39+
yield keyword.control;
40+
}
41+
} else if /(?:declare|export|function|local|readonly|source)\>/ {
42+
if /\w+/ {
43+
yield other;
44+
} else {
45+
yield keyword.other;
46+
}
47+
} else if /-?(?:0[xX][\da-fA-F]+|\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/ {
48+
if /\w+/ {
49+
yield other;
50+
} else {
51+
yield constant.numeric;
52+
}
53+
} else if /([A-Za-z_][\w-]*)\s*\(/ {
54+
yield $1 as method;
55+
} else if /[A-Za-z_][\w-]*/ {
56+
// Gobble any other tokens that should not be highlighted
57+
}
58+
59+
yield other;
60+
}
61+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#[display_name = "JavaScript"]
2+
#[path = "**/*.cjs"]
3+
#[path = "**/*.js"]
4+
#[path = "**/*.jsx"]
5+
#[path = "**/*.mjs"]
6+
pub fn javascript() {
7+
until /$/ {
8+
yield other;
9+
10+
if /\/\/.*/ {
11+
yield comment;
12+
} else if /\/\*/ {
13+
loop {
14+
yield comment;
15+
await input;
16+
if /\*\// {
17+
yield comment;
18+
break;
19+
}
20+
}
21+
} else if /'/ {
22+
until /$/ {
23+
yield string;
24+
if /\\./ {}
25+
else if /'/ { yield string; break; }
26+
await input;
27+
}
28+
} else if /"/ {
29+
until /$/ {
30+
yield string;
31+
if /\\./ {}
32+
else if /"/ { yield string; break; }
33+
await input;
34+
}
35+
} else if /`/ {
36+
loop {
37+
yield string;
38+
if /\\./ {}
39+
else if /`/ { yield string; break; }
40+
await input;
41+
}
42+
} else if /(?:if|else|switch|case|default|for|while|do|break|continue|try|catch|finally|throw|return)\>/ {
43+
if /\w+/ {
44+
yield other;
45+
} else {
46+
yield keyword.control;
47+
}
48+
} else if /(?:async|await|class|const|delete|export|extends|function|import|in|instanceof|let|new|of|super|this|typeof|var|void|yield)\>/ {
49+
if /\w+/ {
50+
yield other;
51+
} else {
52+
yield keyword.other;
53+
}
54+
} else if /(?:true|false|null|undefined|NaN|Infinity)\>/ {
55+
if /\w+/ {
56+
yield other;
57+
} else {
58+
yield constant.language;
59+
}
60+
} else if /-?(?:0[xX][\da-fA-F]+|0[bB][01]+|0[oO][0-7]+|\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/ {
61+
if /\w+/ {
62+
yield other;
63+
} else {
64+
yield constant.numeric;
65+
}
66+
} else if /([A-Za-z_$][\w$]*)\s*\(/ {
67+
yield $1 as method;
68+
} else if /[A-Za-z_$][\w$]*/ {
69+
// Gobble any other tokens that should not be highlighted
70+
}
71+
72+
yield other;
73+
}
74+
}

crates/lsh/definitions/markdown.lsh

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,27 @@ pub fn markdown() {
1818
yield comment;
1919
} else if /```/ {
2020
// NOTE: These checks are sorted alphabetically.
21-
if /(?i:diff)/ {
21+
if /(?i:bash|sh|shell)/ {
22+
loop {
23+
await input;
24+
if /\s*```/ {
25+
return;
26+
} else {
27+
bash();
28+
if /.*/ {}
29+
}
30+
}
31+
} else if /(?i:zsh)/ {
32+
loop {
33+
await input;
34+
if /\s*```/ {
35+
return;
36+
} else {
37+
zsh();
38+
if /.*/ {}
39+
}
40+
}
41+
} else if /(?i:diff)/ {
2242
loop {
2343
await input;
2444
if /\s*```/ {
@@ -30,6 +50,16 @@ pub fn markdown() {
3050
if /.*/ {}
3151
}
3252
}
53+
} else if /(?i:javascript|js|jsx|mjs|cjs)/ {
54+
loop {
55+
await input;
56+
if /\s*```/ {
57+
return;
58+
} else {
59+
javascript();
60+
if /.*/ {}
61+
}
62+
}
3363
} else if /(?i:json)/ {
3464
loop {
3565
await input;
@@ -40,6 +70,16 @@ pub fn markdown() {
4070
if /.*/ {}
4171
}
4272
}
73+
} else if /(?i:py|python)/ {
74+
loop {
75+
await input;
76+
if /\s*```/ {
77+
return;
78+
} else {
79+
python();
80+
if /.*/ {}
81+
}
82+
}
4383
} else if /(?i:yaml)/ {
4484
loop {
4585
await input;

0 commit comments

Comments
 (0)