Yog li, yog tias koj xav sau qee qhov rais los teeb tsa xswitcher (Kuv tsis paub meej) Tsis muaj teeb meem xav tau "nrog rau qhov damn config ntawm koj li."
Rau tag nrho lwm tus, cov syntax yog raws li "key = tus nqi" (thiab cia li ob peb qhov kev xaiv nyuaj ntxiv, xws li = [qee, uas, array]) kuv twv yooj yim intuitively.
Qhov nthuav yog qhov ntawd "hluav taws" nyob rau tib lub sijhawm (kwv yees 2013). Tsuas yog, tsis zoo li kuv, tus sau TOML tau nkag mus rau qhov ntsuas kom raug.
Yog li ntawd, tam sim no nws yooj yim dua rau kuv los kho nws qhov kev siv kom haum rau kuv tus kheej, thiab tsis ua rau lwm tus.
Feem ntau, peb siv TOML (zoo ib yam li Windows INI qub). Thiab peb muaj ib tug configuration nyob rau hauv uas peb piav qhia txog yuav ua li cas muab ib tug series ntawm hooks nyob ntawm seb cov txheej txheem scan codes tshiab los ntawm cov keyboard. Hauv qab no, ib feem ntawm daim, yog dab tsi tau tshwm sim txog tam sim no. Thiab piav qhia tias vim li cas kuv thiaj txiav txim siab li no.
0. Basic abstractions
Luam theej duab kos npe. Ib yam dab tsi yuav tsum tau ua tiav txog qhov no, vim tsuas yog cov lej digital tsis yog tib neeg nyeem tau (uas tsuas yog kuv loloswitcher).
Kuv tshee tawm "ecodes.go" los ntawm "golang-evdev" (Kuv tub nkees heev los saib qhov qub, txawm hais tias tus sau qhia nws zoo heev). Kuv kho me ntsis (rau tam sim no) ib yam dab tsi uas txaus ntshai heev. Zoo li βLEFTBRACEβ β βL_BRACEβ.
Tsis tas li ntawd, nws tau qhia txog lub tswvyim ntawm "lub xeev cov yuam sij". Txij li cov qauv sau ntawv tsis tu ncua tsis tso cai rau cov lus ntev. (Tab sis nws tso cai rau koj mus xyuas nrog tsawg kawg nkaus nyiaj siv ua haujlwm. Yog tias koj tsuas yog siv cov ntaub ntawv "direct" xwb.)
Yuav muaj ib tug built-in "deuplicator" ntawm dab tsi yog nias. Yog li, lub xeev "repeat" = 2 yuav raug sau ΠΎΠ΄ΠΈΠ½ ib zaug.
1. Cov qauv ntu
[Templates] # "@name@" to simplify expressions
# Words can consist of these chars (regex)
"WORD" = "([0-9A-Z`;']|[LR]_BRACE|COMMA|DOT|SLASH|KP[0-9])"
Dab tsi yog ib lo lus tib neeg nrog lub suab lus suav nrog? (txawm yog teeb meem ntawm graphemes aka "hieroglyphs")? Qee yam txaus ntshai "daim ntawv". Yog li ntawd, kuv tam sim qhia lub tswvyim ntawm "template".
2. Yuav ua li cas thaum ib yam dab tsi raug nyem (lwm tus lej scan tau tuaj txog)
[ActionKeys]
# Collect key and do the test for command sequence
# !!! Repeat codes (code=2) must be collected once per key!
Add = ["1..0", "=", "BS", "Q..]", "L_CTRL..CAPS", "N_LOCK", "S_LOCK",
"KP7..KPDOT", "R_CTRL", "KPSLASH", "R_ALT", "KPEQUAL..PAUSE",
"KPCOMMA", "L_META..COMPOSE", "KPLEFTPAREN", "KPRIGHTPAREN"]
# Drop all collected keys, including this. This is default action.
Drop = ["ESC", "-", "TAB", "ENTER", "KPENTER", "LINEFEED..POWER"]
# Store extra map for these keys, when any is in "down" state.
# State is checked via "OFF:"|"ON:" conditions in action.
# (Also, state of these keys must persist between buffer drops.)
# ??? How to deal with CAPS and "LOCK"-keys ???
StateKeys = ["L_CTRL", "L_SHIFT", "L_ALT", "L_META", "CAPS", "N_LOCK", "S_LOCK",
"R_CTRL", "R_SHIFT", "R_ALT", "R_META"]
# Test only, but don't collect.
# E.g., I use F12 instead of BREAK on dumb laptops whith shitty keyboards (new ThinkPads)
Test = ["F1..F10", "ZENKAKUHANKAKU", "102ND", "F11", "F12",
"RO..KPJPCOMMA", "SYSRQ", "SCALE", "HANGEUL..YEN",
"STOP..SCROLLDOWN", "NEW..MAX"]
Tag nrho muaj 768 codes. (Tab sis "tsuas yog nyob rau hauv rooj plaub" Kuv tso ntes "xws li" rau hauv xswitcher code).
Hauv kuv tau piav qhia txog kev sau cov array nrog kev txuas mus rau cov haujlwm "yuav ua li cas". Nyob rau hauv golang no (dam ntawd) Nws muab tawm kom yooj yim thiab pom tseeb.
# Some behaviour can depend on application currently doing the input.
[[WindowClasses]]
# VNC, VirtualBox, qemu etc. emulates there input independently, so never intercept.
# With the exception of some stupid VNC clients, which does high-level (layout-based) keyboard input.
Regex = "^VirtualBox"
Actions = "" # Do nothing while focus stays in VirtualBox
[[WindowClasses]]
Regex = "^konsole"
# In general, mouse clicks leads to unpredictable (at the low-level where xswitcher resides) cursor jumps.
# So, it's good choise to drop all buffers after click.
# But some windows, e.g. terminals, can stay out of this problem.
MouseClickDrops = 0
Actions = "Actions"
[[WindowClasses]] # Default behaviour: no Regex (or wildcard like ".")
MouseClickDrops = 1
Actions = "Actions"
Cov kab ntawm lub rooj yog nyob rau hauv ob chav square brackets nrog nws lub npe. Nws tsis tuaj yeem yooj yim tawm ntawm tus puav. Nyob ntawm lub qhov rais tam sim no, koj tuaj yeem xaiv cov kev xaiv hauv qab no:
Koj tus kheej txheej ntawm "cov yuam sij kub" "Kev Ua = ...". Yog tias tsis yog / khoob, tsis ua dab tsi.
Hloov "MouseClickDrops" - yuav ua li cas thaum pom tus nas nyem. Txij li thaum lub sijhawm uas xswitcher tau qhib tsis muaj cov ntsiab lus hais txog "qhov twg lawv nyem," peb rov pib qhov tsis yog los ntawm lub neej ntawd. Tab sis hauv terminals (piv txwv li) koj tsis tas yuav ua qhov no (feem ntau).
4. Ib qho (lossis ob peb) ntu ββntawm kev nias ua rau ib qho lossis lwm qhov sib txuas
# action = [ regex1, regex2, ... ]
# "CLEAN" state: all keys are released
[Actions]
# Inverse regex is hard to understand, so extract negation to external condition.
# Expresions will be checked in direct order, one-by-one. Condition succceds when ALL results are True.
# Maximum key sequence length, extra keys will be dropped. More length - more CPU.
SeqLength = 8
# Drop word buffer and start collecting new one
NewWord = [ "OFF:(CTRL|ALT|META) SEQ:(((BACK)?SPACE|[LR]_SHIFT):[01],)*(@WORD@:1)", # "@WORD@:0" then collects the char
"SEQ:(@WORD@:2,@WORD@:0)", # Drop repeated char at all: unlikely it needs correction
"SEQ:((KP)?MINUS|(KP)?ENTER|ESC|TAB)" ] # Be more flexible: chars line "-" can start new word, but must not completelly invalidate buffer!
# Drop all buffers
NewSentence = [ "SEQ:(ENTER:0)" ]
# Single char must be deleted by single BS, so there is need in compose sequence detector.
Compose = [ "OFF:(CTRL|L_ALT|META|SHIFT) SEQ:(R_ALT:1,(R_ALT:2,)?(,@WORD@:1,@WORD@:0){2},R_ALT:0)" ]
"Action.RetypeWord" = [ "OFF:(CTRL|ALT|META|SHIFT) SEQ:(PAUSE:0)" ]
"Action.CyclicSwitch" = [ "OFF:(R_CTRL|ALT|META|SHIFT) SEQ:(L_CTRL:1,L_CTRL:0)" ] # Single short LEFT CONTROL
"Action.Respawn" = [ "OFF:(CTRL|ALT|META|SHIFT) SEQ:(S_LOCK:2,S_LOCK:0)" ] # Long-pressed SCROLL LOCK
"Action.Layout0" = [ "OFF:(CTRL|ALT|META|R_SHIFT) SEQ:(L_SHIFT:1,L_SHIFT:0)" ] # Single short LEFT SHIFT
"Action.Layout1" = [ "OFF:(CTRL|ALT|META|L_SHIFT) SEQ:(R_SHIFT:1,R_SHIFT:0)" ] # Single short RIGHT SHIFT
"Action.Hook1" = [ "OFF:(CTRL|R_ALT|META|SHIFT) SEQ:(L_ALT:1,L_ALT:0)" ]
Hooks muab faib ua ob hom. Built-in, nrog rau tus kheej piav npe (NewWord, NewSentence, Compose) thiab programmable.
Txhua ntu yuav tsum tau piav qhia hauv qab no nrog tib lub npe.
Txhawm rau kom tsis txhob cuam tshuam tib neeg lub siab nrog "liab qab" tsis tu ncua (los ntawm kev paub, lawv sau ntawvtej zaum ib tug ntawm kaum cov kws tshaj lij), Kuv tam sim siv cov syntax ntxiv.
"OFF:" (los yog "ON:") ua ntej regexp (kev qhia tsis tu ncua) xav kom cov nyees khawm hauv qab no raug tso tawm (los yog nias).
Tom ntej no kuv yuav ua qhov "tsis ncaj ncees" tsis tu ncua. Nrog cais cov khoom ntawm cov kav dej "|". Txhawm rau txo cov ntaub ntawv xws li "[LR]_SHIFT" (qhov no yog qhov tsis tsim nyog).
"SEQ:" Yog tias qhov xwm txheej dhau los tau ua tiav (lossis tsis tuaj), ces peb kuaj xyuas qhov "ib txwm" qhia tsis tu ncua. Yog xav paub ntxiv, kuv xa mus rau ^W lub tsev qiv ntawv "regexp". Vim kuv tseem tsis tau thab mus nrhiav cov degree ntawm compatibility nrog kuv nyiam pcre ("perl compatible").
Cov lus qhia yog sau rau hauv daim ntawv "BUTTON_1: CODE1, BUTTON_2: CODE2" thiab lwm yam, nyob rau hauv qhov kev txiav txim uas tau txais cov lej scan.
Daim tshev yeej ib txwm "snuged" mus rau qhov kawg ntawm qhov sib lawv liag, yog li tsis tas yuav ntxiv "$" rau tus Tsov tus tw.
Tag nrho cov tshev hauv ib kab yog ua ib qho tom qab lwm qhov thiab ua ke los ntawm "Kuv". Tab sis txij li tus nqi tau piav qhia tias yog ib qho array, koj tuaj yeem sau ib qho kev kuaj xyuas tom qab lub comma. Yog tias qhov no xav tau rau qee yam.
nqi "Luas = 8" txwv qhov loj ntawm qhov tsis tawm tsam uas txhua qhov kev kuaj xyuas tau ua. Vim Kuv muaj (txog tam sim no) yeej tsis tau ntsib kev txom nyem hauv kuv lub neej.
5. Kev teeb tsa cov hooks tau piav qhia hauv ntu dhau los
# Action is the array, so actions could be chained (m.b., infinitely... Have I to check this?).
# For each action type, extra named parameters could be collected. Invalid parameters will be ignored(?).
[Action.RetypeWord] # Switch layout, drop last word and type it again
Action = [ "Action.CyclicSwitch", "RetypeWord" ] # Call Switch() between layouts tuned below, then RetypeWord()
[Action.CyclicSwitch] # Cyclic layout switching
Action = [ "Switch" ] # Internal layout switcher func
Layouts = [0, 1]
[Action.Layout0] # Direct layout selection
Action = [ "Layout" ] # Internal layout selection func
Layout = 0
[Action.Layout1] # Direct layout selection
Action = [ "Layout" ] # Internal layout selection func
Layout = 1
[Action.Respawn] # Completely respawn xswitcher. Reload config as well
Action = [ "Respawn" ]
[Action.Hook1] # Run external commands
Action = [ "Exec" ]
Exec = "/path/to/exec -a -b --key_x"
Wait = 1
SendBuffer = "Word" # External hook can process collected buffer by it's own means.
Qhov tseem ceeb ntawm no yog "Action = [Array]". Zoo ib yam li cov seem dhau los, muaj kev txwv tsis pub ua hauv kev ua haujlwm. Thiab qhov muaj peev xwm ntawm docking tsis txwv hauv txoj cai (sau "Action.XXX" thiab tsis txhob tub nkeeg dhau los sau lwm ntu rau nws).
Tshwj xeeb tshaj yog, retyping ntawm ib lo lus nyob rau hauv kho layout yog muab faib ua ob ntu: βhloov lub layout raws li tau teev tseg rau ntawdβ ΠΈ "retype" ("RetypeWord").
Qhov seem tsis yog sau rau "dictionary" ("map" in golang) rau ib qho kev nqis tes ua, lawv cov npe nyob ntawm qhov tau sau hauv "Action".
Ob peb yam sib txawv tuaj yeem piav qhia hauv ib heap (seem). Los yog koj tuaj yeem rub nws sib nrug. Raws li kuv tau qhia saum toj no.
Kuv tau teeb tsa "Exec" tam sim ntawd los ua cov ntawv sau sab nraud. Nrog rau kev xaiv thawb lub kaw tsis rau hauv stdin.
"Tos = 1" β tos kom cov txheej txheem khiav kom tiav.
Tej zaum, "mus rau heap" koj yuav xav tso cov neeg ntxiv rau hauv ib puag ncig. cov ntaub ntawv xws li lub npe ntawm lub qhov rais chav kawm uas nws tau cuam tshuam. βKoj puas xav txuas koj tus tuav? Nov yog qhov chaw koj yuav tsum mus. "
Pheej (exhaled). Zoo li kuv tsis nco qab dab tsi.
Oops! Yog, kuv tsis tau hnov ββqab ...
Qhov kev tso tawm nyob qhov twg? Nyob rau hauv hard code? Zoo li ntawd:
[ScanDevices]
# Must exist on start. Self-respawn in case it is younger then 30s
Test = "/dev/input/event0"
Respawn = 30
# Search mask
Search = "/dev/input/event*"
# In my thinkPads there are such a pseudo-keyboards whith tons of unnecessary events
Bypass = "(?i)Video|Camera" # "(?i)" obviously differs from "classic" pcre's.
Kuv tsis nco qab / ua yuam kev qhov twg? (tsis muaj txoj hauv kev no), Kuv vam tias cov neeg nyeem nyeem yuav tsis ua tub nkeeg dhau los ua rau lawv lub qhov ntswg.