Skip to content

Commit 0dc4bc1

Browse files
committed
next/previous completion popup with Ctrl-n/Ctrl-p
1 parent 070a1d9 commit 0dc4bc1

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

src/main/clojure/fominok/ideahelix/core.clj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
(ns fominok.ideahelix.core
66
(:require
77
[cider.nrepl :refer (cider-nrepl-handler)]
8-
[fominok.ideahelix.editor :refer [handle-editor-event state-atom]]
8+
[fominok.ideahelix.editor :refer [handle-editor-event state-atom quit-insert-mode]]
99
[fominok.ideahelix.editor.selection :refer :all]
1010
[fominok.ideahelix.editor.ui :as ui]
1111
[nrepl.server :refer [start-server]])
@@ -53,4 +53,10 @@
5353
(ihx-apply-selection! document))))))))
5454

5555

56+
(defn focus-lost
57+
[project ^Editor editor]
58+
(let [state (or (get @state-atom project) {:mode :normal})]
59+
(quit-insert-mode project state (.getDocument editor))))
60+
61+
5662
(defonce -server (start-server :port 7888 :handler cider-nrepl-handler))

src/main/clojure/fominok/ideahelix/editor.clj

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
[fominok.ideahelix.editor.util :refer [get-editor-height]]
1414
[fominok.ideahelix.keymap :refer [defkeymap]])
1515
(:import
16+
(com.intellij.codeInsight.lookup
17+
LookupManager)
18+
(com.intellij.codeInsight.lookup.impl
19+
LookupImpl)
1620
(com.intellij.ide.actions.searcheverywhere
1721
SearchEverywhereManager)
1822
(com.intellij.openapi.actionSystem
@@ -40,7 +44,7 @@
4044
1))))
4145

4246

43-
(defn- quit-insert-mode
47+
(defn quit-insert-mode
4448
[project state document]
4549
(doseq [[editor {:keys [mark-action pre-selections]}] (:per-editor state)]
4650
(restore-selections pre-selections (:insertion-kind state) editor document)
@@ -517,7 +521,24 @@
517521
(\o
518522
[editor] (actions editor "UnsplitAll")
519523
[state] (assoc state :mode :normal))
520-
(_ [state] (assoc state :mode :normal))))
524+
(_ [state] (assoc state :mode :normal)))
525+
526+
(:insert
527+
((:or (:ctrl \n) (:ctrl \u000e))
528+
"Select next completion item"
529+
[state editor event]
530+
(when (= (.getID event) KeyEvent/KEY_PRESSED)
531+
(when-let [^LookupImpl lookup (LookupManager/getActiveLookup editor)]
532+
(.setSelectedIndex lookup (inc (.getSelectedIndex lookup)))
533+
state)))
534+
((:or (:ctrl \p) (:ctrl \u0010))
535+
"Select next completion item"
536+
[state editor event]
537+
(when (= (.getID event) KeyEvent/KEY_PRESSED)
538+
(when-let [^LookupImpl lookup (LookupManager/getActiveLookup editor)]
539+
(.setSelectedIndex lookup (dec (.getSelectedIndex lookup)))
540+
state)))
541+
(_ [state] (assoc state :pass true))))
521542

522543

523544
(defn handle-editor-event
@@ -533,14 +554,14 @@
533554
(= (.getKeyCode event) KeyEvent/VK_ESCAPE) (result-fn)
534555
(and debounce (= (.getID event) KeyEvent/KEY_TYPED))
535556
(assoc project-state :debounce false)
536-
:else :pass)
557+
:else (result-fn))
537558
(if (= (.getID event) KeyEvent/KEY_PRESSED)
538559
(result-fn)
539560
nil))
540561
(catch StartMarkAction$AlreadyStartedException _
541562
(quit-insert-mode project project-state (.getDocument editor))))]
542563
(cond
543-
(= :pass result) false
564+
(:pass result) false
544565
(map? result) (do
545566
(.consume event)
546567
(let [new-state (merge project-state result)]

src/main/clojure/fominok/ideahelix/keymap.clj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
;; One of possible dependencies of the statement to expect.
5252
(s/def ::dep
5353
(s/or :char (partial = 'char) ; typed character
54+
:event (partial = 'event) ; keyboard event that triggered this handler
5455
:editor (partial = 'editor) ; editor in focus
5556
:state (partial = 'state) ; ideahelix->project state
5657
:document (partial = 'document) ; document instance running in the editor
@@ -148,6 +149,7 @@
148149
(into [] (mapcat
149150
(fn [[kw sym]]
150151
[sym (case kw
152+
:event event
151153
:state project-state
152154
:project project
153155
:document `(.getDocument ~editor)

src/main/kotlin/fominok/ideahelix/Init.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class Init : ProjectActivity {
2727
override suspend fun execute(project: Project) {
2828
val pushEvent: IFn
2929
val focusEditor: IFn
30+
val focusLost: IFn
3031

3132
// Per https://plugins.jetbrains.com/docs/intellij/plugin-class-loaders.html#using-serviceloader:
3233
val currentThread = Thread.currentThread()
@@ -40,6 +41,7 @@ class Init : ProjectActivity {
4041

4142
pushEvent = Clojure.`var`("fominok.ideahelix.core", "push-event") as IFn
4243
focusEditor = Clojure.`var`("fominok.ideahelix.core", "focus-editor") as IFn
44+
focusLost = Clojure.`var`("fominok.ideahelix.core", "focus-lost") as IFn
4345
} finally {
4446
currentThread.contextClassLoader = originalClassLoader
4547
}
@@ -72,6 +74,13 @@ class Init : ProjectActivity {
7274
focusEditor.invoke(project, editor)
7375
})
7476
}
77+
78+
override fun focusLost(editor: Editor) {
79+
super.focusLost(editor)
80+
applicationManager.invokeLater({
81+
focusLost.invoke(project, editor)
82+
})
83+
}
7584
}, project)
7685

7786

0 commit comments

Comments
 (0)