mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 21:33:09 +00:00
Eliminate the global list of scoped transient commandlines
Store this in a parser's libdata instead.
This commit is contained in:
parent
421cf92380
commit
1baa479bbf
5 changed files with 20 additions and 55 deletions
|
@ -85,24 +85,6 @@ wcstring_list_t builtin_get_names();
|
|||
void builtin_get_names(std::vector<completion_t> *list);
|
||||
const wchar_t *builtin_get_desc(const wcstring &b);
|
||||
|
||||
/// Support for setting and removing transient command lines. This is used by
|
||||
/// 'complete -C' in order to make the commandline builtin operate on the string
|
||||
/// to complete instead of operating on whatever is to be completed. It's also
|
||||
/// used by completion wrappers, to allow a command to appear as the command
|
||||
/// being wrapped for the purposes of completion.
|
||||
///
|
||||
/// Instantiating an instance of builtin_commandline_scoped_transient_t pushes
|
||||
/// the command as the new transient commandline. The destructor removes it. It
|
||||
/// will assert if construction/destruction does not happen in a stack-like
|
||||
/// (LIFO) order.
|
||||
class builtin_commandline_scoped_transient_t {
|
||||
size_t token;
|
||||
|
||||
public:
|
||||
explicit builtin_commandline_scoped_transient_t(const wcstring &cmd);
|
||||
~builtin_commandline_scoped_transient_t();
|
||||
};
|
||||
|
||||
wcstring builtin_help_get(parser_t &parser, const wchar_t *cmd);
|
||||
|
||||
void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "input.h"
|
||||
#include "io.h"
|
||||
#include "parse_util.h"
|
||||
#include "parser.h"
|
||||
#include "proc.h"
|
||||
#include "reader.h"
|
||||
#include "tokenizer.h"
|
||||
|
@ -35,36 +36,6 @@ enum {
|
|||
APPEND_MODE // insert at end of current token/command/buffer
|
||||
};
|
||||
|
||||
static owning_lock<wcstring_list_t> &get_transient_stack() {
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
static owning_lock<wcstring_list_t> s_transient_stack;
|
||||
return s_transient_stack;
|
||||
}
|
||||
|
||||
static bool get_top_transient(wcstring *out_result) {
|
||||
auto stack = get_transient_stack().acquire();
|
||||
if (stack->empty()) {
|
||||
return false;
|
||||
}
|
||||
out_result->assign(stack->back());
|
||||
return true;
|
||||
}
|
||||
|
||||
builtin_commandline_scoped_transient_t::builtin_commandline_scoped_transient_t(
|
||||
const wcstring &cmd) {
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
auto stack = get_transient_stack().acquire();
|
||||
stack->push_back(cmd);
|
||||
this->token = stack->size();
|
||||
}
|
||||
|
||||
builtin_commandline_scoped_transient_t::~builtin_commandline_scoped_transient_t() {
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
auto stack = get_transient_stack().acquire();
|
||||
assert(this->token == stack->size());
|
||||
stack->pop_back();
|
||||
}
|
||||
|
||||
/// Replace/append/insert the selection with/at/after the specified string.
|
||||
///
|
||||
/// \param begin beginning of selection
|
||||
|
@ -178,8 +149,10 @@ int builtin_commandline(parser_t &parser, io_streams_t &streams, wchar_t **argv)
|
|||
int paging_mode = 0;
|
||||
const wchar_t *begin = NULL, *end = NULL;
|
||||
|
||||
const auto &ld = parser.libdata();
|
||||
wcstring transient_commandline;
|
||||
if (get_top_transient(&transient_commandline)) {
|
||||
if (!ld.transient_commandlines.empty()) {
|
||||
transient_commandline = ld.transient_commandlines.back();
|
||||
current_buffer = transient_commandline.c_str();
|
||||
current_cursor_pos = transient_commandline.size();
|
||||
} else {
|
||||
|
|
|
@ -329,9 +329,10 @@ int builtin_complete(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0, 0,
|
||||
0);
|
||||
|
||||
// Create a scoped transient command line, so that bulitin_commandline will see our
|
||||
// Create a scoped transient command line, so that builtin_commandline will see our
|
||||
// argument, not the reader buffer.
|
||||
builtin_commandline_scoped_transient_t temp_buffer(do_complete_param);
|
||||
parser.libdata().transient_commandlines.push_back(do_complete_param);
|
||||
cleanup_t remove_transient([&] { parser.libdata().transient_commandlines.pop_back(); });
|
||||
|
||||
if (parser.libdata().builtin_complete_recursion_level < 1) {
|
||||
parser.libdata().builtin_complete_recursion_level++;
|
||||
|
|
|
@ -1557,15 +1557,19 @@ void completer_t::perform() {
|
|||
// Perhaps set a transient commandline so that custom completions
|
||||
// buitin_commandline will refer to the wrapped command. But not if
|
||||
// we're doing autosuggestions.
|
||||
std::unique_ptr<builtin_commandline_scoped_transient_t> bcst;
|
||||
if (depth > 0 && !(flags & completion_request_t::autosuggestion)) {
|
||||
bcst = make_unique<builtin_commandline_scoped_transient_t>(cmdline);
|
||||
bool wants_transient =
|
||||
depth > 0 && !(flags & completion_request_t::autosuggestion);
|
||||
if (wants_transient) {
|
||||
parser->libdata().transient_commandlines.push_back(cmdline);
|
||||
}
|
||||
// Now invoke any custom completions for this command.
|
||||
if (!complete_param(cmd, previous_argument_unescape,
|
||||
current_argument_unescape, !had_ddash)) {
|
||||
do_file = false;
|
||||
}
|
||||
if (wants_transient) {
|
||||
parser->libdata().transient_commandlines.pop_back();
|
||||
}
|
||||
};
|
||||
walk_wrap_chain(cmd, *cmd_node.source_range(), receiver);
|
||||
}
|
||||
|
|
|
@ -163,7 +163,12 @@ struct library_data_t {
|
|||
const wchar_t *current_filename{};
|
||||
|
||||
/// List of events that have been sent but have not yet been delivered because they are blocked.
|
||||
std::vector<shared_ptr<event_t>> blocked_events;
|
||||
std::vector<shared_ptr<event_t>> blocked_events{};
|
||||
|
||||
/// A stack of fake values to be returned by builtin_commandline. This is used by the completion
|
||||
/// machinery when wrapping: e.g. if `tig` wraps `git` then git completions need to see git on
|
||||
/// the command line.
|
||||
wcstring_list_t transient_commandlines{};
|
||||
};
|
||||
|
||||
class parser_t : public std::enable_shared_from_this<parser_t> {
|
||||
|
|
Loading…
Reference in a new issue