Ислоҳи тарҳбандии Xswitcher барои Linux: қадами дуюм

соли нашри қаблӣ (xswitcher дар марҳилаи "исботи консепсия") бисёр фикру мулоҳизаҳои созанда гирифтанд (ки хуб аст), Ман вақти холии худро ба таҳияи лоиҳа идома медодам. Ҳоло ман мехоҳам каме аз шумо сарф кунам ... Қадами дуюм чандон маъмулӣ нахоҳад буд: пешниҳод / муҳокимаи тарҳи конфигуратсия.

Ислоҳи тарҳбандии Xswitcher барои Linux: қадами дуюм

Ба гунае маълум мешавад, ки барномасозони муқаррарӣ насб кардани ҳамаи ин назоратҳоро бениҳоят дилгиркунанда меҳисобанд.

Барои он ки беасос набошад, дарун мисоли он чизест, ки ман бо он сарукор дорам.
Дар маҷмӯъ, Apache Kafka ва ZooKeeper хеле хуб тарҳрезӣ шудааст (ва хуб амалӣ карда шудааст).
- Конфигуратсия? Аммо дилгиркунанда аст! Dumb xml (зеро он "аз қуттӣ" аст).
- Оҳ, шумо низ мехоҳед ACL? Аммо ин хеле дилгиркунанда аст! Tap-blooper... Чизе монанди ин.

Аммо дар кори ман ин тамоман баръакс аст. Дуруст (Афсус, қариб ҳеҷ гоҳ бори аввал) модели сохта ба шумо имкон медиҳад, ки минбаъд ба осонӣ ва табиӣ идома диҳед (Қариб) диаграмма ҷамъ кунед.

Ман ба наздикӣ мақолаеро дар Ҳабре дар бораи меҳнати сахти олимони маълумот пайдо кардам ...
Маълум мешавад, ки ин лахза барои онхо пурра ба амал омадааст. Ва дар амалияи ман, чунон ки мегуянд, «версияи сабук». Моделҳои сершумор, барномасозони ботаҷриба бо OOP дар омода ва ғайра. — ин ҳама баъдтар ҳангоми парвоз кардан пайдо мешавад. Аммо дизайнер бояд аз ҷое дар ин ҷо ва ҳоло оғоз кунад.

Ба нукта бирасед. Ман TOML-ро ҳамчун асоси синтаксисӣ гирифтам аз ин шахрванд.

Зеро у (TOML) аз як тараф, инсон таҳриршаванда аст. Аз тарафи дигар, он 1:1 ба ҳама гуна синтаксисҳои маъмултарин тарҷума карда мешавад: XML, JSON, YAML.
Гузашта аз ин, татбиқе, ки ман аз "github.com/BurntSushi/toml" истифода мекардам, гарчанде ки мӯдтарин нест (ҳанӯз синтаксиси 1.4), аз ҷиҳати синтаксисӣ бо ҳамон JSON ("сохташуда") мувофиқ аст.

Яъне, агар шумо хоҳед, шумо метавонед танҳо бигӯед, ки "бо он TOML-и шумо аз ҷангал гузаред, ман XXX мехоҳам" ва кодро танҳо бо як сатр "ҷасб кунед".

Ҳамин тариқ, агар шумо хоҳед, ки баъзе тирезаҳоро барои танзими xswitcher нависед (Бовар надорам) "Бо ин конфигуратсияи лаънатии шумо" ягон мушкилот интизор нест.

Барои ҳамаи дигарон, синтаксис ба "калид = арзиш" асос ёфтааст (ва аслан якчанд вариантҳои мураккабтар, ба монанди = [баъзе, он, массив]) гумон мекунам
ба таври интуитивӣ қулай.
Чизи ҷолиб он аст "сӯхта" тақрибан ҳамон вақт (тақрибан 2013). Танҳо, бар хилофи ман, муаллифи TOML дар миқёси дуруст ворид шуд.

Аз ин рӯ, ҳоло барои ман осонтар аст, ки татбиқи онро ба худам мувофиқ созам, на баръакс.

Умуман, мо TOML-ро мегирем (ба Windows INI-и кӯҳна хеле монанд аст). Ва мо конфигуратсия дорем, ки дар он мо тавсиф мекунем, ки чӣ гуна як қатор қалмоқҳоро вобаста ба маҷмӯи рамзҳои скании охирин аз клавиатура пайваст кунем. Дар поён, порча ба порча он чизест, ки то ҳол рӯй дод. Ва шарҳи он ки чаро ман ин тавр қарор додам.

