mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Some adopton of tnode_t in complete.cpp
This commit is contained in:
parent
cfe355554c
commit
618996a166
3 changed files with 35 additions and 13 deletions
|
@ -1294,10 +1294,10 @@ 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--;
|
||||
}
|
||||
const parse_node_t *plain_statement = tree.find_node_matching_source_location(
|
||||
symbol_plain_statement, position_in_statement, NULL);
|
||||
|
||||
if (plain_statement == NULL) {
|
||||
auto plain_statement = tnode_t<grammar::plain_statement>{
|
||||
&tree, tree.find_node_matching_source_location(symbol_plain_statement,
|
||||
position_in_statement, NULL)};
|
||||
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
|
||||
// there was whitespace; don't do an autosuggestion in that case. Also don't do it if we
|
||||
|
@ -1327,15 +1327,14 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
}
|
||||
completer.complete_param_expand(current_token, do_file);
|
||||
} else {
|
||||
assert(plain_statement->has_source() &&
|
||||
plain_statement->type == symbol_plain_statement);
|
||||
assert(plain_statement && plain_statement.has_source());
|
||||
|
||||
// Get the command node.
|
||||
const parse_node_t *cmd_node =
|
||||
tree.get_child(*plain_statement, 0, parse_token_type_string);
|
||||
tnode_t<grammar::tok_string> cmd_node = plain_statement.child<0>();
|
||||
assert(cmd_node && cmd_node.has_source() && "Expected command node to be valid");
|
||||
|
||||
// Get the actual command string.
|
||||
if (cmd_node) current_command = cmd_node->get_source(cmd);
|
||||
current_command = cmd_node.get_source(cmd);
|
||||
|
||||
// Check the decoration.
|
||||
switch (tree.decoration_for_plain_statement(*plain_statement)) {
|
||||
|
@ -1363,7 +1362,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
}
|
||||
}
|
||||
|
||||
if (cmd_node && cmd_node->location_in_or_at_end_of_source_range(pos)) {
|
||||
if (cmd_node.location_in_or_at_end_of_source_range(pos)) {
|
||||
// Complete command filename.
|
||||
completer.complete_cmd(current_token, use_function, use_builtin, use_command,
|
||||
use_implicit_cd);
|
||||
|
@ -1394,7 +1393,7 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
// of the argument, then the current argument is the matching one, and the
|
||||
// previous argument is the one before it.
|
||||
bool cursor_in_whitespace =
|
||||
!plain_statement->location_in_or_at_end_of_source_range(pos);
|
||||
!plain_statement.location_in_or_at_end_of_source_range(pos);
|
||||
if (cursor_in_whitespace) {
|
||||
current_argument = L"";
|
||||
previous_argument = matching_arg;
|
||||
|
@ -1452,8 +1451,9 @@ void complete(const wcstring &cmd_with_subcmds, std::vector<completion_t> *out_c
|
|||
assert(wrap_chain.at(i) == current_command_unescape);
|
||||
} else if (!(flags & COMPLETION_REQUEST_AUTOSUGGESTION)) {
|
||||
wcstring faux_cmdline = cmd;
|
||||
faux_cmdline.replace(cmd_node->source_start,
|
||||
cmd_node->source_length, wrap_chain.at(i));
|
||||
faux_cmdline.replace(cmd_node.source_range()->start,
|
||||
cmd_node.source_range()->length,
|
||||
wrap_chain.at(i));
|
||||
transient_cmd = make_unique<builtin_commandline_scoped_transient_t>(
|
||||
faux_cmdline);
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ struct alternative {
|
|||
#define DEF_ALT(T) struct T : public alternative
|
||||
#define ALT_BODY(T) \
|
||||
BODY(T) \
|
||||
using type_tuple = std::tuple<>; \
|
||||
static const production_element_t *resolve(const parse_token_t &, const parse_token_t &, \
|
||||
parse_node_tag_t *);
|
||||
|
||||
|
|
|
@ -256,6 +256,14 @@ class tnode_t {
|
|||
assert((!n || n->type == Type::token) && "node has wrong type");
|
||||
}
|
||||
|
||||
/// Temporary conversion to parse_node_t to assist in migration.
|
||||
/* implicit */ operator const parse_node_t &() const {
|
||||
assert(nodeptr && "Empty tnode_t");
|
||||
return *nodeptr;
|
||||
}
|
||||
|
||||
/* implicit */ operator const parse_node_t *() const { return nodeptr; }
|
||||
|
||||
/// Return the underlying (type-erased) node.
|
||||
const parse_node_t *node() const { return nodeptr; }
|
||||
|
||||
|
@ -274,6 +282,10 @@ class tnode_t {
|
|||
return nodeptr->get_source(str);
|
||||
}
|
||||
|
||||
bool location_in_or_at_end_of_source_range(size_t loc) const {
|
||||
return nodeptr && nodeptr->location_in_or_at_end_of_source_range(loc);
|
||||
}
|
||||
|
||||
/// Type-safe access to a child at the given index.
|
||||
template <node_offset_t Index>
|
||||
tnode_t<child_at<Type, Index>> child() const {
|
||||
|
@ -282,6 +294,15 @@ class tnode_t {
|
|||
if (nodeptr) child = tree->get_child(*nodeptr, Index, child_type::token);
|
||||
return tnode_t<child_type>{tree, child};
|
||||
}
|
||||
|
||||
/// Type-safe access to a node's parent.
|
||||
/// If the parent exists and has type ParentType, return it.
|
||||
/// Otherwise return a missing tnode.
|
||||
template <class ParentType>
|
||||
tnode_t<ParentType> try_get_parent() const {
|
||||
if (!nodeptr) return {};
|
||||
return {tree, tree->get_parent(*nodeptr, ParentType::token)};
|
||||
}
|
||||
};
|
||||
|
||||
/// The big entry point. Parse a string, attempting to produce a tree for the given goal type.
|
||||
|
|
Loading…
Reference in a new issue