mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-24 19:32:30 +08:00
tnode_t adoption of find_nodes
This commit is contained in:
parent
618996a166
commit
4d68877f51
|
@ -1294,9 +1294,9 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
while (position_in_statement > 0 && cmd.at(position_in_statement - 1) == L' ') {
|
||||
position_in_statement--;
|
||||
}
|
||||
auto plain_statement = tnode_t<grammar::plain_statement>{
|
||||
&tree, tree.find_node_matching_source_location(symbol_plain_statement,
|
||||
position_in_statement, NULL)};
|
||||
auto plain_statement =
|
||||
tnode_t<grammar::plain_statement>::find_node_matching_source_location(
|
||||
&tree, position_in_statement, nullptr);
|
||||
if (!plain_statement) {
|
||||
// Not part of a plain statement. This could be e.g. a for loop header, case expression,
|
||||
// etc. Do generic file completions (issue #1309). If we had to backtrack, it means
|
||||
|
@ -1368,15 +1368,14 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
use_implicit_cd);
|
||||
} else {
|
||||
// Get all the arguments.
|
||||
const parse_node_tree_t::parse_node_list_t all_arguments =
|
||||
tree.find_nodes(*plain_statement, symbol_argument);
|
||||
auto all_arguments = tnode_t<grammar::argument>::find_nodes(&tree, plain_statement);
|
||||
|
||||
// See whether we are in an argument. We may also be in a redirection, or nothing at
|
||||
// all.
|
||||
size_t matching_arg_index = -1;
|
||||
for (size_t i = 0; i < all_arguments.size(); i++) {
|
||||
const parse_node_t *node = all_arguments.at(i);
|
||||
if (node->location_in_or_at_end_of_source_range(position_in_statement)) {
|
||||
tnode_t<grammar::argument> arg = all_arguments.at(i);
|
||||
if (arg.location_in_or_at_end_of_source_range(position_in_statement)) {
|
||||
matching_arg_index = i;
|
||||
break;
|
||||
}
|
||||
|
@ -1386,7 +1385,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
wcstring current_argument, previous_argument;
|
||||
if (matching_arg_index != (size_t)(-1)) {
|
||||
const wcstring matching_arg =
|
||||
all_arguments.at(matching_arg_index)->get_source(cmd);
|
||||
all_arguments.at(matching_arg_index).get_source(cmd);
|
||||
|
||||
// If the cursor is in whitespace, then the "current" argument is empty and the
|
||||
// previous argument is the matching one. But if the cursor was in or at the end
|
||||
|
@ -1401,13 +1400,13 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
current_argument = matching_arg;
|
||||
if (matching_arg_index > 0) {
|
||||
previous_argument =
|
||||
all_arguments.at(matching_arg_index - 1)->get_source(cmd);
|
||||
all_arguments.at(matching_arg_index - 1).get_source(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we have a preceding double-dash.
|
||||
for (size_t i = 0; i < matching_arg_index; i++) {
|
||||
if (all_arguments.at(i)->get_source(cmd) == L"--") {
|
||||
if (all_arguments.at(i).get_source(cmd) == L"--") {
|
||||
had_ddash = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1417,9 +1416,10 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
// If we are not in an argument, we may be in a redirection.
|
||||
bool in_redirection = false;
|
||||
if (matching_arg_index == (size_t)(-1)) {
|
||||
const parse_node_t *redirection = tree.find_node_matching_source_location(
|
||||
symbol_redirection, position_in_statement, plain_statement);
|
||||
in_redirection = (redirection != NULL);
|
||||
if (tnode_t<grammar::redirection>::find_node_matching_source_location(
|
||||
&tree, position_in_statement, plain_statement)) {
|
||||
in_redirection = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool do_file = false, handle_as_special_cd = false;
|
||||
|
|
|
@ -3394,14 +3394,12 @@ static bool test_1_parse_ll2(const wcstring &src, wcstring *out_cmd, wcstring *o
|
|||
}
|
||||
|
||||
// Get the statement. Should only have one.
|
||||
const parse_node_tree_t::parse_node_list_t stmt_nodes =
|
||||
tree.find_nodes(tree.at(0), symbol_plain_statement);
|
||||
if (stmt_nodes.size() != 1) {
|
||||
say(L"Unexpected number of statements (%lu) found in '%ls'", stmt_nodes.size(),
|
||||
src.c_str());
|
||||
auto stmts = tnode_t<grammar::plain_statement>::find_nodes(&tree, &tree.at(0));
|
||||
if (stmts.size() != 1) {
|
||||
say(L"Unexpected number of statements (%lu) found in '%ls'", stmts.size(), src.c_str());
|
||||
return false;
|
||||
}
|
||||
const parse_node_t &stmt = *stmt_nodes.at(0);
|
||||
tnode_t<grammar::plain_statement> stmt = stmts.at(0);
|
||||
|
||||
// Return its decoration.
|
||||
*out_deco = tree.decoration_for_plain_statement(stmt);
|
||||
|
|
|
@ -166,7 +166,7 @@ class parse_node_tree_t : public std::vector<parse_node_t> {
|
|||
// Find all the nodes of a given type underneath a given node, up to max_count of them.
|
||||
typedef std::vector<const parse_node_t *> parse_node_list_t;
|
||||
parse_node_list_t find_nodes(const parse_node_t &parent, parse_token_type_t type,
|
||||
size_t max_count = (size_t)(-1)) const;
|
||||
size_t max_count = size_t(-1)) const;
|
||||
|
||||
// Finds the last node of a given type underneath a given node, or NULL if it could not be
|
||||
// found. If parent is NULL, this finds the last node in the tree of that type.
|
||||
|
@ -286,6 +286,14 @@ class tnode_t {
|
|||
return nodeptr && nodeptr->location_in_or_at_end_of_source_range(loc);
|
||||
}
|
||||
|
||||
static tnode_t find_node_matching_source_location(const parse_node_tree_t *tree,
|
||||
size_t source_loc,
|
||||
const parse_node_t *parent) {
|
||||
assert(tree && "null tree");
|
||||
return tnode_t{tree,
|
||||
tree->find_node_matching_source_location(Type::token, source_loc, parent)};
|
||||
}
|
||||
|
||||
/// Type-safe access to a child at the given index.
|
||||
template <node_offset_t Index>
|
||||
tnode_t<child_at<Type, Index>> child() const {
|
||||
|
@ -303,6 +311,20 @@ class tnode_t {
|
|||
if (!nodeptr) return {};
|
||||
return {tree, tree->get_parent(*nodeptr, ParentType::token)};
|
||||
}
|
||||
|
||||
static std::vector<tnode_t> find_nodes(const parse_node_tree_t *tree,
|
||||
const parse_node_t *parent,
|
||||
size_t max_count = size_t(-1)) {
|
||||
assert(tree && "null tree");
|
||||
assert(parent && "null parent");
|
||||
auto ptrs = tree->find_nodes(*parent, Type::token, max_count);
|
||||
std::vector<tnode_t> result;
|
||||
result.reserve(ptrs.size());
|
||||
for (const parse_node_t *np : ptrs) {
|
||||
result.emplace_back(tree, np);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.
|
||||
|
|
Loading…
Reference in New Issue
Block a user