From 10b2f09cb8a5054037529a62bf111d297ee86955 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Fri, 8 Feb 2019 21:32:09 -0500 Subject: Add sh syntax to hi --- bin/hi.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ bin/man1/hi.1 | 39 +++++++++++++++++++++++---------------- 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/bin/hi.c b/bin/hi.c index 5101ead3..182fc3b1 100644 --- a/bin/hi.c +++ b/bin/hi.c @@ -1,3 +1,4 @@ +/* vim: set foldmethod=marker foldlevel=0: */ /* Copyright (C) 2019 C. McEnroe * * This program is free software: you can redistribute it and/or modify @@ -167,6 +168,54 @@ static const struct Syntax MdocSyntax[] = { }; // }}} +// sh syntax {{{ +static const struct Syntax ShSyntax[] = { + { Keyword, .subexp = 2, .pattern = + WB "(" + "!|case|do|done|elif|else|esac|fi|for|if|in|then|until|while" + ")" WB + }, + { Keyword, .subexp = 2, .pattern = + WB "(" + "alias|bg|cd|command|false|fc|fg|getopts|jobs|kill|newgrp|pwd|read" + "|true|umask|unalias|wait" + ")" WB + }, + { Keyword, .subexp = 2, .pattern = + WB "(" + "[.:]|break|continue|eval|exec|exit|export|local|readonly|return|set" + "|shift|times|trap|unset" + ")" WB + }, + { String, + .pattern = PATTERN_DQ }, + { String, .subexp = 1, + .pattern = "<<-?" WS "EOF.*(\n)", + .pattend = "^\t*EOF$" }, + { Escape, .parent = SET(String), + .pattern = "[\\][\"$\\`]" }, + { String, .parent = ~SET(Escape), + .pattern = "[\\]." }, + { Interp, .parent = ~SET(Escape), + .pattern = "[$]([!#$*-?@]|[_[:alnum:]]+)" }, + { Interp, .parent = ~SET(Escape), + .pattern = "[$][{][^}]*[}]" }, + { Interp, .parent = ~SET(Escape), + .pattern = "[$][(][^)]*[)]" "|" "`[^`]*`" }, + { String, + .pattern = "'[^']*'" }, + { String, .subexp = 1, + .pattern = "<<-?" WS "'EOF'.*(\n)", + .pattend = "^\t*EOF$" }, + { Normal, .parent = SET(String), + .pattern = "^\t*EOF$" }, + { Comment, .parent = ~SET(String), .subexp = 2, + .pattern = "(^|" WS ")" "(#.*)" }, + { Todo, .parent = SET(Comment), + .pattern = PATTERN_TODO }, +}; +// }}} + static const struct Language { const char *name; const char *pattern; @@ -176,6 +225,7 @@ static const struct Language { { "c", "[.][ch]$", CSyntax, ARRAY_LEN(CSyntax) }, { "make", "[.]mk$|^Makefile$", MakeSyntax, ARRAY_LEN(MakeSyntax) }, { "mdoc", "[.][1-9]$", MdocSyntax, ARRAY_LEN(MdocSyntax) }, + { "sh", "[.]sh$", ShSyntax, ARRAY_LEN(ShSyntax) }, }; static regex_t compile(const char *pattern, int flags) { diff --git a/bin/man1/hi.1 b/bin/man1/hi.1 index ad3957f1..77bb1c46 100644 --- a/bin/man1/hi.1 +++ b/bin/man1/hi.1 @@ -27,30 +27,22 @@ is read from standard input. . .Pp The arguments are as follows: -.Bl -tag -width Ds +.Bl -tag -width "-f format" .It Fl c Compile all regular expressions and exit. .It Fl f Ar format Set the output format. -The default -.Ar format -is -.Cm ansi . .It Fl l Ar lang Set the input language. -If a -.Ar file -is provided, -the input language -may be inferred from its name. .It Fl n Ar name Override the name used to infer the input language. .El . -.Pp -The output formats are as follows: -.Bl -tag -offset indent -width "html-document" +.Ss Output Formats +The default output format is +.Cm ansi . +.Bl -tag -width "html-document" .It Cm ansi ANSI terminal escape codes. .It Cm irc @@ -61,9 +53,15 @@ HTML fragment. HTML document. .El . -.Pp -The languages are as follows: -.Bl -tag -offset indent -width "make" +.Ss Input Languages +If no input language is set with +.Fl l , +it may be inferred from the name set by +.Fl n +or from the provided +.Ar file +name. +.Bl -tag -width "make" .It Cm c The C11 language. .It Cm make @@ -75,4 +73,13 @@ one level of nesting with the same delimiter. The .Xr mdoc 7 language. +.It Cm sh +The POSIX +.Xr sh 1 +language. +Here-documents are correctly highlighted +only with a delimiter of +.Ql EOF . +Arbitrarily nested strings and command substitutions +are not highlighted correctly. .El -- cgit 1.4.1