fix(keymap): make modifier layers discoverable (#249)
This commit is contained in:
@@ -102,6 +102,8 @@ In keyboard view, enable an exact Super, Ctrl, Shift, and Alt layer. Occupied
|
|||||||
keys open the shortcuts assigned to that combination; unoccupied keys can be
|
keys open the shortcuts assigned to that combination; unoccupied keys can be
|
||||||
sent directly to the creator. Change the physical layout from the keyboard
|
sent directly to the creator. Change the physical layout from the keyboard
|
||||||
size selector while editing shortcuts, or set its default in plugin settings.
|
size selector while editing shortcuts, or set its default in plugin settings.
|
||||||
|
When a key is occupied in another modifier layer, select it and use the layer
|
||||||
|
buttons in the details card to jump directly to the matching combination.
|
||||||
|
|
||||||
In list view, type into the search box to filter the complete category tree.
|
In list view, type into the search box to filter the complete category tree.
|
||||||
Sequential shortcuts such as workspaces 1 through 9 can optionally be folded
|
Sequential shortcuts such as workspaces 1 through 9 can optionally be folded
|
||||||
|
|||||||
+72
-3
@@ -286,6 +286,33 @@ local function activeModifierSignature()
|
|||||||
return table.concat(ordered, "+")
|
return table.concat(ordered, "+")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function modifierSignatureLabel(signature)
|
||||||
|
if signature == "" then return tr("panel.keyboard.no_modifiers") end
|
||||||
|
local labels = {}
|
||||||
|
for modifier in tostring(signature):gmatch("[^+]+") do
|
||||||
|
labels[#labels + 1] = modifier == "CTRL" and "Ctrl"
|
||||||
|
or (modifier == "SUPER" and "Super" or (modifier == "SHIFT" and "Shift" or (
|
||||||
|
modifier == "ALT" and "Alt" or modifier
|
||||||
|
)))
|
||||||
|
end
|
||||||
|
return table.concat(labels, " + ")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function modifierSignatureSelectable(signature)
|
||||||
|
for modifier in tostring(signature):gmatch("[^+]+") do
|
||||||
|
if activeModifiers[modifier] == nil then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function selectModifierSignature(signature)
|
||||||
|
local selected = {}
|
||||||
|
for modifier in tostring(signature):gmatch("[^+]+") do selected[modifier] = true end
|
||||||
|
for _, modifier in ipairs(MODIFIER_ORDER) do
|
||||||
|
activeModifiers[modifier] = selected[modifier] == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function expandedKeys(value)
|
local function expandedKeys(value)
|
||||||
local canonical = canonicalKey(value)
|
local canonical = canonicalKey(value)
|
||||||
local first, last = canonical:match("^(%d)%-(%d)$")
|
local first, last = canonical:match("^(%d)%-(%d)$")
|
||||||
@@ -341,6 +368,19 @@ local function keyCallback(id, code)
|
|||||||
return callback
|
return callback
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local layerCallbackCache = {}
|
||||||
|
local function layerCallback(signature)
|
||||||
|
local callback = layerCallbackCache[signature]
|
||||||
|
if callback == nil then
|
||||||
|
callback = function()
|
||||||
|
selectModifierSignature(signature)
|
||||||
|
render()
|
||||||
|
end
|
||||||
|
layerCallbackCache[signature] = callback
|
||||||
|
end
|
||||||
|
return callback
|
||||||
|
end
|
||||||
|
|
||||||
local function contains(haystack, needle)
|
local function contains(haystack, needle)
|
||||||
return string.find(normalized(haystack), needle, 1, true) ~= nil
|
return string.find(normalized(haystack), needle, 1, true) ~= nil
|
||||||
end
|
end
|
||||||
@@ -1059,6 +1099,17 @@ local function selectedKeyDetails(index)
|
|||||||
|
|
||||||
local signature = activeModifierSignature()
|
local signature = activeModifierSignature()
|
||||||
local entries = asArray(index.exact[signature .. "|" .. selectedKeyboardKey])
|
local entries = asArray(index.exact[signature .. "|" .. selectedKeyboardKey])
|
||||||
|
local otherSignatures = {}
|
||||||
|
local seenSignatures = {}
|
||||||
|
for _, entry in ipairs(asArray(index.any[selectedKeyboardKey])) do
|
||||||
|
local entrySignature = modifierSignature(entry.bind.modifiers)
|
||||||
|
if entrySignature ~= signature and not seenSignatures[entrySignature] then
|
||||||
|
seenSignatures[entrySignature] = true
|
||||||
|
otherSignatures[#otherSignatures + 1] = entrySignature
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.sort(otherSignatures)
|
||||||
|
local usedOnAnotherLayer = #entries == 0 and #otherSignatures > 0
|
||||||
local chordParts = {}
|
local chordParts = {}
|
||||||
for _, modifier in ipairs(MODIFIER_ORDER) do
|
for _, modifier in ipairs(MODIFIER_ORDER) do
|
||||||
if activeModifiers[modifier] then
|
if activeModifiers[modifier] then
|
||||||
@@ -1073,8 +1124,11 @@ local function selectedKeyDetails(index)
|
|||||||
ui.row({ gap = 8, align = "center" }, {
|
ui.row({ gap = 8, align = "center" }, {
|
||||||
ui.label({ text = chord, color = "on_surface", fontSize = 13, fontWeight = "bold", flexGrow = 1 }),
|
ui.label({ text = chord, color = "on_surface", fontSize = 13, fontWeight = "bold", flexGrow = 1 }),
|
||||||
ui.label({
|
ui.label({
|
||||||
text = #entries > 0 and tr("panel.keyboard.occupied") or tr("panel.keyboard.free"),
|
text = #entries > 0 and tr("panel.keyboard.occupied") or (
|
||||||
color = #entries > 0 and asString(cfg("category_color"), "primary") or "on_surface_variant",
|
usedOnAnotherLayer and tr("panel.keyboard.other_layer") or tr("panel.keyboard.free")
|
||||||
|
),
|
||||||
|
color = (#entries > 0 or usedOnAnotherLayer)
|
||||||
|
and asString(cfg("category_color"), "primary") or "on_surface_variant",
|
||||||
fontSize = 11,
|
fontSize = 11,
|
||||||
fontWeight = "bold",
|
fontWeight = "bold",
|
||||||
}),
|
}),
|
||||||
@@ -1082,11 +1136,26 @@ local function selectedKeyDetails(index)
|
|||||||
}
|
}
|
||||||
if #entries == 0 then
|
if #entries == 0 then
|
||||||
children[#children + 1] = ui.label({
|
children[#children + 1] = ui.label({
|
||||||
text = tr("panel.keyboard.free_hint"),
|
text = tr(usedOnAnotherLayer and "panel.keyboard.other_layer_hint" or "panel.keyboard.free_hint"),
|
||||||
color = "on_surface_variant",
|
color = "on_surface_variant",
|
||||||
fontSize = 11,
|
fontSize = 11,
|
||||||
maxLines = 2,
|
maxLines = 2,
|
||||||
})
|
})
|
||||||
|
if usedOnAnotherLayer then
|
||||||
|
local layerButtons = {
|
||||||
|
ui.label({ text = tr("panel.keyboard.available_layers"), color = "on_surface_variant", fontSize = 10 }),
|
||||||
|
}
|
||||||
|
for _, otherSignature in ipairs(otherSignatures) do
|
||||||
|
layerButtons[#layerButtons + 1] = ui.button({
|
||||||
|
text = modifierSignatureLabel(otherSignature),
|
||||||
|
variant = "outline",
|
||||||
|
controlSize = "sm",
|
||||||
|
enabled = modifierSignatureSelectable(otherSignature),
|
||||||
|
onClick = layerCallback(otherSignature),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
children[#children + 1] = ui.row({ gap = 6, align = "center" }, layerButtons)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
for entryIndex, entry in ipairs(entries) do
|
for entryIndex, entry in ipairs(entries) do
|
||||||
if entryIndex > 5 then
|
if entryIndex > 5 then
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
id = "blackbartblues/keymap"
|
id = "blackbartblues/keymap"
|
||||||
name = "Keymap"
|
name = "Keymap"
|
||||||
version = "1.3.5"
|
version = "1.3.6"
|
||||||
plugin_api = 9
|
plugin_api = 9
|
||||||
author = "blackbartblues"
|
author = "blackbartblues"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -289,6 +289,7 @@
|
|||||||
"unknown": "The service returned an unknown error."
|
"unknown": "The service returned an unknown error."
|
||||||
},
|
},
|
||||||
"keyboard": {
|
"keyboard": {
|
||||||
|
"available_layers": "Used with",
|
||||||
"clear_modifiers": "Clear modifiers",
|
"clear_modifiers": "Clear modifiers",
|
||||||
"free": "Free",
|
"free": "Free",
|
||||||
"free_hint": "This combination is not used in the currently selected layer.",
|
"free_hint": "This combination is not used in the currently selected layer.",
|
||||||
@@ -307,6 +308,7 @@
|
|||||||
"no_modifiers": "No modifiers",
|
"no_modifiers": "No modifiers",
|
||||||
"occupied": "Occupied",
|
"occupied": "Occupied",
|
||||||
"other_layer": "Used on another layer",
|
"other_layer": "Used on another layer",
|
||||||
|
"other_layer_hint": "This key is assigned with different modifiers. Choose a layer below to view its shortcuts.",
|
||||||
"outside": "{count} shortcuts outside the keyboard view",
|
"outside": "{count} shortcuts outside the keyboard view",
|
||||||
"select_hint": "Select modifiers, then click a key to inspect that combination.",
|
"select_hint": "Select modifiers, then click a key to inspect that combination.",
|
||||||
"summary": "{layer}: {count} occupied keys",
|
"summary": "{layer}: {count} occupied keys",
|
||||||
|
|||||||
Reference in New Issue
Block a user