1
0
mirror of https://github.com/chylex/IntelliJ-Keyboard-Master.git synced 2025-05-03 14:34:06 +02:00

Add code completion popup shortcut to go back up a page

This commit is contained in:
chylex 2021-10-14 02:52:52 +02:00
parent 16df8a3150
commit a496b253ba
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
5 changed files with 52 additions and 25 deletions

View File

@ -10,6 +10,7 @@ class PluginConfigurable : Configurable {
private val codeCompletionItemShortcuts = JBTextField(20)
private val codeCompletionNextPageShortcut = JBTextField(2)
private val codeCompletionPrevPageShortcut = JBTextField(2)
override fun getDisplayName(): String {
return "Keyboard Master"
@ -20,6 +21,7 @@ class PluginConfigurable : Configurable {
titledRow("Code Completion") {
row("Item shortcuts:") { component(codeCompletionItemShortcuts) }
row("Next page shortcut:") { component(codeCompletionNextPageShortcut) }
row("Prev page shortcut:") { component(codeCompletionPrevPageShortcut) }
}
}
@ -34,6 +36,7 @@ class PluginConfigurable : Configurable {
PluginConfiguration.modify {
it.codeCompletionItemShortcuts = codeCompletionItemShortcuts.text
it.codeCompletionNextPageShortcut = codeCompletionNextPageShortcut.text.firstOrNull()?.code ?: 0
it.codeCompletionPrevPageShortcut = codeCompletionPrevPageShortcut.text.firstOrNull()?.code ?: 0
}
}
@ -41,6 +44,7 @@ class PluginConfigurable : Configurable {
PluginConfiguration.read {
codeCompletionItemShortcuts.text = it.codeCompletionItemShortcuts
codeCompletionNextPageShortcut.text = it.codeCompletionNextPageShortcut.let { code -> if (code == 0) "" else code.toChar().toString() }
codeCompletionPrevPageShortcut.text = it.codeCompletionPrevPageShortcut.let { code -> if (code == 0) "" else code.toChar().toString() }
}
}
}

View File

@ -14,6 +14,7 @@ import com.intellij.util.xmlb.XmlSerializerUtil
class PluginConfiguration : PersistentStateComponent<PluginConfiguration> {
var codeCompletionItemShortcuts = "123456789"
var codeCompletionNextPageShortcut: Int = '0'.code
var codeCompletionPrevPageShortcut: Int = 0
companion object {
private val instance: PluginConfiguration
@ -32,7 +33,7 @@ class PluginConfiguration : PersistentStateComponent<PluginConfiguration> {
}
private fun update(instance: PluginConfiguration) = with(instance) {
CodeCompletionPopupConfiguration.updateShortcuts(codeCompletionItemShortcuts, codeCompletionNextPageShortcut)
CodeCompletionPopupConfiguration.updateShortcuts(codeCompletionItemShortcuts, codeCompletionNextPageShortcut, codeCompletionPrevPageShortcut)
}
}

View File

@ -5,7 +5,8 @@ import com.intellij.util.containers.IntIntHashMap
object CodeCompletionPopupConfiguration {
const val SHORTCUT_NONE = -1
const val SHORTCUT_NEXT_PAGE = 0
const val SHORTCUT_NEXT_PAGE = -2
const val SHORTCUT_PREV_PAGE = -3
private val charToShortcutMap = IntIntHashMap(16, SHORTCUT_NONE)
private var hintTexts = mutableListOf<String>()
@ -17,13 +18,19 @@ object CodeCompletionPopupConfiguration {
PluginConfiguration.load()
}
fun updateShortcuts(itemShortcutChars: String, nextPageShortcutCode: Int) {
fun updateShortcuts(itemShortcutChars: String, nextPageShortcutCode: Int, previousPageShortcutCode: Int) {
charToShortcutMap.clear()
if (nextPageShortcutCode != 0) {
charToShortcutMap[nextPageShortcutCode] = SHORTCUT_NEXT_PAGE
}
if (previousPageShortcutCode != 0) {
charToShortcutMap[previousPageShortcutCode] = SHORTCUT_PREV_PAGE
}
for ((index, char) in itemShortcutChars.withIndex()) {
charToShortcutMap[char.code] = index + 1
charToShortcutMap[char.code] = index
}
hintTexts.clear()

View File

@ -8,6 +8,7 @@ import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.actionSystem.TypedActionHandler
import com.intellij.ui.ScrollingUtil
import javax.swing.ListModel
/**
* Handles configured key bindings inside a code completion popup menu.
@ -30,30 +31,44 @@ class CodeCompletionPopupKeyHandler(originalHandler: TypedActionHandler?) : Type
return false
}
val offset = CodeCompletionPopupListener.getLookupOffset(lookup)
val offset = CodeCompletionPopupListener.getPageOffset(lookup)
if (shortcutItem == CodeCompletionPopupConfiguration.SHORTCUT_NEXT_PAGE) {
val list = lookup.list
val itemCount = list.model.size
val shortcutCount = CodeCompletionPopupConfiguration.itemShortcutCount
val topIndex = (offset + shortcutCount).let { if (it >= itemCount) 0 else it }
CodeCompletionPopupListener.setLookupOffset(lookup, topIndex)
lookup.selectedIndex = topIndex
ScrollingUtil.ensureRangeIsVisible(list, topIndex, topIndex + shortcutCount - 1)
lookup.markSelectionTouched()
lookup.refreshUi(false, true)
setPageOffset(lookup) {
val newTopIndex = offset + CodeCompletionPopupConfiguration.itemShortcutCount
if (newTopIndex >= it.size) 0 else newTopIndex
}
}
else if (shortcutItem == CodeCompletionPopupConfiguration.SHORTCUT_PREV_PAGE) {
setPageOffset(lookup) {
val newTopIndex = offset - CodeCompletionPopupConfiguration.itemShortcutCount
if (newTopIndex < 0) 0 else newTopIndex
}
}
else {
if (!lookup.isFocused) {
lookup.lookupFocusDegree = LookupFocusDegree.FOCUSED
lookup.refreshUi(false, true)
}
lookup.selectedIndex = offset + shortcutItem - 1
selectItem(lookup, offset + shortcutItem)
}
return true
}
private inline fun setPageOffset(lookup: LookupImpl, getNewTopIndex: (ListModel<*>) -> Int) {
val list = lookup.list
val newTopIndex = getNewTopIndex(list.model)
CodeCompletionPopupListener.setPageOffset(lookup, newTopIndex)
lookup.selectedIndex = newTopIndex
ScrollingUtil.ensureRangeIsVisible(list, newTopIndex, newTopIndex + CodeCompletionPopupConfiguration.itemShortcutCount - 1)
lookup.markSelectionTouched()
lookup.refreshUi(false, true)
}
private fun selectItem(lookup: LookupImpl, index: Int) {
if (!lookup.isFocused) {
lookup.lookupFocusDegree = LookupFocusDegree.FOCUSED
lookup.refreshUi(false, true)
}
lookup.selectedIndex = index
}
}

View File

@ -14,7 +14,7 @@ class CodeCompletionPopupListener : LookupManagerListener {
private val OFFSET_KEY = Key.create<Int>("chylexKeyboardMasterOffset")
private val IS_MODIFIED_KEY = Key.create<Boolean>("chylexKeyboardMasterModified")
fun getLookupOffset(lookup: LookupImpl): Int {
fun getPageOffset(lookup: LookupImpl): Int {
val offset = lookup.getUserData(OFFSET_KEY)
if (offset == null || offset >= lookup.list.model.size) {
return 0
@ -24,7 +24,7 @@ class CodeCompletionPopupListener : LookupManagerListener {
}
}
fun setLookupOffset(lookup: LookupImpl, newOffset: Int) {
fun setPageOffset(lookup: LookupImpl, newOffset: Int) {
lookup.putUserData(OFFSET_KEY, newOffset)
}
}
@ -40,7 +40,7 @@ class CodeCompletionPopupListener : LookupManagerListener {
newLookup.addPresentationCustomizer { item, presentation ->
val itemList = newLookup.list.model
val itemCount = itemList.size
val offset = getLookupOffset(newLookup)
val offset = getPageOffset(newLookup)
for (index in 0 until CodeCompletionPopupConfiguration.itemShortcutCount) {
val itemIndex = offset + index