mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 13:39:02 +00:00
Change to make the lookahead array a std::stack instead of a static 4k list(!)
This commit is contained in:
parent
464f1f44aa
commit
e152cfac34
3 changed files with 65 additions and 47 deletions
|
@ -14,6 +14,8 @@ Implementation file for the low level input library
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#include <stack>
|
||||||
|
#include <list>
|
||||||
#ifdef HAVE_SYS_SELECT_H
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,15 +36,30 @@ Implementation file for the low level input library
|
||||||
*/
|
*/
|
||||||
#define WAIT_ON_ESCAPE 10
|
#define WAIT_ON_ESCAPE 10
|
||||||
|
|
||||||
/**
|
/** Characters that have been read and returned by the sequence matching code */
|
||||||
Characters that have been read and returned by the sequence matching code
|
static std::stack<wint_t, std::list<wint_t> > lookahead_list;
|
||||||
*/
|
|
||||||
static wint_t lookahead_arr[1024];
|
|
||||||
|
|
||||||
/**
|
static bool has_lookahead(void)
|
||||||
Number of entries in lookahead_arr
|
{
|
||||||
*/
|
return ! lookahead_list.empty();
|
||||||
static int lookahead_count = 0;
|
}
|
||||||
|
|
||||||
|
static wint_t lookahead_pop(void)
|
||||||
|
{
|
||||||
|
wint_t result = lookahead_list.top();
|
||||||
|
lookahead_list.pop();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lookahead_push(wint_t c)
|
||||||
|
{
|
||||||
|
lookahead_list.push(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static wint_t lookahead_top(void)
|
||||||
|
{
|
||||||
|
return lookahead_list.top();
|
||||||
|
}
|
||||||
|
|
||||||
/** Callback function for handling interrupts on reading */
|
/** Callback function for handling interrupts on reading */
|
||||||
static int (*interrupt_handler)();
|
static int (*interrupt_handler)();
|
||||||
|
@ -115,9 +132,9 @@ static wint_t readb()
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (lookahead_count)
|
if (has_lookahead())
|
||||||
{
|
{
|
||||||
return lookahead_arr[--lookahead_count];
|
return lookahead_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -144,18 +161,18 @@ static wint_t readb()
|
||||||
{
|
{
|
||||||
debug(3, L"Wake up on universal variable event");
|
debug(3, L"Wake up on universal variable event");
|
||||||
env_universal_read_all();
|
env_universal_read_all();
|
||||||
if (lookahead_count)
|
if (has_lookahead())
|
||||||
{
|
{
|
||||||
return lookahead_arr[--lookahead_count];
|
return lookahead_pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioport > 0 && FD_ISSET(ioport, &fdset))
|
if (ioport > 0 && FD_ISSET(ioport, &fdset))
|
||||||
{
|
{
|
||||||
iothread_service_completion();
|
iothread_service_completion();
|
||||||
if (lookahead_count)
|
if (has_lookahead())
|
||||||
{
|
{
|
||||||
return lookahead_arr[--lookahead_count];
|
return lookahead_pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +196,7 @@ static wint_t readb()
|
||||||
|
|
||||||
wchar_t input_common_readch(int timed)
|
wchar_t input_common_readch(int timed)
|
||||||
{
|
{
|
||||||
if (lookahead_count == 0)
|
if (! has_lookahead())
|
||||||
{
|
{
|
||||||
if (timed)
|
if (timed)
|
||||||
{
|
{
|
||||||
|
@ -247,19 +264,19 @@ wchar_t input_common_readch(int timed)
|
||||||
{
|
{
|
||||||
if (!timed)
|
if (!timed)
|
||||||
{
|
{
|
||||||
while ((lookahead_count >= 0) && (lookahead_arr[lookahead_count-1] == WEOF))
|
while (has_lookahead() && lookahead_top() == WEOF)
|
||||||
lookahead_count--;
|
lookahead_pop();
|
||||||
if (lookahead_count == 0)
|
if (! has_lookahead())
|
||||||
return input_common_readch(0);
|
return input_common_readch(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lookahead_arr[--lookahead_count];
|
return lookahead_pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void input_common_unreadch(wint_t ch)
|
void input_common_unreadch(wint_t ch)
|
||||||
{
|
{
|
||||||
lookahead_arr[lookahead_count++] = ch;
|
lookahead_push(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
46
screen.cpp
46
screen.cpp
|
@ -175,7 +175,7 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
size_t res = 0;
|
size_t res = 0;
|
||||||
size_t j, k;
|
size_t j, k;
|
||||||
*out_prompt_lines = 1;
|
*out_prompt_lines = 1;
|
||||||
|
|
||||||
for (j=0; prompt[j]; j++)
|
for (j=0; prompt[j]; j++)
|
||||||
{
|
{
|
||||||
if (prompt[j] == L'\x1b')
|
if (prompt[j] == L'\x1b')
|
||||||
|
@ -186,7 +186,7 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
size_t p;
|
size_t p;
|
||||||
int len=0;
|
int len=0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Detect these terminfo color escapes with parameter
|
Detect these terminfo color escapes with parameter
|
||||||
value 0..7, all of which don't move the cursor
|
value 0..7, all of which don't move the cursor
|
||||||
|
@ -199,7 +199,7 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
set_background,
|
set_background,
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Detect these semi-common terminfo escapes without any
|
Detect these semi-common terminfo escapes without any
|
||||||
parameter values, all of which don't move the cursor
|
parameter values, all of which don't move the cursor
|
||||||
|
@ -228,12 +228,12 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
enter_secure_mode
|
enter_secure_mode
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
for (p=0; p < sizeof esc / sizeof *esc && !found; p++)
|
for (p=0; p < sizeof esc / sizeof *esc && !found; p++)
|
||||||
{
|
{
|
||||||
if (!esc[p])
|
if (!esc[p])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (k=0; k<8; k++)
|
for (k=0; k<8; k++)
|
||||||
{
|
{
|
||||||
len = try_sequence(tparm(esc[p],k), &prompt[j]);
|
len = try_sequence(tparm(esc[p],k), &prompt[j]);
|
||||||
|
@ -245,7 +245,7 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PCA for term256 support, let's just detect the escape codes directly */
|
/* PCA for term256 support, let's just detect the escape codes directly */
|
||||||
if (! found)
|
if (! found)
|
||||||
{
|
{
|
||||||
|
@ -256,8 +256,8 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (p=0; p < (sizeof(esc2)/sizeof(char *)) && !found; p++)
|
for (p=0; p < (sizeof(esc2)/sizeof(char *)) && !found; p++)
|
||||||
{
|
{
|
||||||
if (!esc2[p])
|
if (!esc2[p])
|
||||||
|
@ -269,14 +269,14 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
*/
|
*/
|
||||||
len = maxi(try_sequence(tparm(esc2[p]), &prompt[j]),
|
len = maxi(try_sequence(tparm(esc2[p]), &prompt[j]),
|
||||||
try_sequence(esc2[p], &prompt[j]));
|
try_sequence(esc2[p], &prompt[j]));
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
j += (len-1);
|
j += (len-1);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
if (prompt[j+1] == L'k')
|
if (prompt[j+1] == L'k')
|
||||||
|
@ -307,7 +307,7 @@ static size_t calc_prompt_width_and_lines(const wchar_t *prompt, size_t *out_pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (prompt[j] == L'\t')
|
else if (prompt[j] == L'\t')
|
||||||
{
|
{
|
||||||
|
@ -1173,40 +1173,40 @@ void s_write(screen_t *s,
|
||||||
void s_reset(screen_t *s, screen_reset_mode_t mode)
|
void s_reset(screen_t *s, screen_reset_mode_t mode)
|
||||||
{
|
{
|
||||||
CHECK(s,);
|
CHECK(s,);
|
||||||
|
|
||||||
bool abandon_line = false, repaint_prompt = false, clear_to_eos = false;
|
bool abandon_line = false, repaint_prompt = false, clear_to_eos = false;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case screen_reset_current_line_contents:
|
case screen_reset_current_line_contents:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case screen_reset_current_line_and_prompt:
|
case screen_reset_current_line_and_prompt:
|
||||||
repaint_prompt = true;
|
repaint_prompt = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case screen_reset_abandon_line:
|
case screen_reset_abandon_line:
|
||||||
abandon_line = true;
|
abandon_line = true;
|
||||||
repaint_prompt = true;
|
repaint_prompt = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case screen_reset_abandon_line_and_clear_to_end_of_screen:
|
case screen_reset_abandon_line_and_clear_to_end_of_screen:
|
||||||
abandon_line = true;
|
abandon_line = true;
|
||||||
repaint_prompt = true;
|
repaint_prompt = true;
|
||||||
clear_to_eos = true;
|
clear_to_eos = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're abandoning the line, we must also be repainting the prompt */
|
/* If we're abandoning the line, we must also be repainting the prompt */
|
||||||
assert(! abandon_line || repaint_prompt);
|
assert(! abandon_line || repaint_prompt);
|
||||||
|
|
||||||
/* If we are not abandoning the line, we need to remember how many lines we had output to, so we can clear the remaining lines in the next call to s_update. This prevents leaving junk underneath the cursor when resizing a window wider such that it reduces our desired line count. */
|
/* If we are not abandoning the line, we need to remember how many lines we had output to, so we can clear the remaining lines in the next call to s_update. This prevents leaving junk underneath the cursor when resizing a window wider such that it reduces our desired line count. */
|
||||||
if (! abandon_line)
|
if (! abandon_line)
|
||||||
{
|
{
|
||||||
s->actual_lines_before_reset = maxi(s->actual_lines_before_reset, s->actual.line_count());
|
s->actual_lines_before_reset = maxi(s->actual_lines_before_reset, s->actual.line_count());
|
||||||
}
|
}
|
||||||
|
|
||||||
int prev_line = s->actual.cursor.y;
|
int prev_line = s->actual.cursor.y;
|
||||||
|
|
||||||
if (repaint_prompt)
|
if (repaint_prompt)
|
||||||
{
|
{
|
||||||
/* If the prompt is multi-line, we need to move up to the prompt's initial line. We do this by lying to ourselves and claiming that we're really below what we consider "line 0" (which is the last line of the prompt). This will cause is to move up to try to get back to line 0, but really we're getting back to the initial line of the prompt. */
|
/* If the prompt is multi-line, we need to move up to the prompt's initial line. We do this by lying to ourselves and claiming that we're really below what we consider "line 0" (which is the last line of the prompt). This will cause is to move up to try to get back to line 0, but really we're getting back to the initial line of the prompt. */
|
||||||
|
@ -1217,21 +1217,21 @@ void s_reset(screen_t *s, screen_reset_mode_t mode)
|
||||||
/* Clear the prompt */
|
/* Clear the prompt */
|
||||||
s->actual_left_prompt.clear();
|
s->actual_left_prompt.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
s->actual.resize(0);
|
s->actual.resize(0);
|
||||||
s->actual.cursor.x = 0;
|
s->actual.cursor.x = 0;
|
||||||
s->actual.cursor.y = 0;
|
s->actual.cursor.y = 0;
|
||||||
|
|
||||||
s->need_clear_lines = true;
|
s->need_clear_lines = true;
|
||||||
s->need_clear_screen = s->need_clear_screen || clear_to_eos;
|
s->need_clear_screen = s->need_clear_screen || clear_to_eos;
|
||||||
|
|
||||||
if (!abandon_line)
|
if (!abandon_line)
|
||||||
{
|
{
|
||||||
/* This should prevent reseting the cursor position during the next repaint. */
|
/* This should prevent reseting the cursor position during the next repaint. */
|
||||||
write_loop(1, "\r", 1);
|
write_loop(1, "\r", 1);
|
||||||
s->actual.cursor.y = prev_line;
|
s->actual.cursor.y = prev_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
fstat(1, &s->prev_buff_1);
|
fstat(1, &s->prev_buff_1);
|
||||||
fstat(2, &s->prev_buff_2);
|
fstat(2, &s->prev_buff_2);
|
||||||
}
|
}
|
||||||
|
|
9
screen.h
9
screen.h
|
@ -149,7 +149,7 @@ public:
|
||||||
actual_lines_before_reset.
|
actual_lines_before_reset.
|
||||||
*/
|
*/
|
||||||
bool need_clear_lines;
|
bool need_clear_lines;
|
||||||
|
|
||||||
/** Whether there may be yet more content after the lines, and we issue a clr_eos if possible. */
|
/** Whether there may be yet more content after the lines, and we issue a clr_eos if possible. */
|
||||||
bool need_clear_screen;
|
bool need_clear_screen;
|
||||||
|
|
||||||
|
@ -217,16 +217,17 @@ void s_write(screen_t *s,
|
||||||
void s_reset(screen_t *s, bool reset_cursor, bool reset_prompt = true);
|
void s_reset(screen_t *s, bool reset_cursor, bool reset_prompt = true);
|
||||||
|
|
||||||
|
|
||||||
enum screen_reset_mode_t {
|
enum screen_reset_mode_t
|
||||||
|
{
|
||||||
/* Do not make a new line, do not repaint the prompt. */
|
/* Do not make a new line, do not repaint the prompt. */
|
||||||
screen_reset_current_line_contents,
|
screen_reset_current_line_contents,
|
||||||
|
|
||||||
/* Do not make a new line, do repaint the prompt. */
|
/* Do not make a new line, do repaint the prompt. */
|
||||||
screen_reset_current_line_and_prompt,
|
screen_reset_current_line_and_prompt,
|
||||||
|
|
||||||
/* Abandon the current line, go to the next one, repaint the prompt */
|
/* Abandon the current line, go to the next one, repaint the prompt */
|
||||||
screen_reset_abandon_line,
|
screen_reset_abandon_line,
|
||||||
|
|
||||||
/* Abandon the current line, go to the next one, clear the rest of the screen */
|
/* Abandon the current line, go to the next one, clear the rest of the screen */
|
||||||
screen_reset_abandon_line_and_clear_to_end_of_screen
|
screen_reset_abandon_line_and_clear_to_end_of_screen
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue