mirror of
https://github.com/chylex/IntelliJ-AceJump.git
synced 2025-09-16 16:24:48 +02:00
Compare commits
2 Commits
43dfec940e
...
broken-ide
Author | SHA1 | Date | |
---|---|---|---|
82de69d53c
|
|||
ffb4573eda
|
@@ -13,7 +13,6 @@ class AceConfigurable : Configurable {
|
|||||||
|
|
||||||
override fun isModified() =
|
override fun isModified() =
|
||||||
panel.allowedChars != settings.allowedChars ||
|
panel.allowedChars != settings.allowedChars ||
|
||||||
panel.prefixChars != settings.prefixChars ||
|
|
||||||
panel.keyboardLayout != settings.layout ||
|
panel.keyboardLayout != settings.layout ||
|
||||||
panel.minQueryLengthInt != settings.minQueryLength ||
|
panel.minQueryLengthInt != settings.minQueryLength ||
|
||||||
panel.editorFadeOpacityPercent != settings.editorFadeOpacity ||
|
panel.editorFadeOpacityPercent != settings.editorFadeOpacity ||
|
||||||
@@ -24,7 +23,6 @@ class AceConfigurable : Configurable {
|
|||||||
|
|
||||||
override fun apply() {
|
override fun apply() {
|
||||||
settings.allowedChars = panel.allowedChars
|
settings.allowedChars = panel.allowedChars
|
||||||
settings.prefixChars = panel.prefixChars
|
|
||||||
settings.layout = panel.keyboardLayout
|
settings.layout = panel.keyboardLayout
|
||||||
settings.minQueryLength = panel.minQueryLengthInt ?: settings.minQueryLength
|
settings.minQueryLength = panel.minQueryLengthInt ?: settings.minQueryLength
|
||||||
settings.editorFadeOpacity = panel.editorFadeOpacityPercent
|
settings.editorFadeOpacity = panel.editorFadeOpacityPercent
|
||||||
|
@@ -8,7 +8,6 @@ import java.awt.Color
|
|||||||
data class AceSettings(
|
data class AceSettings(
|
||||||
var layout: KeyLayout = QWERTY,
|
var layout: KeyLayout = QWERTY,
|
||||||
var allowedChars: String = layout.allChars,
|
var allowedChars: String = layout.allChars,
|
||||||
var prefixChars: String = ";",
|
|
||||||
var minQueryLength: Int = 1,
|
var minQueryLength: Int = 1,
|
||||||
var editorFadeOpacity: Int = 70,
|
var editorFadeOpacity: Int = 70,
|
||||||
|
|
||||||
|
@@ -26,7 +26,6 @@ import kotlin.reflect.KProperty
|
|||||||
@Suppress("UsePropertyAccessSyntax")
|
@Suppress("UsePropertyAccessSyntax")
|
||||||
internal class AceSettingsPanel {
|
internal class AceSettingsPanel {
|
||||||
private val tagAllowedCharsField = JBTextField()
|
private val tagAllowedCharsField = JBTextField()
|
||||||
private val tagPrefixCharsField = JBTextField()
|
|
||||||
private val keyboardLayoutCombo = ComboBox<KeyLayout>()
|
private val keyboardLayoutCombo = ComboBox<KeyLayout>()
|
||||||
private val keyboardLayoutArea = JBTextArea().apply { isEditable = false }
|
private val keyboardLayoutArea = JBTextArea().apply { isEditable = false }
|
||||||
private val minQueryLengthField = JBTextField()
|
private val minQueryLengthField = JBTextField()
|
||||||
@@ -45,7 +44,6 @@ internal class AceSettingsPanel {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
tagAllowedCharsField.apply { font = Font("monospaced", font.style, font.size) }
|
tagAllowedCharsField.apply { font = Font("monospaced", font.style, font.size) }
|
||||||
tagPrefixCharsField.apply { font = Font("monospaced", font.style, font.size) }
|
|
||||||
keyboardLayoutArea.apply { font = Font("monospaced", font.style, font.size) }
|
keyboardLayoutArea.apply { font = Font("monospaced", font.style, font.size) }
|
||||||
keyboardLayoutCombo.setupEnumItems { keyChars = it.rows.joinToString("\n") }
|
keyboardLayoutCombo.setupEnumItems { keyChars = it.rows.joinToString("\n") }
|
||||||
}
|
}
|
||||||
@@ -53,7 +51,6 @@ internal class AceSettingsPanel {
|
|||||||
internal val rootPanel: JPanel = panel {
|
internal val rootPanel: JPanel = panel {
|
||||||
group("Characters and Layout") {
|
group("Characters and Layout") {
|
||||||
row("Allowed characters in tags:") { cell(tagAllowedCharsField).columns(COLUMNS_LARGE) }
|
row("Allowed characters in tags:") { cell(tagAllowedCharsField).columns(COLUMNS_LARGE) }
|
||||||
row("Allowed prefix characters in tags:") { cell(tagPrefixCharsField).columns(COLUMNS_MEDIUM) }
|
|
||||||
row("Keyboard layout:") { cell(keyboardLayoutCombo).columns(COLUMNS_SHORT) }
|
row("Keyboard layout:") { cell(keyboardLayoutCombo).columns(COLUMNS_SHORT) }
|
||||||
row("Keyboard design:") { cell(keyboardLayoutArea).columns(COLUMNS_SHORT) }
|
row("Keyboard design:") { cell(keyboardLayoutArea).columns(COLUMNS_SHORT) }
|
||||||
}
|
}
|
||||||
@@ -81,7 +78,6 @@ internal class AceSettingsPanel {
|
|||||||
|
|
||||||
// Property-to-property delegation: https://stackoverflow.com/q/45074596/1772342
|
// Property-to-property delegation: https://stackoverflow.com/q/45074596/1772342
|
||||||
internal var allowedChars by tagAllowedCharsField
|
internal var allowedChars by tagAllowedCharsField
|
||||||
internal var prefixChars by tagPrefixCharsField
|
|
||||||
internal var keyboardLayout by keyboardLayoutCombo
|
internal var keyboardLayout by keyboardLayoutCombo
|
||||||
internal var keyChars by keyboardLayoutArea
|
internal var keyChars by keyboardLayoutArea
|
||||||
internal var minQueryLength by minQueryLengthField
|
internal var minQueryLength by minQueryLengthField
|
||||||
@@ -101,7 +97,6 @@ internal class AceSettingsPanel {
|
|||||||
|
|
||||||
fun reset(settings: AceSettings) {
|
fun reset(settings: AceSettings) {
|
||||||
allowedChars = settings.allowedChars
|
allowedChars = settings.allowedChars
|
||||||
prefixChars = settings.prefixChars
|
|
||||||
keyboardLayout = settings.layout
|
keyboardLayout = settings.layout
|
||||||
minQueryLength = settings.minQueryLength.toString()
|
minQueryLength = settings.minQueryLength.toString()
|
||||||
editorFadeOpacityPercent = settings.editorFadeOpacity
|
editorFadeOpacityPercent = settings.editorFadeOpacity
|
||||||
|
@@ -5,32 +5,46 @@ package org.acejump.input
|
|||||||
* ergonomically difficult they are to press.
|
* ergonomically difficult they are to press.
|
||||||
*/
|
*/
|
||||||
@Suppress("unused", "SpellCheckingInspection")
|
@Suppress("unused", "SpellCheckingInspection")
|
||||||
enum class KeyLayout(internal val rows: Array<String>, priority: String, internal val characterRemapping: Map<Char, Char> = emptyMap()) {
|
enum class KeyLayout(
|
||||||
|
internal val rows: Array<String>,
|
||||||
|
priority: String,
|
||||||
|
private val characterSides: Pair<Set<Char>, Set<Char>> = Pair(emptySet(), emptySet()),
|
||||||
|
internal val characterRemapping: Map<Char, Char> = emptyMap(),
|
||||||
|
) {
|
||||||
COLEMK(arrayOf("1234567890", "qwfpgjluy", "arstdhneio", "zxcvbkm"), priority = "tndhseriaovkcmbxzgjplfuwyq5849673210"),
|
COLEMK(arrayOf("1234567890", "qwfpgjluy", "arstdhneio", "zxcvbkm"), priority = "tndhseriaovkcmbxzgjplfuwyq5849673210"),
|
||||||
WORKMN(arrayOf("1234567890", "qdrwbjfup", "ashtgyneoi", "zxmcvkl"), priority = "tnhegysoaiclvkmxzwfrubjdpq5849673210"),
|
WORKMN(arrayOf("1234567890", "qdrwbjfup", "ashtgyneoi", "zxmcvkl"), priority = "tnhegysoaiclvkmxzwfrubjdpq5849673210"),
|
||||||
DVORAK(arrayOf("1234567890", "pyfgcrl", "aoeuidhtns", "qjkxbmwvz"), priority = "uhetidonasxkbjmqwvzgfycprl5849673210"),
|
DVORAK(arrayOf("1234567890", "pyfgcrl", "aoeuidhtns", "qjkxbmwvz"), priority = "uhetidonasxkbjmqwvzgfycprl5849673210"),
|
||||||
QWERTY(arrayOf("1234567890", "qwertyuiop", "asdfghjkl", "zxcvbnm"), priority = "fjghdkslavncmbxzrutyeiwoqp5849673210"),
|
QWERTY(arrayOf("1234567890", "qwertyuiop", "asdfghjkl", "zxcvbnm"), priority = "fjghdkslavncmbxzrutyeiwoqp5849673210"),
|
||||||
QWERTZ(arrayOf("1234567890", "qwertzuiop", "asdfghjkl", "yxcvbnm"), priority = "fjghdkslavncmbxyrutzeiwoqp5849673210"),
|
QWERTZ(arrayOf("1234567890", "qwertzuiop", "asdfghjkl", "yxcvbnm"), priority = "fjghdkslavncmbxyrutzeiwoqp5849673210"),
|
||||||
QWERTZ_CZ(arrayOf("1234567890", "qwertzuiop", "asdfghjkl", "yxcvbnm"), priority = "fjghdkslavncmbxyrutzeiwoqp5849673210", characterRemapping = mapOf(
|
QWERTZ_CZ(
|
||||||
'+' to '1',
|
arrayOf("1234567890", "qwertzuiop", "asdfghjkl", "yxcvbnm"),
|
||||||
'ě' to '2',
|
priority = "fjghdkslavncmbxyrutzeiwoqp5849673210",
|
||||||
'š' to '3',
|
characterSides = sides("", ""),
|
||||||
'č' to '4',
|
characterRemapping = mapOf(
|
||||||
'ř' to '5',
|
'+' to '1',
|
||||||
'ž' to '6',
|
'ě' to '2',
|
||||||
'ý' to '7',
|
'š' to '3',
|
||||||
'á' to '8',
|
'č' to '4',
|
||||||
'í' to '9',
|
'ř' to '5',
|
||||||
'é' to '0'
|
'ž' to '6',
|
||||||
)),
|
'ý' to '7',
|
||||||
|
'á' to '8',
|
||||||
|
'í' to '9',
|
||||||
|
'é' to '0'
|
||||||
|
)
|
||||||
|
),
|
||||||
QGMLWY(arrayOf("1234567890", "qgmlwyfub", "dstnriaeoh", "zxcvjkp"), priority = "naterisodhvkcpjxzlfmuwygbq5849673210"),
|
QGMLWY(arrayOf("1234567890", "qgmlwyfub", "dstnriaeoh", "zxcvjkp"), priority = "naterisodhvkcpjxzlfmuwygbq5849673210"),
|
||||||
QGMLWB(arrayOf("1234567890", "qgmlwbyuv", "dstnriaeoh", "zxcfjkp"), priority = "naterisodhfkcpjxzlymuwbgvq5849673210"),
|
QGMLWB(arrayOf("1234567890", "qgmlwbyuv", "dstnriaeoh", "zxcfjkp"), priority = "naterisodhfkcpjxzlymuwbgvq5849673210"),
|
||||||
NORMAN(arrayOf("1234567890", "qwdfkjurl", "asetgynioh", "zxcvbpm"), priority = "tneigysoahbvpcmxzjkufrdlwq5849673210");
|
NORMAN(arrayOf("1234567890", "qwdfkjurl", "asetgynioh", "zxcvbpm"), priority = "tneigysoahbvpcmxzjkufrdlwq5849673210");
|
||||||
|
|
||||||
internal val allChars = rows.joinToString("").toCharArray().apply(CharArray::sort).joinToString("")
|
internal val allChars = rows.joinToString("").toCharArray().apply(CharArray::sort).joinToString("")
|
||||||
internal val allPriorities = priority.mapIndexed { index, char -> char to index }.toMap()
|
private val allPriorities = priority.mapIndexed { index, char -> char to index }.toMap()
|
||||||
|
|
||||||
internal inline fun priority(crossinline tagToChar: (String) -> Char): (String) -> Int {
|
internal fun priority(): (Char) -> Int {
|
||||||
return { allPriorities.getOrDefault(tagToChar(it), Int.MAX_VALUE) }
|
return { allPriorities.getOrDefault(it, Int.MAX_VALUE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sides(left: String, right: String): Pair<Set<Char>, Set<Char>> {
|
||||||
|
return Pair(left.toCharArray().toSet(), right.toCharArray().toSet())
|
||||||
|
}
|
||||||
|
@@ -7,17 +7,14 @@ import org.acejump.config.AceSettings
|
|||||||
* with repeated keys (ex. FF, JJ) or adjacent keys (ex. GH, UJ).
|
* with repeated keys (ex. FF, JJ) or adjacent keys (ex. GH, UJ).
|
||||||
*/
|
*/
|
||||||
internal object KeyLayoutCache {
|
internal object KeyLayoutCache {
|
||||||
/**
|
lateinit var allowedCharsSorted: List<Char>
|
||||||
* Returns all possible two key tags, pre-sorted according to [tagOrder].
|
|
||||||
*/
|
|
||||||
lateinit var allPossibleTagsLowercase: List<String>
|
|
||||||
private set
|
private set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before any lazily initialized properties are used, to ensure that they are initialized even if the settings are missing.
|
* Called before any lazily initialized properties are used, to ensure that they are initialized even if the settings are missing.
|
||||||
*/
|
*/
|
||||||
fun ensureInitialized(settings: AceSettings) {
|
fun ensureInitialized(settings: AceSettings) {
|
||||||
if (!::allPossibleTagsLowercase.isInitialized) {
|
if (!::allowedCharsSorted.isInitialized) {
|
||||||
reset(settings)
|
reset(settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,22 +23,17 @@ internal object KeyLayoutCache {
|
|||||||
* Re-initializes cached data according to updated settings.
|
* Re-initializes cached data according to updated settings.
|
||||||
*/
|
*/
|
||||||
fun reset(settings: AceSettings) {
|
fun reset(settings: AceSettings) {
|
||||||
@Suppress("ConvertLambdaToReference")
|
val allowedCharList = processCharList(settings.allowedChars)
|
||||||
val allSuffixChars = processCharList(settings.allowedChars).ifEmpty { processCharList(settings.layout.allChars).toList() }
|
|
||||||
val allPrefixChars = processCharList(settings.prefixChars).filterNot(allSuffixChars::contains).plus("")
|
|
||||||
|
|
||||||
val tagOrder = compareBy(
|
allowedCharsSorted = if (allowedCharList.isEmpty()) {
|
||||||
String::length,
|
processCharList(settings.layout.allChars)
|
||||||
{ if (it.length == 1) Int.MIN_VALUE else allPrefixChars.indexOf(it.first().toString()) },
|
}
|
||||||
settings.layout.priority(String::last)
|
else {
|
||||||
)
|
allowedCharList.sortedWith(compareBy(settings.layout.priority()))
|
||||||
|
}
|
||||||
allPossibleTagsLowercase = allSuffixChars
|
|
||||||
.flatMap { suffix -> allPrefixChars.map { prefix -> "$prefix$suffix" } }
|
|
||||||
.sortedWith(tagOrder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processCharList(charList: String): Set<String> {
|
private fun processCharList(charList: String): List<Char> {
|
||||||
return charList.toCharArray().map(Char::lowercase).toSet()
|
return charList.toCharArray().map(Char::lowercaseChar).distinct()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ class Tagger(private val editors: List<Editor>, results: Map<Editor, IntList>) {
|
|||||||
.flatMap { (editor, sites) -> sites.map { site -> Tag(editor, site) } }
|
.flatMap { (editor, sites) -> sites.map { site -> Tag(editor, site) } }
|
||||||
.sortedWith(siteOrder(editors, caches))
|
.sortedWith(siteOrder(editors, caches))
|
||||||
|
|
||||||
tagMap = KeyLayoutCache.allPossibleTagsLowercase.zip(tagSites).toMap()
|
tagMap = generateTags(tagSites).zip(tagSites).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun type(char: Char): TaggingResult {
|
internal fun type(char: Char): TaggingResult {
|
||||||
@@ -61,6 +61,35 @@ class Tagger(private val editors: List<Editor>, results: Map<Editor, IntList>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
private fun generateTags(tagSites: List<Tag>): List<String> {
|
||||||
|
val allowedChars = KeyLayoutCache.allowedCharsSorted
|
||||||
|
|
||||||
|
val tags = mutableListOf<String>()
|
||||||
|
var remainingTagCount = tagSites.size
|
||||||
|
|
||||||
|
outer@ for (i in allowedChars.indices) {
|
||||||
|
val c1 = allowedChars[i]
|
||||||
|
|
||||||
|
if (remainingTagCount <= allowedChars.size - i) {
|
||||||
|
tags.add(c1.toString())
|
||||||
|
if (--remainingTagCount <= 0) {
|
||||||
|
break@outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (c2 in allowedChars) {
|
||||||
|
tags.add("$c1$c2")
|
||||||
|
|
||||||
|
if (--remainingTagCount <= 0) {
|
||||||
|
break@outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags
|
||||||
|
}
|
||||||
|
|
||||||
private fun sortResults(results: Map<Editor, IntList>, caches: Map<Editor, EditorOffsetCache>) {
|
private fun sortResults(results: Map<Editor, IntList>, caches: Map<Editor, EditorOffsetCache>) {
|
||||||
for ((editor, offsets) in results) {
|
for ((editor, offsets) in results) {
|
||||||
val cache = caches.getValue(editor)
|
val cache = caches.getValue(editor)
|
||||||
|
Reference in New Issue
Block a user