diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2013-10-07 01:04:37 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2013-10-07 01:04:37 -0700 |
commit | 20ccda69f4319cadbfb242f139e48a84699b503d (patch) | |
tree | f837469b9ef96d37a651f12f5d24d4df0d5f1783 /highlight.cpp | |
parent | 14741518a7fc52f110dcd5ca71216b423520b789 (diff) |
Command highlighting works
Diffstat (limited to 'highlight.cpp')
-rw-r--r-- | highlight.cpp | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/highlight.cpp b/highlight.cpp index 9837d95c..a8e8326e 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -1800,23 +1800,9 @@ static void color_children(const parse_node_tree_t &tree, const parse_node_t &pa } } -/* Color a possibly decorated command */ -static void color_command(const wcstring &src, const parse_node_tree_t &tree, const parse_node_t &cmd_node, enum parse_statement_decoration_t decoration, std::vector<int> &color_array, const wcstring &working_directory, const env_vars_snapshot_t &vars) +/* Determine if a command is valid */ +static bool command_is_valid(const wcstring &cmd, enum parse_statement_decoration_t decoration, const wcstring &working_directory, const env_vars_snapshot_t &vars) { - if (! cmd_node.has_source()) - return; - - /* Get the source of the command */ - wcstring cmd(src, cmd_node.source_start, cmd_node.source_length); - - /* Try expanding it. If we cannot, it's an error. */ - bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS); - if (! expanded || has_expand_reserved(cmd)) - { - color_node(cmd_node, HIGHLIGHT_ERROR, color_array); - return; - } - /* Determine which types we check, based on the decoration */ bool builtin_ok = true, function_ok = true, abbreviation_ok = true, command_ok = true, implicit_cd_ok = true; if (decoration == parse_statement_decoration_command) @@ -1859,9 +1845,8 @@ static void color_command(const wcstring &src, const parse_node_tree_t &tree, co if (! is_valid && implicit_cd_ok) is_valid = path_can_be_implicit_cd(cmd, NULL, working_directory.c_str(), vars); - /* Color the node */ - int color = is_valid ? HIGHLIGHT_COMMAND : HIGHLIGHT_ERROR; - color_node(cmd_node, color, color_array); + /* Return what we got */ + return is_valid; } void highlight_shell_magic(const wcstring &buff, std::vector<int> &color, size_t pos, wcstring_list_t *error, const env_vars_snapshot_t &vars) @@ -1874,6 +1859,7 @@ void highlight_shell_magic(const wcstring &buff, std::vector<int> &color, size_t if (length == 0) return; + /* Start out at zero */ std::fill(color.begin(), color.end(), 0); /* Do something sucky and get the current working directory on this background thread. This should really be passed in. */ @@ -1925,25 +1911,45 @@ void highlight_shell_magic(const wcstring &buff, std::vector<int> &color, size_t break; case symbol_redirection: + { color_children(parse_tree, node, parse_token_type_string, HIGHLIGHT_REDIRECTION, color); - break; + } + break; case parse_token_type_background: case parse_token_type_end: + { color_node(node, HIGHLIGHT_END, color); - break; + } + break; case symbol_plain_statement: { - // Color the command - const parse_node_t *cmd = parse_tree.get_child(node, 0, parse_token_type_string); - if (cmd != NULL) + // Get the decoration from the parent + enum parse_statement_decoration_t decoration = parse_statement_decoration_none; + const parse_node_t *decorated_statement = parse_tree.get_parent(node, symbol_decorated_statement); + if (decorated_statement != NULL) { - enum parse_statement_decoration_t decoration = static_cast<enum parse_statement_decoration_t>(node.tag); - color_command(buff, parse_tree, *cmd, decoration, color, working_directory, vars); + decoration = static_cast<enum parse_statement_decoration_t>(decorated_statement->production_idx); } - // Color arguments + /* Color the command */ + const parse_node_t *cmd_node = parse_tree.get_child(node, 0, parse_token_type_string); + if (cmd_node != NULL && cmd_node->has_source()) + { + bool is_valid_cmd = false; + wcstring cmd(buff, cmd_node->source_start, cmd_node->source_length); + + /* Try expanding it. If we cannot, it's an error. */ + bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS); + if (expanded && ! has_expand_reserved(cmd)) + { + is_valid_cmd = command_is_valid(cmd, decoration, working_directory, vars); + } + color_node(*cmd_node, is_valid_cmd ? HIGHLIGHT_COMMAND : HIGHLIGHT_ERROR, color); + } + + /* Color arguments */ const parse_node_t *arguments = parse_tree.get_child(node, 1, symbol_arguments_or_redirections_list); if (arguments != NULL) { @@ -1978,8 +1984,13 @@ void highlight_shell_magic(const wcstring &buff, std::vector<int> &color, size_t for (parse_node_tree_t::const_iterator iter = parse_tree.begin(); iter != parse_tree.end(); ++iter) { const parse_node_t &node = *iter; - /* See if this node contains the cursor */ - if (node.type == symbol_argument && node.source_contains_location(pos)) + + /* Must be an argument with source */ + if (node.type != symbol_argument || ! node.has_source()) + continue; + + /* See if this node contains the cursor. We check <= source_length so that, when backspacing (and the cursor is just beyond the last token), we may still underline it */ + if (pos >= node.source_start && pos - node.source_start <= node.source_length) { /* See if this is a valid path */ if (node_is_potential_path(buff, node, working_directory)) |