Xswitcher layout corrector pro Linux: gradus duos

Quia prior publication (xswitcher ad "probationem conceptus" scaenae) satis multum ad utiles opiniones accepit (quod est nice)Perrexi otium meum impendia developing. Nunc volo modicum tempus terere tuorum... Secundus gradus non erit satis usitatior: propositio/disceptatio de configuratione designatio.

Xswitcher layout corrector pro Linux: gradus duos

Nescio quomodo evenit ut programmatores normales incredibiliter taediosam inveniant ad has omnes potestates erigendas.

Ut non vanum sit, intus est exemplum quod agimus.
Super praeclare concepta (et bene instructa) Apache Kafka & ZooKeeper.
- Configuratio? Sed amet! Mutum xml (quia est "ex arca").
- Oh, visne etiam ACL? Sed sic amet! Tap-blooper... Aliquid tale.

Sed in opere meo prorsus contrarium est. ius (Ei, nunquam fere primum) constructum exemplar sinit ulterius facile et naturaliter (Fere) tabula convenire.

Nuper incidi articulum de Habre de labore notitiarum scientiarum...
Evenit ut hoc momentum illis plene impleatur. Et in usu meo, ut aiunt, "versio levis". Multi-volumen exempla, programmatores condiendi cum OOP parati, etc. β€” hoc omnes postea apparebunt, si aufert. Sed eget mauris ac nunc aliquet interdum.

Get ad rem. Tulit TOML ut ex syntactic ex hoc civis.

Quia ille (TOML) ex altera parte, homo editabilis. Aliunde transfertur 1:1 in syntaxes communiores: XML, JSON, YAML.
Actio autem usus sum a "github.com/BurntSushi/toml", etsi non celeberrima (adhuc 1.4 syntaxis), syntaxi compatitur cum JSON.

Hoc est, si vis, simpliciter dicere potes "ire per silvas cum isto TOML tuo, volo XXX" et "sarcinare" codicem una tantum linea.

Quapropter, si vis scribere aliquas fenestras ad xswitcher configurare (Non sum certus) Nullae difficultates expectantur "hoc tuum config damn."

Pro omnibus aliis, syntaxin "clavem = valorem" fundatur (and literally a couple of more perplexis options, like = [quidam, that, array]) Suspicor
intuenti conveniens.
Quid interest, quod "combussit" circa idem tempus (circa MMXIII). Tantum, dissimilem me, auctor TOML recte libram ingressus est.

Ideo nunc facilius est me accommodare ad exsequendum me, et non vice versa.

In universum sumimus TOML (veteris Fenestrae simillimum INI). Et configurationem habemus in qua describimus quomodo unci seriem apponere pendentes ex statuto ultimi codicis e claviaturae scan. Infra, per partes, id est, quod hactenus evenit. Et explicandum est cur hoc modo statuerim.

