mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 22:03:12 +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);
|
void builtin_get_names(std::vector<completion_t> *list);
|
||||||
const wchar_t *builtin_get_desc(const wcstring &b);
|
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);
|
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,
|
void builtin_print_help(parser_t &parser, io_streams_t &streams, const wchar_t *cmd,
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "parse_util.h"
|
#include "parse_util.h"
|
||||||
|
#include "parser.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
#include "reader.h"
|
#include "reader.h"
|
||||||
#include "tokenizer.h"
|
#include "tokenizer.h"
|
||||||
|
@ -35,36 +36,6 @@ enum {
|
||||||
APPEND_MODE // insert at end of current token/command/buffer
|
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.
|
/// Replace/append/insert the selection with/at/after the specified string.
|
||||||
///
|
///
|
||||||
/// \param begin beginning of selection
|
/// \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;
|
int paging_mode = 0;
|
||||||
const wchar_t *begin = NULL, *end = NULL;
|
const wchar_t *begin = NULL, *end = NULL;
|
||||||
|
|
||||||
|
const auto &ld = parser.libdata();
|
||||||
wcstring transient_commandline;
|
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_buffer = transient_commandline.c_str();
|
||||||
current_cursor_pos = transient_commandline.size();
|
current_cursor_pos = transient_commandline.size();
|
||||||
} else {
|
} 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,
|
parse_util_token_extent(do_complete_param.c_str(), do_complete_param.size(), &token, 0, 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.
|
// 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) {
|
if (parser.libdata().builtin_complete_recursion_level < 1) {
|
||||||
parser.libdata().builtin_complete_recursion_level++;
|
parser.libdata().builtin_complete_recursion_level++;
|
||||||
|
|
|
@ -1557,15 +1557,19 @@ void completer_t::perform() {
|
||||||
// Perhaps set a transient commandline so that custom completions
|
// Perhaps set a transient commandline so that custom completions
|
||||||
// buitin_commandline will refer to the wrapped command. But not if
|
// buitin_commandline will refer to the wrapped command. But not if
|
||||||
// we're doing autosuggestions.
|
// we're doing autosuggestions.
|
||||||
std::unique_ptr<builtin_commandline_scoped_transient_t> bcst;
|
bool wants_transient =
|
||||||
if (depth > 0 && !(flags & completion_request_t::autosuggestion)) {
|
depth > 0 && !(flags & completion_request_t::autosuggestion);
|
||||||
bcst = make_unique<builtin_commandline_scoped_transient_t>(cmdline);
|
if (wants_transient) {
|
||||||
|
parser->libdata().transient_commandlines.push_back(cmdline);
|
||||||
}
|
}
|
||||||
// Now invoke any custom completions for this command.
|
// Now invoke any custom completions for this command.
|
||||||
if (!complete_param(cmd, previous_argument_unescape,
|
if (!complete_param(cmd, previous_argument_unescape,
|
||||||
current_argument_unescape, !had_ddash)) {
|
current_argument_unescape, !had_ddash)) {
|
||||||
do_file = false;
|
do_file = false;
|
||||||
}
|
}
|
||||||
|
if (wants_transient) {
|
||||||
|
parser->libdata().transient_commandlines.pop_back();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
walk_wrap_chain(cmd, *cmd_node.source_range(), receiver);
|
walk_wrap_chain(cmd, *cmd_node.source_range(), receiver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,12 @@ struct library_data_t {
|
||||||
const wchar_t *current_filename{};
|
const wchar_t *current_filename{};
|
||||||
|
|
||||||
/// List of events that have been sent but have not yet been delivered because they are blocked.
|
/// 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> {
|
class parser_t : public std::enable_shared_from_this<parser_t> {
|
||||||
|
|
Loading…
Reference in a new issue