mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
Autodetect common escape codes in fish_prompt output
darcs-hash:20051213101859-ac50b-0ff01bb168d894d401d3d93cc11740789bac0d62.gz
This commit is contained in:
parent
9c32709fe1
commit
8bf0a14bd5
|
@ -915,17 +915,11 @@ The default \c fish prompt is
|
|||
<p>
|
||||
<pre>
|
||||
function fish_prompt -d "Write out the prompt"
|
||||
printf '\%s\@\%s\%s\\n\%s\%s\\n> ' (whoami) (hostname|cut -d . -f 1) (set_color \$fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
printf '\%s\@\%s\%s\%s\%s> ' (whoami) (hostname|cut -d . -f 1) (set_color \$fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
end
|
||||
</pre>
|
||||
</p>
|
||||
|
||||
If you are using \c set_color or other commands that output escape
|
||||
codes to change the font settings of the terminal, you must always and
|
||||
every such sequence with a newline. This is needed since fish needs to
|
||||
know that exact length of the prompt in order to tetect when the
|
||||
cursor reaches the end of the line. Any newlines in the output of the
|
||||
\c fish_prompt command are ignored.
|
||||
|
||||
\subsection title Programmable title
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ end
|
|||
# long it is.
|
||||
|
||||
function fish_prompt -d "Write out the prompt"
|
||||
printf '%s@%s \n%s\n%s\n%s\n> ' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
printf '%s@%s %s%s%s> \n' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
|
||||
end
|
||||
|
||||
#
|
||||
|
|
2
output.c
2
output.c
|
@ -128,7 +128,7 @@ void set_color( int c, int c2 )
|
|||
{
|
||||
c = c2 = FISH_COLOR_NORMAL;
|
||||
if( fg )
|
||||
writembs( tparm( set_a_foreground, 0 ) );
|
||||
writembs( tparm( fg, 0 ) );
|
||||
writembs( exit_attribute_mode );
|
||||
return;
|
||||
}
|
||||
|
|
137
reader.c
137
reader.c
|
@ -620,6 +620,129 @@ void reader_write_title()
|
|||
set_color( FISH_COLOR_RESET, FISH_COLOR_RESET );
|
||||
}
|
||||
|
||||
/**
|
||||
Tests if the specified narrow character sequence is present at the
|
||||
specified position of the specified wide character string. All of
|
||||
\c seq must match, but str may be longer than seq.
|
||||
*/
|
||||
static int try_sequence( char *seq, wchar_t *str )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0;; i++ )
|
||||
{
|
||||
if( !seq[i] )
|
||||
return i;
|
||||
|
||||
if( seq[i] != str[i] )
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the width of the specified prompt. Does some clever magic
|
||||
to detect common escape sequences that may be embeded in a prompt,
|
||||
such as color codes.
|
||||
*/
|
||||
static int calc_prompt_width( array_list_t *arr )
|
||||
{
|
||||
int res = 0;
|
||||
int i, j, k;
|
||||
|
||||
for( i=0; i<al_get_count( arr ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( arr, i );
|
||||
|
||||
for( j=0; next[j]; j++ )
|
||||
{
|
||||
if( next[j] == L'\e' )
|
||||
{
|
||||
/*
|
||||
This is the start of an escape code. Try to guess it's width.
|
||||
*/
|
||||
int l;
|
||||
int len=0;
|
||||
int found = 0;
|
||||
|
||||
/*
|
||||
Test these color escapes with parameter value 0..7
|
||||
*/
|
||||
char * esc[] =
|
||||
{
|
||||
set_a_foreground,
|
||||
set_a_background,
|
||||
set_foreground,
|
||||
set_background,
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
Test these regular escapes without any parameter values
|
||||
*/
|
||||
char *esc2[] =
|
||||
{
|
||||
enter_bold_mode,
|
||||
exit_attribute_mode,
|
||||
enter_underline_mode,
|
||||
exit_underline_mode,
|
||||
enter_standout_mode,
|
||||
exit_standout_mode,
|
||||
flash_screen
|
||||
}
|
||||
;
|
||||
|
||||
for( l=0; l < (sizeof(esc)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc[l] )
|
||||
continue;
|
||||
|
||||
for( k=0; k<8; k++ )
|
||||
{
|
||||
len = try_sequence( tparm(esc[l],k), &next[j] );
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( l=0; l < (sizeof(esc2)/sizeof(char *)) && !found; l++ )
|
||||
{
|
||||
if( !esc2[l] )
|
||||
continue;
|
||||
/*
|
||||
Test both padded and unpadded version, just to
|
||||
be safe. Most versions of tparm don't actually
|
||||
seem to do anything these days.
|
||||
*/
|
||||
len = maxi( try_sequence( tparm(esc2[l]), &next[j] ),
|
||||
try_sequence( esc2[l], &next[j] ));
|
||||
|
||||
if( len )
|
||||
{
|
||||
j += (len-1);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Ordinary decent character. Just add width.
|
||||
*/
|
||||
res += wcwidth( next[j] );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Write the prompt to screen. If data->exec_prompt is set, the prompt
|
||||
command is first evaluated, and the title will be reexecuted as
|
||||
|
@ -649,14 +772,8 @@ static void write_prompt()
|
|||
al_init( &prompt_list );
|
||||
}
|
||||
}
|
||||
data->prompt_width=0;
|
||||
for( i=0; i<al_get_count( &prompt_list ); i++ )
|
||||
{
|
||||
wchar_t *next = (wchar_t *)al_get( &prompt_list, i );
|
||||
if( *next == L'\e' )
|
||||
continue;
|
||||
data->prompt_width += my_wcswidth( next );
|
||||
}
|
||||
|
||||
data->prompt_width=calc_prompt_width( &prompt_list );
|
||||
|
||||
data->exec_prompt = 0;
|
||||
reader_write_title();
|
||||
|
@ -2509,9 +2626,7 @@ wchar_t *reader_readline()
|
|||
if( last_char != R_YANK && last_char != R_YANK_POP )
|
||||
yank=0;
|
||||
|
||||
|
||||
|
||||
switch (c)
|
||||
switch( c )
|
||||
{
|
||||
|
||||
/* go to beginning of line*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user