1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 21:27:44 +00:00

Shell: Do not manually write to the editor buffer when completing paths

This commit is contained in:
AnotherTest 2020-04-12 22:12:39 +04:30 committed by Andreas Kling
parent 6d5d668585
commit 2a460aa369

View file

@ -1080,7 +1080,6 @@ int main(int argc, char** argv)
String path; String path;
Vector<String> suggestions; Vector<String> suggestions;
editor.suggest(token.length(), 0);
ssize_t last_slash = token.length() - 1; ssize_t last_slash = token.length() - 1;
while (last_slash >= 0 && token[last_slash] != '/') while (last_slash >= 0 && token[last_slash] != '/')
--last_slash; --last_slash;
@ -1099,57 +1098,36 @@ int main(int argc, char** argv)
path = g.cwd; path = g.cwd;
} }
// This is a bit naughty, but necessary without reordering the loop // the invariant part of the token is actually just the last segment
// below. The loop terminates early, meaning that // e.g. in `cd /foo/bar', 'bar' is the invariant
// the suggestions list is incomplete. // since we are not suggesting anything starting with
// We only do this if the token is empty though. // `/foo/', but rather just `bar...'
if (token.is_empty()) { editor.suggest(token.length(), 0);
Core::DirIterator suggested_files(path, Core::DirIterator::SkipDots);
while (suggested_files.has_next()) {
suggestions.append(suggested_files.next_path());
}
}
String completion;
bool seen_others = false;
Core::DirIterator files(path, Core::DirIterator::SkipDots); Core::DirIterator files(path, Core::DirIterator::SkipDots);
while (files.has_next()) { while (files.has_next()) {
auto file = files.next_path(); auto file = files.next_path();
if (file.starts_with(token)) { if (file.starts_with(token)) {
if (!token.is_empty()) suggestions.append(file);
suggestions.append(file);
if (completion.is_empty()) {
completion = file; // Will only be set once.
} else {
editor.cut_mismatching_chars(completion, file, token.length());
if (completion.is_empty()) // We cut everything off!
return suggestions;
seen_others = true;
}
} }
} }
if (completion.is_empty())
return suggestions;
// If we have characters to add, add them.
if (completion.length() > token.length())
editor.insert(completion.substring(token.length(), completion.length() - token.length()));
// If we have a single match and it's a directory, we add a slash. If it's // If we have a single match and it's a directory, we add a slash. If it's
// a regular file, we add a space, unless we already have one. // a regular file, we add a space, unless we already have one.
if (!seen_others) { if (suggestions.size() == 1) {
auto& completion = suggestions[0];
String file_path = String::format("%s/%s", path.characters(), completion.characters()); String file_path = String::format("%s/%s", path.characters(), completion.characters());
struct stat program_status; struct stat program_status;
int stat_error = stat(file_path.characters(), &program_status); int stat_error = stat(file_path.characters(), &program_status);
if (!stat_error) { if (!stat_error) {
if (S_ISDIR(program_status.st_mode)) if (S_ISDIR(program_status.st_mode))
editor.insert('/'); completion = String::format("%s/", suggestions[0].characters());
else if (editor.cursor() == editor.buffer().size() || editor.buffer_at(editor.cursor()) != ' ') else if (editor.cursor() == editor.buffer().size() || editor.buffer_at(editor.cursor()) != ' ')
editor.insert(' '); completion = String::format("%s ", suggestions[0].characters());
} }
} }
return {}; // Return an empty vector return suggestions;
}; };
signal(SIGINT, [](int) { signal(SIGINT, [](int) {