aboutsummaryrefslogtreecommitdiffhomepage
path: root/highlight.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-11-18 16:30:30 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-11-18 16:30:30 -0800
commit9992b8eb0e3366ff8a3948aa0b66a19c3c12c737 (patch)
tree6dda0fef85812016fbba9ea067c9d586092b506d /highlight.cpp
parentbab69f26724028d16054a3daf5c78aad7c67bb2d (diff)
Apply new indentation, brace, and whitespace style
Diffstat (limited to 'highlight.cpp')
-rw-r--r--highlight.cpp1813
1 files changed, 931 insertions, 882 deletions
diff --git a/highlight.cpp b/highlight.cpp
index 0cc76502..a7ec044e 100644
--- a/highlight.cpp
+++ b/highlight.cpp
@@ -40,58 +40,65 @@
*/
#define VAR_COUNT ( sizeof(highlight_var)/sizeof(wchar_t *) )
-static void highlight_universal_internal( const wcstring &buff, std::vector<int> &color, size_t pos );
+static void highlight_universal_internal(const wcstring &buff, std::vector<int> &color, size_t pos);
/**
The environment variables used to specify the color of different tokens.
*/
static const wchar_t * const highlight_var[] =
{
- L"fish_color_normal",
- L"fish_color_error",
- L"fish_color_command",
- L"fish_color_end",
- L"fish_color_param",
- L"fish_color_comment",
- L"fish_color_match",
- L"fish_color_search_match",
- L"fish_color_operator",
- L"fish_color_escape",
- L"fish_color_quote",
- L"fish_color_redirection",
- L"fish_color_valid_path",
+ L"fish_color_normal",
+ L"fish_color_error",
+ L"fish_color_command",
+ L"fish_color_end",
+ L"fish_color_param",
+ L"fish_color_comment",
+ L"fish_color_match",
+ L"fish_color_search_match",
+ L"fish_color_operator",
+ L"fish_color_escape",
+ L"fish_color_quote",
+ L"fish_color_redirection",
+ L"fish_color_valid_path",
L"fish_color_autosuggestion"
};
/* If the given path looks like it's relative to the working directory, then prepend that working directory. */
-static wcstring apply_working_directory(const wcstring &path, const wcstring &working_directory) {
+static wcstring apply_working_directory(const wcstring &path, const wcstring &working_directory)
+{
if (path.empty() || working_directory.empty())
return path;
/* We're going to make sure that if we want to prepend the wd, that the string has no leading / */
bool prepend_wd;
- switch (path.at(0)) {
- case L'/':
- case L'~':
- prepend_wd = false;
- break;
- default:
- prepend_wd = true;
- break;
+ switch (path.at(0))
+ {
+ case L'/':
+ case L'~':
+ prepend_wd = false;
+ break;
+ default:
+ prepend_wd = true;
+ break;
}
- if (! prepend_wd) {
+ if (! prepend_wd)
+ {
/* No need to prepend the wd, so just return the path we were given */
return path;
- } else {
+ }
+ else
+ {
/* Remove up to one ./ */
wcstring path_component = path;
- if (string_prefixes_string(L"./", path_component)) {
+ if (string_prefixes_string(L"./", path_component))
+ {
path_component.erase(0, 2);
}
/* Removing leading /s */
- while (string_prefixes_string(L"/", path_component)) {
+ while (string_prefixes_string(L"/", path_component))
+ {
path_component.erase(0, 1);
}
@@ -111,10 +118,13 @@ bool fs_is_case_insensitive(const wcstring &path, int fd, case_sensitivity_cache
#ifdef _PC_CASE_SENSITIVE
/* Try the cache first */
case_sensitivity_cache_t::iterator cache = case_sensitivity_cache.find(path);
- if (cache != case_sensitivity_cache.end()) {
+ if (cache != case_sensitivity_cache.end())
+ {
/* Use the cached value */
result = cache->second;
- } else {
+ }
+ else
+ {
/* Ask the system. A -1 value means error (so assume case sensitive), a 1 value means case sensitive, and a 0 value means case insensitive */
long ret = fpathconf(fd, _PC_CASE_SENSITIVE);
result = (ret == 0);
@@ -132,10 +142,10 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
{
ASSERT_IS_BACKGROUND_THREAD();
- const bool require_dir = !! (flags & PATH_REQUIRE_DIR);
+ const bool require_dir = !!(flags & PATH_REQUIRE_DIR);
wcstring clean_path;
- int has_magic = 0;
- bool result = false;
+ int has_magic = 0;
+ bool result = false;
wcstring path(const_path);
if (flags & PATH_EXPAND_TILDE)
@@ -143,41 +153,41 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
// debug( 1, L"%ls -> %ls ->%ls", path, tilde, unescaped );
- for( size_t i=0; i < path.size(); i++)
+ for (size_t i=0; i < path.size(); i++)
{
wchar_t c = path.at(i);
- switch( c )
+ switch (c)
{
- case PROCESS_EXPAND:
- case VARIABLE_EXPAND:
- case VARIABLE_EXPAND_SINGLE:
- case BRACKET_BEGIN:
- case BRACKET_END:
- case BRACKET_SEP:
- case ANY_CHAR:
- case ANY_STRING:
- case ANY_STRING_RECURSIVE:
- {
- has_magic = 1;
- break;
- }
+ case PROCESS_EXPAND:
+ case VARIABLE_EXPAND:
+ case VARIABLE_EXPAND_SINGLE:
+ case BRACKET_BEGIN:
+ case BRACKET_END:
+ case BRACKET_SEP:
+ case ANY_CHAR:
+ case ANY_STRING:
+ case ANY_STRING_RECURSIVE:
+ {
+ has_magic = 1;
+ break;
+ }
- case INTERNAL_SEPARATOR:
- {
- break;
- }
+ case INTERNAL_SEPARATOR:
+ {
+ break;
+ }
- default:
- {
- clean_path.push_back(c);
- break;
- }
+ default:
+ {
+ clean_path.push_back(c);
+ break;
+ }
}
}
- if( ! has_magic && ! clean_path.empty() )
+ if (! has_magic && ! clean_path.empty())
{
/* Don't test the same path multiple times, which can happen if the path is absolute and the CDPATH contains multiple entries */
std::set<wcstring> checked_paths;
@@ -185,7 +195,8 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
/* Keep a cache of which paths / filesystems are case sensitive */
case_sensitivity_cache_t case_sensitivity_cache;
- for (size_t wd_idx = 0; wd_idx < directories.size() && ! result; wd_idx++) {
+ for (size_t wd_idx = 0; wd_idx < directories.size() && ! result; wd_idx++)
+ {
const wcstring &wd = directories.at(wd_idx);
const wcstring abs_path = apply_working_directory(clean_path, wd);
@@ -200,7 +211,8 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
if (must_be_full_dir)
{
struct stat buf;
- if (0 == wstat(abs_path, &buf) && S_ISDIR(buf.st_mode)) {
+ if (0 == wstat(abs_path, &buf) && S_ISDIR(buf.st_mode))
+ {
result = true;
/* Return the path suffix, not the whole absolute path */
if (out_path)
@@ -220,7 +232,8 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
if (out_path)
*out_path = clean_path;
}
- else if ((dir = wopendir(dir_name))) {
+ else if ((dir = wopendir(dir_name)))
+ {
// We opened the dir_name; look for a string where the base name prefixes it
wcstring ent;
@@ -234,23 +247,28 @@ bool is_potential_path(const wcstring &const_path, const wcstring_list_t &direct
/* Determine which function to call to check for prefixes */
bool (*prefix_func)(const wcstring &, const wcstring &);
- if (case_insensitive) {
+ if (case_insensitive)
+ {
prefix_func = string_prefixes_string_case_insensitive;
- } else {
+ }
+ else
+ {
prefix_func = string_prefixes_string;
}
if (prefix_func(base_name, ent) && (! require_dir || is_dir))
{
result = true;
- if (out_path) {
+ if (out_path)
+ {
/* We want to return the path in the same "form" as it was given. Take the given path, get its basename. Append that to the output if the basename actually prefixes the path (which it won't if the given path contains no slashes), and isn't a slash (so we don't duplicate slashes). Then append the directory entry. */
out_path->clear();
const wcstring path_base = wdirname(const_path);
- if (prefix_func(path_base, const_path)) {
+ if (prefix_func(path_base, const_path))
+ {
out_path->append(path_base);
if (! string_suffixes_string(L"/", *out_path))
out_path->push_back(L'/');
@@ -277,10 +295,13 @@ static bool is_potential_cd_path(const wcstring &path, const wcstring &working_d
{
wcstring_list_t directories;
- if (string_prefixes_string(L"./", path)) {
+ if (string_prefixes_string(L"./", path))
+ {
/* Ignore the CDPATH in this case; just use the working directory */
directories.push_back(working_directory);
- } else {
+ }
+ else
+ {
/* Get the CDPATH */
env_var_t cdpath = env_get_string(L"CDPATH");
if (cdpath.missing_or_empty())
@@ -299,362 +320,364 @@ static bool is_potential_cd_path(const wcstring &path, const wcstring &working_d
/* Call is_potential_path with all of these directories */
bool result = is_potential_path(path, directories, flags | PATH_REQUIRE_DIR, out_path);
#if 0
- if (out_path) {
+ if (out_path)
+ {
printf("%ls -> %ls\n", path.c_str(), out_path->c_str());
}
#endif
return result;
}
-rgb_color_t highlight_get_color( int highlight, bool is_background )
+rgb_color_t highlight_get_color(int highlight, bool is_background)
{
- size_t idx=0;
- rgb_color_t result;
-
- if( highlight < 0 )
- return rgb_color_t::normal();
- if( highlight > (1<<VAR_COUNT) )
- return rgb_color_t::normal();
- for( size_t i=0; i<VAR_COUNT; i++ )
- {
- if( highlight & (1<<i ))
+ size_t idx=0;
+ rgb_color_t result;
+
+ if (highlight < 0)
+ return rgb_color_t::normal();
+ if (highlight > (1<<VAR_COUNT))
+ return rgb_color_t::normal();
+ for (size_t i=0; i<VAR_COUNT; i++)
{
- idx = i;
- break;
+ if (highlight & (1<<i))
+ {
+ idx = i;
+ break;
+ }
}
- }
- env_var_t val_wstr = env_get_string( highlight_var[idx]);
+ env_var_t val_wstr = env_get_string(highlight_var[idx]);
// debug( 1, L"%d -> %d -> %ls", highlight, idx, val );
- if (val_wstr.missing())
- val_wstr = env_get_string( highlight_var[0]);
+ if (val_wstr.missing())
+ val_wstr = env_get_string(highlight_var[0]);
- if( ! val_wstr.missing() )
- result = parse_color( val_wstr, is_background );
+ if (! val_wstr.missing())
+ result = parse_color(val_wstr, is_background);
- if( highlight & HIGHLIGHT_VALID_PATH )
- {
- env_var_t val2_wstr = env_get_string( L"fish_color_valid_path" );
- const wcstring val2 = val2_wstr.missing() ? L"" : val2_wstr.c_str();
-
- rgb_color_t result2 = parse_color( val2, is_background );
- if( result.is_normal() )
- result = result2;
- else
+ if (highlight & HIGHLIGHT_VALID_PATH)
{
- if( result2.is_bold() )
- result.set_bold(true);
- if( result2.is_underline() )
- result.set_underline(true);
+ env_var_t val2_wstr = env_get_string(L"fish_color_valid_path");
+ const wcstring val2 = val2_wstr.missing() ? L"" : val2_wstr.c_str();
+
+ rgb_color_t result2 = parse_color(val2, is_background);
+ if (result.is_normal())
+ result = result2;
+ else
+ {
+ if (result2.is_bold())
+ result.set_bold(true);
+ if (result2.is_underline())
+ result.set_underline(true);
+ }
}
- }
- return result;
+ return result;
}
/**
Highlight operators (such as $, ~, %, as well as escaped characters.
*/
-static void highlight_param( const wcstring &buffstr, std::vector<int> &colors, wcstring_list_t *error )
+static void highlight_param(const wcstring &buffstr, std::vector<int> &colors, wcstring_list_t *error)
{
const wchar_t * const buff = buffstr.c_str();
- enum {e_unquoted, e_single_quoted, e_double_quoted} mode = e_unquoted;
- size_t in_pos, len = buffstr.size();
- int bracket_count=0;
- int normal_status = colors.at(0);
-
- for (in_pos=0; in_pos<len; in_pos++)
- {
- wchar_t c = buffstr.at(in_pos);
- switch( mode )
+ enum {e_unquoted, e_single_quoted, e_double_quoted} mode = e_unquoted;
+ size_t in_pos, len = buffstr.size();
+ int bracket_count=0;
+ int normal_status = colors.at(0);
+
+ for (in_pos=0; in_pos<len; in_pos++)
{
- /*
- Mode 0 means unquoted string
- */
- case e_unquoted:
- {
- if( c == L'\\' )
+ wchar_t c = buffstr.at(in_pos);
+ switch (mode)
{
- size_t start_pos = in_pos;
- in_pos++;
-
- if( wcschr( L"~%", buff[in_pos] ) )
- {
- if( in_pos == 1 )
- {
- colors.at(start_pos) = HIGHLIGHT_ESCAPE;
- colors.at(in_pos+1) = normal_status;
- }
- }
- else if( buff[in_pos]==L',' )
- {
- if( bracket_count )
+ /*
+ Mode 0 means unquoted string
+ */
+ case e_unquoted:
+ {
+ if (c == L'\\')
{
- colors.at(start_pos) = HIGHLIGHT_ESCAPE;
- colors.at(in_pos+1) = normal_status;
- }
- }
- else if( wcschr( L"abefnrtv*?$(){}[]'\"<>^ \\#;|&", buff[in_pos] ) )
- {
- colors.at(start_pos)=HIGHLIGHT_ESCAPE;
- colors.at(in_pos+1)=normal_status;
- }
- else if( wcschr( L"c", buff[in_pos] ) )
+ size_t start_pos = in_pos;
+ in_pos++;
+
+ if (wcschr(L"~%", buff[in_pos]))
+ {
+ if (in_pos == 1)
{
- colors.at(start_pos)=HIGHLIGHT_ESCAPE;
- if (in_pos+2 < colors.size())
- colors.at(in_pos+2)=normal_status;
- }
- else if( wcschr( L"uUxX01234567", buff[in_pos] ) )
- {
- int i;
- long long res=0;
- int chars=2;
- int base=16;
-
- wchar_t max_val = ASCII_MAX;
-
- switch( buff[in_pos] )
- {
- case L'u':
- {
- chars=4;
- max_val = UCS2_MAX;
- break;
- }
+ colors.at(start_pos) = HIGHLIGHT_ESCAPE;
+ colors.at(in_pos+1) = normal_status;
+ }
+ }
+ else if (buff[in_pos]==L',')
+ {
+ if (bracket_count)
+ {
+ colors.at(start_pos) = HIGHLIGHT_ESCAPE;
+ colors.at(in_pos+1) = normal_status;
+ }
+ }
+ else if (wcschr(L"abefnrtv*?$(){}[]'\"<>^ \\#;|&", buff[in_pos]))
+ {
+ colors.at(start_pos)=HIGHLIGHT_ESCAPE;
+ colors.at(in_pos+1)=normal_status;
+ }
+ else if (wcschr(L"c", buff[in_pos]))
+ {
+ colors.at(start_pos)=HIGHLIGHT_ESCAPE;
+ if (in_pos+2 < colors.size())
+ colors.at(in_pos+2)=normal_status;
+ }
+ else if (wcschr(L"uUxX01234567", buff[in_pos]))
+ {
+ int i;
+ long long res=0;
+ int chars=2;
+ int base=16;
- case L'U':
- {
- chars=8;
- max_val = WCHAR_MAX;
- break;
- }
+ wchar_t max_val = ASCII_MAX;
- case L'x':
- {
- break;
- }
+ switch (buff[in_pos])
+ {
+ case L'u':
+ {
+ chars=4;
+ max_val = UCS2_MAX;
+ break;
+ }
- case L'X':
- {
- max_val = BYTE_MAX;
- break;
- }
+ case L'U':
+ {
+ chars=8;
+ max_val = WCHAR_MAX;
+ break;
+ }
- default:
- {
- base=8;
- chars=3;
- in_pos--;
- break;
- }
- }
+ case L'x':
+ {
+ break;
+ }
- for( i=0; i<chars; i++ )
- {
- long d = convert_digit( buff[++in_pos],base);
+ case L'X':
+ {
+ max_val = BYTE_MAX;
+ break;
+ }
- if( d < 0 )
- {
- in_pos--;
- break;
- }
+ default:
+ {
+ base=8;
+ chars=3;
+ in_pos--;
+ break;
+ }
+ }
- res=(res*base)|d;
- }
+ for (i=0; i<chars; i++)
+ {
+ long d = convert_digit(buff[++in_pos],base);
+
+ if (d < 0)
+ {
+ in_pos--;
+ break;
+ }
+
+ res=(res*base)|d;
+ }
+
+ if ((res <= max_val))
+ {
+ colors.at(start_pos) = HIGHLIGHT_ESCAPE;
+ colors.at(in_pos+1) = normal_status;
+ }
+ else
+ {
+ colors.at(start_pos) = HIGHLIGHT_ERROR;
+ colors.at(in_pos+1) = normal_status;
+ }
+ }
- if( (res <= max_val) )
- {
- colors.at(start_pos) = HIGHLIGHT_ESCAPE;
- colors.at(in_pos+1) = normal_status;
}
else
{
- colors.at(start_pos) = HIGHLIGHT_ERROR;
- colors.at(in_pos+1) = normal_status;
- }
- }
+ switch (buff[in_pos])
+ {
+ case L'~':
+ case L'%':
+ {
+ if (in_pos == 0)
+ {
+ colors.at(in_pos) = HIGHLIGHT_OPERATOR;
+ colors.at(in_pos+1) = normal_status;
+ }
+ break;
+ }
- }
- else
- {
- switch( buff[in_pos]){
- case L'~':
- case L'%':
- {
- if( in_pos == 0 )
- {
- colors.at(in_pos) = HIGHLIGHT_OPERATOR;
- colors.at(in_pos+1) = normal_status;
- }
- break;
- }
+ case L'$':
+ {
+ wchar_t n = buff[in_pos+1];
+ colors.at(in_pos) = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
+ colors.at(in_pos+1) = normal_status;
+ break;
+ }
- case L'$':
- {
- wchar_t n = buff[in_pos+1];
- colors.at(in_pos) = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
- colors.at(in_pos+1) = normal_status;
- break;
- }
+ case L'*':
+ case L'?':
+ case L'(':
+ case L')':
+ {
+ colors.at(in_pos) = HIGHLIGHT_OPERATOR;
+ colors.at(in_pos+1) = normal_status;
+ break;
+ }
- case L'*':
- case L'?':
- case L'(':
- case L')':
- {
- colors.at(in_pos) = HIGHLIGHT_OPERATOR;
- colors.at(in_pos+1) = normal_status;
- break;
- }
+ case L'{':
+ {
+ colors.at(in_pos) = HIGHLIGHT_OPERATOR;
+ colors.at(in_pos+1) = normal_status;
+ bracket_count++;
+ break;
+ }
- case L'{':
- {
- colors.at(in_pos) = HIGHLIGHT_OPERATOR;
- colors.at(in_pos+1) = normal_status;
- bracket_count++;
- break;
- }
+ case L'}':
+ {
+ colors.at(in_pos) = HIGHLIGHT_OPERATOR;
+ colors.at(in_pos+1) = normal_status;
+ bracket_count--;
+ break;
+ }
- case L'}':
- {
- colors.at(in_pos) = HIGHLIGHT_OPERATOR;
- colors.at(in_pos+1) = normal_status;
- bracket_count--;
- break;
- }
+ case L',':
+ {
+ if (bracket_count)
+ {
+ colors.at(in_pos) = HIGHLIGHT_OPERATOR;
+ colors.at(in_pos+1) = normal_status;
+ }
- case L',':
- {
- if( bracket_count )
- {
- colors.at(in_pos) = HIGHLIGHT_OPERATOR;
- colors.at(in_pos+1) = normal_status;
- }
+ break;
+ }
- break;
- }
+ case L'\'':
+ {
+ colors.at(in_pos) = HIGHLIGHT_QUOTE;
+ mode = e_single_quoted;
+ break;
+ }
- case L'\'':
- {
- colors.at(in_pos) = HIGHLIGHT_QUOTE;
- mode = e_single_quoted;
- break;
- }
+ case L'\"':
+ {
+ colors.at(in_pos) = HIGHLIGHT_QUOTE;
+ mode = e_double_quoted;
+ break;
+ }
- case L'\"':
- {
- colors.at(in_pos) = HIGHLIGHT_QUOTE;
- mode = e_double_quoted;
- break;
+ }
}
-
- }
+ break;
}
- break;
- }
- /*
- Mode 1 means single quoted string, i.e 'foo'
- */
- case e_single_quoted:
- {
- if( c == L'\\' )
+ /*
+ Mode 1 means single quoted string, i.e 'foo'
+ */
+ case e_single_quoted:
{
- size_t start_pos = in_pos;
- switch( buff[++in_pos] )
- {
- case '\\':
- case L'\'':
+ if (c == L'\\')
{
- colors.at(start_pos) = HIGHLIGHT_ESCAPE;
- colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
- break;
- }
+ size_t start_pos = in_pos;
+ switch (buff[++in_pos])
+ {
+ case '\\':
+ case L'\'':
+ {
+ colors.at(start_pos) = HIGHLIGHT_ESCAPE;
+ colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
+ break;
+ }
+
+ case 0:
+ {
+ return;
+ }
- case 0:
+ }
+
+ }
+ if (c == L'\'')
{
- return;
+ mode = e_unquoted;
+ colors.at(in_pos+1) = normal_status;
}
- }
-
+ break;
}
- if( c == L'\'' )
+
+ /*
+ Mode 2 means double quoted string, i.e. "foo"
+ */
+ case e_double_quoted:
{
- mode = e_unquoted;
- colors.at(in_pos+1) = normal_status;
- }
+ switch (c)
+ {
+ case '"':
+ {
+ mode = e_unquoted;
+ colors.at(in_pos+1) = normal_status;
+ break;
+ }
- break;
- }
+ case '\\':
+ {
+ size_t start_pos = in_pos;
+ switch (buff[++in_pos])
+ {
+ case L'\0':
+ {
+ return;
+ }
- /*
- Mode 2 means double quoted string, i.e. "foo"
- */
- case e_double_quoted:
- {
- switch( c )
- {
- case '"':
- {
- mode = e_unquoted;
- colors.at(in_pos+1) = normal_status;
- break;
- }
+ case '\\':
+ case L'$':
+ case '"':
+ {
+ colors.at(start_pos) = HIGHLIGHT_ESCAPE;
+ colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
+ break;
+ }
+ }
+ break;
+ }
- case '\\':
- {
- size_t start_pos = in_pos;
- switch( buff[++in_pos] )
+ case '$':
{
- case L'\0':
- {
- return;
- }
-
- case '\\':
- case L'$':
- case '"':
- {
- colors.at(start_pos) = HIGHLIGHT_ESCAPE;
+ wchar_t n = buff[in_pos+1];
+ colors.at(in_pos) = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
break;
- }
}
- break;
- }
- case '$':
- {
- wchar_t n = buff[in_pos+1];
- colors.at(in_pos) = (n==L'$'||wcsvarchr(n))? HIGHLIGHT_OPERATOR:HIGHLIGHT_ERROR;
- colors.at(in_pos+1) = HIGHLIGHT_QUOTE;
+ }
break;
- }
-
}
- break;
- }
+ }
}
- }
}
-static int has_expand_reserved( const wchar_t *str )
+static int has_expand_reserved(const wchar_t *str)
{
- while( *str )
- {
- if( *str >= EXPAND_RESERVED &&
- *str <= EXPAND_RESERVED_END )
+ while (*str)
{
- return 1;
+ if (*str >= EXPAND_RESERVED &&
+ *str <= EXPAND_RESERVED_END)
+ {
+ return 1;
+ }
+ str++;
}
- str++;
- }
- return 0;
+ return 0;
}
/* 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 */
@@ -669,103 +692,104 @@ static bool autosuggest_parse_command(const wcstring &str, wcstring *out_command
bool had_cmd = false;
tokenizer tok;
- for (tok_init( &tok, str.c_str(), TOK_ACCEPT_UNFINISHED | TOK_SQUASH_ERRORS); tok_has_next(&tok); tok_next(&tok))
+ for (tok_init(&tok, str.c_str(), TOK_ACCEPT_UNFINISHED | TOK_SQUASH_ERRORS); tok_has_next(&tok); tok_next(&tok))
{
int last_type = tok_last_type(&tok);
- switch( last_type )
+ switch (last_type)
{
- case TOK_STRING:
+ case TOK_STRING:
+ {
+ if (had_cmd)
{
- if( had_cmd )
+ /* Parameter to the command. We store these escaped. */
+ 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. We store these escaped. */
- 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;
}
+ break;
+ }
- case TOK_PIPE:
- case TOK_BACKGROUND:
- case TOK_END:
+ 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;
}
+ tok_next(&tok);
+ break;
+ }
- case TOK_COMMENT:
- case TOK_ERROR:
- default:
- {
- 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 );
+ tok_destroy(&tok);
/* Remember our command if we have one */
- if (had_cmd) {
+ 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;
@@ -775,7 +799,8 @@ static bool autosuggest_parse_command(const wcstring &str, wcstring *out_command
/* We have to return an escaped string here */
-bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_directory, wcstring &outSuggestion) {
+bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_directory, wcstring &outSuggestion)
+{
if (str.empty())
return false;
@@ -789,7 +814,8 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di
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 */
const wcstring escaped_dir = parsed_arguments.back();
wcstring suggested_path;
@@ -821,13 +847,16 @@ bool autosuggest_suggest_special(const wcstring &str, const wcstring &working_di
outSuggestion.append(escaped_suggested_path);
if (quote != L'\0') outSuggestion.push_back(quote);
}
- } else {
+ }
+ else
+ {
/* Either an error or some other command, so we don't handle it specially */
}
return result;
}
-bool autosuggest_validate_from_history(const history_item_t &item, file_detection_context_t &detector, const wcstring &working_directory, const env_vars_snapshot_t &vars) {
+bool autosuggest_validate_from_history(const history_item_t &item, file_detection_context_t &detector, const wcstring &working_directory, const env_vars_snapshot_t &vars)
+{
ASSERT_IS_BACKGROUND_THREAD();
bool handled = false, suggestionOK = false;
@@ -839,24 +868,33 @@ bool autosuggest_validate_from_history(const history_item_t &item, file_detectio
if (! autosuggest_parse_command(item.str(), &parsed_command, &parsed_arguments, &parsed_last_arg_pos))
return 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();
if (expand_one(dir, EXPAND_SKIP_CMDSUBST))
{
handled = true;
bool is_help = string_prefixes_string(dir, L"--help") || string_prefixes_string(dir, L"-h");
- if (is_help) {
+ if (is_help)
+ {
suggestionOK = false;
- } else {
+ }
+ else
+ {
wcstring path;
bool can_cd = path_get_cdpath(dir, &path, working_directory.c_str(), vars);
- if (! can_cd) {
+ if (! can_cd)
+ {
suggestionOK = false;
- } else if (paths_are_same_file(working_directory, path)) {
+ }
+ else if (paths_are_same_file(working_directory, path))
+ {
/* Don't suggest the working directory as the path! */
suggestionOK = false;
- } else {
+ }
+ else
+ {
suggestionOK = true;
}
}
@@ -864,7 +902,8 @@ bool autosuggest_validate_from_history(const history_item_t &item, file_detectio
}
/* If not handled specially, handle it here */
- if (! handled) {
+ if (! handled)
+ {
bool cmd_ok = false;
if (path_get_path(parsed_command, NULL))
@@ -876,12 +915,15 @@ bool autosuggest_validate_from_history(const history_item_t &item, file_detectio
cmd_ok = true;
}
- if (cmd_ok) {
+ if (cmd_ok)
+ {
const path_list_t &paths = item.get_required_paths();
- if (paths.empty()) {
+ if (paths.empty())
+ {
suggestionOK= true;
}
- else {
+ else
+ {
detector.potential_paths = paths;
suggestionOK = detector.paths_are_valid(paths);
}
@@ -892,20 +934,21 @@ bool autosuggest_validate_from_history(const history_item_t &item, file_detectio
}
// This function does I/O
-static void tokenize( const wchar_t * const buff, std::vector<int> &color, const size_t pos, wcstring_list_t *error, const wcstring &working_directory, const env_vars_snapshot_t &vars) {
+static void tokenize(const wchar_t * const buff, std::vector<int> &color, const size_t pos, wcstring_list_t *error, const wcstring &working_directory, const env_vars_snapshot_t &vars)
+{
ASSERT_IS_BACKGROUND_THREAD();
- wcstring cmd;
- int had_cmd=0;
- wcstring last_cmd;
+ wcstring cmd;
+ int had_cmd=0;
+ wcstring last_cmd;
- int accept_switches = 1;
+ int accept_switches = 1;
- int use_function = 1;
- int use_command = 1;
- int use_builtin = 1;
+ int use_function = 1;
+ int use_command = 1;
+ int use_builtin = 1;
- CHECK( buff, );
+ CHECK(buff,);
if (buff[0] == L'\0')
return;
@@ -913,356 +956,359 @@ static void tokenize( const wchar_t * const buff, std::vector<int> &color, const
std::fill(color.begin(), color.end(), -1);
tokenizer tok;
- for( tok_init( &tok, buff, TOK_SHOW_COMMENTS | TOK_SQUASH_ERRORS );
- tok_has_next( &tok );
- tok_next( &tok ) )
- {
- int last_type = tok_last_type( &tok );
-
- switch( last_type )
+ for (tok_init(&tok, buff, TOK_SHOW_COMMENTS | TOK_SQUASH_ERRORS);
+ tok_has_next(&tok);
+ tok_next(&tok))
{
- case TOK_STRING:
- {
- if( had_cmd )
- {
-
- /*Parameter */
- wchar_t *param = tok_last( &tok );
- if( param[0] == L'-' )
- {
- if (wcscmp( param, L"--" ) == 0 )
- {
- accept_switches = 0;
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_PARAM;
- }
- else if( accept_switches )
- {
- if( complete_is_valid_option( last_cmd, param, error, false /* no autoload */ ) )
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_PARAM;
- else
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- }
- else
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_PARAM;
- }
- }
- else
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_PARAM;
- }
-
- if( cmd == L"cd" )
- {
- wcstring dir = tok_last( &tok );
- if (expand_one(dir, EXPAND_SKIP_CMDSUBST))
- {
- int is_help = string_prefixes_string(dir, L"--help") || string_prefixes_string(dir, L"-h");
- if( !is_help && ! is_potential_cd_path(dir, working_directory, PATH_EXPAND_TILDE, NULL))
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- }
- }
- }
-
- /* Highlight the parameter. highlight_param wants to write one more color than we have characters (hysterical raisins) so allocate one more in the vector. But don't copy it back. */
- const wcstring param_str = param;
- size_t tok_pos = tok_get_pos(&tok);
-
- std::vector<int>::const_iterator where = color.begin() + tok_pos;
- std::vector<int> subcolors(where, where + param_str.size());
- subcolors.push_back(-1);
- highlight_param(param_str, subcolors, error);
+ int last_type = tok_last_type(&tok);
- /* Copy the subcolors back into our colors array */
- std::copy(subcolors.begin(), subcolors.begin() + param_str.size(), color.begin() + tok_pos);
- }
- else
+ switch (last_type)
+ {
+ case TOK_STRING:
{
- /*
- Command. First check that the command actually exists.
- */
- cmd = tok_last( &tok );
- bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS);
- if (! expanded || has_expand_reserved(cmd.c_str()))
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- }
- else
- {
- bool is_cmd = false;
- int is_subcommand = 0;
- int mark = tok_get_pos( &tok );
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_COMMAND;
-
- if( parser_keywords_is_subcommand( cmd ) )
+ if (had_cmd)
{
- int sw;
+ /*Parameter */
+ wchar_t *param = tok_last(&tok);
+ if (param[0] == L'-')
+ {
+ if (wcscmp(param, L"--") == 0)
+ {
+ accept_switches = 0;
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_PARAM;
+ }
+ else if (accept_switches)
+ {
+ if (complete_is_valid_option(last_cmd, param, error, false /* no autoload */))
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_PARAM;
+ else
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ }
+ else
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_PARAM;
+ }
+ }
+ else
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_PARAM;
+ }
- if( cmd == L"builtin")
- {
- use_function = 0;
- use_command = 0;
- use_builtin = 1;
- }
- else if( cmd == L"command")
- {
- use_command = 1;
- use_function = 0;
- use_builtin = 0;
- }
+ if (cmd == L"cd")
+ {
+ wcstring dir = tok_last(&tok);
+ if (expand_one(dir, EXPAND_SKIP_CMDSUBST))
+ {
+ int is_help = string_prefixes_string(dir, L"--help") || string_prefixes_string(dir, L"-h");
+ if (!is_help && ! is_potential_cd_path(dir, working_directory, PATH_EXPAND_TILDE, NULL))
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ }
+ }
+ }
- tok_next( &tok );
+ /* Highlight the parameter. highlight_param wants to write one more color than we have characters (hysterical raisins) so allocate one more in the vector. But don't copy it back. */
+ const wcstring param_str = param;
+ size_t tok_pos = tok_get_pos(&tok);
- sw = parser_keywords_is_switch( tok_last( &tok ) );
+ std::vector<int>::const_iterator where = color.begin() + tok_pos;
+ std::vector<int> subcolors(where, where + param_str.size());
+ subcolors.push_back(-1);
+ highlight_param(param_str, subcolors, error);
- if( !parser_keywords_is_block( cmd ) &&
- sw == ARG_SWITCH )
- {
+ /* Copy the subcolors back into our colors array */
+ std::copy(subcolors.begin(), subcolors.begin() + param_str.size(), color.begin() + tok_pos);
+ }
+ else
+ {
/*
- The 'builtin' and 'command' builtins
- are normally followed by another
- command, but if they are invoked
- with a switch, they aren't.
-
+ Command. First check that the command actually exists.
*/
- use_command = 1;
- use_function = 1;
- use_builtin = 2;
- }
- else
- {
- if( sw == ARG_SKIP )
+ cmd = tok_last(&tok);
+ bool expanded = expand_one(cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS);
+ if (! expanded || has_expand_reserved(cmd.c_str()))
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_PARAM;
- mark = tok_get_pos( &tok );
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
}
+ else
+ {
+ bool is_cmd = false;
+ int is_subcommand = 0;
+ int mark = tok_get_pos(&tok);
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_COMMAND;
- is_subcommand = 1;
- }
- tok_set_pos( &tok, mark );
- }
+ if (parser_keywords_is_subcommand(cmd))
+ {
- if( !is_subcommand )
- {
- /*
- OK, this is a command, it has been
- successfully expanded and everything
- looks ok. Lets check if the command
- exists.
- */
-
- /*
- First check if it is a builtin or
- function, since we don't have to stat
- any files for that
- */
- if (! is_cmd && use_builtin )
- is_cmd = builtin_exists( cmd );
-
- if (! is_cmd && use_function )
- is_cmd = function_exists_no_autoload( cmd, vars );
-
- /*
- Moving on to expensive tests
- */
-
- /*
- Check if this is a regular command
- */
- if (! is_cmd && use_command )
+ int sw;
+
+ if (cmd == L"builtin")
+ {
+ use_function = 0;
+ use_command = 0;
+ use_builtin = 1;
+ }
+ else if (cmd == L"command")
+ {
+ use_command = 1;
+ use_function = 0;
+ use_builtin = 0;
+ }
+
+ tok_next(&tok);
+
+ sw = parser_keywords_is_switch(tok_last(&tok));
+
+ if (!parser_keywords_is_block(cmd) &&
+ sw == ARG_SWITCH)
+ {
+ /*
+ The 'builtin' and 'command' builtins
+ are normally followed by another
+ command, but if they are invoked
+ with a switch, they aren't.
+
+ */
+ use_command = 1;
+ use_function = 1;
+ use_builtin = 2;
+ }
+ else
+ {
+ if (sw == ARG_SKIP)
{
- is_cmd = path_get_path( cmd, NULL, vars );
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_PARAM;
+ mark = tok_get_pos(&tok);
}
- /* Maybe it is a path for a implicit cd command. */
- if (! is_cmd)
+ is_subcommand = 1;
+ }
+ tok_set_pos(&tok, mark);
+ }
+
+ if (!is_subcommand)
+ {
+ /*
+ OK, this is a command, it has been
+ successfully expanded and everything
+ looks ok. Lets check if the command
+ exists.
+ */
+
+ /*
+ First check if it is a builtin or
+ function, since we don't have to stat
+ any files for that
+ */
+ if (! is_cmd && use_builtin)
+ is_cmd = builtin_exists(cmd);
+
+ if (! is_cmd && use_function)
+ is_cmd = function_exists_no_autoload(cmd, vars);
+
+ /*
+ Moving on to expensive tests
+ */
+
+ /*
+ Check if this is a regular command
+ */
+ if (! is_cmd && use_command)
+ {
+ is_cmd = path_get_path(cmd, NULL, vars);
+ }
+
+ /* Maybe it is a path for a implicit cd command. */
+ if (! is_cmd)
+ {
+ if (use_builtin || (use_function && function_exists_no_autoload(L"cd", vars)))
+ is_cmd = path_can_be_implicit_cd(cmd, NULL, working_directory.c_str(), vars);
+ }
+
+ if (is_cmd)
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_COMMAND;
+ }
+ else
+ {
+ if (error)
{
- if (use_builtin || (use_function && function_exists_no_autoload( L"cd", vars)))
- is_cmd = path_can_be_implicit_cd(cmd, NULL, working_directory.c_str(), vars);
+ error->push_back(format_string(L"Unknown command \'%ls\'", cmd.c_str()));
}
+ color.at(tok_get_pos(&tok)) = (HIGHLIGHT_ERROR);
+ }
+ had_cmd = 1;
+ }
- if( is_cmd )
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_COMMAND;
- }
- else
- {
- if( error ) {
- error->push_back(format_string(L"Unknown command \'%ls\'", cmd.c_str()));
- }
- color.at(tok_get_pos( &tok )) = (HIGHLIGHT_ERROR);
- }
- had_cmd = 1;
- }
+ if (had_cmd)
+ {
+ last_cmd = tok_last(&tok);
+ }
+ }
- if( had_cmd )
- {
- last_cmd = tok_last( &tok );
}
- }
-
+ break;
}
- break;
- }
-
- case TOK_REDIRECT_NOCLOB:
- case TOK_REDIRECT_OUT:
- case TOK_REDIRECT_IN:
- case TOK_REDIRECT_APPEND:
- case TOK_REDIRECT_FD:
- {
- if( !had_cmd )
+
+ case TOK_REDIRECT_NOCLOB:
+ case TOK_REDIRECT_OUT:
+ case TOK_REDIRECT_IN:
+ case TOK_REDIRECT_APPEND:
+ case TOK_REDIRECT_FD:
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- if( error )
- error->push_back(L"Redirection without a command");
- break;
- }
+ if (!had_cmd)
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ if (error)
+ error->push_back(L"Redirection without a command");
+ break;
+ }
- wcstring target_str;
- const wchar_t *target=NULL;
+ wcstring target_str;
+ const wchar_t *target=NULL;
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_REDIRECTION;
- tok_next( &tok );
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_REDIRECTION;
+ tok_next(&tok);
- /*
- Check that we are redirecting into a file
- */
-
- switch( tok_last_type( &tok ) )
- {
- case TOK_STRING:
- {
- target_str = tok_last( &tok );
- if (expand_one(target_str, EXPAND_SKIP_CMDSUBST)) {
- target = target_str.c_str();
- }
/*
- Redirect filename may contain a cmdsubst.
- If so, it will be ignored/not flagged.
+ Check that we are redirecting into a file
*/
- }
+
+ switch (tok_last_type(&tok))
+ {
+ case TOK_STRING:
+ {
+ target_str = tok_last(&tok);
+ if (expand_one(target_str, EXPAND_SKIP_CMDSUBST))
+ {
+ target = target_str.c_str();
+ }
+ /*
+ Redirect filename may contain a cmdsubst.
+ If so, it will be ignored/not flagged.
+ */
+ }
break;
- default:
- {
- size_t pos = tok_get_pos(&tok);
- if (pos < color.size()) {
- color.at(pos) = HIGHLIGHT_ERROR;
- }
- if( error )
- error->push_back(L"Invalid redirection");
- }
+ default:
+ {
+ size_t pos = tok_get_pos(&tok);
+ if (pos < color.size())
+ {
+ color.at(pos) = HIGHLIGHT_ERROR;
+ }
+ if (error)
+ error->push_back(L"Invalid redirection");
+ }
- }
+ }
- if( target != 0 )
- {
- wcstring dir = target;
- size_t slash_idx = dir.find_last_of(L'/');
- struct stat buff;
- /*
- If file is in directory other than '.', check
- that the directory exists.
- */
- if( slash_idx != wcstring::npos )
- {
- dir.resize(slash_idx);
- if( wstat( dir, &buff ) == -1 )
+ if (target != 0)
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- if( error )
- error->push_back(format_string(L"Directory \'%ls\' does not exist", dir.c_str()));
+ wcstring dir = target;
+ size_t slash_idx = dir.find_last_of(L'/');
+ struct stat buff;
+ /*
+ If file is in directory other than '.', check
+ that the directory exists.
+ */
+ if (slash_idx != wcstring::npos)
+ {
+ dir.resize(slash_idx);
+ if (wstat(dir, &buff) == -1)
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ if (error)
+ error->push_back(format_string(L"Directory \'%ls\' does not exist", dir.c_str()));
+
+ }
+ }
+ /*
+ If the file is read from or appended to, check
+ if it exists.
+ */
+ if (last_type == TOK_REDIRECT_IN ||
+ last_type == TOK_REDIRECT_APPEND)
+ {
+ if (wstat(target, &buff) == -1)
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ if (error)
+ error->push_back(format_string(L"File \'%ls\' does not exist", target));
+ }
+ }
+ if (last_type == TOK_REDIRECT_NOCLOB)
+ {
+ if (wstat(target, &buff) != -1)
+ {
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ if (error)
+ error->push_back(format_string(L"File \'%ls\' exists", target));
+ }
+ }
}
- }
-
- /*
- If the file is read from or appended to, check
- if it exists.
- */
- if( last_type == TOK_REDIRECT_IN ||
- last_type == TOK_REDIRECT_APPEND )
- {
- if( wstat( target, &buff ) == -1 )
+ break;
+ }
+
+ case TOK_PIPE:
+ case TOK_BACKGROUND:
+ {
+ if (had_cmd)
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- if( error )
- error->push_back(format_string(L"File \'%ls\' does not exist", target));
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_END;
+ had_cmd = 0;
+ use_command = 1;
+ use_function = 1;
+ use_builtin = 1;
+ accept_switches = 1;
}
- }
- if( last_type == TOK_REDIRECT_NOCLOB )
- {
- if( wstat( target, &buff ) != -1 )
+ else
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- if( error )
- error->push_back(format_string(L"File \'%ls\' exists", target));
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ if (error)
+ error->push_back(L"No job to put in background");
}
- }
+
+ break;
}
- break;
- }
- case TOK_PIPE:
- case TOK_BACKGROUND:
- {
- if( had_cmd )
+ case TOK_END:
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_END;
- had_cmd = 0;
- use_command = 1;
- use_function = 1;
- use_builtin = 1;
- accept_switches = 1;
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_END;
+ had_cmd = 0;
+ use_command = 1;
+ use_function = 1;
+ use_builtin = 1;
+ accept_switches = 1;
+ break;
}
- else
+
+ case TOK_COMMENT:
{
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- if( error )
- error->push_back(L"No job to put in background" );
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_COMMENT;
+ break;
}
- break;
- }
-
- case TOK_END:
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_END;
- had_cmd = 0;
- use_command = 1;
- use_function = 1;
- use_builtin = 1;
- accept_switches = 1;
- break;
- }
-
- case TOK_COMMENT:
- {
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_COMMENT;
- break;
- }
-
- case TOK_ERROR:
- default:
- {
- /*
- If the tokenizer reports an error, highlight it as such.
- */
- if( error )
- error->push_back(tok_last( &tok));
- color.at(tok_get_pos( &tok )) = HIGHLIGHT_ERROR;
- break;
- }
+ case TOK_ERROR:
+ default:
+ {
+ /*
+ If the tokenizer reports an error, highlight it as such.
+ */
+ if (error)
+ error->push_back(tok_last(&tok));
+ color.at(tok_get_pos(&tok)) = HIGHLIGHT_ERROR;
+ break;
+ }
+ }
}
- }
- tok_destroy( &tok );
+ tok_destroy(&tok);
}
// PCA This function does I/O, (calls is_potential_path, path_get_path, maybe others) and so ought to only run on a background thread
-void highlight_shell( const wcstring &buff, std::vector<int> &color, size_t pos, wcstring_list_t *error, const env_vars_snapshot_t &vars )
+void highlight_shell(const wcstring &buff, std::vector<int> &color, size_t pos, wcstring_list_t *error, const env_vars_snapshot_t &vars)
{
ASSERT_IS_BACKGROUND_THREAD();
@@ -1270,8 +1316,8 @@ void highlight_shell( const wcstring &buff, std::vector<int> &color, size_t pos,
assert(buff.size() == color.size());
- if( length == 0 )
- return;
+ if (length == 0)
+ return;
std::fill(color.begin(), color.end(), -1);
@@ -1281,78 +1327,79 @@ void highlight_shell( const wcstring &buff, std::vector<int> &color, size_t pos,
/* Tokenize the string */
tokenize(buff.c_str(), color, pos, error, working_directory, vars);
- /*
- Locate and syntax highlight cmdsubsts recursively
- */
+ /*
+ Locate and syntax highlight cmdsubsts recursively
+ */
- wchar_t * const subbuff = wcsdup(buff.c_str());
+ wchar_t * const subbuff = wcsdup(buff.c_str());
wchar_t * subpos = subbuff;
- int done=0;
+ int done=0;
- while( 1 )
- {
- wchar_t *begin, *end;
-
- if( parse_util_locate_cmdsubst(subpos, &begin, &end, 1) <= 0)
+ while (1)
{
- break;
- }
+ wchar_t *begin, *end;
- if( !*end )
- done=1;
- else
- *end=0;
+ if (parse_util_locate_cmdsubst(subpos, &begin, &end, 1) <= 0)
+ {
+ break;
+ }
+
+ if (!*end)
+ done=1;
+ else
+ *end=0;
//our subcolors start at color + (begin-subbuff)+1
size_t start = begin - subbuff + 1, len = wcslen(begin + 1);
std::vector<int> subcolors(len, -1);
- highlight_shell( begin+1, subcolors, -1, error, vars );
+ highlight_shell(begin+1, subcolors, -1, error, vars);
// insert subcolors
std::copy(subcolors.begin(), subcolors.end(), color.begin() + start);
// highlight the end of the subcommand
assert(end >= subbuff);
- if ((size_t)(end - subbuff) < length) {
+ if ((size_t)(end - subbuff) < length)
+ {
color.at(end-subbuff)=HIGHLIGHT_OPERATOR;
}
- if( done )
- break;
+ if (done)
+ break;
- subpos = end+1;
- }
+ subpos = end+1;
+ }
free(subbuff);
- /*
- The highlighting code only changes the first element when the
- color changes. This fills in the rest.
- */
- int last_val=0;
- for( size_t i=0; i < buff.size(); i++ )
- {
- if( color.at(i) >= 0 )
- last_val = color.at(i);
- else
- color.at(i) = last_val;
- }
+ /*
+ The highlighting code only changes the first element when the
+ color changes. This fills in the rest.
+ */
+ int last_val=0;
+ for (size_t i=0; i < buff.size(); i++)
+ {
+ if (color.at(i) >= 0)
+ last_val = color.at(i);
+ else
+ color.at(i) = last_val;
+ }
- /*
- Color potentially valid paths in a special path color if they
- are the current token.
- For reasons that I don't yet understand, it's required that pos be allowed to be length (e.g. when backspacing).
- */
- if( pos <= length )
- {
+ /*
+ Color potentially valid paths in a special path color if they
+ are the current token.
+ For reasons that I don't yet understand, it's required that pos be allowed to be length (e.g. when backspacing).
+ */
+ if (pos <= length)
+ {
const wchar_t *cbuff = buff.c_str();
- const wchar_t *tok_begin, *tok_end;
- parse_util_token_extent( cbuff, pos, &tok_begin, &tok_end, 0, 0 );
- if( tok_begin && tok_end )
- {
- wcstring token(tok_begin, tok_end-tok_begin);
- const wcstring_list_t working_directory_list(1, working_directory);
+ const wchar_t *tok_begin, *tok_end;
+ parse_util_token_extent(cbuff, pos, &tok_begin, &tok_end, 0, 0);
+ if (tok_begin && tok_end)
+ {
+ wcstring token(tok_begin, tok_end-tok_begin);
+ const wcstring_list_t working_directory_list(1, working_directory);
if (unescape_string(token, 1))
{
/* Big hack: is_potential_path expects a tilde, but unescape_string gives us HOME_DIRECTORY. Put it back. */
@@ -1360,31 +1407,32 @@ void highlight_shell( const wcstring &buff, std::vector<int> &color, size_t pos,
token.at(0) = L'~';
if (is_potential_path(token, working_directory_list, PATH_EXPAND_TILDE))
{
- for( ptrdiff_t i=tok_begin-cbuff; i < (tok_end-cbuff); i++ )
+ for (ptrdiff_t i=tok_begin-cbuff; i < (tok_end-cbuff); i++)
{
// Don't color HIGHLIGHT_ERROR because it looks dorky. For example, trying to cd into a non-directory would show an underline and also red.
- if (! (color.at(i) & HIGHLIGHT_ERROR)) {
+ if (!(color.at(i) & HIGHLIGHT_ERROR))
+ {
color.at(i) |= HIGHLIGHT_VALID_PATH;
}
}
}
}
+ }
}
- }
- highlight_universal_internal( buff, color, pos );
+ highlight_universal_internal(buff, color, pos);
- /*
- Spaces should not be highlighted at all, since it makes cursor look funky in some terminals
- */
- for( size_t i=0; i < buff.size(); i++ )
- {
- if( iswspace(buff.at(i)) )
+ /*
+ Spaces should not be highlighted at all, since it makes cursor look funky in some terminals
+ */
+ for (size_t i=0; i < buff.size(); i++)
{
- color.at(i)=0;
+ if (iswspace(buff.at(i)))
+ {
+ color.at(i)=0;
+ }
}
- }
}
@@ -1392,116 +1440,117 @@ void highlight_shell( const wcstring &buff, std::vector<int> &color, size_t pos,
/**
Perform quote and parenthesis highlighting on the specified string.
*/
-static void highlight_universal_internal( const wcstring &buffstr, std::vector<int> &color, size_t pos )
+static void highlight_universal_internal(const wcstring &buffstr, std::vector<int> &color, size_t pos)
{
assert(buffstr.size() == color.size());
- if( pos < buffstr.size() )
- {
-
- /*
- Highlight matching quotes
- */
- if( (buffstr.at(pos) == L'\'') || (buffstr.at(pos) == L'\"') )
+ if (pos < buffstr.size())
{
- std::vector<long> lst;
- int level=0;
- wchar_t prev_q=0;
+ /*
+ Highlight matching quotes
+ */
+ if ((buffstr.at(pos) == L'\'') || (buffstr.at(pos) == L'\"'))
+ {
+ std::vector<long> lst;
+
+ int level=0;
+ wchar_t prev_q=0;
const wchar_t * const buff = buffstr.c_str();
- const wchar_t *str = buff;
+ const wchar_t *str = buff;
- int match_found=0;
+ int match_found=0;
- while(*str)
- {
- switch( *str )
- {
- case L'\\':
- str++;
- break;
- case L'\"':
- case L'\'':
- if( level == 0 )
- {
- level++;
- lst.push_back(str-buff);
- prev_q = *str;
- }
- else
+ while (*str)
{
- if( prev_q == *str )
- {
- long pos1, pos2;
-
- level--;
- pos1 = lst.back();
- pos2 = str-buff;
- if( pos1==pos || pos2==pos )
+ switch (*str)
{
- color.at(pos1)|=HIGHLIGHT_MATCH<<16;
- color.at(pos2)|=HIGHLIGHT_MATCH<<16;
- match_found = 1;
+ case L'\\':
+ str++;
+ break;
+ case L'\"':
+ case L'\'':
+ if (level == 0)
+ {
+ level++;
+ lst.push_back(str-buff);
+ prev_q = *str;
+ }
+ else
+ {
+ if (prev_q == *str)
+ {
+ long pos1, pos2;
+
+ level--;
+ pos1 = lst.back();
+ pos2 = str-buff;
+ if (pos1==pos || pos2==pos)
+ {
+ color.at(pos1)|=HIGHLIGHT_MATCH<<16;
+ color.at(pos2)|=HIGHLIGHT_MATCH<<16;
+ match_found = 1;
+ }
+ prev_q = *str==L'\"'?L'\'':L'\"';
+ }
+ else
+ {
+ level++;
+ lst.push_back(str-buff);
+ prev_q = *str;
+ }
+ }
+
+ break;
}
- prev_q = *str==L'\"'?L'\'':L'\"';
- }
- else
- {
- level++;
- lst.push_back(str-buff);
- prev_q = *str;
- }
+ if ((*str == L'\0'))
+ break;
+
+ str++;
}
- break;
+ if (!match_found)
+ color.at(pos) = HIGHLIGHT_ERROR<<16;
}
- if( (*str == L'\0'))
- break;
- str++;
- }
-
- if( !match_found )
- color.at(pos) = HIGHLIGHT_ERROR<<16;
- }
-
- /*
- Highlight matching parenthesis
- */
+ /*
+ Highlight matching parenthesis
+ */
const wchar_t c = buffstr.at(pos);
- if( wcschr( L"()[]{}", c ) )
- {
- int step = wcschr(L"({[", c)?1:-1;
- wchar_t dec_char = *(wcschr( L"()[]{}", c ) + step);
- wchar_t inc_char = c;
- int level = 0;
- int match_found=0;
- for (long i=pos; i >= 0 && (size_t)i < buffstr.size(); i+=step) {
- const wchar_t test_char = buffstr.at(i);
- if( test_char == inc_char )
- level++;
- if( test_char == dec_char )
- level--;
- if( level == 0 )
+ if (wcschr(L"()[]{}", c))
{
- long pos2 = i;
- color.at(pos)|=HIGHLIGHT_MATCH<<16;
- color.at(pos2)|=HIGHLIGHT_MATCH<<16;
- match_found=1;
- break;
- }
- }
+ int step = wcschr(L"({[", c)?1:-1;
+ wchar_t dec_char = *(wcschr(L"()[]{}", c) + step);
+ wchar_t inc_char = c;
+ int level = 0;
+ int match_found=0;
+ for (long i=pos; i >= 0 && (size_t)i < buffstr.size(); i+=step)
+ {
+ const wchar_t test_char = buffstr.at(i);
+ if (test_char == inc_char)
+ level++;
+ if (test_char == dec_char)
+ level--;
+ if (level == 0)
+ {
+ long pos2 = i;
+ color.at(pos)|=HIGHLIGHT_MATCH<<16;
+ color.at(pos2)|=HIGHLIGHT_MATCH<<16;
+ match_found=1;
+ break;
+ }
+ }
- if( !match_found )
- color[pos] = HIGHLIGHT_ERROR<<16;
+ if (!match_found)
+ color[pos] = HIGHLIGHT_ERROR<<16;
+ }
}
- }
}
-void highlight_universal( const wcstring &buff, std::vector<int> &color, size_t pos, wcstring_list_t *error, const env_vars_snapshot_t &vars )
+void highlight_universal(const wcstring &buff, std::vector<int> &color, size_t pos, wcstring_list_t *error, const env_vars_snapshot_t &vars)
{
assert(buff.size() == color.size());
std::fill(color.begin(), color.end(), 0);
- highlight_universal_internal( buff, color, pos );
+ highlight_universal_internal(buff, color, pos);
}