[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemacs-commit] qemacs extra-modes.c
From: |
Charlie Gordon |
Subject: |
[Qemacs-commit] qemacs extra-modes.c |
Date: |
Thu, 10 Apr 2014 08:02:00 +0000 |
CVSROOT: /sources/qemacs
Module name: qemacs
Changes by: Charlie Gordon <chqrlie> 14/04/10 08:02:00
Modified files:
. : extra-modes.c
Log message:
add mode for vim script files
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/extra-modes.c?cvsroot=qemacs&r1=1.13&r2=1.14
Patches:
Index: extra-modes.c
===================================================================
RCS file: /sources/qemacs/qemacs/extra-modes.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- extra-modes.c 7 Apr 2014 20:51:47 -0000 1.13
+++ extra-modes.c 10 Apr 2014 08:01:50 -0000 1.14
@@ -330,6 +330,270 @@
return 0;
}
+/*---------------- Vim/Visual Vim coloring ----------------*/
+
+static char const vim_cmd_keywords[] = {
+ /* Only a subset of commands are recognized */
+ "|brea[k]|cal[l]|cat[ch]|command|con[tinue]|delc[ommand]"
+ "|delf[unction]|el[se]|elsei[f]|end|endfo[r]|endfu[nction]|endi[f]"
+ "|endt[ry]|endw[hile]|ex[ecute]|fina[lly]|fini[sh]|for"
+ "|fun[ction]|if|hi[ghlight]|let|norm|pu[t]|redraws[tatus]|res[ize]"
+ "|retu[rn]|ru[ntime]|se[t]|setl[ocal]|sil[ent]|syn|synt[ax]"
+ "|try|unl[et]|ve[rsion]|wh[ile]|y[ank]"
+ "|"
+};
+
+static char const vim_keywords[] = {
+ "|self|in"
+ "|"
+};
+
+static char const vim_syn_keywords[] = {
+ "|case|ignore|match|keyword|include|cluster|region|sync|clear"
+ "|nextgroup|contained|contains|display|oneline|start|end"
+ "|skipwhite|keepend|excludenl|skipnl|skip|keepend|fromstart"
+ "|minlines|maxlines|containedin|extend|transparent|fold"
+ "|matchgroup|add|grouphere|groupthere|linebreaks"
+ "|"
+};
+
+enum {
+ VIM_STYLE_TEXT = QE_STYLE_DEFAULT,
+ VIM_STYLE_COMMENT = QE_STYLE_COMMENT,
+ VIM_STYLE_STRING = QE_STYLE_STRING,
+ VIM_STYLE_REGEX = QE_STYLE_STRING,
+ VIM_STYLE_NUMBER = QE_STYLE_NUMBER,
+ VIM_STYLE_KEYWORD = QE_STYLE_KEYWORD,
+ VIM_STYLE_IDENTIFIER = QE_STYLE_DEFAULT,
+ VIM_STYLE_FUNCTION = QE_STYLE_FUNCTION,
+};
+
+enum {
+ VIM_STATE_CMD,
+ VIM_STATE_ARG,
+ VIM_STATE_SYN,
+};
+
+static int is_vim_keyword(unsigned int *str, int from, int to,
+ const char *list)
+{
+ char keyword[MAX_KEYWORD_SIZE];
+ const char *p;
+ int c, i, len = to - from;
+
+ if (len >= MAX_KEYWORD_SIZE)
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ c = str[from + i];
+ if (c >= 0x80)
+ return 0;
+ keyword[i] = c;
+ }
+ keyword[len] = '\0';
+
+ /* check for exact match or non ambiguous prefix */
+ for (p = list; *p != '\0';) {
+ for (i = 0;
+ p[i] != '\0' && p[i] != ' ' && p[i] != '[' && p[i] != '|';
+ i++) {
+ continue;
+ }
+ if (i <= len && !memcmp(p, keyword, i)) {
+ if (i == len)
+ return 1;
+ if (p[i] == '[' && !memcmp(p + i + 1, keyword + i, len - i))
+ return 1;
+ }
+ for (p += i; *p != '\0' && (c = *p++) != ' ' && c != '|';)
+ continue;
+ }
+ return 0;
+}
+
+static void vim_colorize_line(QEColorizeContext *cp,
+ unsigned int *str, int n, int mode_flags)
+{
+ int i = 0, j, start, c, state, comm, level, style;
+
+ while (qe_isblank(str[i])) {
+ i++;
+ }
+ if (str[i] == '\\') {
+ i++;
+ level = cp->colorize_state & 15;
+ state = cp->colorize_state >> 4;
+ comm = 0;
+ } else {
+ state = VIM_STATE_CMD;
+ level = 0;
+ comm = 1;
+ }
+
+ while (i < n) {
+ start = i;
+ c = str[i++];
+ switch (c) {
+ case '\'':
+ comm = 0;
+ /* parse string const */
+ while (i < n) {
+ if (str[i++] == c)
+ break;
+ }
+ SET_COLOR(str, start, i, VIM_STYLE_STRING);
+ continue;
+ case '/':
+ if (state == VIM_STATE_SYN
+ && (qe_isblank(str[i - 2]) || str[i - 2] == '=')) {
+ /* parse regex */
+ while (i < n) {
+ if (str[i] == '\\' && i + 1 < n) {
+ i += 2;
+ } else
+ if (str[i++] == c)
+ break;
+ }
+ SET_COLOR(str, start, i, VIM_STYLE_REGEX);
+ continue;
+ }
+ break;
+ case '+':
+ if (state == VIM_STATE_SYN
+ && (qe_isblank(str[i - 2]) || str[i - 2] == '=')) {
+ /* parse string const */
+ for (j = i; j < n;) {
+ if (str[j++] == c) {
+ i = j;
+ SET_COLOR(str, start, i, VIM_STYLE_STRING);
+ break;
+ }
+ }
+ continue;
+ }
+ break;
+ case '\"':
+ if (comm) {
+ i = n;
+ SET_COLOR(str, start, i, VIM_STYLE_COMMENT);
+ continue;
+ }
+ /* parse string const */
+ style = VIM_STYLE_COMMENT;
+ while (i < n) {
+ if (str[i] == '\\' && i + 1 < n) {
+ i += 2;
+ } else
+ if (str[i++] == c) {
+ style = VIM_STYLE_STRING;
+ break;
+ }
+ }
+ SET_COLOR(str, start, i, style);
+ continue;
+ case '|':
+ if (str[i] == '|') {
+ i++;
+ } else {
+ state = VIM_STATE_CMD;
+ comm = 1;
+ }
+ continue;
+ case '(':
+ comm = 0;
+ level++;
+ continue;
+ case ')':
+ level--;
+ if (!level)
+ comm = 1;
+ continue;
+ case ' ':
+ case '\t':
+ case ',':
+ case '$':
+ continue;
+ default:
+ comm = 0;
+ break;
+ }
+ /* parse numbers */
+ if (qe_isdigit(c)) {
+ for (; i < n; i++) {
+ if (!qe_isalnum(str[i]) && str[i] != '.')
+ break;
+ }
+ SET_COLOR(str, start, i, VIM_STYLE_NUMBER);
+ continue;
+ }
+ /* parse identifiers and keywords */
+ if (qe_isalpha_(c)) {
+ for (; i < n; i++) {
+ if (!qe_isalnum_(str[i]) && str[i] != '#')
+ break;
+ }
+ style = VIM_STYLE_IDENTIFIER;
+
+ if (state == VIM_STATE_CMD) {
+ state = VIM_STATE_ARG;
+ if (is_vim_keyword(str, start, i, vim_cmd_keywords)) {
+ if (is_vim_keyword(str, start, i, "syn[tax]")) {
+ state = VIM_STATE_SYN;
+ }
+ if (str[i] == '!')
+ i++;
+ style = VIM_STYLE_KEYWORD;
+ }
+ } else
+ if (state == VIM_STATE_SYN) {
+ if (is_vim_keyword(str, start, i, vim_syn_keywords)) {
+ style = VIM_STYLE_KEYWORD;
+ }
+ } else {
+ if (is_vim_keyword(str, start, i, vim_keywords)) {
+ style = VIM_STYLE_KEYWORD;
+ }
+ }
+ if (style == VIM_STYLE_IDENTIFIER) {
+ if (str[i] == '(' || (str[i] == ' ' && str[i + 1] == '('))
+ style = VIM_STYLE_FUNCTION;
+ }
+ SET_COLOR(str, start, i, style);
+ continue;
+ }
+ }
+ cp->colorize_state = (state << 4) | (level & 15);
+}
+
+static int vim_mode_probe(ModeDef *mode, ModeProbeData *p)
+{
+ if (match_extension(p->filename, mode->extensions))
+ return 80;
+
+ return 1;
+}
+
+static CmdDef vim_commands[] = {
+ CMD_DEF_END,
+};
+
+static ModeDef vim_mode;
+
+static int vim_init(void)
+{
+ /* vim mode is almost like the text mode, so we copy and patch it */
+ memcpy(&vim_mode, &text_mode, sizeof(ModeDef));
+ vim_mode.name = "Vim";
+ vim_mode.extensions = "vim";
+ vim_mode.mode_probe = vim_mode_probe;
+ vim_mode.colorize_func = vim_colorize_line;
+
+ qe_register_mode(&vim_mode);
+ qe_register_cmd_table(vim_commands, &vim_mode);
+
+ return 0;
+}
+
/*---------------- Pascal/Turbo Pascal/Delphi coloring ----------------*/
/* Should do Delphi specific things */
@@ -2034,6 +2298,7 @@
{
asm_init();
basic_init();
+ vim_init();
pascal_init();
ini_init();
ps_init();