0. Basic abstractiones

  • Scan codicem vocabulorum. De hac re aliquid certius faciendum est, cum solum Codices digitales omnino non sint homines-readabiles (ut iustus me) loloswitcher).
    Excussi "ecodes.go" ex "golang-evdev" (nimis piger eram ad fontem originis spectare, quamvis auctor id plane culturae indicasset). Correxi paulum (iam) quod satis formidolosum erat. Velut "LEFTBRACE" β†’ "L_BRACE".
  • Praeterea notionem "clavium civitatis" induxit. Quia grammatica regularis usus non admittit per longos locos. (Sed id permittit ut caput minimi inspicias. Si tantum "directum" recording uteris.
  • In "deduplicatore" constructus erit expressi. Ita status "repeat" = II scribetur ΠΎΠ΄ΠΈΠ½ tempus.

1. Templates section

[Templates] # "@name@" to simplify expressions
 # Words can consist of these chars (regex)
 "WORD" = "([0-9A-Z`;']|[LR]_BRACE|COMMA|DOT|SLASH|KP[0-9])"

Quid humana vox cum notatione phonetica consistit? (Vel materia graphematum aka "hieroglyphis")? Quaedam horribilia "schedam". Ideo conceptum "templati" statim introduco.

2. Quid facere cum aliquid est clicked (alius scan codice advenit)

[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"]

Sunt in summa 768 codicibus. (Sed modo in casu" comprehendens in xswitcher codicem inserui.
Intus descripsimus complens aciem nexus ad functiones "quid facere". In golang hoc est (subito) Contigit ut commoda et aperta.

  • Hoc loco ad minimum reducere instituo. In favorem processus flexibilioris (infra ostendam).

3. mensam cum fenestra classes

# 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"

Ordines tabellae duplices uncis quadratis suo nomine sunt. Facilius non potuit ius off vespertilio. Secundum fenestram currently activam, sequentes optiones eligere potes:

  • Pro- prium institutum "clavium calidum" "actiones = ...". Si non/inanis, nihil.
  • Switch "MouseClickDrops" - quid facere cum mure click detegitur. Cum in puncto quo xswitcher volvitur nulla sunt singularia de "ubi deprimunt", quiddam per defaltam exponimus. Sed in terminalibus (exempli gratia) hoc facere non debes (plerumque).

4. unus (vel plures) series clicks felis vel alius hamo

# 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)" ]

Unci in duo genera dividuntur. Instructa, nomina cum "loqui" (NewWord, Novo Sententia, Componere) et programmatibus.

Nomina programmabilia incipiunt cum "Actio". Quod TOML v1.4, nomina cum punctis in virgulis esse debent.

Singulae partes infra describi debent cum eodem nomine.

Ne regularibus "nudis" animos hominum (experientia, eorum" scriboforte ex decem doctorum) Statim efficiendi syntaxin additam.

  • "DE:" (or "DE:") ante regexp (regulariter expressum) require ut sequentes bullae dimittantur (vel expressae).
    Deinde regularem expressionem "iniquam" facturus sum. Separata iniecta inter tibias frusta" |". Ad redigendum numerum monumentorum sicut "[LR]_SHIFT" (ubi hoc plane non est necessarium).
  • "SEQ:" Si prior conditio occurrit (vel absens), tunc contra "normalem" expressionem regularem refutamus. For details, I immediately send to ^W the "regemp" library. Quia adhuc non molesti sumus invenire gradum compatibilitatis cum dilectu meo pcre (β€œperl compatible”).
  • Locutio scripta est in forma "BUTTON_1: CODE1, BUTTON_2: CODE2" etc., eo ordine quo scan codices recipiuntur.
  • Perscriptio semper "snugged" ad finem sequentis, ideo non est caudae addere "$".
  • Omnes compescit in una linea fiunt deinceps et componuntur per ego. Sed quia valor ordinatus describitur, alterum reprehendo post comma scribere potes. Si hoc aliqua ratione opus sit.
  • valorem "SeqLength = 8" finit magnitudinem quiddam contra quod omnes compescit aguntur. Quod Ego nunquam in vita mea infinitas opes offendit.

5. constituendi uncinos de quibus in praecedente articulo

# 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.

Summa hic est "Actionis = [Array]". Similis sectioni praecedente, in actionibus aedificata est limitata copia. Possibilitas autem docendi non terminatur in principio (scribe "Action.XXX" et noli nimis piger esse ut aliam partem scribam pro ea..
Praesertim retypio vocabuli in correcto in duas partes dividitur; "Mutare layout ut certa ibi" ΠΈ "Retype" ("RetypeWord").

Reliquae parametri ad "dictionarium" scriptae sunt. ("map" in golang) ad actionem datam, eorum index pendet ab eo quod in "Actione" scriptum est.

Plures actiones in uno acervo describi possunt (sectiones). Vel distrahere potes. ut supra ostendi.

Statim constituo "Exec" actionem ad scriptum externum exequendum. Optione impulsum memoriae quiddam in stdin.

  • "Exspecta = 1" β€” exspecta processum currens ad perficiendum.
  • Probabiliter "ad cumulum" etiam homines in ambitu ponere vis. ut indicium quasi nomen fenestrae classis a quo interceptus sit.
    "Visne tracto coniungere tuum? Hoc est quo ire debes."

Phew (exhalatus). Videtur quasi nihil oblitus sum.

Oops! Yeah, oblitus non sum...
Ubi est Lorem configuratione? in codice duro? Sicut quod:

[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.

Ubi oblitus sum / Fallitur? (Nullo modo sine hoc)Profecto spero attentis lectores non fore nimis piger nasos eorum captandos.

Fortuna!

Source: www.habr.com