aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-05-06 13:36:51 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-05-06 13:36:51 -0700
commit71a8d39372936ef52da45cb368eb314ec120b2c6 (patch)
treebd02abd8160ada9695c9213a1bdcea45343123a8
parent90826e403121c7d878ba1ce4aa172ac5e96afeb5 (diff)
Fix to restore completions that use command substitution (like cd)
Fix to adopt the same escaping code for both completions and autosuggestions
-rw-r--r--complete.cpp3
-rw-r--r--expand.cpp2
-rw-r--r--parser.cpp9
-rw-r--r--parser.h7
-rw-r--r--reader.cpp162
5 files changed, 18 insertions, 165 deletions
diff --git a/complete.cpp b/complete.cpp
index be06ab31..ea83af2b 100644
--- a/complete.cpp
+++ b/complete.cpp
@@ -1163,7 +1163,8 @@ void completer_t::complete_from_args( const wcstring &str,
std::vector<completion_t> possible_comp;
bool is_autosuggest = (this->type == COMPLETE_AUTOSUGGEST);
- parser_t parser(is_autosuggest ? PARSER_TYPE_COMPLETIONS_ONLY : PARSER_TYPE_GENERAL);
+ bool show_errors = ! is_autosuggest;
+ parser_t parser(PARSER_TYPE_COMPLETIONS_ONLY, show_errors);
/* If type is COMPLETE_AUTOSUGGEST, it means we're on a background thread, so don't call proc_push_interactive */
if (! is_autosuggest)
diff --git a/expand.cpp b/expand.cpp
index 905f7f98..c6e85191 100644
--- a/expand.cpp
+++ b/expand.cpp
@@ -1419,7 +1419,7 @@ static void remove_internal_separator2( wcstring &s, int conv )
int expand_string( const wcstring &input, std::vector<completion_t> &output, expand_flags_t flags )
{
- parser_t parser(PARSER_TYPE_ERRORS_ONLY);
+ parser_t parser(PARSER_TYPE_ERRORS_ONLY, true /* show errors */);
std::vector<completion_t> list1, list2;
std::vector<completion_t> *in, *out;
diff --git a/parser.cpp b/parser.cpp
index 513bf316..3b4beb0f 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -356,8 +356,9 @@ static const struct block_lookup_entry block_lookup[]=
};
-parser_t::parser_t(enum parser_type_t type) :
+parser_t::parser_t(enum parser_type_t type, bool errors) :
parser_type(type),
+ show_errors(errors),
error_code(0),
err_pos(0),
current_tokenizer(NULL),
@@ -374,7 +375,7 @@ parser_t &parser_t::principal_parser(void)
{
ASSERT_IS_NOT_FORKED_CHILD();
ASSERT_IS_MAIN_THREAD();
- static parser_t parser(PARSER_TYPE_GENERAL);
+ static parser_t parser(PARSER_TYPE_GENERAL, true);
return parser;
}
@@ -762,12 +763,12 @@ void parser_t::print_errors_stderr()
int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &args )
{
tokenizer tok;
- const bool show_errors = (this->parser_type == PARSER_TYPE_GENERAL || this->parser_type == PARSER_TYPE_ERRORS_ONLY);
expand_flags_t eflags = 0;
if (! show_errors)
eflags |= EXPAND_NO_DESCRIPTIONS;
- if (this->parser_type != PARSER_TYPE_GENERAL)
+ // Completions need command substitution (for example, the cd completion uses this)
+ if (this->parser_type != PARSER_TYPE_GENERAL && this->parser_type != PARSER_TYPE_COMPLETIONS_ONLY)
eflags |= EXPAND_SKIP_CMDSUBST;
/*
diff --git a/parser.h b/parser.h
index 5ce83292..ca97fc73 100644
--- a/parser.h
+++ b/parser.h
@@ -269,9 +269,12 @@ class parser_t {
enum parser_type_t parser_type;
std::vector<block_t> blocks;
+ /** Whether or not we output errors */
+ const bool show_errors;
+
/** Last error code */
int error_code;
-
+
/** Position of last error */
int err_pos;
@@ -330,7 +333,7 @@ class parser_t {
static parser_t &principal_parser();
/** Create a parser of the given type */
- parser_t(enum parser_type_t type);
+ parser_t(enum parser_type_t type, bool show_errors);
/** The current innermost block, allocated with new */
block_t *current_block;
diff --git a/reader.cpp b/reader.cpp
index 18ecfdca..0beefbd0 100644
--- a/reader.cpp
+++ b/reader.cpp
@@ -866,7 +866,7 @@ static void get_param( const wchar_t *cmd,
int unfinished;
tokenizer tok;
- tok_init( &tok, cmd, TOK_ACCEPT_UNFINISHED );
+ tok_init( &tok, cmd, TOK_ACCEPT_UNFINISHED | TOK_SQUASH_ERRORS );
for( ; tok_has_next( &tok ); tok_next( &tok ) )
{
@@ -936,7 +936,7 @@ static void get_param( const wchar_t *cmd,
\param inout_cursor_pos On input, the location of the cursor within the command line. On output, the new desired position.
\return The completed string
*/
-static wcstring completion_insert_helper(const wcstring &val_str, int flags, const wcstring &command_line, size_t *inout_cursor_pos)
+static wcstring completion_apply_to_command_line(const wcstring &val_str, int flags, const wcstring &command_line, size_t *inout_cursor_pos)
{
wchar_t *replaced;
const wchar_t *val = val_str.c_str();
@@ -1067,151 +1067,13 @@ static wcstring completion_insert_helper(const wcstring &val_str, int flags, con
static void completion_insert( const wchar_t *val, int flags )
{
size_t cursor = data->buff_pos;
- wcstring new_command_line = completion_insert_helper(val, flags, data->command_line, &cursor);
+ wcstring new_command_line = completion_apply_to_command_line(val, flags, data->command_line, &cursor);
reader_set_buffer(new_command_line, cursor);
/* Since we just inserted a completion, don't immediately do a new autosuggestion */
data->suppress_autosuggestion = true;
}
-static void completion_insert_old( const wchar_t *val, int flags )
-{
- assert(data != NULL);
-
- wchar_t *replaced;
-
- wchar_t quote;
- bool add_space = !(flags & COMPLETE_NO_SPACE);
- bool do_replace = !!(flags & COMPLETE_NO_CASE);
- bool do_escape = !(flags & COMPLETE_DONT_ESCAPE);
-
- // debug( 0, L"Insert completion %ls with flags %d", val, flags);
-
- if( do_replace )
- {
-
- int move_cursor;
- const wchar_t *begin, *end;
- wchar_t *escaped;
-
- const wchar_t *buff = data->command_line.c_str();
- parse_util_token_extent( buff, data->buff_pos, &begin, 0, 0, 0 );
- end = buff + data->buff_pos;
-
- wcstring sb(buff, begin - buff);
-
- if( do_escape )
- {
- escaped = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
- sb.append( escaped );
- move_cursor = wcslen(escaped);
- free( escaped );
- }
- else
- {
- sb.append( val );
- move_cursor = wcslen(val);
- }
-
-
- if( add_space )
- {
- sb.append( L" " );
- move_cursor += 1;
- }
-
- sb.append( end );
-
- reader_set_buffer( sb, (begin-buff)+move_cursor );
-
- reader_super_highlight_me_plenty( data->buff_pos );
- reader_repaint();
-
- }
- else
- {
-
- if( do_escape )
- {
- get_param( data->command_line.c_str(),
- data->buff_pos,
- &quote,
- 0, 0, 0 );
-
- if( quote == L'\0' )
- {
- replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
- }
- else
- {
- int unescapable=0;
-
- const wchar_t *pin;
- wchar_t *pout;
-
- replaced = pout =
- (wchar_t *)malloc( sizeof(wchar_t)*(wcslen(val) + 1) );
-
- for( pin=val; *pin; pin++ )
- {
- switch( *pin )
- {
- case L'\n':
- case L'\t':
- case L'\b':
- case L'\r':
- unescapable=1;
- break;
- default:
- *pout++ = *pin;
- break;
- }
- }
- if( unescapable )
- {
- free( replaced );
- wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED );
- replaced = wcsdupcat( L" ", tmp );
- free( tmp);
- replaced[0]=quote;
- }
- else
- *pout = 0;
- }
- }
- else
- {
- replaced = wcsdup(val);
- }
-
- if( insert_string( replaced ) )
- {
- /*
- Print trailing space since this is the only completion
- */
- if( add_space )
- {
-
- if( quote &&
- (data->command_line.c_str()[data->buff_pos] != quote ) )
- {
- /*
- This is a quoted parameter, first print a quote
- */
- insert_char( quote );
- }
- insert_char( L' ' );
- }
-
- /* Since we just inserted a completion, don't immediately do a new autosuggestion */
- data->suppress_autosuggestion = true;
- }
-
- free(replaced);
-
- }
-}
-
/**
Run the fish_pager command to display the completion list. If the
fish_pager outputs any text, it is inserted into the input
@@ -1446,22 +1308,8 @@ struct autosuggestion_context_t {
complete(search_string, completions, COMPLETE_AUTOSUGGEST, &this->commands_to_load);
if (! completions.empty()) {
const completion_t &comp = completions.at(0);
- this->autosuggestion = this->search_string;
-
- if (comp.flags & COMPLETE_NO_CASE) {
- /* The completion contains the whole current token, not merely a suffix */
-
- const wchar_t *begin;
- const wchar_t *buff = data->command_line.c_str();
- parse_util_token_extent( buff, data->buff_pos, &begin, 0, 0, 0 );
-
- size_t start = begin - buff;
- assert(data->buff_pos >= start);
- this->autosuggestion.replace(start, data->buff_pos - start, comp.completion);
- } else {
- /* The completion contains only a suffix */
- this->autosuggestion.append(comp.completion);
- }
+ size_t cursor = this->cursor_pos;
+ this->autosuggestion = completion_apply_to_command_line(comp.completion.c_str(), comp.flags, this->search_string, &cursor);
return 1;
}