コード例 #1
0
ファイル: screen.cpp プロジェクト: ridiculousfish/fish-shell
/// Calculate layout information for the given prompt. Does some clever magic to detect common
/// escape sequences that may be embeded in a prompt, such as those to set visual attributes.
static prompt_layout_t calc_prompt_layout(const wcstring &prompt, layout_cache_t &cache) {
    if (auto cached_layout = cache.find_prompt_layout(prompt)) {
        return *cached_layout;
    }

    prompt_layout_t prompt_layout = {1, 0, 0};
    size_t current_line_width = 0;

    for (int j = 0; prompt[j]; j++) {
        if (prompt[j] == L'\x1B') {
            // This is the start of an escape code. Skip over it if it's at least one char long.
            size_t len = escape_code_length(&prompt[j]);
            if (len > 0) j += len - 1;
        } else if (prompt[j] == L'\t') {
            current_line_width = next_tab_stop(current_line_width);
        } else if (prompt[j] == L'\n' || prompt[j] == L'\f') {
            // PCA: At least one prompt uses \f\r as a newline. It's unclear to me what this is
            // meant to do, but terminals seem to treat it as a newline so we do the same.
            current_line_width = 0;
            prompt_layout.line_count += 1;
        } else if (prompt[j] == L'\r') {
            current_line_width = 0;
        } else {
            // Ordinary char. Add its width with care to ignore control chars which have width -1.
            current_line_width += fish_wcwidth_min_0(prompt[j]);
            if (current_line_width > prompt_layout.max_line_width) {
                prompt_layout.max_line_width = current_line_width;
            }
        }
    }
    prompt_layout.last_line_width = current_line_width;
    cache.add_prompt_layout(prompt, prompt_layout);
    return prompt_layout;
}
コード例 #2
0
ファイル: screen.cpp プロジェクト: AlexShiLucky/fish-shell
/// Calculate layout information for the given prompt. Does some clever magic to detect common
/// escape sequences that may be embeded in a prompt, such as color codes.
static prompt_layout_t calc_prompt_layout(const wchar_t *prompt) {
    size_t current_line_width = 0;
    size_t j;

    prompt_layout_t prompt_layout = {};
    prompt_layout.line_count = 1;

    for (j = 0; prompt[j]; j++) {
        if (prompt[j] == L'\x1b') {
            // This is the start of an escape code. Skip over it if it's at least one character
            // long.
            size_t escape_len = escape_code_length(&prompt[j]);
            if (escape_len > 0) {
                j += escape_len - 1;
            }
        } else if (prompt[j] == L'\t') {
            current_line_width = next_tab_stop(current_line_width);
        } else if (prompt[j] == L'\n' || prompt[j] == L'\f') {
            // PCA: At least one prompt uses \f\r as a newline. It's unclear to me what this is
            // meant to do, but terminals seem to treat it as a newline so we do the same.
            current_line_width = 0;
            prompt_layout.line_count += 1;
        } else if (prompt[j] == L'\r') {
            current_line_width = 0;
        } else {
            // Ordinary decent character. Just add width. This returns -1 for a control character -
            // don't add that.
            current_line_width += fish_wcwidth_min_0(prompt[j]);
            prompt_layout.max_line_width = maxi(prompt_layout.max_line_width, current_line_width);
        }
    }
    prompt_layout.last_line_width = current_line_width;
    return prompt_layout;
}
コード例 #3
0
ファイル: ex_5_12_entab.c プロジェクト: clockmaker002/kandr2
int main(int argc, char *argv[])
{
    int column = 0;
    int space_run = 0;
    int c;
    if (argc > 1) {
        argv++;
        while (argv[0]) {
            if (argv[0][0] == '-')
                to_i(&argv[0][1], &tab_start);
            if (argv[0][0] == '+')
                to_i(&argv[0][1], &tab_width);
            argv++;
        }
    }

    while ((c = getchar()) != EOF) {
        if (c == ' ') {
            ++space_run;
        }
        else if (c == '\n') {
            column = -1;
            space_run = 0;
            putchar(c);
        } else {
            if (space_run == 1) {
                putchar(' ');
                space_run = 0;
            }
            while (space_run > 0) {
                int start_of_space_run = column - space_run;
                int next_stop = next_tab_stop(start_of_space_run);
                if (next_stop <= column) {
                    putchar('\t');
                    space_run -= next_stop - start_of_space_run;
                } else {
                    for (; space_run > 0; space_run--)
                        putchar(' ');
                }
            }

            putchar(c);
        }
        ++column;
    }
}
コード例 #4
0
ファイル: screen.c プロジェクト: brentdax/fishfish
/**
   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( wchar_t *prompt )
{
	int res = 0;
	int j, k;

	for( j=0; prompt[j]; j++ )
	{
		if( prompt[j] == L'\x1b' )
		{
			/*
			  This is the start of an escape code. Try to guess it's width.
			*/
			int l;
			int len=0;
			int found = 0;

			/*
			  Detect these terminfo color escapes with parameter
			  value 0..7, all of which don't move the cursor
			*/
			char * esc[] =
				{
					set_a_foreground,
					set_a_background,
					set_foreground,
					set_background,
				}
			;

			/*
			  Detect these semi-common terminfo escapes without any
			  parameter values, all of which don't move the cursor
			*/
			char *esc2[] =
				{
					enter_bold_mode,
					exit_attribute_mode,
					enter_underline_mode,
					exit_underline_mode,
					enter_standout_mode,
					exit_standout_mode,
					flash_screen,
					enter_subscript_mode,
					exit_subscript_mode,
					enter_superscript_mode,
					exit_superscript_mode,
					enter_blink_mode,
					enter_italics_mode,
					exit_italics_mode,
					enter_reverse_mode,
					enter_shadow_mode,
					exit_shadow_mode,
					enter_standout_mode,
					exit_standout_mode,
					enter_secure_mode
				}
			;

			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), &prompt[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]), &prompt[j] ),
					    try_sequence( esc2[l], &prompt[j] ));

				if( len )
				{
					j += (len-1);
					found = 1;
				}
			}

			if( !found )
			{
				if( prompt[j+1] == L'k' )
				{
					wchar_t *term_name = env_get( L"TERM" );
					if( term_name && wcsstr( term_name, L"screen" ) == term_name )
					{
						wchar_t *end;
						j+=2;
						found = 1;
						end = wcsstr( &prompt[j], L"\x1b\\" );
						if( end )
						{
							/*
							  You'd thing this should be
							  '(end-prompt)+2', in order to move j
							  past the end of the string, but there is
							  a 'j++' at the end of each lap, so j
							  should always point to the last menged
							  character, e.g. +1.
							*/
							j = (end-prompt)+1;
						}
						else
						{
							break;
						}
					}
				}
			}

		}
		else if( prompt[j] == L'\t' )
		{
			res = next_tab_stop( res );
		}
		else if( prompt[j] == L'\n' )
		{
			res = 0;
		}
		else
		{
			/*
			  Ordinary decent character. Just add width.
			*/
			res += wcwidth( prompt[j] );
		}
	}
	return res;
}
コード例 #5
0
ファイル: screen.cpp プロジェクト: NewXX/fish-shell
/**
   Calculate layout information for the given prompt. Does some clever magic
   to detect common escape sequences that may be embeded in a prompt,
   such as color codes.
*/
static prompt_layout_t calc_prompt_layout(const wchar_t *prompt)
{
    size_t current_line_width = 0;
    size_t j, k;

    prompt_layout_t prompt_layout = {};
    prompt_layout.line_count = 1;

    for (j=0; prompt[j]; j++)
    {
        if (prompt[j] == L'\x1b')
        {
            /*
             This is the start of an escape code. Try to guess its width.
             */
            size_t p;
            int len=0;
            bool found = false;

            /*
             Detect these terminfo color escapes with parameter
             value 0..7, all of which don't move the cursor
             */
            char * const esc[] =
            {
                set_a_foreground,
                set_a_background,
                set_foreground,
                set_background,
            }
            ;

            /*
             Detect these semi-common terminfo escapes without any
             parameter values, all of which don't move the cursor
             */
            char * const esc2[] =
            {
                enter_bold_mode,
                exit_attribute_mode,
                enter_underline_mode,
                exit_underline_mode,
                enter_standout_mode,
                exit_standout_mode,
                flash_screen,
                enter_subscript_mode,
                exit_subscript_mode,
                enter_superscript_mode,
                exit_superscript_mode,
                enter_blink_mode,
                enter_italics_mode,
                exit_italics_mode,
                enter_reverse_mode,
                enter_shadow_mode,
                exit_shadow_mode,
                enter_standout_mode,
                exit_standout_mode,
                enter_secure_mode
            }
            ;

            for (p=0; p < sizeof esc / sizeof *esc && !found; p++)
            {
                if (!esc[p])
                    continue;

                for (k=0; k<8; k++)
                {
                    len = try_sequence(tparm(esc[p],k), &prompt[j]);
                    if (len)
                    {
                        j += (len-1);
                        found = true;
                        break;
                    }
                }
            }

            /* PCA for term256 support, let's just detect the escape codes directly */
            if (! found)
            {
                len = is_term256_escape(&prompt[j]);
                if (len)
                {
                    j += (len - 1);
                    found = true;
                }
            }


            for (p=0; p < (sizeof(esc2)/sizeof(char *)) && !found; p++)
            {
                if (!esc2[p])
                    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[p]), &prompt[j]),
                           try_sequence(esc2[p], &prompt[j]));

                if (len)
                {
                    j += (len-1);
                    found = true;
                }
            }

            if (!found)
            {
                if (prompt[j+1] == L'k')
                {
                    const env_var_t term_name = env_get_string(L"TERM");
                    if (!term_name.missing() && wcsstr(term_name.c_str(), L"screen") == term_name)
                    {
                        const wchar_t *end;
                        j+=2;
                        found = true;
                        end = wcsstr(&prompt[j], L"\x1b\\");
                        if (end)
                        {
                            /*
                             You'd thing this should be
                             '(end-prompt)+2', in order to move j
                             past the end of the string, but there is
                             a 'j++' at the end of each lap, so j
                             should always point to the last menged
                             character, e.g. +1.
                             */
                            j = (end-prompt)+1;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

        }
        else if (prompt[j] == L'\t')
        {
            current_line_width = next_tab_stop(current_line_width);
        }
        else if (prompt[j] == L'\n' || prompt[j] == L'\f')
        {
            /* PCA: At least one prompt uses \f\r as a newline. It's unclear to me what this is meant to do, but terminals seem to treat it as a newline so we do the same. */
            current_line_width = 0;
            prompt_layout.line_count += 1;
        }
        else if (prompt[j] == L'\r')
        {
            current_line_width = 0;
        }
        else
        {
            /* Ordinary decent character. Just add width. This returns -1 for a control character - don't add that. */
            current_line_width += fish_wcwidth_min_0(prompt[j]);
            prompt_layout.max_line_width = maxi(prompt_layout.max_line_width, current_line_width);
        }
    }
    prompt_layout.last_line_width = current_line_width;
    return prompt_layout;
}