From a80d4e2dd4138663aefe9db5f4b39c537defd8e7 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Fri, 19 Jun 2015 14:34:30 +0000 Subject: [PATCH] improves markdown mode * made verbatim block coloring completely generic using language name lookup * removed global references to most snytax coloring modes --- clang.c | 4 +-- extra-modes.c | 8 ++--- markdown.c | 84 ++++++++++++++++++++++++--------------------------- qe.c | 29 ++++++++++-------- qe.h | 8 +---- swift.c | 2 +- 6 files changed, 64 insertions(+), 71 deletions(-) diff --git a/clang.c b/clang.c index e50528b..3b167c4 100644 --- a/clang.c +++ b/clang.c @@ -1753,7 +1753,7 @@ ModeDef as_mode = { .fallback = &c_mode, }; -ModeDef java_mode = { +static ModeDef java_mode = { .name = "Java", .extensions = "jav|java", .colorize_func = c_colorize_line, @@ -1765,7 +1765,7 @@ ModeDef java_mode = { .fallback = &c_mode, }; -ModeDef scala_mode = { +static ModeDef scala_mode = { .name = "Scala", .extensions = "scala|sbt", .colorize_func = c_colorize_line, diff --git a/extra-modes.c b/extra-modes.c index 48edec2..b3894b5 100644 --- a/extra-modes.c +++ b/extra-modes.c @@ -1708,7 +1708,7 @@ static void lua_colorize_line(QEColorizeContext *cp, cp->colorize_state = state; } -ModeDef lua_mode = { +static ModeDef lua_mode = { .name = "Lua", .extensions = "lua", .shell_handlers = "lua", @@ -2183,7 +2183,7 @@ static void haskell_colorize_line(QEColorizeContext *cp, cp->colorize_state = state; } -ModeDef haskell_mode = { +static ModeDef haskell_mode = { .name = "Haskell", .extensions = "hs|haskell", .shell_handlers = "haskell", @@ -2401,7 +2401,7 @@ static void python_colorize_line(QEColorizeContext *cp, cp->colorize_state = state; } -ModeDef python_mode = { +static ModeDef python_mode = { .name = "Python", .extensions = "py|pyt", .shell_handlers = "python|python2.6|python2.7", @@ -2882,7 +2882,7 @@ static int ruby_mode_probe(ModeDef *mode, ModeProbeData *p) return 1; } -ModeDef ruby_mode = { +static ModeDef ruby_mode = { .name = "Ruby", .extensions = "rb|gemspec", .keywords = ruby_keywords, diff --git a/markdown.c b/markdown.c index c23154b..e0ad98d 100644 --- a/markdown.c +++ b/markdown.c @@ -49,26 +49,12 @@ enum { IN_MKD_HTML_BLOCK = 0x8000, IN_MKD_HTML_COMMENT = 0xC000, MKD_LANG_SHIFT = 11, - MKD_LANG_MAX = 16, + MKD_LANG_MAX = (IN_MKD_BLOCK >> MKD_LANG_SHIFT), MKD_LEVEL_SHIFT = 8, MKD_LEVEL_MAX = 7, }; -ModeDef *mkd_lang_def[MKD_LANG_MAX - 1] = { - NULL, - &js_mode, - &java_mode, - &scala_mode, - &php_mode, - &csharp_mode, - &python_mode, - &ruby_mode, - &haskell_mode, - &lua_mode, - &swift_mode, - &cpp_mode, - &c_mode, -}; +ModeDef *mkd_lang_def[MKD_LANG_MAX + 1]; #define MKD_BULLET_STYLES 4 static int MkdBulletStyles[MKD_BULLET_STYLES] = { @@ -127,27 +113,6 @@ static void mkd_colorize_line(QEColorizeContext *cp, return; } - if (colstate & IN_MKD_HTML_BLOCK) { - if (str[i] != '<' && str[i] != '\0' && !qe_isblank(str[i])) { - /* formating error, exit html block */ - colstate = 0; - } - } - - if ((colstate & IN_MKD_HTML_BLOCK) - || (str[i] == '<' && str[i + 1] != '/')) { - /* block level HTML markup */ - colstate &= ~IN_MKD_HTML_BLOCK; - cp->colorize_state = colstate; - htmlsrc_mode.colorize_func(cp, str, n, &htmlsrc_mode); - colstate = cp->colorize_state; - colstate |= IN_MKD_HTML_BLOCK; - if ((str[i] & CHAR_MASK) == '<' && (str[i + 1] & CHAR_MASK) == '/') - colstate = 0; - cp->colorize_state = colstate; - return; - } - if (str[i] == '>') { if (str[++i] == ' ') i++; @@ -167,7 +132,7 @@ static void mkd_colorize_line(QEColorizeContext *cp, cp->colorize_state = colstate & IN_MKD_LANG_STATE; - if (lang < countof(mkd_lang_def) && mkd_lang_def[lang]) { + if (mkd_lang_def[lang]) { mkd_lang_def[lang]->colorize_func(cp, str + i, n - i, mkd_lang_def[lang]); } else { SET_COLOR(str, i, n, MKD_STYLE_CODE); @@ -180,6 +145,27 @@ static void mkd_colorize_line(QEColorizeContext *cp, return; } + if (colstate & IN_MKD_HTML_BLOCK) { + if (i < n && str[i] != '<' && !qe_isblank(str[i])) { + /* formating error, exit html block */ + colstate = 0; + } + } + + if ((colstate & IN_MKD_HTML_BLOCK) + || (str[i] == '<' && (str[i + 1] == '!' || str[i + 1] == '?' || qe_isalpha(str[i + 1])))) { + /* block level HTML markup */ + colstate &= ~IN_MKD_HTML_BLOCK; + cp->colorize_state = colstate; + htmlsrc_mode.colorize_func(cp, str, n, &htmlsrc_mode); + colstate = cp->colorize_state; + colstate |= IN_MKD_HTML_BLOCK; + if ((str[i] & CHAR_MASK) == '<' && (str[i + 1] & CHAR_MASK) == '/') + colstate = 0; + cp->colorize_state = colstate; + return; + } + if (str[i] == '#') { /* Check for heading: initial string of '#' followed by ' ' */ for (i++; str[i] == '#'; i++) @@ -218,15 +204,25 @@ static void mkd_colorize_line(QEColorizeContext *cp, if (ustrstart(str + i, "~~~", NULL) || ustrstart(str + i, "```", NULL)) { /* verbatim block */ - int lang; + char lang_name[16]; + int lang = MKD_LANG_MAX, len; + ModeDef *m; colstate &= ~(IN_MKD_BLOCK | IN_MKD_LANG_STATE); - for (j = i + 3; qe_isspace(str[j]); j++) + for (i += 3; qe_isspace(str[i]); i++) continue; - for (lang = 1; lang < countof(mkd_lang_def); lang++) { - if (mkd_lang_def[lang] - && ustristart(str + j, mkd_lang_def[lang]->name, NULL)) - break; + for (len = 0; i < n && qe_isalnum_(str[i]); i++) { + if (len < countof(lang_name) - 1) + lang_name[len++] = str[i]; + } + lang_name[len] = '\0'; + if (len > 0 && (m = qe_find_mode(lang_name, MODEF_SYNTAX)) != NULL) { + for (lang = 1; lang < MKD_LANG_MAX; lang++) { + if (mkd_lang_def[lang] == NULL) + mkd_lang_def[lang] = m; + if (mkd_lang_def[lang] == m) + break; + } } colstate |= lang << MKD_LANG_SHIFT; i = n; diff --git a/qe.c b/qe.c index 283f68d..a73bbf8 100644 --- a/qe.c +++ b/qe.c @@ -90,6 +90,21 @@ static int generic_mode_probe(ModeDef *mode, ModeProbeData *p) return 1; } +ModeDef *qe_find_mode(const char *name, int flags) +{ + QEmacsState *qs = &qe_state; + ModeDef *m; + + for (m = qs->first_mode; m; m = m->next) { + if ((m->flags & flags) == flags) { + if ((m->name && !strcasecmp(m->name, name)) + || (m->mode_name && !strcasecmp(m->mode_name, name))) + break; + } + } + return m; +} + void qe_register_mode(ModeDef *m, int flags) { QEmacsState *qs = &qe_state; @@ -183,18 +198,6 @@ void mode_completion(CompleteState *cp) } } -static ModeDef *find_mode(const char *name) -{ - QEmacsState *qs = &qe_state; - ModeDef *m; - - for (m = qs->first_mode; m != NULL; m = m->next) { - if (strequal(m->mode_name, name)) - break; - } - return m; -} - /* commands handling */ CmdDef *qe_find_cmd(const char *cmd_name) @@ -1890,7 +1893,7 @@ void do_set_mode(EditState *s, const char *name) ModeDef *m; /* XXX: should check if mode is appropriate */ - m = find_mode(name); + m = qe_find_mode(name, 0); if (m) edit_set_mode(s, m); else diff --git a/qe.h b/qe.h index 9f8effc..7ae0ce3 100644 --- a/qe.h +++ b/qe.h @@ -1510,6 +1510,7 @@ typedef struct CmdDef { #define CMD_DEF_END \ { 0, 0, NULL, { NULL }, CMD_void, 0 } +ModeDef *qe_find_mode(const char *name, int flags); void qe_register_mode(ModeDef *m, int flags); void mode_completion(CompleteState *cp); void qe_register_cmd_table(CmdDef *cmds, ModeDef *m); @@ -1987,18 +1988,11 @@ void do_dired(EditState *s); extern ModeDef c_mode; extern ModeDef cpp_mode; extern ModeDef js_mode; -extern ModeDef java_mode; -extern ModeDef scala_mode; extern ModeDef php_mode; extern ModeDef csharp_mode; extern ModeDef css_mode; -extern ModeDef swift_mode; extern ModeDef xml_mode; extern ModeDef htmlsrc_mode; -extern ModeDef lua_mode; -extern ModeDef haskell_mode; -extern ModeDef python_mode; -extern ModeDef ruby_mode; /* html.c */ diff --git a/swift.c b/swift.c index 11655d4..2517ed6 100644 --- a/swift.c +++ b/swift.c @@ -328,7 +328,7 @@ static const char swift_types[] = { "CChar32|CFloat|CDouble|" }; -ModeDef swift_mode = { +static ModeDef swift_mode = { .name = "Swift", .extensions = "swift", .shell_handlers = "swift",