mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-20 05:41:14 -03:00
Let read read from fds other than 0
This allows read </dev/tty to work. Fixes #7358
This commit is contained in:
@@ -609,7 +609,7 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
|
||||
reader_data_t(std::shared_ptr<parser_t> parser, history_t *hist, reader_config_t &&conf)
|
||||
: conf(std::move(conf)),
|
||||
parser_ref(std::move(parser)),
|
||||
inputter(*parser_ref),
|
||||
inputter(*parser_ref, conf.stdin),
|
||||
history(hist) {}
|
||||
|
||||
void update_buff_pos(editable_line_t *el, maybe_t<size_t> new_pos = none_t());
|
||||
@@ -2122,7 +2122,7 @@ static void reader_interactive_init(parser_t &parser) {
|
||||
}
|
||||
|
||||
// Configure terminal attributes
|
||||
if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &shell_modes) == -1) {
|
||||
if (errno == EIO) {
|
||||
redirect_tty_output();
|
||||
}
|
||||
@@ -2700,7 +2700,7 @@ maybe_t<char_event_t> reader_data_t::read_normal_chars(readline_loop_state_t &rl
|
||||
while (accumulated_chars.size() < limit) {
|
||||
bool allow_commands = (accumulated_chars.empty());
|
||||
auto evt = inputter.readch(allow_commands);
|
||||
if (!event_is_normal_char(evt) || !can_read(STDIN_FILENO)) {
|
||||
if (!event_is_normal_char(evt) || !can_read(conf.stdin)) {
|
||||
event_needing_handling = std::move(evt);
|
||||
break;
|
||||
} else if (evt.input_style == char_input_style_t::notfirst && accumulated_chars.empty() &&
|
||||
@@ -3636,8 +3636,10 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
|
||||
|
||||
/// A helper that kicks off syntax highlighting, autosuggestion computing, and repaints.
|
||||
auto color_suggest_repaint_now = [this] {
|
||||
this->update_autosuggestion();
|
||||
this->super_highlight_me_plenty();
|
||||
if (conf.stdin == STDIN_FILENO) {
|
||||
this->update_autosuggestion();
|
||||
this->super_highlight_me_plenty();
|
||||
}
|
||||
if (this->is_repaint_needed()) this->layout_and_repaint(L"toplevel");
|
||||
this->force_exec_prompt_and_repaint = false;
|
||||
};
|
||||
@@ -3646,10 +3648,10 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
|
||||
force_exec_prompt_and_repaint = true;
|
||||
|
||||
// Get the current terminal modes. These will be restored when the function returns.
|
||||
if (tcgetattr(STDIN_FILENO, &old_modes) == -1 && errno == EIO) redirect_tty_output();
|
||||
if (tcgetattr(conf.stdin, &old_modes) == -1 && errno == EIO) redirect_tty_output();
|
||||
|
||||
// Set the new modes.
|
||||
if (tcsetattr(0, TCSANOW, &shell_modes) == -1) {
|
||||
if (tcsetattr(conf.stdin, TCSANOW, &shell_modes) == -1) {
|
||||
int err = errno;
|
||||
if (err == EIO) {
|
||||
redirect_tty_output();
|
||||
@@ -3756,7 +3758,7 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
|
||||
|
||||
// Redraw the command line. This is what ensures the autosuggestion is hidden, etc. after the
|
||||
// user presses enter.
|
||||
if (this->is_repaint_needed()) this->layout_and_repaint(L"prepare to execute");
|
||||
if (this->is_repaint_needed() || conf.stdin != STDIN_FILENO) this->layout_and_repaint(L"prepare to execute");
|
||||
|
||||
// Emit a newline so that the output is on the line after the command.
|
||||
// But do not emit a newline if the cursor has wrapped onto a new line all its own - see #6826.
|
||||
@@ -3764,6 +3766,12 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
|
||||
ignore_result(write(STDOUT_FILENO, "\n", 1));
|
||||
}
|
||||
|
||||
// HACK: If stdin isn't the same terminal as stdout, we just moved the cursor.
|
||||
// For now, just reset it to the beginning of the line.
|
||||
if (conf.stdin != STDIN_FILENO) {
|
||||
ignore_result(write(STDOUT_FILENO, "\r", 1));
|
||||
}
|
||||
|
||||
// Ensure we have no pager contents when we exit.
|
||||
if (!pager.empty()) {
|
||||
// Clear to end of screen to erase the pager contents.
|
||||
@@ -3775,7 +3783,7 @@ maybe_t<wcstring> reader_data_t::readline(int nchars_or_0) {
|
||||
if (s_exit_state != exit_state_t::finished_handlers) {
|
||||
// The order of the two conditions below is important. Try to restore the mode
|
||||
// in all cases, but only complain if interactive.
|
||||
if (tcsetattr(0, TCSANOW, &old_modes) == -1 &&
|
||||
if (tcsetattr(conf.stdin, TCSANOW, &old_modes) == -1 &&
|
||||
session_interactivity() != session_interactivity_t::not_interactive) {
|
||||
if (errno == EIO) redirect_tty_output();
|
||||
wperror(L"tcsetattr"); // return to previous mode
|
||||
|
||||
Reference in New Issue
Block a user