mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-28 04:35:09 +00:00
lint: Use early exit/continue
This commit is contained in:
parent
eab836864e
commit
6192e2453e
1 changed files with 111 additions and 109 deletions
|
@ -122,73 +122,73 @@ bool is_potential_path(const wcstring &potential_path_fragment, const wcstring_l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_magic && !clean_potential_path_fragment.empty()) {
|
if (has_magic || clean_potential_path_fragment.empty()) {
|
||||||
// Don't test the same path multiple times, which can happen if the path is absolute and the
|
return result;
|
||||||
// CDPATH contains multiple entries.
|
}
|
||||||
std::set<wcstring> checked_paths;
|
|
||||||
|
|
||||||
// Keep a cache of which paths / filesystems are case sensitive.
|
// Don't test the same path multiple times, which can happen if the path is absolute and the
|
||||||
case_sensitivity_cache_t case_sensitivity_cache;
|
// CDPATH contains multiple entries.
|
||||||
|
std::set<wcstring> checked_paths;
|
||||||
|
|
||||||
for (size_t wd_idx = 0; wd_idx < directories.size() && !result; wd_idx++) {
|
// Keep a cache of which paths / filesystems are case sensitive.
|
||||||
const wcstring &wd = directories.at(wd_idx);
|
case_sensitivity_cache_t case_sensitivity_cache;
|
||||||
|
|
||||||
const wcstring abs_path =
|
for (size_t wd_idx = 0; wd_idx < directories.size() && !result; wd_idx++) {
|
||||||
path_apply_working_directory(clean_potential_path_fragment, wd);
|
const wcstring &wd = directories.at(wd_idx);
|
||||||
|
|
||||||
// Skip this if it's empty or we've already checked it.
|
const wcstring abs_path = path_apply_working_directory(clean_potential_path_fragment, wd);
|
||||||
if (abs_path.empty() || checked_paths.count(abs_path)) continue;
|
|
||||||
checked_paths.insert(abs_path);
|
|
||||||
|
|
||||||
// If we end with a slash, then it must be a directory.
|
// Skip this if it's empty or we've already checked it.
|
||||||
bool must_be_full_dir = abs_path.at(abs_path.size() - 1) == L'/';
|
if (abs_path.empty() || checked_paths.count(abs_path)) continue;
|
||||||
if (must_be_full_dir) {
|
checked_paths.insert(abs_path);
|
||||||
struct stat buf;
|
|
||||||
if (0 == wstat(abs_path, &buf) && S_ISDIR(buf.st_mode)) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// We do not end with a slash; it does not have to be a directory.
|
|
||||||
DIR *dir = NULL;
|
|
||||||
const wcstring dir_name = wdirname(abs_path);
|
|
||||||
const wcstring filename_fragment = wbasename(abs_path);
|
|
||||||
if (dir_name == L"/" && filename_fragment == L"/") {
|
|
||||||
// cd ///.... No autosuggestion.
|
|
||||||
result = true;
|
|
||||||
} else if ((dir = wopendir(dir_name))) {
|
|
||||||
// Check if we're case insensitive.
|
|
||||||
const bool do_case_insensitive =
|
|
||||||
fs_is_case_insensitive(dir_name, dirfd(dir), case_sensitivity_cache);
|
|
||||||
|
|
||||||
wcstring matched_file;
|
// If we end with a slash, then it must be a directory.
|
||||||
|
bool must_be_full_dir = abs_path.at(abs_path.size() - 1) == L'/';
|
||||||
|
if (must_be_full_dir) {
|
||||||
|
struct stat buf;
|
||||||
|
if (0 == wstat(abs_path, &buf) && S_ISDIR(buf.st_mode)) {
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We do not end with a slash; it does not have to be a directory.
|
||||||
|
DIR *dir = NULL;
|
||||||
|
const wcstring dir_name = wdirname(abs_path);
|
||||||
|
const wcstring filename_fragment = wbasename(abs_path);
|
||||||
|
if (dir_name == L"/" && filename_fragment == L"/") {
|
||||||
|
// cd ///.... No autosuggestion.
|
||||||
|
result = true;
|
||||||
|
} else if ((dir = wopendir(dir_name))) {
|
||||||
|
// Check if we're case insensitive.
|
||||||
|
const bool do_case_insensitive =
|
||||||
|
fs_is_case_insensitive(dir_name, dirfd(dir), case_sensitivity_cache);
|
||||||
|
|
||||||
// We opened the dir_name; look for a string where the base name prefixes it
|
wcstring matched_file;
|
||||||
// Don't ask for the is_dir value unless we care, because it can cause extra
|
|
||||||
// filesystem access.
|
|
||||||
wcstring ent;
|
|
||||||
bool is_dir = false;
|
|
||||||
while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL)) {
|
|
||||||
// Maybe skip directories.
|
|
||||||
if (require_dir && !is_dir) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string_prefixes_string(filename_fragment, ent) ||
|
// We opened the dir_name; look for a string where the base name prefixes it Don't
|
||||||
(do_case_insensitive &&
|
// ask for the is_dir value unless we care, because it can cause extra filesystem
|
||||||
string_prefixes_string_case_insensitive(filename_fragment, ent))) {
|
// access.
|
||||||
// We matched.
|
wcstring ent;
|
||||||
matched_file = ent;
|
bool is_dir = false;
|
||||||
break;
|
while (wreaddir_resolving(dir, dir_name, ent, require_dir ? &is_dir : NULL)) {
|
||||||
}
|
// Maybe skip directories.
|
||||||
|
if (require_dir && !is_dir) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
closedir(dir);
|
|
||||||
|
|
||||||
// We succeeded if we found a match.
|
if (string_prefixes_string(filename_fragment, ent) ||
|
||||||
result = !matched_file.empty();
|
(do_case_insensitive &&
|
||||||
|
string_prefixes_string_case_insensitive(filename_fragment, ent))) {
|
||||||
|
matched_file = ent; // we matched
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
result = !matched_file.empty(); // we succeeded if we found a match
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,24 +354,25 @@ bool autosuggest_validate_from_history(const history_item_t &item,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not handled specially, handle it here.
|
if (handled) {
|
||||||
if (!handled) {
|
return suggestionOK;
|
||||||
bool cmd_ok = false;
|
}
|
||||||
|
|
||||||
if (path_get_path(parsed_command, NULL)) {
|
// Not handled specially so handle it here.
|
||||||
cmd_ok = true;
|
bool cmd_ok = false;
|
||||||
} else if (builtin_exists(parsed_command) ||
|
if (path_get_path(parsed_command, NULL)) {
|
||||||
function_exists_no_autoload(parsed_command, vars)) {
|
cmd_ok = true;
|
||||||
cmd_ok = true;
|
} else if (builtin_exists(parsed_command) ||
|
||||||
}
|
function_exists_no_autoload(parsed_command, vars)) {
|
||||||
|
cmd_ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd_ok) {
|
if (cmd_ok) {
|
||||||
const path_list_t &paths = item.get_required_paths();
|
const path_list_t &paths = item.get_required_paths();
|
||||||
if (paths.empty()) {
|
if (paths.empty()) {
|
||||||
suggestionOK = true;
|
suggestionOK = true;
|
||||||
} else {
|
} else {
|
||||||
suggestionOK = detector.paths_are_valid(paths);
|
suggestionOK = detector.paths_are_valid(paths);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1093,26 +1094,27 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
|
||||||
// Color the command.
|
// Color the command.
|
||||||
const parse_node_t *cmd_node =
|
const parse_node_t *cmd_node =
|
||||||
parse_tree.get_child(node, 0, parse_token_type_string);
|
parse_tree.get_child(node, 0, parse_token_type_string);
|
||||||
if (cmd_node != NULL && cmd_node->has_source()) {
|
if (cmd_node == NULL || !cmd_node->has_source()) {
|
||||||
bool is_valid_cmd = false;
|
break; // not much as we can do without a node that has source text
|
||||||
if (!this->io_ok) {
|
|
||||||
// We cannot check if the command is invalid, so just assume it's valid.
|
|
||||||
is_valid_cmd = true;
|
|
||||||
} else {
|
|
||||||
// Check to see if the command is valid.
|
|
||||||
wcstring cmd(buff, cmd_node->source_start, cmd_node->source_length);
|
|
||||||
|
|
||||||
// Try expanding it. If we cannot, it's an error.
|
|
||||||
bool expanded = expand_one(
|
|
||||||
cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS);
|
|
||||||
if (expanded && !has_expand_reserved(cmd)) {
|
|
||||||
is_valid_cmd =
|
|
||||||
command_is_valid(cmd, decoration, working_directory, vars);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->color_node(*cmd_node,
|
|
||||||
is_valid_cmd ? highlight_spec_command : highlight_spec_error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_valid_cmd = false;
|
||||||
|
if (!this->io_ok) {
|
||||||
|
// We cannot check if the command is invalid, so just assume it's valid.
|
||||||
|
is_valid_cmd = true;
|
||||||
|
} else {
|
||||||
|
// Check to see if the command is valid.
|
||||||
|
wcstring cmd(buff, cmd_node->source_start, cmd_node->source_length);
|
||||||
|
|
||||||
|
// Try expanding it. If we cannot, it's an error.
|
||||||
|
bool expanded = expand_one(
|
||||||
|
cmd, EXPAND_SKIP_CMDSUBST | EXPAND_SKIP_VARIABLES | EXPAND_SKIP_JOBS);
|
||||||
|
if (expanded && !has_expand_reserved(cmd)) {
|
||||||
|
is_valid_cmd = command_is_valid(cmd, decoration, working_directory, vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->color_node(*cmd_node,
|
||||||
|
is_valid_cmd ? highlight_spec_command : highlight_spec_error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case symbol_arguments_or_redirections_list:
|
case symbol_arguments_or_redirections_list:
|
||||||
|
@ -1141,29 +1143,29 @@ const highlighter_t::color_array_t &highlighter_t::highlight() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->io_ok && this->cursor_pos <= this->buff.size()) {
|
if (!this->io_ok || this->cursor_pos > this->buff.size()) {
|
||||||
// If the cursor is over an argument, and that argument is a valid path, underline it.
|
return color_array;
|
||||||
for (parse_node_tree_t::const_iterator iter = parse_tree.begin(); iter != parse_tree.end();
|
}
|
||||||
++iter) {
|
|
||||||
const parse_node_t &node = *iter;
|
|
||||||
|
|
||||||
// Must be an argument with source.
|
// If the cursor is over an argument, and that argument is a valid path, underline it.
|
||||||
if (node.type != symbol_argument || !node.has_source()) continue;
|
for (parse_node_tree_t::const_iterator iter = parse_tree.begin(); iter != parse_tree.end();
|
||||||
|
++iter) {
|
||||||
|
const parse_node_t &node = *iter;
|
||||||
|
|
||||||
// See if this node contains the cursor. We check <= source_length so that, when
|
// Must be an argument with source.
|
||||||
// backspacing (and the cursor is just beyond the last token), we may still underline
|
if (node.type != symbol_argument || !node.has_source()) continue;
|
||||||
// it.
|
|
||||||
if (this->cursor_pos >= node.source_start &&
|
// See if this node contains the cursor. We check <= source_length so that, when backspacing
|
||||||
this->cursor_pos - node.source_start <= node.source_length &&
|
// (and the cursor is just beyond the last token), we may still underline it.
|
||||||
node_is_potential_path(buff, node, working_directory)) {
|
if (this->cursor_pos >= node.source_start &&
|
||||||
// It is, underline it.
|
this->cursor_pos - node.source_start <= node.source_length &&
|
||||||
for (size_t i = node.source_start; i < node.source_start + node.source_length;
|
node_is_potential_path(buff, node, working_directory)) {
|
||||||
i++) {
|
// It is, underline it.
|
||||||
// Don't color highlight_spec_error because it looks dorky. For example,
|
for (size_t i = node.source_start; i < node.source_start + node.source_length; i++) {
|
||||||
// trying to cd into a non-directory would show an underline and also red.
|
// Don't color highlight_spec_error because it looks dorky. For example,
|
||||||
if (highlight_get_primary(this->color_array.at(i)) != highlight_spec_error) {
|
// trying to cd into a non-directory would show an underline and also red.
|
||||||
this->color_array.at(i) |= highlight_modifier_valid_path;
|
if (highlight_get_primary(this->color_array.at(i)) != highlight_spec_error) {
|
||||||
}
|
this->color_array.at(i) |= highlight_modifier_valid_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue