Atunse ifilelẹ Xswitcher fun Linux: igbesẹ meji

Bi ti tẹlẹ atejade (xswitcher ni "ẹri ti Erongba" ipele) gba oyimbo kan pupo ti todara esi (eyi ti o dara), Mo tẹsiwaju lati lo akoko ọfẹ mi ni idagbasoke iṣẹ naa. Bayi Mo fẹ lati na diẹ ninu rẹ ... Igbesẹ keji kii yoo jẹ deede: imọran / ijiroro ti apẹrẹ iṣeto.

Atunse ifilelẹ Xswitcher fun Linux: igbesẹ meji

Bakan o wa ni jade wipe deede pirogirama ri ti o ti iyalẹnu alaidun lati ṣeto soke gbogbo awọn wọnyi idari.

Ni ibere ki o má ba ni ipilẹ, inu jẹ apẹẹrẹ ti ohun ti Mo n ṣe pẹlu.
Lapapọ loyun daradara (ati imuse daradara) Apache Kafka & ZooKeeper.
- Iṣeto ni? Sugbon o jẹ alaidun! Dumb xml (nitori pe “jade kuro ninu apoti”).
- Oh, ṣe o tun fẹ ACL kan? Sugbon o ni ki alaidun! Tẹ-blooper... Nkankan bi iyẹn.

Ṣugbọn ninu iṣẹ mi o jẹ idakeji. Ọtun (alas, o fẹrẹ kii ṣe igba akọkọ) awoṣe ti a ṣe gba ọ laaye lati tẹsiwaju siwaju ni irọrun ati nipa ti ara (Fere) jọ a aworan atọka.

Laipẹ Mo wa nkan kan lori Habré nipa iṣẹ takuntakun ti awọn onimọ-jinlẹ data…
O wa ni jade wipe akoko yi ti wa ni kikun mọ fun wọn. Ati ninu iṣe mi, bi wọn ṣe sọ, “ẹya ina”. Awọn awoṣe iwọn-pupọ, awọn olupilẹṣẹ akoko pẹlu OOP ni imurasilẹ, ati bẹbẹ lọ. - gbogbo eyi yoo han nigbamii nigbati / ti o ba ya. Ṣugbọn onise nilo lati bẹrẹ ibikan nibi ati bayi.

Gba si ojuami. Mo mu TOML bi ipilẹ syntactic lati ara ilu yii.

Nitoripe oun (TOML) lori awọn ọkan ọwọ, eda eniyan-editable. Ní ọwọ́ kejì ẹ̀wẹ̀, ó jẹ́ ìtúmọ̀ 1:1 sí èyíkéyìí nínú àwọn ìtumọ̀ tí ó wọ́pọ̀: XML, JSON, YAML.
Pẹlupẹlu, imuse ti mo lo lati "github.com/BurntSushi/toml", biotilejepe kii ṣe julọ asiko (si tun 1.4 sintasi), syntactically ni ibamu pẹlu kanna ("itumọ ti ni") JSON.

Iyẹn ni, ti o ba fẹ, o le sọ nirọrun “lọ nipasẹ awọn igbo pẹlu TOML ti tirẹ, Mo fẹ XXX” ati “patch” koodu pẹlu laini kan.

Nitorinaa, ti o ba fẹ kọ diẹ ninu awọn window lati tunto xswitcher (Ko da mi loju) Ko si awọn iṣoro ti o nireti “pẹlu atunto ti tirẹ.”

Fun gbogbo awọn miiran, sintasi naa da lori “bọtini = iye” (ati itumọ ọrọ gangan tọkọtaya awọn aṣayan idiju diẹ sii, bii = [diẹ ninu, iyẹn, orun]) Mo ro
intuitively rọrun.
Ohun ti o yanilenu ni pe "sisun" ni ayika akoko kanna (ni ayika 2013). Nikan, ko dabi emi, onkọwe ti TOML wọle lori iwọn to dara.

Nitorinaa, ni bayi o rọrun fun mi lati ṣatunṣe imuse rẹ lati baamu fun ara mi, kii ṣe idakeji.

Ni gbogbogbo, a ya TOML (gan iru si atijọ Windows INI). Ati pe a ni iṣeto ni ninu eyiti a ṣe apejuwe bi o ṣe le so lẹsẹsẹ awọn kio da lori ṣeto ti awọn koodu ọlọjẹ tuntun lati keyboard. Ni isalẹ, nkan nipa nkan, ni ohun ti o ṣẹlẹ titi di isisiyi. Ati alaye idi ti Mo pinnu ni ọna yii.

0. Awọn abstractions ipilẹ

  • Ọlọjẹ koodu designations. Ohunkan pato nilo lati ṣee ṣe nipa eyi, niwọn igba ti awọn koodu oni-nọmba larọrun kii ṣe kika eniyan (iyẹn ni emi kan loloswitcher).
    Mo gbon "ecodes.go" lati "golang-evdev" (Mo jẹ ọlẹ pupọ lati wo orisun atilẹba, botilẹjẹpe onkọwe tọka si ni aṣa). Mo ṣe atunṣe diẹ (fun bayi) nkan ti o bẹru pupọ. Bi "LEFTBRACE" → "L_BRACE".
  • Ni afikun, o ṣafihan imọran ti “awọn bọtini ipinlẹ”. Niwọn igba ti girama ti a lo nigbagbogbo ko gba laaye fun awọn aye gigun. (Ṣugbọn o gba ọ laaye lati ṣayẹwo pẹlu iwọn kekere. Ti o ba lo igbasilẹ “taara” nikan.)
  • Nibẹ ni yio je kan-itumọ ti ni "deduplicator" ti ohun ti a tẹ. Bayi, ipinle "tun"=2 yoo kọ один aago.

1. Awọn awoṣe apakan

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

Kini ọrọ ede eniyan pẹlu ami akiyesi phonetic ni ninu? (boya ọrọ kan ti graphemes aka “hieroglyphs”)? Diẹ ninu awọn iru “dì” ẹru. Nitorinaa, Mo ṣafihan lẹsẹkẹsẹ imọran ti “awoṣe”.

2. Kini lati ṣe nigbati nkan ba tẹ (koodu ọlọjẹ miiran ti de)

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

Awọn koodu 768 wa lapapọ. (Ṣugbọn "o kan ni irú" Mo fi sii mimu "awọn iyanilẹnu" sinu koodu xswitcher).
Ninu inu Mo ṣe apejuwe kikun akojọpọ pẹlu awọn ọna asopọ si awọn iṣẹ “kini lati ṣe”. Ni golang eyi ni (lojiji) O wa ni irọrun ati kedere.

  • Mo gbero lati dinku “Ju silẹ” si o kere ju ni aaye yii. Ni ojurere ti iṣelọpọ irọrun diẹ sii (Emi yoo fi han ni isalẹ).

3. Tabili pẹlu window kilasi

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

Awọn ori ila ti tabili wa ni awọn biraketi onigun mẹrin meji pẹlu orukọ rẹ. Ko le ti rọrun lati inu adan naa. Ti o da lori window ti n ṣiṣẹ lọwọlọwọ, o le yan awọn aṣayan wọnyi:

  • Eto tirẹ ti “awọn bọtini gbona” “Awọn iṣe =…”. Ti ko ba / sofo, ma ṣe ohunkohun.
  • Yipada “MouseClickDrops” - kini lati ṣe nigbati a ba rii tẹ Asin kan. Niwọn bi aaye ti xswitcher ti wa ni titan ko si awọn alaye nipa “ibiti wọn ti tẹ,” a tunto ifipamọ nipasẹ aiyipada. Ṣugbọn ni awọn ebute (fun apẹẹrẹ) o ko ni lati ṣe eyi (nigbagbogbo).

4. Ọkan (tabi pupọ) awọn ilana ti awọn titẹ nfa ọkan tabi miiran kio

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

Awọn kio ti pin si awọn oriṣi meji. Ti a ṣe sinu, pẹlu awọn orukọ “sọ” (NewWord, NewSentence, Compose) ati siseto.

Awọn orukọ eto bẹrẹ pẹlu “Iṣe.” Nitori TOML v1.4, awọn orukọ pẹlu aami gbọdọ wa ni awọn agbasọ ọrọ.

Kọọkan apakan yẹ ki o wa ni apejuwe ni isalẹ pẹlu orukọ kanna.

Ni ibere ki o má ba fẹ ọkàn eniyan pẹlu "ihoho" deede (lati iriri, wọn lati kọboya ọkan ninu mẹwa awọn akosemose), Mo ṣe imuse afikun sintasi lẹsẹkẹsẹ.

  • "PA:" (tabi "ON:") ṣaaju ki o to regexp (ikosile deede) nilo pe awọn bọtini atẹle ni tu silẹ (tabi tẹ).
    Nigbamii Emi yoo ṣe ikosile deede “aiṣedeede”. Pẹlu lọtọ yiyewo awọn ege laarin awọn paipu "|". Lati le dinku nọmba awọn igbasilẹ bii "[LR]_SHIFT" (nibiti eyi ko ṣe pataki).
  • "SEQ:" Ti ipo iṣaaju ba pade (tabi ko si), lẹhinna a ṣayẹwo lodi si ikosile deede “deede”. Fun awọn alaye, Mo fi ranṣẹ si ^W ile-ikawe “regexp” lẹsẹkẹsẹ. Nitoripe Emi ko tun ni wahala lati wa iwọn ibamu pẹlu pcre ayanfẹ mi (“ibaramu perl”).
  • A kọ ọrọ naa sinu fọọmu naa "BUTTON_1: CODE1, BUTTON_2: CODE2" ati bẹbẹ lọ, ni aṣẹ ti awọn koodu ọlọjẹ ti gba.
  • Ayẹwo ti wa ni nigbagbogbo "snugged" si opin ti awọn ọkọọkan, nitorina ko si iwulo lati ṣafikun “$” si iru.
  • Gbogbo awọn sọwedowo ni ila kan ni a ṣe ni ọkọọkan ati pe a ni idapo nipasẹ "I". Ṣugbọn niwọn bi a ti ṣe apejuwe iye naa bi opo, o le kọ ayẹwo yiyan lẹhin aami idẹsẹ. Ti eyi ba nilo fun idi kan.
  • Itumo "Ipari Aaya = 8" fi opin si iwọn ifipamọ lodi si eyiti gbogbo awọn sọwedowo ṣe. Nitori Mo ni (titi di bayi) ko pade awọn orisun ailopin ninu igbesi aye mi.

5. Ṣiṣeto awọn kio ti a ṣalaye ninu apakan ti tẹlẹ

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

Ohun akọkọ nibi ni "Ise = [Ara]". Iru si apakan ti tẹlẹ, eto ti o lopin ti awọn iṣe ti a ṣe sinu wa. Ati pe o ṣeeṣe ti docking ko ni opin ni ipilẹ (kọ "Action.XXX" ati maṣe ọlẹ pupọ lati kọ apakan miiran fun rẹ).
Ní pàtàkì, títún ọ̀rọ̀ kan tẹ̀ sínú ìtòlẹ́sẹẹsẹ àtúnṣe ti pín sí apá méjì: "Yi ifilelẹ naa pada gẹgẹbi pato nibẹ" и “Tẹ̀ tẹ” (“Tẹ̀dà Word”).

Awọn paramita to ku ni a kọ si “itumọ-itumọ” ("maapu" ni golang) fun iṣẹ kan, atokọ wọn da lori ohun ti a kọ sinu “Iṣe”.

Awọn iṣe oriṣiriṣi pupọ ni a le ṣe apejuwe ni okiti kan (awọn apakan). Tabi o le fa o yato si. Bi mo ti fihan loke.

Mo ṣeto lẹsẹkẹsẹ igbese “Exec” lati ṣiṣẹ iwe afọwọkọ ita. Pẹlu aṣayan lati Titari ifipamọ ti o gbasilẹ sinu stdin.

  • "Duro = 1" - duro fun ilana ṣiṣe lati pari.
  • Boya, "si okiti" iwọ yoo fẹ lati fi awọn eniyan afikun si ayika. alaye gẹgẹbi orukọ ti kilasi window lati eyiti o ti gba wọle.
    “Ṣe o fẹ sopọ oluṣakoso rẹ bi? Eyi ni ibiti o nilo lati lọ. ”

Phew (ti jade). O dabi pe Emi ko gbagbe ohunkohun.

Ops! Bẹẹni, Emi ko gbagbe ...
Nibo ni iṣeto ifilọlẹ wa? Ni koodu lile? Bẹ yẹn:

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

Nibo ni MO gbagbe / ṣe aṣiṣe kan? (ko si ọna laisi eyi), Mo nireti gaan pe awọn oluka ti o tẹtisi kii yoo jẹ ọlẹ pupọ lati pa imu wọn.

Ti o dara orire!

orisun: www.habr.com

Fi ọrọìwòye kun