diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2012-05-07 17:43:05 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2012-05-07 17:43:05 -0700 |
commit | 4df6b599b8bd6302aa4fa3b5f18161f5549c59eb (patch) | |
tree | 78cf365ec4b007f1d1cf61898d79f65df0f6dc6c /highlight.cpp | |
parent | 0c79bb6e7c679552faba6cb333592eb1da26db35 (diff) |
Eliminate the silly autosuggest_parsed_command_t class; make it just a function
Diffstat (limited to 'highlight.cpp')
-rw-r--r-- | highlight.cpp | 219 |
1 files changed, 109 insertions, 110 deletions
diff --git a/highlight.cpp b/highlight.cpp index 41897c24..21a7e3b0 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -601,131 +601,122 @@ static int has_expand_reserved( const wchar_t *str ) return 0; } -/* A class representing the result of parsing a command line, containing both the last command and its arguments. This is used by autosuggestions */ -class autosuggest_parsed_command_t { - public: - /* The command, like "cd" */ - wcstring command; - - /* Arguments to the command */ - wcstring_list_t arguments; +/* Parse a command line. Return by reference the last command, its arguments, and the offset in the string of the beginning of the last argument. This is used by autosuggestions */ +static bool autosuggest_parse_command(const wcstring &str, wcstring *out_command, wcstring_list_t *out_arguments, int *out_last_arg_pos) +{ + if (str.empty()) + return false; - /* Position in the string of the start of the last argument */ - int last_arg_pos; + wcstring cmd; + wcstring_list_t args; + int arg_pos = -1; - autosuggest_parsed_command_t(const wcstring &str) { - if (str.empty()) - return; - - wcstring cmd; - wcstring_list_t args; - int arg_pos = -1; + bool had_cmd = false; + tokenizer tok; + for (tok_init( &tok, str.c_str(), TOK_SQUASH_ERRORS); tok_has_next(&tok); tok_next(&tok)) + { + int last_type = tok_last_type(&tok); - bool had_cmd = false; - tokenizer tok; - for (tok_init( &tok, str.c_str(), TOK_SQUASH_ERRORS); tok_has_next(&tok); tok_next(&tok)) + switch( last_type ) { - int last_type = tok_last_type(&tok); - - switch( last_type ) + case TOK_STRING: { - case TOK_STRING: + if( had_cmd ) { - if( had_cmd ) + /* Parameter to the command */ + args.push_back(tok_last(&tok)); + arg_pos = tok_get_pos(&tok); + } + else + { + /* Command. First check that the command actually exists. */ + wcstring local_cmd = tok_last( &tok ); + bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES); + if (! expanded || has_expand_reserved(cmd.c_str())) { - /* Parameter to the command */ - args.push_back(tok_last(&tok)); - arg_pos = tok_get_pos(&tok); + /* We can't expand this cmd, ignore it */ } else - { - /* Command. First check that the command actually exists. */ - wcstring local_cmd = tok_last( &tok ); - bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES); - if (! expanded || has_expand_reserved(cmd.c_str())) - { - /* We can't expand this cmd, ignore it */ - } - else + { + bool is_subcommand = false; + int mark = tok_get_pos(&tok); + + if (parser_keywords_is_subcommand(cmd)) { - bool is_subcommand = false; - int mark = tok_get_pos(&tok); + int sw; + tok_next( &tok ); - if (parser_keywords_is_subcommand(cmd)) + sw = parser_keywords_is_switch( tok_last( &tok ) ); + if( !parser_keywords_is_block( cmd ) && + sw == ARG_SWITCH ) { - int sw; - tok_next( &tok ); - - sw = parser_keywords_is_switch( tok_last( &tok ) ); - if( !parser_keywords_is_block( cmd ) && - sw == ARG_SWITCH ) - { - /* It's an argument to the subcommand itself */ - } - else - { - if( sw == ARG_SKIP ) - mark = tok_get_pos( &tok ); - is_subcommand = true; - } - tok_set_pos( &tok, mark ); + /* It's an argument to the subcommand itself */ } - - if (!is_subcommand) + else { - /* It's really a command */ - had_cmd = true; - cmd = local_cmd; + if( sw == ARG_SKIP ) + mark = tok_get_pos( &tok ); + is_subcommand = true; } + tok_set_pos( &tok, mark ); } + if (!is_subcommand) + { + /* It's really a command */ + had_cmd = true; + cmd = local_cmd; + } } - break; - } - case TOK_REDIRECT_NOCLOB: - case TOK_REDIRECT_OUT: - case TOK_REDIRECT_IN: - case TOK_REDIRECT_APPEND: - case TOK_REDIRECT_FD: - { - if( !had_cmd ) - { - break; - } - tok_next( &tok ); - break; } - - case TOK_PIPE: - case TOK_BACKGROUND: - case TOK_END: + break; + } + + case TOK_REDIRECT_NOCLOB: + case TOK_REDIRECT_OUT: + case TOK_REDIRECT_IN: + case TOK_REDIRECT_APPEND: + case TOK_REDIRECT_FD: + { + if( !had_cmd ) { - had_cmd = false; - cmd.empty(); - args.empty(); - arg_pos = -1; break; } - - case TOK_COMMENT: - case TOK_ERROR: - default: - { - break; - } + tok_next( &tok ); + break; } + + case TOK_PIPE: + case TOK_BACKGROUND: + case TOK_END: + { + had_cmd = false; + cmd.empty(); + args.empty(); + arg_pos = -1; + break; + } + + case TOK_COMMENT: + case TOK_ERROR: + default: + { + break; + } } - tok_destroy( &tok ); - - /* Remember our command if we have one */ - if (had_cmd) { - this->command.swap(cmd); - this->arguments.swap(args); - this->last_arg_pos = arg_pos; - } - } -}; + } + tok_destroy( &tok ); + + /* Remember our command if we have one */ + if (had_cmd) { + if (out_command) out_command->swap(cmd); + if (out_arguments) out_arguments->swap(args); + if (out_last_arg_pos) *out_last_arg_pos = arg_pos; + } + return had_cmd; +} + bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_directory, wcstring &outSuggestion) { if (str.empty()) @@ -735,12 +726,16 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di /* Parse the string */ - const autosuggest_parsed_command_t parsed(str); + wcstring parsed_command; + wcstring_list_t parsed_arguments; + int parsed_last_arg_pos = -1; + if (! autosuggest_parse_command(str, &parsed_command, &parsed_arguments, &parsed_last_arg_pos)) + return false; bool result = false; - if (parsed.command == L"cd" && ! parsed.arguments.empty()) { + if (parsed_command == L"cd" && ! parsed_arguments.empty()) { /* We can possibly handle this specially */ - wcstring dir = parsed.arguments.back(); + wcstring dir = parsed_arguments.back(); wcstring suggested_path; /* We always return true because we recognized the command. This prevents us from falling back to dumber algorithms; for example we won't suggest a non-directory for the cd command. */ @@ -780,7 +775,7 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di /* Success */ outSuggestion = str; - outSuggestion.erase(parsed.last_arg_pos); + outSuggestion.erase(parsed_last_arg_pos); outSuggestion.append(suggested_path); } } else { @@ -794,13 +789,17 @@ bool autosuggest_special_validate_from_history(const wcstring &str, const wcstri assert(outSuggestionOK != NULL); bool handled = false, suggestionOK = false; - - /* Parse the string */ - autosuggest_parsed_command_t parsed(str); - - if (parsed.command == L"cd" && ! parsed.arguments.empty()) { + + /* Parse the string */ + wcstring parsed_command; + wcstring_list_t parsed_arguments; + int parsed_last_arg_pos = -1; + if (! autosuggest_parse_command(str, &parsed_command, &parsed_arguments, &parsed_last_arg_pos)) + return false; + + if (parsed_command == L"cd" && ! parsed_arguments.empty()) { /* We can possibly handle this specially */ - wcstring dir = parsed.arguments.back(); + wcstring dir = parsed_arguments.back(); if (expand_one(dir, EXPAND_SKIP_CMDSUBST)) { handled = true; |