0. Абстраксияҳои асосӣ

  • Нишонаҳои коди скан. Дар ин бора бешубҳа коре кардан лозим аст, зеро рамзҳои рақамӣ комилан барои одамон хонда намешаванд (ин танҳо ман loloswitcher).
    Ман "ecodes.go"-ро аз "golang-evdev" ларзондам (ман барои нигоҳ кардан ба манбаи аслӣ хеле танбал будам, гарчанде ки муаллиф онро ба таври фарҳангӣ нишон додааст). Ман каме (ҳоло) чизеро, ки хеле тарснок буд, ислоҳ кардам. Мисли "LEFBRACE" → "L_BRACE".
  • Илова бар ин, ӯ мафҳуми «калидҳои давлатӣ»-ро муаррифӣ кард. Азбаски грамматикаи муқаррарии истифодашуда барои порчаҳои дароз иҷозат намедиҳад. (Аммо он ба шумо имкон медиҳад, ки бо ҳадди ақали хароҷот тафтиш кунед. Агар шумо танҳо сабти "мустақим" -ро истифода баред.)
  • Дар он ҷо як "дедупликатор" -и дарунсохташуда мавҷуд хоҳад буд. Ҳамин тариқ, ҳолати "такрор" = 2 навишта мешавад один маротиба.

1. Бахши Шаблонҳо

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

Калимаи забони инсон бо аломати фонетикӣ аз чӣ иборат аст? (ё масъалаи графемаҳо, яъне "иероглифҳо")? Як навъ «варақ» даҳшатнок. Аз ин рӯ, ман фавран мафҳуми «шаблон»-ро ворид мекунам.

2. Вақте ки чизе клик мешавад, чӣ бояд кард (коди дигари скан омад)

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

Дар маҷмӯъ 768 рамз вуҷуд дорад. (Аммо "танҳо дар сурати" ман "сюрпризҳо" -ро ба рамзи xswitcher ворид кардам).
Дар дохили он ман пур кардани массивро бо истинод ба функсияҳои "чӣ бояд кард" тавсиф кардам. Дар Голанг ин аст (ногаҳон) Он қулай ва аён гардид.

  • Ман нақша дорам, ки дар ин ҷо "Трапа" -ро то ҳадди аққал кам кунам. Ба тарафдории коркарди фасењтар (ман онро дар зер нишон медињам).

3. Ҷадвал бо синфҳои тиреза

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

Сатрҳои ҷадвал дар қавсҳои чоркунҷаи дукарата бо номи он ҷойгир шудаанд. Дарҳол осонтар шуда наметавонист. Вобаста ба равзанаи фаъол, шумо метавонед имконоти зеринро интихоб кунед:

  • Маҷмӯи худи шумо "калидҳои гарм" "Амалҳо = ...". Агар не/холӣ, ҳеҷ кор накунед.
  • Гузаронидани "MouseClickDrops" - ҳангоми ошкор шудани пахши муш чӣ бояд кард. Азбаски дар лаҳзае, ки xswitcher фаъол аст, тафсилоти "куҷои онҳо клик кардан" вуҷуд надорад, мо буферро ба таври нобаёнӣ аз нав танзим мекунем. Аммо дар терминалҳо (масалан) ба шумо лозим нест, ки ин корро кунед (одатан).

4. Як (ё якчанд) пайдарпайии кликҳо ин ё он қалмоқро ба вуҷуд меоранд

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

Гулҳо ба ду намуд тақсим мешаванд. Дарунсохт, бо номҳои "сухангӯӣ" (NewWord, NewSentence, Compose) ва барномарезишаванда.

Номҳои барномарезишаванда бо "Амал" оғоз мешаванд. Зеро TOML v1.4, номҳо бо нуқтаҳо бояд дар нохунак бошанд.

Ҳар як бахш бояд дар зер тавсиф карда шавад бо ҳамон ном.

