aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_getln.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r--src/nvim/ex_getln.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 54e5bcb9ff..386e9e81aa 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -66,6 +66,8 @@
#include "nvim/lib/kvec.h"
#include "nvim/api/private/helpers.h"
#include "nvim/highlight_defs.h"
+#include "nvim/viml/parser/parser.h"
+#include "nvim/viml/parser/expressions.h"
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
@@ -2341,6 +2343,62 @@ void free_cmdline_buf(void)
enum { MAX_CB_ERRORS = 1 };
+/// Color expression cmdline using built-in expressions parser
+///
+/// @param[in] colored_ccline Command-line to color.
+/// @param[out] ret_ccline_colors What should be colored.
+///
+/// Always colors the whole cmdline.
+static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
+ ColoredCmdline *const ret_ccline_colors)
+ FUNC_ATTR_NONNULL_ALL
+{
+ ParserLine plines[] = {
+ {
+ .data = (const char *)colored_ccline->cmdbuff,
+ .size = STRLEN(colored_ccline->cmdbuff),
+ .allocated = false,
+ },
+ { NULL, 0, false },
+ };
+ ParserLine *plines_p = plines;
+ ParserHighlight colors;
+ kvi_init(colors);
+ ParserState pstate;
+ viml_parser_init(
+ &pstate, parser_simple_get_line, &plines_p, &colors);
+ ExprAST east = viml_pexpr_parse(&pstate, kExprFlagsDisallowEOC);
+ viml_pexpr_free_ast(east);
+ viml_parser_destroy(&pstate);
+ kv_resize(ret_ccline_colors->colors, kv_size(colors));
+ size_t prev_end = 0;
+ for (size_t i = 0 ; i < kv_size(colors) ; i++) {
+ const ParserHighlightChunk chunk = kv_A(colors, i);
+ if (chunk.start.col != prev_end) {
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = chunk.start.col,
+ .attr = 0,
+ }));
+ }
+ const int id = syn_name2id((const char_u *)chunk.group);
+ const int attr = (id == 0 ? 0 : syn_id2attr(id));
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = chunk.start.col,
+ .end = chunk.end_col,
+ .attr = attr,
+ }));
+ prev_end = chunk.end_col;
+ }
+ if (prev_end < (size_t)colored_ccline->cmdlen) {
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = (size_t)colored_ccline->cmdlen,
+ .attr = 0,
+ }));
+ }
+}
+
/// Color command-line
///
/// Should use built-in command parser or user-specified one. Currently only the
@@ -2422,13 +2480,8 @@ static bool color_cmdline(const CmdlineInfo *const colored_ccline,
tl_ret = try_leave(&tstate, &err);
can_free_cb = true;
} else if (colored_ccline->cmdfirstc == '=') {
- try_enter(&tstate);
- err_errmsg = N_(
- "E5409: Unable to get g:Nvim_color_expr callback: %s");
- dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_expr"),
- &color_cb);
- tl_ret = try_leave(&tstate, &err);
- can_free_cb = true;
+ color_expr_cmdline(colored_ccline, ret_ccline_colors);
+ can_free_cb = false;
}
if (!tl_ret || !dgc_ret) {
goto color_cmdline_error;