From 91c745e4b5c5b6d231e11b7e90f02f69c96023b7 Mon Sep 17 00:00:00 2001 From: axel Date: Thu, 5 Oct 2006 07:39:48 +1000 Subject: [PATCH] Add the possibility to set the cursor position using the commandline builtin darcs-hash:20061004213948-ac50b-3f673edeb01390bb3f280812d90bc8469f2f8ba8.gz --- builtin.c | 2 +- builtin.h | 1 + builtin_commandline.c | 85 +++++++++++++++++++++--------- doc_src/commandline.txt | 26 +++++---- reader.c | 8 +-- share/completions/commandline.fish | 3 ++ 6 files changed, 86 insertions(+), 39 deletions(-) diff --git a/builtin.c b/builtin.c index 94ce93999..caceef30b 100644 --- a/builtin.c +++ b/builtin.c @@ -2296,7 +2296,7 @@ static int builtin_fg( wchar_t **argv ) if( *end ) { sb_printf( sb_err, - _( L"%ls: Argument '%ls' is not a number\n" ), + BUILTIN_ERR_NOT_NUMBER, argv[0], argv[1] ); builtin_print_help( argv[0], sb_err ); diff --git a/builtin.h b/builtin.h index 59959e337..2f98c741a 100644 --- a/builtin.h +++ b/builtin.h @@ -84,6 +84,7 @@ enum */ #define BUILTIN_END_BLOCK_UNKNOWN _( L"%ls: Unknown block type '%ls'\n" ) +#define BUILTIN_ERR_NOT_NUMBER _( L"%ls: Argument '%ls' is not a number\n" ) /** Stringbuffer used to represent standard output */ diff --git a/builtin_commandline.c b/builtin_commandline.c index 5db06bd81..b9e1fc074 100644 --- a/builtin_commandline.c +++ b/builtin_commandline.c @@ -58,7 +58,7 @@ static int current_cursor_pos = -1; /** Returns the current commandline buffer. */ -static const wchar_t *get_buffer() +static wchar_t *get_buffer() { return current_buffer; } @@ -206,6 +206,9 @@ static int builtin_commandline( wchar_t **argv ) int function_mode = 0; int tokenize = 0; + + int cursor_mode = 0; + wchar_t *begin, *end; current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer(); if( current_buffer ) @@ -283,6 +286,10 @@ static int builtin_commandline( wchar_t **argv ) L"input", required_argument, 0, 'I' } , + { + L"cursor", no_argument, 0, 'C' + } + , { 0, 0, 0, 0 } @@ -293,7 +300,7 @@ static int builtin_commandline( wchar_t **argv ) int opt = wgetopt_long( argc, argv, - L"aijpctwforhI:", + L"aijpctwforhI:C", long_options, &opt_index ); if( opt == -1 ) @@ -353,7 +360,10 @@ static int builtin_commandline( wchar_t **argv ) current_cursor_pos = wcslen( woptarg ); break; - + case 'C': + cursor_mode = 1; + break; + case 'h': builtin_print_help( argv[0], sb_out ); return 0; @@ -371,16 +381,13 @@ static int builtin_commandline( wchar_t **argv ) /* Check for invalid switch combinations */ - if( buffer_part || cut_at_cursor || append_mode || tokenize ) + if( buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode ) { sb_printf(sb_err, BUILTIN_ERR_COMBO, argv[0] ); - sb_append2(sb_err, - parser_current_line(), - L"\n", - (void *)0); + builtin_print_help( argv[0], sb_err ); return 1; } @@ -391,10 +398,6 @@ static int builtin_commandline( wchar_t **argv ) BUILTIN_ERR_MISSING, argv[0] ); - sb_append2( sb_err, - parser_current_line(), - L"\n", - (void *)0 ); builtin_print_help( argv[0], sb_err ); return 1; } @@ -403,7 +406,6 @@ static int builtin_commandline( wchar_t **argv ) wint_t c = input_get_code( argv[i] ); if( c != -1 ) { -// fwprintf( stderr, L"Add function %ls (%d)\n", argv[i], c ); /* input_unreadch inserts the specified keypress or readline function at the top of the stack of unused @@ -413,15 +415,10 @@ static int builtin_commandline( wchar_t **argv ) } else { -// fwprintf( stderr, L"BLUR %ls %d\n", argv[i], c ); - sb_append2( sb_err, - argv[0], - L": Unknown readline function '", - argv[i], - L"'\n", - parser_current_line(), - L"\n", - (void *)0 ); + sb_printf( sb_err, + _(L"%ls: Unknown readline function '%ls'\n"), + argv[0], + argv[i] ); builtin_print_help( argv[0], sb_err ); return 1; } @@ -444,9 +441,19 @@ static int builtin_commandline( wchar_t **argv ) return 1; } + if( (buffer_part || tokenize || cut_at_cursor) && cursor_mode ) + { + sb_printf( sb_err, + BUILTIN_ERR_COMBO, + argv[0] ); + + builtin_print_help( argv[0], sb_err ); + return 1; + } + + if( (tokenize || cut_at_cursor) && (argc-woptind) ) { - sb_printf( sb_err, BUILTIN_ERR_COMBO2, argv[0], @@ -480,9 +487,39 @@ static int builtin_commandline( wchar_t **argv ) { buffer_part = STRING_MODE; } + + if( cursor_mode ) + { + if( argc-woptind ) + { + wchar_t *endptr; + int new_pos; + errno = 0; + + new_pos = wcstol( argv[woptind], &endptr, 10 ); + if( *endptr || errno ) + { + sb_printf( sb_err, + BUILTIN_ERR_NOT_NUMBER, + argv[0], + argv[woptind] ); + builtin_print_help( argv[0], sb_err ); + } + + current_buffer = reader_get_buffer(); + new_pos = maxi( 0, mini( new_pos, wcslen( current_buffer ) ) ); + reader_set_buffer( current_buffer, new_pos ); + return 0; + } + else + { + sb_printf( sb_out, L"%d\n", reader_get_cursor_pos() ); + return 0; + } - wchar_t *begin, *end; + } + switch( buffer_part ) { case STRING_MODE: diff --git a/doc_src/commandline.txt b/doc_src/commandline.txt index 55085e8d9..b8834ee85 100644 --- a/doc_src/commandline.txt +++ b/doc_src/commandline.txt @@ -9,8 +9,22 @@ - \c CMD is the new value of the commandline. If unspecified, the current value of the commandline is written to standard output. +The following switches change what the commandline builtin does + +- \c -C or \c --cursor set or get the current cursor position, not + the contents of the buffer. If no argument is given, the current + cursor position is printed, otherwise the argument is interpreted + as the new cursor position. +- \c -f or \c --function inject readline functions into the + reader. This option can not be combined with any other option. It + will cause any additional arguments to be interpreted as readline + functions, and these functions will be injected into the reader, so + that they will be returned to the reader before any additional + actual keypresses are read. + + The following switches change the way \c commandline updates the -commandline +commandline buffer - \c -a or \c --append do not remove the current commandline, append the specified string at the end of it @@ -28,20 +42,12 @@ or updated - \c -t or \c --current_token select the current token. The following switch changes the way \c commandline prints the current -commandline +commandline buffer - \c -c or \c --cut-at-cursor only print selection up until the current cursor position - \c -o or \c --tokenize tokenize the selection and print one string-type token per line -Other switches - -- \c -f or \c --function inject readline functions into the - reader. This option can not be combined with any other option. It - will cause any additional arguments to be interpreted as readline - functions, and these functions will be injected into the reader, so - that they will be returned to the reader before any additional - actual keypresses are read. If commandline is called during a call to complete a given string using complete -C STRING, commandline will consider the diff --git a/reader.c b/reader.c index d6cc284df..2bfa470cf 100644 --- a/reader.c +++ b/reader.c @@ -1253,8 +1253,6 @@ static int handle_completions( array_list_t *comp ) columns, then four, etc. completion_try_print always succeeds with one column. */ -/* - */ } free( prefix ); @@ -1714,11 +1712,13 @@ void reader_set_buffer( wchar_t *b, int p ) data->buff_len = l; check_size(); - wcscpy( data->buff, b ); + + if( data->buff != b ) + wcscpy( data->buff, b ); if( p>=0 ) { - data->buff_pos=p; + data->buff_pos=mini( p, l ); } else { diff --git a/share/completions/commandline.fish b/share/completions/commandline.fish index 3ffc31b6d..ebefe1706 100644 --- a/share/completions/commandline.fish +++ b/share/completions/commandline.fish @@ -10,3 +10,6 @@ complete -c commandline -s b -l current-buffer -d (N_ "Select entire command lin complete -c commandline -s c -l cut-at-cursor -d (N_ "Only return that part of the command line before the cursor") complete -c commandline -s f -l function -d (N_ "Inject readline functions to reader") +complete -c commandline -s I -l input -d (N_ "Specify command to operate on") +complete -c commandline -s C -l cursor -d (N_ "Set/get cursor position, not buffer contents") +