Барои он ки бо мунтазами «урён» майнаи одамон наафтад (аз таҷриба, онҳо нависедшояд аз даҳ як нафар мутахассисон), Ман фавран синтаксиси иловагиро амалӣ мекунам.

  • "OFF:" (ё "ON:") пеш аз regexp (ифодаи муқаррарӣ) талаб мекунад, ки тугмаҳои зерин озод карда шаванд (ё пахш карда шаванд).
    Минбаъд ман як ифодаи муқаррарии "беадолатона" хоҳам дод. Бо тафтиши алохидаи порчахои байни кубурхо «|». Барои кам кардани шумораи сабтҳо ба монанди "[LR]_SHIFT" (дар ҷое ки ин ба таври возеҳ лозим нест).
  • "СЕҚ:" Агар шарти қаблӣ иҷро шуда бошад (ё вуҷуд надошта бошад), пас мо бо ифодаи муқаррарии "муқаррарӣ" тафтиш мекунем. Барои тафсилот, ман фавран ба ^W китобхонаи "regexp" мефиристам. Зеро ман то ҳол барои фаҳмидани дараҷаи мутобиқат бо pcre дӯстдоштаи худ ("perl мувофиқ") ташвиш надидам.
  • Ифода дар шакл навишта шудааст "BUTTON_1: CODE1, BUTTON_2: CODE2" ва ғайра, бо тартиби қабули кодҳои скан.
  • Чек ҳамеша ба охири пайдарпаӣ "часпонида мешавад", бинобар ин ба дум илова кардани "$" лозим нест.
  • Ҳама санҷишҳо дар як сатр паси дигар гузаронида мешаванд ва бо "ман" муттаҳид мешаванд. Аммо азбаски арзиш ҳамчун массив тасвир шудааст, шумо метавонед пас аз вергул чеки алтернативӣ нависед. Агар ин бо ягон сабаб лозим бошад.
  • арзиши "Дарозии пайдарпай = 8" андозаи буферро, ки бар зидди он ҳама санҷишҳо анҷом дода мешаванд, маҳдуд мекунад. Зеро Ман (то ҳол) дар ҳаёти худ ҳеҷ гоҳ ба захираҳои беохир дучор нашудаам.

5. Муқаррар кардани қалмоқҳои дар боби қаблӣ тавсифшуда

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

Дар ин ҷо чизи асосӣ ин аст "Амал = [Массив]". Монанди фасли қаблӣ, маҷмӯи маҳдуди амалҳои дарунсохт мавҷуд аст. Ва имконияти пайвастшавӣ аз рӯи принсип маҳдуд нест ("Action.XXX" -ро нависед ва барои навиштани бахши дигар барои он танбал нашавед).
Аз љумла, дубора чоп кардани калима дар тарҳи ислоҳшуда ба ду қисм тақсим мешавад: "Тарҳангро тавре ки дар он ҷо нишон дода шудааст, тағир диҳед" и "аз нав чоп кунед" ("RetypeWord").

Параметрҳои боқимонда ба "лугат" навишта мешаванд ("харита" дар Голанг) барои амали додашуда, рӯйхати онҳо аз он чизе, ки дар "Амал" навишта шудааст, вобаста аст.

Якчанд амалҳои гуногунро дар як тӯда тавсиф кардан мумкин аст (қисмҳо). Ё шумо метавонед онро ҷудо кунед. Чунон ки дар боло нишон додам.

Ман фавран амали "Exec" -ро барои иҷрои скрипти беруна муқаррар кардам. Бо имкони тела додани буфери сабтшуда ба stdin.

  • "Интизор шавед = 1" - интизор шавед, ки раванди иҷрошаванда анҷом ёбад.
  • Эҳтимол, "ба теппа" шумо мехоҳед, ки одамони иловагиро дар муҳити атроф ҷойгир кунед. маълумот ба монанди номи синфи тиреза, ки аз он боздошта шудааст.
    "Оё шумо мехоҳед коркардкунандаи худро пайваст кунед? Ин ҷоест, ки шумо бояд равед. ”

Фу (нафас кашида). Чунин ба назар мерасад, ки ман ҳеҷ чизро фаромӯш накардаам.

Оҳ! Ҳа, фаромӯш накардам...
Конфигуратсияи оғозёбӣ дар куҷост? Дар рамзи сахт? Ҳамин тавр:

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

Ман дар куҷо фаромӯш кардаам/хато кардаам? (бе ин роҳ нест), Ман дар ҳақиқат умедворам, ки хонандагони бодиққат барои кашидани бинии худ танбал нахоҳанд шуд.

Барори кор

Манбаъ: will.com

Илова Эзоҳ