aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.def.h300
-rw-r--r--syntax.h10
-rw-r--r--ui-curses.c422
-rw-r--r--ui-curses.h21
-rw-r--r--ui.h10
-rw-r--r--view.c19
-rw-r--r--vis.c2
7 files changed, 590 insertions, 194 deletions
diff --git a/config.def.h b/config.def.h
index a7c8c13..cdfe24b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1539,6 +1539,7 @@ enum {
COLOR_SYNTAX7,
COLOR_SYNTAX8,
COLOR_SYNTAX9,
+ COLOR_SYNTAX_LAST, /* below are only aliases */
COLOR_KEYWORD = COLOR_SYNTAX1,
COLOR_CONSTANT = COLOR_SYNTAX4,
COLOR_DATATYPE = COLOR_SYNTAX2,
@@ -1562,19 +1563,19 @@ enum {
COLOR_EOF = COLOR_WHITESPACE,
};
-static Color colors[] = {
- [COLOR_NOHILIT] = { .fg = UI_COLOR_DEFAULT, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- [COLOR_SYNTAX0] = { .fg = UI_COLOR_RED, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_BOLD },
- [COLOR_SYNTAX1] = { .fg = UI_COLOR_GREEN, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_BOLD },
- [COLOR_SYNTAX2] = { .fg = UI_COLOR_GREEN, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- [COLOR_SYNTAX3] = { .fg = UI_COLOR_MAGENTA, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_BOLD },
- [COLOR_SYNTAX4] = { .fg = UI_COLOR_MAGENTA, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- [COLOR_SYNTAX5] = { .fg = UI_COLOR_BLUE, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_BOLD },
- [COLOR_SYNTAX6] = { .fg = UI_COLOR_RED, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- [COLOR_SYNTAX7] = { .fg = UI_COLOR_BLUE, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- [COLOR_SYNTAX8] = { .fg = UI_COLOR_CYAN, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- [COLOR_SYNTAX9] = { .fg = UI_COLOR_YELLOW, .bg = UI_COLOR_DEFAULT, .attr = UI_ATTR_NORMAL },
- { /* empty last element, array terminator */ }
+static const char *styles[] = {
+ [COLOR_NOHILIT] = "",
+ [COLOR_SYNTAX0] = "fore:red,bold",
+ [COLOR_SYNTAX1] = "fore:green,bold",
+ [COLOR_SYNTAX2] = "fore:green",
+ [COLOR_SYNTAX3] = "fore:magenta,bold",
+ [COLOR_SYNTAX4] = "fore:magenta",
+ [COLOR_SYNTAX5] = "fore:blue,bold",
+ [COLOR_SYNTAX6] = "fore:red",
+ [COLOR_SYNTAX7] = "fore:blue",
+ [COLOR_SYNTAX8] = "fore:cyan",
+ [COLOR_SYNTAX9] = "fore:yellow",
+ [COLOR_SYNTAX_LAST] = NULL,
};
/* Syntax color definitions per file type. Each rule consists of a regular
@@ -1592,46 +1593,46 @@ static Color colors[] = {
#define SYNTAX_MULTILINE_COMMENT { \
"(/\\*([^*]|\\*+[^*/])*\\*+/|/\\*([^*]|\\*+[^*/])*$|^([^/]|/+[^/*])*\\*/)", \
- &colors[COLOR_COMMENT], \
+ COLOR_COMMENT, \
true, /* multiline */ \
}
#define SYNTAX_SINGLE_LINE_COMMENT { \
"(//.*)", \
- &colors[COLOR_COMMENT], \
+ COLOR_COMMENT, \
}
#define SYNTAX_LITERAL { \
"('(\\\\.|.)')|"B"(0x[0-9A-Fa-f]+|[0-9]+)"B, \
- &colors[COLOR_LITERAL], \
+ COLOR_LITERAL, \
}
#define SYNTAX_STRING { \
"(\"(\\\\.|[^\"])*\")", \
- &colors[COLOR_STRING], \
+ COLOR_STRING, \
false, /* multiline */ \
}
#define SYNTAX_CONSTANT { \
B"[A-Z_][0-9A-Z_]+"B, \
- &colors[COLOR_CONSTANT], \
+ COLOR_CONSTANT, \
}
#define SYNTAX_BRACKET { \
"(\\(|\\)|\\{|\\}|\\[|\\])", \
- &colors[COLOR_BRACKETS], \
+ COLOR_BRACKETS, \
}
#define SYNTAX_C_PREPROCESSOR { \
"(^#[\\t ]*(define|include(_next)?|(un|ifn?)def|endif|el(if|se)|if|warning|error|pragma)?)", \
- &colors[COLOR_PREPROCESSOR], \
+ COLOR_PREPROCESSOR, \
}
-#define SYNTAX_SPACES { "\xC2\xB7", &colors[COLOR_SPACES] }
-#define SYNTAX_TABS { "\xE2\x96\xB6", &colors[COLOR_TABS] }
-#define SYNTAX_TABS_FILL { " ", &colors[COLOR_TABS] }
-#define SYNTAX_EOL { "\xE2\x8F\x8E", &colors[COLOR_EOL] }
-#define SYNTAX_EOF { "~", &colors[COLOR_EOF] }
+#define SYNTAX_SPACES { "\xC2\xB7", COLOR_SPACES }
+#define SYNTAX_TABS { "\xE2\x96\xB6", COLOR_TABS }
+#define SYNTAX_TABS_FILL { " ", COLOR_TABS }
+#define SYNTAX_EOL { "\xE2\x8F\x8E", COLOR_EOL }
+#define SYNTAX_EOF { "~", COLOR_EOF }
/* these rules are applied top to bottom, first match wins. Therefore more 'greedy'
* rules such as for comments should be the first entries.
@@ -1647,6 +1648,7 @@ static Syntax syntaxes[] = {{
"set show spaces=0 tabs=1 newlines=1",
NULL
},
+ .styles = styles,
.symbols = {
SYNTAX_SPACES,
SYNTAX_TABS,
@@ -1663,93 +1665,97 @@ static Syntax syntaxes[] = {{
SYNTAX_BRACKET,
{
"<[a-zA-Z0-9\\.\\-_/]+\\.(c(pp|xx)?|h(pp|xx)?|cc)>",
- &colors[COLOR_STRING],
+ COLOR_STRING,
},
SYNTAX_C_PREPROCESSOR,
{
B"(for|if|while|do|else|case|default|switch|try|throw|catch|operator|new|delete)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(float|double|bool|char|int|short|long|sizeof|enum|void|static|const|struct|union|"
"typedef|extern|(un)?signed|inline|((s?size)|((u_?)?int(8|16|32|64|ptr)))_t|class|"
"namespace|template|public|protected|private|typename|this|friend|virtual|using|"
"mutable|volatile|register|explicit)"B,
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{
B"(goto|continue|break|return)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
}}
},{
.name = "sh",
.file = "\\.sh$",
+ .styles = styles,
.rules = {{
"#.*$",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},
SYNTAX_STRING,
{
"^[0-9A-Z_]+\\(\\)",
- &colors[COLOR_CONSTANT],
+ COLOR_CONSTANT,
},{
"\\$[?!@#$?*-]",
- &colors[COLOR_VARIABLE],
+ COLOR_VARIABLE,
},{
"\\$\\{[A-Za-z_][0-9A-Za-z_]+\\}",
- &colors[COLOR_VARIABLE],
+ COLOR_VARIABLE,
},{
"\\$[A-Za-z_][0-9A-Za-z_]+",
- &colors[COLOR_VARIABLE],
+ COLOR_VARIABLE,
},{
B"(case|do|done|elif|else|esac|exit|fi|for|function|if|in|local|read|return|select|shift|then|time|until|while)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
"(\\{|\\}|\\(|\\)|\\;|\\]|\\[|`|\\\\|\\$|<|>|!|=|&|\\|)",
- &colors[COLOR_BRACKETS],
+ COLOR_BRACKETS,
}}
},{
.name = "makefile",
.file = "(Makefile[^/]*|\\.mk)$",
+ .styles = styles,
.rules = {{
"#.*$",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{
"\\$+[{(][a-zA-Z0-9_-]+[})]",
- &colors[COLOR_VARIABLE],
+ COLOR_VARIABLE,
},{
B"(if|ifeq|else|endif)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
"^[^ ]+:",
- &colors[COLOR_TARGET],
+ COLOR_TARGET,
},{
"[:(+?=)]",
- &colors[COLOR_BRACKETS],
+ COLOR_BRACKETS,
}}
},{
.name = "man",
.file = "\\.[1-9]x?$",
+ .styles = styles,
.rules = {{
"\\.(BR?|I[PR]?).*$",
- &colors[COLOR_SYNTAX0],
+ COLOR_SYNTAX0,
},{
"\\.(S|T)H.*$",
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
},{
"\\.(br|DS|RS|RE|PD)",
- &colors[COLOR_SYNTAX3],
+ COLOR_SYNTAX3,
},{
"(\\.(S|T)H|\\.TP)",
- &colors[COLOR_SYNTAX4],
+ COLOR_SYNTAX4,
},{
"\\.(BR?|I[PR]?|PP)",
- &colors[COLOR_SYNTAX5],
+ COLOR_SYNTAX5,
},{
"\\\\f[BIPR]",
- &colors[COLOR_SYNTAX6],
+ COLOR_SYNTAX6,
}}
},{
.name = "vala",
.file = "\\.(vapi|vala)$",
+ .styles = styles,
.rules = {
SYNTAX_MULTILINE_COMMENT,
SYNTAX_SINGLE_LINE_COMMENT,
@@ -1759,20 +1765,21 @@ static Syntax syntaxes[] = {{
SYNTAX_BRACKET,
{
B"(for|if|while|do|else|case|default|switch|get|set|value|out|ref|enum)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(uint|uint8|uint16|uint32|uint64|bool|byte|ssize_t|size_t|char|double|string|float|int|long|short|this|base|transient|void|true|false|null|unowned|owned)"B,
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{
B"(try|catch|throw|finally|continue|break|return|new|sizeof|signal|delegate)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
B"(abstract|class|final|implements|import|instanceof|interface|using|private|public|static|strictfp|super|throws)"B,
- &colors[COLOR_KEYWORD2],
+ COLOR_KEYWORD2,
}}
},{
.name = "java",
.file = "\\.java$",
+ .styles = styles,
.rules = {
SYNTAX_MULTILINE_COMMENT,
SYNTAX_SINGLE_LINE_COMMENT,
@@ -1782,20 +1789,21 @@ static Syntax syntaxes[] = {{
SYNTAX_BRACKET,
{
B"(for|if|while|do|else|case|default|switch)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(boolean|byte|char|double|float|int|long|short|transient|void|true|false|null)"B,
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{
B"(try|catch|throw|finally|continue|break|return|new)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
B"(abstract|class|extends|final|implements|import|instanceof|interface|native|package|private|protected|public|static|strictfp|this|super|synchronized|throws|volatile)"B,
- &colors[COLOR_KEYWORD2],
+ COLOR_KEYWORD2,
}}
},{
.name = "javascript",
.file = "\\.(js|json)$",
+ .styles = styles,
.rules = {
SYNTAX_SINGLE_LINE_COMMENT,
SYNTAX_LITERAL,
@@ -1803,22 +1811,22 @@ static Syntax syntaxes[] = {{
SYNTAX_BRACKET,
{
B"(true|false|null|undefined)"B,
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{
B"(NaN|Infinity)"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
"(\"(\\\\.|[^\"])*\"|\'(\\\\.|[^\'])*\')",
- &colors[COLOR_STRING],
+ COLOR_STRING,
},{
B"(for|if|while|do|in|else|case|default|switch|try|throw|catch|operator|new|delete)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(continue|break|return)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
B"(case|class|const|debugger|default|enum|export|extends|finally|function|implements|import|instanceof|let|this|typeof|var|with|yield)"B,
- &colors[COLOR_KEYWORD2],
+ COLOR_KEYWORD2,
}}
},{
.name = "lua",
@@ -1828,167 +1836,172 @@ static Syntax syntaxes[] = {{
"set autoindent",
NULL
},
+ .styles = styles,
.rules = {{
"--\\[(=*)\\[([^]]*)\\](=*)\\]",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
true,
},{
"--.*$",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{
"(\\[(=*)\\[([^]]*)\\](=*)\\]|^([^][]*)\\](=*)\\])",
- &colors[COLOR_STRING],
+ COLOR_STRING,
true,
},
SYNTAX_STRING,
{
B"([0-9]*\\.)?[0-9]+([eE]([\\+-])?[0-9]+)?"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"0x[0-9a-fA-F]+"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"(false|nil|true)"B,
- &colors[COLOR_CONSTANT],
+ COLOR_CONSTANT,
},{
"(\\.\\.\\.)",
- &colors[COLOR_CONSTANT],
+ COLOR_CONSTANT,
},{
B"(break|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(and|not|or)"B,
- &colors[COLOR_OPERATOR],
+ COLOR_OPERATOR,
},{
"(\\+|-|\\*|/|%|\\^|#|[=~<>]=|<|>|\\.\\.)",
- &colors[COLOR_OPERATOR],
+ COLOR_OPERATOR,
},
SYNTAX_BRACKET,
}
},{
.name = "ruby",
.file = "\\.rb$",
+ .styles = styles,
.rules = {{
"(#[^{].*$|#$)",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{
"(\\$|@|@@)?"B"[A-Z]+[0-9A-Z_a-z]*",
- &colors[COLOR_VARIABLE],
+ COLOR_VARIABLE,
},{
B"(__FILE__|__LINE__|BEGIN|END|alias|and|begin|break|case|class|def|defined\?|do|else|elsif|end|ensure|false|for|if|in|module|next|nil|not|or|redo|rescue|retry|return|self|super|then|true|undef|unless|until|when|while|yield)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
"([ ]|^):[0-9A-Z_]+"B,
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
},{
"(/([^/]|(\\/))*/[iomx]*|%r\\{([^}]|(\\}))*\\}[iomx]*)",
- &colors[COLOR_SYNTAX3],
+ COLOR_SYNTAX3,
},{
"(`[^`]*`|%x\\{[^}]*\\})",
- &colors[COLOR_SYNTAX4],
+ COLOR_SYNTAX4,
},{
"(\"([^\"]|(\\\\\"))*\"|%[QW]?\\{[^}]*\\}|%[QW]?\\([^)]*\\)|%[QW]?<[^>]*>|%[QW]?\\[[^]]*\\]|%[QW]?\\$[^$]*\\$|%[QW]?\\^[^^]*\\^|%[QW]?![^!]*!|\'([^\']|(\\\\\'))*\'|%[qw]\\{[^}]*\\}|%[qw]\\([^)]*\\)|%[qw]<[^>]*>|%[qw]\\[[^]]*\\]|%[qw]\\$[^$]*\\$|%[qw]\\^[^^]*\\^|%[qw]![^!]*!)",
- &colors[COLOR_SYNTAX5],
+ COLOR_SYNTAX5,
},{
"#\\{[^}]*\\}",
- &colors[COLOR_SYNTAX6],
+ COLOR_SYNTAX6,
}}
},{
.name = "python",
.file = "\\.py$",
+ .styles = styles,
.rules = {{
"(#.*$|#$)",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{
"(\"\"\".*\"\"\")",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
true, /* multiline */
},{
B"(and|class|def|not|or|return|yield|is)"B,
- &colors[COLOR_KEYWORD2],
+ COLOR_KEYWORD2,
},{
B"(from|import|as)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(if|elif|else|while|for|in|try|with|except|in|break|continue|finally)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
B"(int|str|float|unicode|int|bool|chr|type|list|dict|tuple)",
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{
"(True|False|None)",
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"[0-9]+\\.[0-9]+([eE][-+]?[0-9]+)?"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"[0-9]+"B"|"B"0[xX][0-9a-fA-F]+"B"|"B"0[oO][0-7]+"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
"(\"(\\\\.|[^\"])*\"|\'(\\\\.|[^\'])*\')",
- &colors[COLOR_STRING],
+ COLOR_STRING,
false, /* multiline */
},{
"(__init__|__str__|__unicode__|__gt__|__lt__|__eq__|__enter__|__exit__|__next__|__getattr__|__getitem__|__setitem__|__call__|__contains__|__iter__|__bool__|__all__|__name__)",
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
}}
},{
.name = "php",
.file = "\\.php$",
+ .styles = styles,
.rules = {
SYNTAX_MULTILINE_COMMENT,
SYNTAX_SINGLE_LINE_COMMENT,
SYNTAX_BRACKET,
{
"(#.*$|#$)",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{
"(\"\"\".*\"\"\")",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
true, /* multiline */
},{
B"(class|interface|extends|implements|new|__construct|__destruct|use|namespace|return)"B,
- &colors[COLOR_KEYWORD2],
+ COLOR_KEYWORD2,
},{
B"(public|private|protected|const|parent|function|->)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(if|else|while|do|for|foreach|in|try|catch|finally|switch|case|default|break|continue|as|=>)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
B"(array|true|false|null)",
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{
B"[0-9]+\\.[0-9]+([eE][-+]?[0-9]+)?"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"[0-9]+"B"|"B"0[xX][0-9a-fA-F]+"B"|"B"0[oO][0-7]+"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
"\\$[a-zA-Z0-9_\\-]+",
- &colors[COLOR_VARIABLE],
+ COLOR_VARIABLE,
},{
"(\"(\\\\.|[^\"])*\"|\'(\\\\.|[^\'])*\')",
- &colors[COLOR_STRING],
+ COLOR_STRING,
false, /* multiline */
},{
"(php|echo|print|var_dump|print_r)",
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
}}
},{
.name = "haskell",
.file = "\\.hs$",
+ .styles = styles,
.rules = {{
"\\{-#.*#-\\}",
- &colors[COLOR_PRAGMA],
+ COLOR_PRAGMA,
},{
"---*([^-!#$%&\\*\\+./<=>\?@\\^|~].*)?$",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
}, {
// These are allowed to be nested, but we can't express that
// with regular expressions
"\\{-.*-\\}",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
true
},
SYNTAX_STRING,
@@ -1998,100 +2011,102 @@ static Syntax syntaxes[] = {{
// I don't want to highlight the whole import line.
// capture group coloring or similar would be nice
"(^import( qualified)?)|"B"(as|hiding|infix[lr]?)"B,
- &colors[COLOR_KEYWORD2],
+ COLOR_KEYWORD2,
},{
B"(module|class|data|deriving|instance|default|where|type|newtype)"B,
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
B"(do|case|of|let|in|if|then|else)"B,
- &colors[COLOR_CONTROL],
+ COLOR_CONTROL,
},{
"('(\\\\.|.)')",
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"[0-9]+\\.[0-9]+([eE][-+]?[0-9]+)?"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
B"[0-9]+"B"|"B"0[xX][0-9a-fA-F]+"B"|"B"0[oO][0-7]+"B,
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{
"("B"[A-Z][a-zA-Z0-9_']*\\.)*"B"[a-zA-Z][a-zA-Z0-9_']*"B,
- &colors[COLOR_NOHILIT],
+ COLOR_NOHILIT,
},{
"("B"[A-Z][a-zA-Z0-9_']*\\.)?[-!#$%&\\*\\+/<=>\\?@\\\\^|~:.][-!#$%&\\*\\+/<=>\\?@\\\\^|~:.]*",
- &colors[COLOR_OPERATOR],
+ COLOR_OPERATOR,
},{
"`("B"[A-Z][a-zA-Z0-9_']*\\.)?[a-z][a-zA-Z0-9_']*`",
- &colors[COLOR_OPERATOR],
+ COLOR_OPERATOR,
},{
"\\(|\\)|\\[|\\]|,|;|_|\\{|\\}",
- &colors[COLOR_BRACKETS],
+ COLOR_BRACKETS,
}}
},{
.name = "markdown",
.file = "\\.(md|mdwn)$",
+ .styles = styles,
.rules = {{
"(^#{1,6}.*$)", //titles
- &colors[COLOR_SYNTAX5],
+ COLOR_SYNTAX5,
},{
"((\\* *){3,}|(_ *){3,}|(- *){3,})", // horizontal rules
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
},{
"(\\*\\*.*\\*\\*)|(__.*__)", // super-bolds
- &colors[COLOR_SYNTAX4],
+ COLOR_SYNTAX4,
},{
"(\\*.*\\*)|(_.*_)", // bolds
- &colors[COLOR_SYNTAX3],
+ COLOR_SYNTAX3,
},{
"(\\[.*\\]\\(.*\\))", //links
- &colors[COLOR_SYNTAX6],
+ COLOR_SYNTAX6,
},{
"(^ *([-\\*\\+]|[0-9]+\\.))", //lists
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
},{
"(^( {4,}|\t+).*$)", // code blocks
- &colors[COLOR_SYNTAX7],
+ COLOR_SYNTAX7,
},{
"(`+.*`+)", // inline code
- &colors[COLOR_SYNTAX7],
+ COLOR_SYNTAX7,
},{
"(^>+.*)", // quotes
- &colors[COLOR_SYNTAX7],
+ COLOR_SYNTAX7,
}}
},{
.name = "ledger",
.file = "\\.(journal|ledger)$",
+ .styles = styles,
.rules = {
{ /* comment */
"^[;#].*",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{ /* value tag */
"( |\t|^ )*; :([^ ][^:]*:)+[ \\t]*$",
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{ /* typed tag */
"( |\t|^ )*; [^:]+::.*",
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
},{ /* tag */
"( |\t|^ )*; [^:]+:.*",
- &colors[COLOR_TYPE],
+ COLOR_TYPE,
},{ /* metadata */
"( |\t|^ )*;.*",
- &colors[COLOR_CONSTANT],
+ COLOR_CONSTANT,
},{ /* date */
"^[0-9][^ \t]+",
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{ /* account */
"^[ \t]+[a-zA-Z:'!*()%&]+",
- &colors[COLOR_IDENTIFIER]
+ COLOR_IDENTIFIER,
},{ /* amount */
"( |\t)[^;]*",
- &colors[COLOR_LITERAL],
+ COLOR_LITERAL,
},{ /* automated transaction */
"^[=~].*",
- &colors[COLOR_TYPE],
+ COLOR_TYPE,
},{ /* directives */
"^[!@]?(account|alias|assert|bucket|capture|check|comment|commodity|define|end|fixed|endfixed|include|payee|apply|tag|test|year|[AYNDCIiOobh])"B".*",
- &colors[COLOR_DATATYPE],
+ COLOR_DATATYPE,
}}
},{
.name = "apl",
@@ -2100,33 +2115,34 @@ static Syntax syntaxes[] = {{
"set number",
NULL
},
+ .styles = styles,
.rules = {{
"(⍝|#).*$",
- &colors[COLOR_COMMENT],
+ COLOR_COMMENT,
},{
"('([^']|'')*')|(\"([^\"]|\"\")*\")",
- &colors[COLOR_STRING],
+ COLOR_STRING,
},{
"^ *(∇|⍫)",
- &colors[COLOR_SYNTAX9],
+ COLOR_SYNTAX9,
},{
"(⎕[a-zA-Z]*)|[⍞χ⍺⍶⍵⍹]",
- &colors[COLOR_KEYWORD],
+ COLOR_KEYWORD,
},{
"[∆⍙_a-zA-Z][∆⍙_¯a-zA-Z0-9]* *:",
- &colors[COLOR_SYNTAX2],
+ COLOR_SYNTAX2,
},{
"[∆⍙_a-zA-Z][∆⍙_¯a-zA-Z0-9]*",
- &colors[COLOR_IDENTIFIER],
+ COLOR_IDENTIFIER,
},{
"¯?(([0-9]+(\\.[0-9]+)?)|\\.[0-9]+)([eE]¯?[0-9]+)?([jJ]¯?(([0-9]+(\\.[0-9]+)?)|\\.[0-9]+)([eE]¯?[0-9]+)?)?",
- &colors[COLOR_CONSTANT],
+ COLOR_CONSTANT,
},{
"[][(){}]",
- &colors[COLOR_BRACKETS],
+ COLOR_BRACKETS,
},{
"[←→◊]",
- &colors[COLOR_SYNTAX3],
+ COLOR_SYNTAX3,
}}
},{
/* empty last element, array terminator */
diff --git a/syntax.h b/syntax.h
index c28a7ea..8ce623e 100644
--- a/syntax.h
+++ b/syntax.h
@@ -4,20 +4,15 @@
#include <regex.h>
typedef struct {
- short fg, bg; /* fore and background color */
- int attr; /* curses attributes */
-} Color;
-
-typedef struct {
char *rule; /* regex to search for */
- Color *color; /* settings to apply in case of a match */
+ int style; /* settings to apply in case of a match */
bool multiline; /* whether . should match new lines */
regex_t regex; /* compiled form of the above rule */
} SyntaxRule;
typedef struct {
char *symbol;
- Color *color;
+ int style;
} SyntaxSymbol;
enum {
@@ -35,6 +30,7 @@ struct Syntax { /* a syntax definition */
char *file; /* apply to files matching this regex */
regex_t file_regex; /* compiled file name regex */
const char **settings;/* settings associated with this file type */
+ const char **styles; /* settings associated with this file type */
SyntaxSymbol symbols[SYNTAX_SYMBOL_LAST]; /* symbols for white space handling */
SyntaxRule rules[24]; /* all rules for this file type */
};
diff --git a/ui-curses.c b/ui-curses.c
index 999da1b..7e74919 100644
--- a/ui-curses.c
+++ b/ui-curses.c
@@ -1,6 +1,14 @@
+/* parts of the color handling code originates from tmux/colour.c and is
+ *
+ * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ */
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
+#include <limits.h>
+#include <ctype.h>
#include <signal.h>
#include <locale.h>
#include <poll.h>
@@ -80,6 +88,7 @@ struct UiCursesWin {
int sidebar_width; /* width of the sidebar showing line numbers etc. */
UiCursesWin *next, *prev; /* pointers to neighbouring windows */
enum UiOption options; /* display settings for this window */
+ attr_t styles[UI_STYLES_MAX];
};
static volatile sig_atomic_t need_resize; /* TODO */
@@ -88,7 +97,362 @@ static void sigwinch_handler(int sig) {
need_resize = true;
}
-static unsigned int color_hash(short fg, short bg) {
+typedef struct {
+ unsigned char i;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+} Color;
+
+static int color_compare(const void *lhs0, const void *rhs0) {
+ const Color *lhs = lhs0, *rhs = rhs0;
+
+ if (lhs->r < rhs->r)
+ return -1;
+ if (lhs->r > rhs->r)
+ return 1;
+
+ if (lhs->g < rhs->g)
+ return -1;
+ if (lhs->g > rhs->g)
+ return 1;
+
+ if (lhs->b < rhs->b)
+ return -1;
+ if (lhs->b > rhs->b)
+ return 1;
+
+ return 0;
+}
+
+/* Work out the nearest color from the 256 color set. */
+static int color_find_rgb(unsigned char r, unsigned char g, unsigned char b)
+{
+ static const Color color_from_256[] = {
+ { 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
+ { 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
+ { 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
+ { 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
+ { 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
+ { 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
+ { 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
+ { 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
+ { 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
+ { 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
+ { 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
+ { 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
+ { 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
+ { 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
+ { 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
+ { 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
+ { 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
+ { 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
+ { 36, 0x5f, 0x00, 0x00 }, { 37, 0x5f, 0x00, 0x5f },
+ { 38, 0x5f, 0x00, 0x87 }, { 39, 0x5f, 0x00, 0xaf },
+ { 40, 0x5f, 0x00, 0xd7 }, { 41, 0x5f, 0x00, 0xff },
+ { 42, 0x5f, 0x5f, 0x00 }, { 43, 0x5f, 0x5f, 0x5f },
+ { 44, 0x5f, 0x5f, 0x87 }, { 45, 0x5f, 0x5f, 0xaf },
+ { 46, 0x5f, 0x5f, 0xd7 }, { 47, 0x5f, 0x5f, 0xff },
+ { 48, 0x5f, 0x87, 0x00 }, { 49, 0x5f, 0x87, 0x5f },
+ { 50, 0x5f, 0x87, 0x87 }, { 51, 0x5f, 0x87, 0xaf },
+ { 52, 0x5f, 0x87, 0xd7 }, { 53, 0x5f, 0x87, 0xff },
+ { 54, 0x5f, 0xaf, 0x00 }, { 55, 0x5f, 0xaf, 0x5f },
+ { 56, 0x5f, 0xaf, 0x87 }, { 57, 0x5f, 0xaf, 0xaf },
+ { 58, 0x5f, 0xaf, 0xd7 }, { 59, 0x5f, 0xaf, 0xff },
+ { 60, 0x5f, 0xd7, 0x00 }, { 61, 0x5f, 0xd7, 0x5f },
+ { 62, 0x5f, 0xd7, 0x87 }, { 63, 0x5f, 0xd7, 0xaf },
+ { 64, 0x5f, 0xd7, 0xd7 }, { 65, 0x5f, 0xd7, 0xff },
+ { 66, 0x5f, 0xff, 0x00 }, { 67, 0x5f, 0xff, 0x5f },
+ { 68, 0x5f, 0xff, 0x87 }, { 69, 0x5f, 0xff, 0xaf },
+ { 70, 0x5f, 0xff, 0xd7 }, { 71, 0x5f, 0xff, 0xff },
+ { 72, 0x87, 0x00, 0x00 }, { 73, 0x87, 0x00, 0x5f },
+ { 74, 0x87, 0x00, 0x87 }, { 75, 0x87, 0x00, 0xaf },
+ { 76, 0x87, 0x00, 0xd7 }, { 77, 0x87, 0x00, 0xff },
+ { 78, 0x87, 0x5f, 0x00 }, { 79, 0x87, 0x5f, 0x5f },
+ { 80, 0x87, 0x5f, 0x87 }, { 81, 0x87, 0x5f, 0xaf },
+ { 82, 0x87, 0x5f, 0xd7 }, { 83, 0x87, 0x5f, 0xff },
+ { 84, 0x87, 0x87, 0x00 }, { 85, 0x87, 0x87, 0x5f },
+ { 86, 0x87, 0x87, 0x87 }, { 87, 0x87, 0x87, 0xaf },
+ { 88, 0x87, 0x87, 0xd7 }, { 89, 0x87, 0x87, 0xff },
+ { 90, 0x87, 0xaf, 0x00 }, { 91, 0x87, 0xaf, 0x5f },
+ { 92, 0x87, 0xaf, 0x87 }, { 93, 0x87, 0xaf, 0xaf },
+ { 94, 0x87, 0xaf, 0xd7 }, { 95, 0x87, 0xaf, 0xff },
+ { 96, 0x87, 0xd7, 0x00 }, { 97, 0x87, 0xd7, 0x5f },
+ { 98, 0x87, 0xd7, 0x87 }, { 99, 0x87, 0xd7, 0xaf },
+ { 100, 0x87, 0xd7, 0xd7 }, { 101, 0x87, 0xd7, 0xff },
+ { 102, 0x87, 0xff, 0x00 }, { 103, 0x87, 0xff, 0x5f },
+ { 104, 0x87, 0xff, 0x87 }, { 105, 0x87, 0xff, 0xaf },
+ { 106, 0x87, 0xff, 0xd7 }, { 107, 0x87, 0xff, 0xff },
+ { 108, 0xaf, 0x00, 0x00 }, { 109, 0xaf, 0x00, 0x5f },
+ { 110, 0xaf, 0x00, 0x87 }, { 111, 0xaf, 0x00, 0xaf },
+ { 112, 0xaf, 0x00, 0xd7 }, { 113, 0xaf, 0x00, 0xff },
+ { 114, 0xaf, 0x5f, 0x00 }, { 115, 0xaf, 0x5f, 0x5f },
+ { 116, 0xaf, 0x5f, 0x87 }, { 117, 0xaf, 0x5f, 0xaf },
+ { 118, 0xaf, 0x5f, 0xd7 }, { 119, 0xaf, 0x5f, 0xff },
+ { 120, 0xaf, 0x87, 0x00 }, { 121, 0xaf, 0x87, 0x5f },
+ { 122, 0xaf, 0x87, 0x87 }, { 123, 0xaf, 0x87, 0xaf },
+ { 124, 0xaf, 0x87, 0xd7 }, { 125, 0xaf, 0x87, 0xff },
+ { 126, 0xaf, 0xaf, 0x00 }, { 127, 0xaf, 0xaf, 0x5f },
+ { 128, 0xaf, 0xaf, 0x87 }, { 129, 0xaf, 0xaf, 0xaf },
+ { 130, 0xaf, 0xaf, 0xd7 }, { 131, 0xaf, 0xaf, 0xff },
+ { 132, 0xaf, 0xd7, 0x00 }, { 133, 0xaf, 0xd7, 0x5f },
+ { 134, 0xaf, 0xd7, 0x87 }, { 135, 0xaf, 0xd7, 0xaf },
+ { 136, 0xaf, 0xd7, 0xd7 }, { 137, 0xaf, 0xd7, 0xff },
+ { 138, 0xaf, 0xff, 0x00 }, { 139, 0xaf, 0xff, 0x5f },
+ { 140, 0xaf, 0xff, 0x87 }, { 141, 0xaf, 0xff, 0xaf },
+ { 142, 0xaf, 0xff, 0xd7 }, { 143, 0xaf, 0xff, 0xff },
+ { 144, 0xd7, 0x00, 0x00 }, { 145, 0xd7, 0x00, 0x5f },
+ { 146, 0xd7, 0x00, 0x87 }, { 147, 0xd7, 0x00, 0xaf },
+ { 148, 0xd7, 0x00, 0xd7 }, { 149, 0xd7, 0x00, 0xff },
+ { 150, 0xd7, 0x5f, 0x00 }, { 151, 0xd7, 0x5f, 0x5f },
+ { 152, 0xd7, 0x5f, 0x87 }, { 153, 0xd7, 0x5f, 0xaf },
+ { 154, 0xd7, 0x5f, 0xd7 }, { 155, 0xd7, 0x5f, 0xff },
+ { 156, 0xd7, 0x87, 0x00 }, { 157, 0xd7, 0x87, 0x5f },
+ { 158, 0xd7, 0x87, 0x87 }, { 159, 0xd7, 0x87, 0xaf },
+ { 160, 0xd7, 0x87, 0xd7 }, { 161, 0xd7, 0x87, 0xff },
+ { 162, 0xd7, 0xaf, 0x00 }, { 163, 0xd7, 0xaf, 0x5f },
+ { 164, 0xd7, 0xaf, 0x87 }, { 165, 0xd7, 0xaf, 0xaf },
+ { 166, 0xd7, 0xaf, 0xd7 }, { 167, 0xd7, 0xaf, 0xff },
+ { 168, 0xd7, 0xd7, 0x00 }, { 169, 0xd7, 0xd7, 0x5f },
+ { 170, 0xd7, 0xd7, 0x87 }, { 171, 0xd7, 0xd7, 0xaf },
+ { 172, 0xd7, 0xd7, 0xd7 }, { 173, 0xd7, 0xd7, 0xff },
+ { 174, 0xd7, 0xff, 0x00 }, { 175, 0xd7, 0xff, 0x5f },
+ { 176, 0xd7, 0xff, 0x87 }, { 177, 0xd7, 0xff, 0xaf },
+ { 178, 0xd7, 0xff, 0xd7 }, { 179, 0xd7, 0xff, 0xff },
+ { 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
+ { 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
+ { 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
+ { 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
+ { 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
+ { 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
+ { 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
+ { 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
+ { 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
+ { 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
+ { 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
+ { 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
+ { 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
+ { 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
+ { 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
+ { 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
+ { 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
+ { 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
+ { 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
+ { 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
+ { 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
+ { 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
+ { 224, 0x58, 0x58, 0x58 }, { 225, 0x62, 0x62, 0x62 },
+ { 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
+ { 228, 0x80, 0x80, 0x80 }, { 229, 0x8a, 0x8a, 0x8a },
+ { 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
+ { 232, 0xa8, 0xa8, 0xa8 }, { 233, 0xb2, 0xb2, 0xb2 },
+ { 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
+ { 236, 0xd0, 0xd0, 0xd0 }, { 237, 0xda, 0xda, 0xda },
+ { 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
+ };
+
+ static const Color color_to_256[] = {
+ { 0, 0x00, 0x00, 0x00 }, { 1, 0x00, 0x00, 0x5f },
+ { 2, 0x00, 0x00, 0x87 }, { 3, 0x00, 0x00, 0xaf },
+ { 4, 0x00, 0x00, 0xd7 }, { 5, 0x00, 0x00, 0xff },
+ { 6, 0x00, 0x5f, 0x00 }, { 7, 0x00, 0x5f, 0x5f },
+ { 8, 0x00, 0x5f, 0x87 }, { 9, 0x00, 0x5f, 0xaf },
+ { 10, 0x00, 0x5f, 0xd7 }, { 11, 0x00, 0x5f, 0xff },
+ { 12, 0x00, 0x87, 0x00 }, { 13, 0x00, 0x87, 0x5f },
+ { 14, 0x00, 0x87, 0x87 }, { 15, 0x00, 0x87, 0xaf },
+ { 16, 0x00, 0x87, 0xd7 }, { 17, 0x00, 0x87, 0xff },
+ { 18, 0x00, 0xaf, 0x00 }, { 19, 0x00, 0xaf, 0x5f },
+ { 20, 0x00, 0xaf, 0x87 }, { 21, 0x00, 0xaf, 0xaf },
+ { 22, 0x00, 0xaf, 0xd7 }, { 23, 0x00, 0xaf, 0xff },
+ { 24, 0x00, 0xd7, 0x00 }, { 25, 0x00, 0xd7, 0x5f },
+ { 26, 0x00, 0xd7, 0x87 }, { 27, 0x00, 0xd7, 0xaf },
+ { 28, 0x00, 0xd7, 0xd7 }, { 29, 0x00, 0xd7, 0xff },
+ { 30, 0x00, 0xff, 0x00 }, { 31, 0x00, 0xff, 0x5f },
+ { 32, 0x00, 0xff, 0x87 }, { 33, 0x00, 0xff, 0xaf },
+ { 34, 0x00, 0xff, 0xd7 }, { 35, 0x00, 0xff, 0xff },
+ { 216, 0x08, 0x08, 0x08 }, { 217, 0x12, 0x12, 0x12 },
+ { 218, 0x1c, 0x1c, 0x1c }, { 219, 0x26, 0x26, 0x26 },
+ { 220, 0x30, 0x30, 0x30 }, { 221, 0x3a, 0x3a, 0x3a },
+ { 222, 0x44, 0x44, 0x44 }, { 223, 0x4e, 0x4e, 0x4e },
+ { 224, 0x58, 0x58, 0x58 }, { 36, 0x5f, 0x00, 0x00 },
+ { 37, 0x5f, 0x00, 0x5f }, { 38, 0x5f, 0x00, 0x87 },
+ { 39, 0x5f, 0x00, 0xaf }, { 40, 0x5f, 0x00, 0xd7 },
+ { 41, 0x5f, 0x00, 0xff }, { 42, 0x5f, 0x5f, 0x00 },
+ { 43, 0x5f, 0x5f, 0x5f }, { 44, 0x5f, 0x5f, 0x87 },
+ { 45, 0x5f, 0x5f, 0xaf }, { 46, 0x5f, 0x5f, 0xd7 },
+ { 47, 0x5f, 0x5f, 0xff }, { 48, 0x5f, 0x87, 0x00 },
+ { 49, 0x5f, 0x87, 0x5f }, { 50, 0x5f, 0x87, 0x87 },
+ { 51, 0x5f, 0x87, 0xaf }, { 52, 0x5f, 0x87, 0xd7 },
+ { 53, 0x5f, 0x87, 0xff }, { 54, 0x5f, 0xaf, 0x00 },
+ { 55, 0x5f, 0xaf, 0x5f }, { 56, 0x5f, 0xaf, 0x87 },
+ { 57, 0x5f, 0xaf, 0xaf }, { 58, 0x5f, 0xaf, 0xd7 },
+ { 59, 0x5f, 0xaf, 0xff }, { 60, 0x5f, 0xd7, 0x00 },
+ { 61, 0x5f, 0xd7, 0x5f }, { 62, 0x5f, 0xd7, 0x87 },
+ { 63, 0x5f, 0xd7, 0xaf }, { 64, 0x5f, 0xd7, 0xd7 },
+ { 65, 0x5f, 0xd7, 0xff }, { 66, 0x5f, 0xff, 0x00 },
+ { 67, 0x5f, 0xff, 0x5f }, { 68, 0x5f, 0xff, 0x87 },
+ { 69, 0x5f, 0xff, 0xaf }, { 70, 0x5f, 0xff, 0xd7 },
+ { 71, 0x5f, 0xff, 0xff }, { 225, 0x62, 0x62, 0x62 },
+ { 226, 0x6c, 0x6c, 0x6c }, { 227, 0x76, 0x76, 0x76 },
+ { 228, 0x80, 0x80, 0x80 }, { 72, 0x87, 0x00, 0x00 },
+ { 73, 0x87, 0x00, 0x5f }, { 74, 0x87, 0x00, 0x87 },
+ { 75, 0x87, 0x00, 0xaf }, { 76, 0x87, 0x00, 0xd7 },
+ { 77, 0x87, 0x00, 0xff }, { 78, 0x87, 0x5f, 0x00 },
+ { 79, 0x87, 0x5f, 0x5f }, { 80, 0x87, 0x5f, 0x87 },
+ { 81, 0x87, 0x5f, 0xaf }, { 82, 0x87, 0x5f, 0xd7 },
+ { 83, 0x87, 0x5f, 0xff }, { 84, 0x87, 0x87, 0x00 },
+ { 85, 0x87, 0x87, 0x5f }, { 86, 0x87, 0x87, 0x87 },
+ { 87, 0x87, 0x87, 0xaf }, { 88, 0x87, 0x87, 0xd7 },
+ { 89, 0x87, 0x87, 0xff }, { 90, 0x87, 0xaf, 0x00 },
+ { 91, 0x87, 0xaf, 0x5f }, { 92, 0x87, 0xaf, 0x87 },
+ { 93, 0x87, 0xaf, 0xaf }, { 94, 0x87, 0xaf, 0xd7 },
+ { 95, 0x87, 0xaf, 0xff }, { 96, 0x87, 0xd7, 0x00 },
+ { 97, 0x87, 0xd7, 0x5f }, { 98, 0x87, 0xd7, 0x87 },
+ { 99, 0x87, 0xd7, 0xaf }, { 100, 0x87, 0xd7, 0xd7 },
+ { 101, 0x87, 0xd7, 0xff }, { 102, 0x87, 0xff, 0x00 },
+ { 103, 0x87, 0xff, 0x5f }, { 104, 0x87, 0xff, 0x87 },
+ { 105, 0x87, 0xff, 0xaf }, { 106, 0x87, 0xff, 0xd7 },
+ { 107, 0x87, 0xff, 0xff }, { 229, 0x8a, 0x8a, 0x8a },
+ { 230, 0x94, 0x94, 0x94 }, { 231, 0x9e, 0x9e, 0x9e },
+ { 232, 0xa8, 0xa8, 0xa8 }, { 108, 0xaf, 0x00, 0x00 },
+ { 109, 0xaf, 0x00, 0x5f }, { 110, 0xaf, 0x00, 0x87 },
+ { 111, 0xaf, 0x00, 0xaf }, { 112, 0xaf, 0x00, 0xd7 },
+ { 113, 0xaf, 0x00, 0xff }, { 114, 0xaf, 0x5f, 0x00 },
+ { 115, 0xaf, 0x5f, 0x5f }, { 116, 0xaf, 0x5f, 0x87 },
+ { 117, 0xaf, 0x5f, 0xaf }, { 118, 0xaf, 0x5f, 0xd7 },
+ { 119, 0xaf, 0x5f, 0xff }, { 120, 0xaf, 0x87, 0x00 },
+ { 121, 0xaf, 0x87, 0x5f }, { 122, 0xaf, 0x87, 0x87 },
+ { 123, 0xaf, 0x87, 0xaf }, { 124, 0xaf, 0x87, 0xd7 },
+ { 125, 0xaf, 0x87, 0xff }, { 126, 0xaf, 0xaf, 0x00 },
+ { 127, 0xaf, 0xaf, 0x5f }, { 128, 0xaf, 0xaf, 0x87 },
+ { 129, 0xaf, 0xaf, 0xaf }, { 130, 0xaf, 0xaf, 0xd7 },
+ { 131, 0xaf, 0xaf, 0xff }, { 132, 0xaf, 0xd7, 0x00 },
+ { 133, 0xaf, 0xd7, 0x5f }, { 134, 0xaf, 0xd7, 0x87 },
+ { 135, 0xaf, 0xd7, 0xaf }, { 136, 0xaf, 0xd7, 0xd7 },
+ { 137, 0xaf, 0xd7, 0xff }, { 138, 0xaf, 0xff, 0x00 },
+ { 139, 0xaf, 0xff, 0x5f }, { 140, 0xaf, 0xff, 0x87 },
+ { 141, 0xaf, 0xff, 0xaf }, { 142, 0xaf, 0xff, 0xd7 },
+ { 143, 0xaf, 0xff, 0xff }, { 233, 0xb2, 0xb2, 0xb2 },
+ { 234, 0xbc, 0xbc, 0xbc }, { 235, 0xc6, 0xc6, 0xc6 },
+ { 236, 0xd0, 0xd0, 0xd0 }, { 144, 0xd7, 0x00, 0x00 },
+ { 145, 0xd7, 0x00, 0x5f }, { 146, 0xd7, 0x00, 0x87 },
+ { 147, 0xd7, 0x00, 0xaf }, { 148, 0xd7, 0x00, 0xd7 },
+ { 149, 0xd7, 0x00, 0xff }, { 150, 0xd7, 0x5f, 0x00 },
+ { 151, 0xd7, 0x5f, 0x5f }, { 152, 0xd7, 0x5f, 0x87 },
+ { 153, 0xd7, 0x5f, 0xaf }, { 154, 0xd7, 0x5f, 0xd7 },
+ { 155, 0xd7, 0x5f, 0xff }, { 156, 0xd7, 0x87, 0x00 },
+ { 157, 0xd7, 0x87, 0x5f }, { 158, 0xd7, 0x87, 0x87 },
+ { 159, 0xd7, 0x87, 0xaf }, { 160, 0xd7, 0x87, 0xd7 },
+ { 161, 0xd7, 0x87, 0xff }, { 162, 0xd7, 0xaf, 0x00 },
+ { 163, 0xd7, 0xaf, 0x5f }, { 164, 0xd7, 0xaf, 0x87 },
+ { 165, 0xd7, 0xaf, 0xaf }, { 166, 0xd7, 0xaf, 0xd7 },
+ { 167, 0xd7, 0xaf, 0xff }, { 168, 0xd7, 0xd7, 0x00 },
+ { 169, 0xd7, 0xd7, 0x5f }, { 170, 0xd7, 0xd7, 0x87 },
+ { 171, 0xd7, 0xd7, 0xaf }, { 172, 0xd7, 0xd7, 0xd7 },
+ { 173, 0xd7, 0xd7, 0xff }, { 174, 0xd7, 0xff, 0x00 },
+ { 175, 0xd7, 0xff, 0x5f }, { 176, 0xd7, 0xff, 0x87 },
+ { 177, 0xd7, 0xff, 0xaf }, { 178, 0xd7, 0xff, 0xd7 },
+ { 179, 0xd7, 0xff, 0xff }, { 237, 0xda, 0xda, 0xda },
+ { 238, 0xe4, 0xe4, 0xe4 }, { 239, 0xee, 0xee, 0xee },
+ { 180, 0xff, 0x00, 0x00 }, { 181, 0xff, 0x00, 0x5f },
+ { 182, 0xff, 0x00, 0x87 }, { 183, 0xff, 0x00, 0xaf },
+ { 184, 0xff, 0x00, 0xd7 }, { 185, 0xff, 0x00, 0xff },
+ { 186, 0xff, 0x5f, 0x00 }, { 187, 0xff, 0x5f, 0x5f },
+ { 188, 0xff, 0x5f, 0x87 }, { 189, 0xff, 0x5f, 0xaf },
+ { 190, 0xff, 0x5f, 0xd7 }, { 191, 0xff, 0x5f, 0xff },
+ { 192, 0xff, 0x87, 0x00 }, { 193, 0xff, 0x87, 0x5f },
+ { 194, 0xff, 0x87, 0x87 }, { 195, 0xff, 0x87, 0xaf },
+ { 196, 0xff, 0x87, 0xd7 }, { 197, 0xff, 0x87, 0xff },
+ { 198, 0xff, 0xaf, 0x00 }, { 199, 0xff, 0xaf, 0x5f },
+ { 200, 0xff, 0xaf, 0x87 }, { 201, 0xff, 0xaf, 0xaf },
+ { 202, 0xff, 0xaf, 0xd7 }, { 203, 0xff, 0xaf, 0xff },
+ { 204, 0xff, 0xd7, 0x00 }, { 205, 0xff, 0xd7, 0x5f },
+ { 206, 0xff, 0xd7, 0x87 }, { 207, 0xff, 0xd7, 0xaf },
+ { 208, 0xff, 0xd7, 0xd7 }, { 209, 0xff, 0xd7, 0xff },
+ { 210, 0xff, 0xff, 0x00 }, { 211, 0xff, 0xff, 0x5f },
+ { 212, 0xff, 0xff, 0x87 }, { 213, 0xff, 0xff, 0xaf },
+ { 214, 0xff, 0xff, 0xd7 }, { 215, 0xff, 0xff, 0xff },
+ };
+
+ static const unsigned char color_256_to_16[256] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 4, 4, 4, 12, 12, 2, 6, 4, 4, 12, 12, 2, 2, 6, 4,
+ 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
+ 10, 10, 10, 14, 1, 5, 4, 4, 12, 12, 3, 8, 4, 4, 12, 12,
+ 2, 2, 6, 4, 12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10,
+ 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 5, 4, 12, 12, 1, 1,
+ 5, 4, 12, 12, 3, 3, 8, 4, 12, 12, 2, 2, 2, 6, 12, 12,
+ 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14, 1, 1, 1, 5,
+ 12, 12, 1, 1, 1, 5, 12, 12, 1, 1, 1, 5, 12, 12, 3, 3,
+ 3, 7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
+ 9, 9, 9, 9, 13, 12, 9, 9, 9, 9, 13, 12, 9, 9, 9, 9,
+ 13, 12, 9, 9, 9, 9, 13, 12, 11, 11, 11, 11, 7, 12, 10, 10,
+ 10, 10, 10, 14, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13,
+ 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9,
+ 9, 13, 11, 11, 11, 11, 11, 15, 0, 0, 0, 0, 0, 0, 8, 8,
+ 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15
+ };
+
+ Color rgb = { .r = r, .g = g, .b = b };
+ const Color *found = bsearch(&rgb, color_to_256, LENGTH(color_to_256),
+ sizeof color_to_256[0], color_compare);
+
+ if (!found) {
+ unsigned lowest = UINT_MAX;
+ found = color_from_256;
+ for (int i = 0; i < 240; i++) {
+ int dr = (int)color_from_256[i].r - r;
+ int dg = (int)color_from_256[i].g - g;
+ int db = (int)color_from_256[i].b - b;
+
+ unsigned int distance = dr * dr + dg * dg + db * db;
+ if (distance < lowest) {
+ lowest = distance;
+ found = &color_from_256[i];
+ }
+ }
+ }
+
+ if (COLORS <= 16)
+ return color_256_to_16[found->i + 16];
+ return found->i + 16;
+}
+
+/* Convert color from string. */
+static int color_fromstring(const char *s)
+{
+ if (*s == '#' && strlen(s) == 7) {
+ const char *cp;
+ unsigned char r, g, b;
+ for (cp = s + 1; isxdigit((unsigned char)*cp); cp++);
+ if (*cp != '\0')
+ return -1;
+ int n = sscanf(s + 1, "%2hhx%2hhx%2hhx", &r, &g, &b);
+ if (n != 3)
+ return -1;
+ return color_find_rgb(r, g, b);
+ }
+
+ if (strcasecmp(s, "black") == 0)
+ return 0;
+ if (strcasecmp(s, "red") == 0)
+ return 1;
+ if (strcasecmp(s, "green") == 0)
+ return 2;
+ if (strcasecmp(s, "yellow") == 0)
+ return 3;
+ if (strcasecmp(s, "blue") == 0)
+ return 4;
+ if (strcasecmp(s, "magenta") == 0)
+ return 5;
+ if (strcasecmp(s, "cyan") == 0)
+ return 6;
+ if (strcasecmp(s, "white") == 0)
+ return 7;
+ return -1;
+}
+
+static unsigned int color_pair_hash(short fg, short bg) {
if (fg == -1)
fg = COLORS;
if (bg == -1)
@@ -96,7 +460,7 @@ static unsigned int color_hash(short fg, short bg) {
return fg * (COLORS + 2) + bg;
}
-static short color_get(short fg, short bg) {
+static short color_pair_get(short fg, short bg) {
static bool has_default_colors;
static short *color2palette, default_fg, default_bg;
static short color_pairs_max, color_pair_current;
@@ -128,13 +492,13 @@ static short color_get(short fg, short bg) {
if (!color2palette || (fg == -1 && bg == -1))
return 0;
- unsigned int index = color_hash(fg, bg);
+ unsigned int index = color_pair_hash(fg, bg);
if (color2palette[index] == 0) {
short oldfg, oldbg;
if (++color_pair_current >= color_pairs_max)
color_pair_current = 1;
pair_content(color_pair_current, &oldfg, &oldbg);
- unsigned int old_index = color_hash(oldfg, oldbg);
+ unsigned int old_index = color_pair_hash(oldfg, oldbg);
if (init_pair(color_pair_current, fg, bg) == OK) {
color2palette[old_index] = 0;
color2palette[index] = color_pair_current;
@@ -144,6 +508,45 @@ static short color_get(short fg, short bg) {
return color2palette[index];
}
+static bool ui_window_syntax_style(UiWin *w, int id, const char *style) {
+ UiCursesWin *win = (UiCursesWin*)w;
+ if (id >= UI_STYLES_MAX)
+ return false;
+ short fg = -1, bg = -1;
+ attr_t attr = A_NORMAL;
+ char *style_copy = strdup(style), *option = style_copy, *next, *p;
+ while (option) {
+ if ((next = strchr(option, ',')))
+ *next++ = '\0';
+ if ((p = strchr(option, ':')))
+ *p++ = '\0';
+ if (!strcasecmp(option, "bold")) {
+ attr |= A_BOLD;
+ } else if (!strcasecmp(option, "notbold")) {
+ attr &= ~A_BOLD;
+#ifdef A_ITALIC
+ } else if (!strcasecmp(option, "italics")) {
+ attr |= A_ITALIC;
+ } else if (!strcasecmp(option, "notitalics")) {
+ attr &= ~A_ITALIC;
+#endif
+ } else if (!strcasecmp(option, "underlined")) {
+ attr |= A_UNDERLINE;
+ } else if (!strcasecmp(option, "notunderlined")) {
+ attr &= ~A_UNDERLINE;
+ } else if (!strcasecmp(option, "fore")) {
+ fg = color_fromstring(p);
+ } else if (!strcasecmp(option, "back")) {
+ bg = color_fromstring(p);
+ }
+ option = next;
+ }
+ attr |= COLOR_PAIR(color_pair_get(fg, bg));
+ win->styles[id] = attr;
+ free(style_copy);
+ return true;
+}
+
static void ui_window_resize(UiCursesWin *win, int width, int height) {
win->width = width;
win->height = height;
@@ -365,7 +768,7 @@ static void ui_window_draw_text(UiWin *w, const Line *line) {
int width = view_width_get(win->view);
for (const Line *l = line; l; l = l->next) {
for (int x = 0; x < width; x++) {
- int attr = l->cells[x].attr;
+ int attr = win->styles[l->cells[x].attr];
if (l->cells[x].cursor && (win->ui->selwin == win || win->ui->prompt_win == win))
attr = A_NORMAL | A_REVERSE;
if (l->cells[x].selected)
@@ -427,6 +830,7 @@ static UiWin *ui_window_new(Ui *ui, View *view, File *file) {
.draw_text = ui_window_draw_text,
.options = ui_window_options,
.reload = ui_window_reload,
+ .syntax_style = ui_window_syntax_style,
};
if (!(win->win = newwin(0, 0, 0, 0)) || !(win->winstatus = newwin(1, 0, 0, 0))) {
@@ -574,7 +978,7 @@ static void ui_terminal_restore(Ui *ui) {
termkey_start(uic->termkey);
}
-Ui *ui_curses_new(Color *colors) {
+Ui *ui_curses_new(void) {
UiCurses *uic = calloc(1, sizeof(UiCurses));
Ui *ui = (Ui*)uic;
@@ -628,12 +1032,6 @@ Ui *ui_curses_new(Color *colors) {
.terminal_restore = ui_terminal_restore,
};
- for (Color *color = colors; color && color->fg; color++) {
- if (color->attr == 0)
- color->attr = A_NORMAL;
- color->attr |= COLOR_PAIR(color_get(color->fg, color->bg));
- }
-
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
diff --git a/ui-curses.h b/ui-curses.h
index b9b63b1..d23f8c3 100644
--- a/ui-curses.h
+++ b/ui-curses.h
@@ -5,26 +5,7 @@
#include "ui.h"
#include "syntax.h"
-enum {
- UI_COLOR_DEFAULT = -1,
- UI_COLOR_BLACK = COLOR_BLACK,
- UI_COLOR_RED = COLOR_RED,
- UI_COLOR_GREEN = COLOR_GREEN,
- UI_COLOR_YELLOW = COLOR_YELLOW,
- UI_COLOR_BLUE = COLOR_BLUE,
- UI_COLOR_MAGENTA = COLOR_MAGENTA,
- UI_COLOR_CYAN = COLOR_CYAN,
- UI_COLOR_WHITE = COLOR_WHITE,
-};
-
-enum {
- UI_ATTR_NORMAL = A_NORMAL,
- UI_ATTR_UNDERLINE = A_UNDERLINE,
- UI_ATTR_REVERSE = A_REVERSE,
- UI_ATTR_BOLD = A_BOLD,
-};
-
-Ui *ui_curses_new(Color *colors);
+Ui *ui_curses_new(void);
void ui_curses_free(Ui*);
#endif
diff --git a/ui.h b/ui.h
index 797b73a..06738cf 100644
--- a/ui.h
+++ b/ui.h
@@ -1,6 +1,10 @@
#ifndef UI_H
#define UI_H
+#include <stdbool.h>
+#include <stdarg.h>
+#include <termkey.h>
+
typedef struct Ui Ui;
typedef struct UiWin UiWin;
@@ -15,9 +19,8 @@ enum UiOption {
UI_OPTION_LINE_NUMBERS_RELATIVE = 1 << 1,
};
-#include <stdbool.h>
-#include <stdarg.h>
-#include <termkey.h>
+#define UI_STYLES_MAX 64
+
#include "text.h"
#include "view.h"
#include "editor.h"
@@ -53,6 +56,7 @@ struct UiWin {
void (*draw_status)(UiWin*);
void (*reload)(UiWin*, File*);
void (*options)(UiWin*, enum UiOption);
+ bool (*syntax_style)(UiWin*, int id, const char *style);
};
#endif
diff --git a/view.c b/view.c
index b8b1dd6..df8aa93 100644
--- a/view.c
+++ b/view.c
@@ -167,8 +167,7 @@ static bool view_addch(View *view, Cell *cell) {
cell->len = w == 0 ? 1 : 0;
int t = w == 0 ? SYNTAX_SYMBOL_TAB : SYNTAX_SYMBOL_TAB_FILL;
strncpy(cell->data, view->symbols[t]->symbol, sizeof(cell->data)-1);
- if (view->symbols[t]->color)
- cell->attr = view->symbols[t]->color->attr;
+ cell->attr = view->symbols[t]->style;
view->line->cells[view->col] = *cell;
view->line->len += cell->len;
view->line->width += cell->width;
@@ -187,8 +186,7 @@ static bool view_addch(View *view, Cell *cell) {
}
strncpy(cell->data, view->symbols[SYNTAX_SYMBOL_EOL]->symbol, sizeof(cell->data)-1);
- if (view->symbols[SYNTAX_SYMBOL_EOL]->color)
- cell->attr = view->symbols[SYNTAX_SYMBOL_EOL]->color->attr;
+ cell->attr = view->symbols[SYNTAX_SYMBOL_EOL]->style;
view->line->cells[view->col] = *cell;
view->line->len += cell->len;
@@ -215,8 +213,7 @@ static bool view_addch(View *view, Cell *cell) {
if (cell->data[0] == ' ') {
strncpy(cell->data, view->symbols[SYNTAX_SYMBOL_SPACE]->symbol, sizeof(cell->data)-1);
- if (view->symbols[SYNTAX_SYMBOL_SPACE]->color)
- cell->attr = view->symbols[SYNTAX_SYMBOL_SPACE]->color->attr;
+ cell->attr = view->symbols[SYNTAX_SYMBOL_SPACE]->style;
}
@@ -405,7 +402,7 @@ void view_draw(View *view) {
if (text + match[i][0].rm_so <= cur && cur < text + match[i][0].rm_eo) {
/* within matched expression */
matched = &match[i][0];
- attrs = rule->color->attr;
+ attrs = rule->style;
break; /* first match views */
}
}
@@ -466,8 +463,7 @@ void view_draw(View *view) {
for (Line *l = view->lastline->next; l; l = l->next) {
strncpy(l->cells[0].data, view->symbols[SYNTAX_SYMBOL_EOF]->symbol, sizeof(l->cells[0].data));
- if (view->symbols[SYNTAX_SYMBOL_EOF]->color)
- l->cells[0].attr =view->symbols[SYNTAX_SYMBOL_EOF]->color->attr;
+ l->cells[0].attr = view->symbols[SYNTAX_SYMBOL_EOF]->style;
for (int x = 1; x < view->width; x++)
l->cells[x] = cell_blank;
l->width = 1;
@@ -844,6 +840,11 @@ void view_syntax_set(View *view, Syntax *syntax) {
else
view->symbols[i] = &symbols_none[i];
}
+ if (syntax) {
+ for (const char **style = syntax->styles; *style; style++) {
+ view->ui->syntax_style(view->ui, style - syntax->styles, *style);
+ }
+ }
}
Syntax *view_syntax_get(View *view) {
diff --git a/vis.c b/vis.c
index 351ad54..e686b73 100644
--- a/vis.c
+++ b/vis.c
@@ -2758,7 +2758,7 @@ int main(int argc, char *argv[]) {
die("Could not load bindings for mode: %s\n", mode->name);
}
- if (!(vis = editor_new(ui_curses_new(colors))))
+ if (!(vis = editor_new(ui_curses_new())))
die("Could not allocate editor core\n");
vis->mode_prev = vis->mode = config->mode;