mirror of
https://github.com/chylex/IntelliJ-Keyboard-Master.git
synced 2025-05-21 05:34:11 +02:00
Add code completion popup shortcut to go back up a page
This commit is contained in:
parent
16df8a3150
commit
a496b253ba
src/main/kotlin/com/chylex/intellij/keyboardmaster
configuration
feature/codeCompletion
@ -10,6 +10,7 @@ class PluginConfigurable : Configurable {
|
|||||||
|
|
||||||
private val codeCompletionItemShortcuts = JBTextField(20)
|
private val codeCompletionItemShortcuts = JBTextField(20)
|
||||||
private val codeCompletionNextPageShortcut = JBTextField(2)
|
private val codeCompletionNextPageShortcut = JBTextField(2)
|
||||||
|
private val codeCompletionPrevPageShortcut = JBTextField(2)
|
||||||
|
|
||||||
override fun getDisplayName(): String {
|
override fun getDisplayName(): String {
|
||||||
return "Keyboard Master"
|
return "Keyboard Master"
|
||||||
@ -20,6 +21,7 @@ class PluginConfigurable : Configurable {
|
|||||||
titledRow("Code Completion") {
|
titledRow("Code Completion") {
|
||||||
row("Item shortcuts:") { component(codeCompletionItemShortcuts) }
|
row("Item shortcuts:") { component(codeCompletionItemShortcuts) }
|
||||||
row("Next page shortcut:") { component(codeCompletionNextPageShortcut) }
|
row("Next page shortcut:") { component(codeCompletionNextPageShortcut) }
|
||||||
|
row("Prev page shortcut:") { component(codeCompletionPrevPageShortcut) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +36,7 @@ class PluginConfigurable : Configurable {
|
|||||||
PluginConfiguration.modify {
|
PluginConfiguration.modify {
|
||||||
it.codeCompletionItemShortcuts = codeCompletionItemShortcuts.text
|
it.codeCompletionItemShortcuts = codeCompletionItemShortcuts.text
|
||||||
it.codeCompletionNextPageShortcut = codeCompletionNextPageShortcut.text.firstOrNull()?.code ?: 0
|
it.codeCompletionNextPageShortcut = codeCompletionNextPageShortcut.text.firstOrNull()?.code ?: 0
|
||||||
|
it.codeCompletionPrevPageShortcut = codeCompletionPrevPageShortcut.text.firstOrNull()?.code ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +44,7 @@ class PluginConfigurable : Configurable {
|
|||||||
PluginConfiguration.read {
|
PluginConfiguration.read {
|
||||||
codeCompletionItemShortcuts.text = it.codeCompletionItemShortcuts
|
codeCompletionItemShortcuts.text = it.codeCompletionItemShortcuts
|
||||||
codeCompletionNextPageShortcut.text = it.codeCompletionNextPageShortcut.let { code -> if (code == 0) "" else code.toChar().toString() }
|
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() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import com.intellij.util.xmlb.XmlSerializerUtil
|
|||||||
class PluginConfiguration : PersistentStateComponent<PluginConfiguration> {
|
class PluginConfiguration : PersistentStateComponent<PluginConfiguration> {
|
||||||
var codeCompletionItemShortcuts = "123456789"
|
var codeCompletionItemShortcuts = "123456789"
|
||||||
var codeCompletionNextPageShortcut: Int = '0'.code
|
var codeCompletionNextPageShortcut: Int = '0'.code
|
||||||
|
var codeCompletionPrevPageShortcut: Int = 0
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val instance: PluginConfiguration
|
private val instance: PluginConfiguration
|
||||||
@ -32,7 +33,7 @@ class PluginConfiguration : PersistentStateComponent<PluginConfiguration> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun update(instance: PluginConfiguration) = with(instance) {
|
private fun update(instance: PluginConfiguration) = with(instance) {
|
||||||
CodeCompletionPopupConfiguration.updateShortcuts(codeCompletionItemShortcuts, codeCompletionNextPageShortcut)
|
CodeCompletionPopupConfiguration.updateShortcuts(codeCompletionItemShortcuts, codeCompletionNextPageShortcut, codeCompletionPrevPageShortcut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ import com.intellij.util.containers.IntIntHashMap
|
|||||||
|
|
||||||
object CodeCompletionPopupConfiguration {
|
object CodeCompletionPopupConfiguration {
|
||||||
const val SHORTCUT_NONE = -1
|
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 val charToShortcutMap = IntIntHashMap(16, SHORTCUT_NONE)
|
||||||
private var hintTexts = mutableListOf<String>()
|
private var hintTexts = mutableListOf<String>()
|
||||||
@ -17,13 +18,19 @@ object CodeCompletionPopupConfiguration {
|
|||||||
PluginConfiguration.load()
|
PluginConfiguration.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateShortcuts(itemShortcutChars: String, nextPageShortcutCode: Int) {
|
fun updateShortcuts(itemShortcutChars: String, nextPageShortcutCode: Int, previousPageShortcutCode: Int) {
|
||||||
charToShortcutMap.clear()
|
charToShortcutMap.clear()
|
||||||
|
|
||||||
if (nextPageShortcutCode != 0) {
|
if (nextPageShortcutCode != 0) {
|
||||||
charToShortcutMap[nextPageShortcutCode] = SHORTCUT_NEXT_PAGE
|
charToShortcutMap[nextPageShortcutCode] = SHORTCUT_NEXT_PAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (previousPageShortcutCode != 0) {
|
||||||
|
charToShortcutMap[previousPageShortcutCode] = SHORTCUT_PREV_PAGE
|
||||||
|
}
|
||||||
|
|
||||||
for ((index, char) in itemShortcutChars.withIndex()) {
|
for ((index, char) in itemShortcutChars.withIndex()) {
|
||||||
charToShortcutMap[char.code] = index + 1
|
charToShortcutMap[char.code] = index
|
||||||
}
|
}
|
||||||
|
|
||||||
hintTexts.clear()
|
hintTexts.clear()
|
||||||
|
@ -8,6 +8,7 @@ import com.intellij.openapi.actionSystem.DataContext
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.actionSystem.TypedActionHandler
|
import com.intellij.openapi.editor.actionSystem.TypedActionHandler
|
||||||
import com.intellij.ui.ScrollingUtil
|
import com.intellij.ui.ScrollingUtil
|
||||||
|
import javax.swing.ListModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles configured key bindings inside a code completion popup menu.
|
* Handles configured key bindings inside a code completion popup menu.
|
||||||
@ -30,30 +31,44 @@ class CodeCompletionPopupKeyHandler(originalHandler: TypedActionHandler?) : Type
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val offset = CodeCompletionPopupListener.getLookupOffset(lookup)
|
val offset = CodeCompletionPopupListener.getPageOffset(lookup)
|
||||||
|
|
||||||
if (shortcutItem == CodeCompletionPopupConfiguration.SHORTCUT_NEXT_PAGE) {
|
if (shortcutItem == CodeCompletionPopupConfiguration.SHORTCUT_NEXT_PAGE) {
|
||||||
val list = lookup.list
|
setPageOffset(lookup) {
|
||||||
val itemCount = list.model.size
|
val newTopIndex = offset + CodeCompletionPopupConfiguration.itemShortcutCount
|
||||||
|
if (newTopIndex >= it.size) 0 else newTopIndex
|
||||||
val shortcutCount = CodeCompletionPopupConfiguration.itemShortcutCount
|
}
|
||||||
val topIndex = (offset + shortcutCount).let { if (it >= itemCount) 0 else it }
|
}
|
||||||
|
else if (shortcutItem == CodeCompletionPopupConfiguration.SHORTCUT_PREV_PAGE) {
|
||||||
CodeCompletionPopupListener.setLookupOffset(lookup, topIndex)
|
setPageOffset(lookup) {
|
||||||
lookup.selectedIndex = topIndex
|
val newTopIndex = offset - CodeCompletionPopupConfiguration.itemShortcutCount
|
||||||
ScrollingUtil.ensureRangeIsVisible(list, topIndex, topIndex + shortcutCount - 1)
|
if (newTopIndex < 0) 0 else newTopIndex
|
||||||
lookup.markSelectionTouched()
|
}
|
||||||
lookup.refreshUi(false, true)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!lookup.isFocused) {
|
selectItem(lookup, offset + shortcutItem)
|
||||||
lookup.lookupFocusDegree = LookupFocusDegree.FOCUSED
|
|
||||||
lookup.refreshUi(false, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
lookup.selectedIndex = offset + shortcutItem - 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ class CodeCompletionPopupListener : LookupManagerListener {
|
|||||||
private val OFFSET_KEY = Key.create<Int>("chylexKeyboardMasterOffset")
|
private val OFFSET_KEY = Key.create<Int>("chylexKeyboardMasterOffset")
|
||||||
private val IS_MODIFIED_KEY = Key.create<Boolean>("chylexKeyboardMasterModified")
|
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)
|
val offset = lookup.getUserData(OFFSET_KEY)
|
||||||
if (offset == null || offset >= lookup.list.model.size) {
|
if (offset == null || offset >= lookup.list.model.size) {
|
||||||
return 0
|
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)
|
lookup.putUserData(OFFSET_KEY, newOffset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ class CodeCompletionPopupListener : LookupManagerListener {
|
|||||||
newLookup.addPresentationCustomizer { item, presentation ->
|
newLookup.addPresentationCustomizer { item, presentation ->
|
||||||
val itemList = newLookup.list.model
|
val itemList = newLookup.list.model
|
||||||
val itemCount = itemList.size
|
val itemCount = itemList.size
|
||||||
val offset = getLookupOffset(newLookup)
|
val offset = getPageOffset(newLookup)
|
||||||
|
|
||||||
for (index in 0 until CodeCompletionPopupConfiguration.itemShortcutCount) {
|
for (index in 0 until CodeCompletionPopupConfiguration.itemShortcutCount) {
|
||||||
val itemIndex = offset + index
|
val itemIndex = offset + index
|
||||||
|
Loading…
Reference in New Issue
Block a user