Skip to content

Commit

Permalink
When a period is typed, auto-invoke code completion (#2924)
Browse files Browse the repository at this point in the history
* merge to main

* when a period is typed, auto-invoke code completion
  • Loading branch information
devoncarew authored Apr 2, 2024
1 parent fc1c8f7 commit 91215f8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
52 changes: 41 additions & 11 deletions pkgs/sketch_pad/lib/editor/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,48 @@ class _EditorWidgetState extends State<EditorWidget> implements EditorService {
CodeMirror? codeMirror;
CompletionType completionType = CompletionType.auto;

final FocusNode _focusNode = FocusNode(onKeyEvent: (node, event) {
// If focused, allow CodeMirror to handle tab.
if (node.hasFocus && event.logicalKey == LogicalKeyboardKey.tab) {
return KeyEventResult.skipRemainingHandlers;
}
late final FocusNode _focusNode;

_EditorWidgetState() {
_focusNode = FocusNode(
onKeyEvent: (node, event) {
if (!node.hasFocus) {
return KeyEventResult.ignored;
}

// If focused, allow CodeMirror to handle tab.
if (event.logicalKey == LogicalKeyboardKey.tab) {
return KeyEventResult.skipRemainingHandlers;
} else if (event is KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.period) {
// On a period, auto-invoke code completions.

// If any modifiers keys are depressed, ignore this event. Note that
// directly querying `HardwareKeyboard.instance` could have a race
// condition (we'd like to read this information directly from the
// event).
if (HardwareKeyboard.instance.isAltPressed ||
HardwareKeyboard.instance.isControlPressed ||
HardwareKeyboard.instance.isMetaPressed ||
HardwareKeyboard.instance.isShiftPressed) {
return KeyEventResult.ignored;
}

// We introduce a delay here to allow codemirror to process the key
// event.
Timer.run(() => showCompletions(autoInvoked: true));

return KeyEventResult.ignored;
});
return KeyEventResult.skipRemainingHandlers;
}

return KeyEventResult.ignored;
},
);
}

@override
void showCompletions() {
completionType = CompletionType.manual;
void showCompletions({required bool autoInvoked}) {
completionType = autoInvoked ? CompletionType.auto : CompletionType.manual;

codeMirror?.execCommand('autocomplete');
}
Expand Down Expand Up @@ -377,8 +407,8 @@ class _EditorWidgetState extends State<EditorWidget> implements EditorService {
.map((suggestion) => suggestion.toHintResult())
.toList();

// Remove hints where both the replacement text and the display text are the
// same.
// Remove hints where both the replacement text and the display text are
// the same.
final memos = <String>{};
hints.retainWhere((hint) {
return memos.add('${hint.text}:${hint.displayText}');
Expand Down
2 changes: 1 addition & 1 deletion pkgs/sketch_pad/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ class _DartPadMainPageState extends State<DartPadMainPage>
if (!appModel.formattingBusy.value) _handleFormatting();
},
keys.codeCompletionKeyActivator: () {
appServices.editorService?.showCompletions();
appServices.editorService?.showCompletions(autoInvoked: false);
},
keys.quickFixKeyActivator1: () {
appServices.editorService?.showQuickFixes();
Expand Down
2 changes: 1 addition & 1 deletion pkgs/sketch_pad/lib/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class ExecutionService {
}

abstract class EditorService {
void showCompletions();
void showCompletions({required bool autoInvoked});
void showQuickFixes();
void jumpTo(AnalysisIssue issue);
int get cursorOffset;
Expand Down

0 comments on commit 91215f8

Please sign in to comment.