|
52 | 52 | #include "editor/editor_string_names.h" |
53 | 53 | #include "editor/file_system/editor_file_system.h" |
54 | 54 | #include "editor/settings/editor_settings.h" |
| 55 | +#include "scene/gui/code_edit.h" |
55 | 56 | #endif |
56 | 57 |
|
57 | 58 | Vector<String> GDScriptLanguage::get_comment_delimiters() const { |
@@ -3443,6 +3444,55 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c |
3443 | 3444 | r_forced = r_result.size() > 0; |
3444 | 3445 | } |
3445 | 3446 |
|
| 3447 | +namespace { |
| 3448 | + |
| 3449 | +/** |
| 3450 | + * @brief Used as the `on_applied` callback for GDScript completions of category `COMPLETION_OVERRIDE_METHOD`. |
| 3451 | + * This method will attempt to automatically apply the `@override` annotation when using completion to generate an override. |
| 3452 | + * If the `@override` annotation is already present, nothing will occur. |
| 3453 | + * |
| 3454 | + * @param code_edit The code editor instance. |
| 3455 | + * @param caret The caret that was used for this application of the completion. |
| 3456 | + */ |
| 3457 | +void _update_overrides_after_completion(CodeEdit *code_edit, int caret) { |
| 3458 | + int line = code_edit->get_caret_line(caret); |
| 3459 | + // Backtrack in the current line and upwards a few lines to search for `@override`. If we don't see it, apply it inline before the `func` keyword. |
| 3460 | + bool has_override_annot = false; |
| 3461 | + int lines_traversed = 0; |
| 3462 | + int func_line = -1; // Generally speaking we expect the line with `func` to be the current line, but for sanity we'll search for it anyway. |
| 3463 | + |
| 3464 | + while (!has_override_annot && lines_traversed < 10 && line >= 0) { |
| 3465 | + String text = code_edit->get_line(line); |
| 3466 | + |
| 3467 | + if (text.contains("func")) { |
| 3468 | + if (func_line == -1) { |
| 3469 | + func_line = line; |
| 3470 | + } else { |
| 3471 | + break; // We've hit another `func` decl. Anything in or above this line doesn't apply to this function anymore. |
| 3472 | + } |
| 3473 | + } |
| 3474 | + |
| 3475 | + if (text.contains("@override")) { |
| 3476 | + has_override_annot = true; |
| 3477 | + break; |
| 3478 | + } |
| 3479 | + |
| 3480 | + line--; |
| 3481 | + lines_traversed++; |
| 3482 | + } |
| 3483 | + |
| 3484 | + // TODO: Review stage - I'd prefer to insert the `@override` on the line before `func`, but I'm not sure how to do that. |
| 3485 | + if (!has_override_annot && func_line != -1) { |
| 3486 | + String text = code_edit->get_line(func_line); |
| 3487 | + code_edit->set_line(func_line, "@override " + text); |
| 3488 | + int caret_col = code_edit->get_caret_column(caret); |
| 3489 | + code_edit->set_caret_line(func_line, true, true, 0, caret); |
| 3490 | + code_edit->set_caret_column(caret_col + strlen("@override "), false, caret); |
| 3491 | + } |
| 3492 | +} |
| 3493 | + |
| 3494 | +} // namespace |
| 3495 | + |
3446 | 3496 | ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptLanguage::CodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) { |
3447 | 3497 | const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; |
3448 | 3498 |
|
@@ -3704,6 +3754,10 @@ ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_pa |
3704 | 3754 | String display_name = member.function->identifier->name; |
3705 | 3755 | display_name += member.function->signature + ":"; |
3706 | 3756 | ScriptLanguage::CodeCompletionOption option(display_name, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION); |
| 3757 | + |
| 3758 | + // When inserting a completion for a function override, we want to automatically add the @override annotation to the completion. |
| 3759 | + option.on_applied = callable_mp_static(_update_overrides_after_completion); |
| 3760 | + |
3707 | 3761 | options.insert(member.function->identifier->name, option); // Insert name instead of display to track duplicates. |
3708 | 3762 | } |
3709 | 3763 | native_type = native_type.class_type->base_type; |
@@ -3778,6 +3832,10 @@ ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_pa |
3778 | 3832 | method_hint += ":"; |
3779 | 3833 |
|
3780 | 3834 | ScriptLanguage::CodeCompletionOption option(method_hint, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION); |
| 3835 | + |
| 3836 | + // When inserting a completion for a function override, we want to automatically add the @override annotation to the completion. |
| 3837 | + option.on_applied = callable_mp_static(_update_overrides_after_completion); |
| 3838 | + |
3781 | 3839 | options.insert(option.display, option); |
3782 | 3840 | } |
3783 | 3841 | } break; |
|
0 commit comments