cmark_syntax/languages/
sh.rs

1use crate::{Highlight, Kind};
2use logos::Logos;
3
4#[derive(Logos, PartialEq, Eq, Clone, Copy, Debug)]
5pub enum Sh {
6    Start,
7
8    #[regex(r"[^\s=$\(\)\{\}]*")]
9    Word,
10
11    #[token("$")]
12    #[regex(r"\$[^{(\s][^\s]*")]
13    #[regex(r"\$\{[^}]*\}")]
14    Parameter,
15
16    #[regex(r#""([^"\n]|\\["\n])*""#)]
17    #[regex("'[^']*'")]
18    Literal,
19
20    #[token("|")]
21    #[token("&")]
22    #[token("||")]
23    #[token("&&")]
24    #[token(";")]
25    #[token("(")]
26    #[token(")")]
27    #[token("<")]
28    #[token(">")]
29    Glyph,
30
31    #[token("\n")]
32    Newline,
33
34    #[token("}")]
35    #[token("]]")]
36    #[regex(r"esac|for|in|done|fi")]
37    Keyword,
38
39    #[token("{")]
40    #[token("[[")]
41    #[regex(r"!|do|then|elif|until|case|else|if|while|function|select")]
42    KeywordCtx,
43
44    #[regex("#[^\n]*")]
45    Comment,
46}
47
48impl Highlight for Sh {
49    const LANG: &'static str = "sh";
50    const START: Sh = Self::Start;
51
52    fn kind(tokens: &[Self; 2]) -> Kind {
53        use Sh::*;
54
55        match tokens {
56            [KeywordCtx, Word] | [Glyph, Word] | [Newline, Word] | [Start, Word] => {
57                Kind::StrongIdentifier
58            }
59            [_, Parameter] => Kind::Identifier,
60            [_, Literal] => Kind::Literal,
61            [_, Glyph] => Kind::Glyph,
62            [_, Keyword] | [_, KeywordCtx] => Kind::Keyword,
63            [_, Comment] => Kind::Comment,
64            _ => Kind::None,
65        }
66    }
67}