HackStudio: Handle autocomplete inside #include's <> and ""

This commit is contained in:
thislooksfun 2021-10-26 23:41:44 -05:00 committed by Andreas Kling
parent 4143f6f906
commit a6a71869d7
2 changed files with 21 additions and 4 deletions

View file

@ -75,7 +75,7 @@ Vector<GUI::AutocompleteProvider::Entry> CppComprehensionEngine::get_suggestions
auto containing_token = document.parser().token_at(position);
if (containing_token.has_value() && containing_token->type() == Token::Type::IncludePath) {
auto results = try_autocomplete_include(document, containing_token.value());
auto results = try_autocomplete_include(document, containing_token.value(), position);
if (results.has_value())
return results.value();
}
@ -637,7 +637,7 @@ Vector<StringView> CppComprehensionEngine::scope_of_node(const ASTNode& node) co
return parent_scope;
}
Optional<Vector<GUI::AutocompleteProvider::Entry>> CppComprehensionEngine::try_autocomplete_include(const DocumentData&, Token include_path_token)
Optional<Vector<GUI::AutocompleteProvider::Entry>> CppComprehensionEngine::try_autocomplete_include(const DocumentData&, Token include_path_token, Cpp::Position const& cursor_position) const
{
VERIFY(include_path_token.type() == Token::Type::IncludePath);
auto partial_include = include_path_token.text().trim_whitespace();
@ -648,14 +648,27 @@ Optional<Vector<GUI::AutocompleteProvider::Entry>> CppComprehensionEngine::try_a
} include_type { Project };
String include_root;
bool already_has_suffix = false;
if (partial_include.starts_with("<")) {
include_root = "/usr/include/";
include_type = System;
if (partial_include.ends_with(">")) {
already_has_suffix = true;
partial_include = partial_include.substring_view(0, partial_include.length() - 1).trim_whitespace();
}
} else if (partial_include.starts_with("\"")) {
include_root = filedb().project_root();
if (partial_include.length() > 1 && partial_include.ends_with("\"")) {
already_has_suffix = true;
partial_include = partial_include.substring_view(0, partial_include.length() - 1).trim_whitespace();
}
} else
return {};
// The cursor is past the end of the <> or "", and so should not trigger autocomplete.
if (already_has_suffix && include_path_token.end() <= cursor_position)
return {};
auto last_slash = partial_include.find_last('/');
auto include_dir = String::empty();
auto partial_basename = partial_include.substring_view((last_slash.has_value() ? last_slash.value() : 0) + 1);
@ -674,7 +687,11 @@ Optional<Vector<GUI::AutocompleteProvider::Entry>> CppComprehensionEngine::try_a
if (!(path.ends_with(".h") || Core::File::is_directory(LexicalPath::join(full_dir, path).string())))
continue;
if (path.starts_with(partial_basename)) {
auto completion = include_type == System ? String::formatted("<{}>", path) : String::formatted("\"{}\"", path);
// FIXME: Place the cursor after the trailing > or ", even if it was
// already typed.
auto prefix = include_type == System ? "<" : "\"";
auto suffix = include_type == System ? ">" : "\"";
auto completion = String::formatted("{}{}{}", prefix, path, already_has_suffix ? "" : suffix);
options.append({ completion, partial_basename.length() + 1, GUI::AutocompleteProvider::Language::Cpp, path });
}
}

View file

@ -129,7 +129,7 @@ private:
OwnPtr<DocumentData> create_document_data(String&& text, const String& filename);
Optional<Vector<GUI::AutocompleteProvider::Entry>> try_autocomplete_property(const DocumentData&, const ASTNode&, Optional<Token> containing_token) const;
Optional<Vector<GUI::AutocompleteProvider::Entry>> try_autocomplete_name(const DocumentData&, const ASTNode&, Optional<Token> containing_token) const;
Optional<Vector<GUI::AutocompleteProvider::Entry>> try_autocomplete_include(const DocumentData&, Token include_path_token);
Optional<Vector<GUI::AutocompleteProvider::Entry>> try_autocomplete_include(const DocumentData&, Token include_path_token, Cpp::Position const& cursor_position) const;
static bool is_symbol_available(const Symbol&, const Vector<StringView>& current_scope, const Vector<StringView>& reference_scope);
Optional<FunctionParamsHint> get_function_params_hint(DocumentData const&, FunctionCall&, size_t argument_index);