Como a publicação anterior (xswitcher na etapa "prova de conceito") recebeu muitas críticas construtivas (o que é bom) , continuei a gastar meu tempo livre no desenvolvimento do projeto. Agora eu quero gastar um pouco do seu ... O segundo passo não será muito familiar: sugestão / discussão sobre o design da configuração.
De alguma forma, os programadores normais estão muito entediados em sintonizar todas essas reviravoltas.Para não ser infundado, é um exemplo do que estou lidando.( ) Apache Kafka & ZooKeeper.
— ? ! - xml ( « »).
— , ACL ? ! -… - .
E no meu trabalho - exatamente o oposto. Corretamente (infelizmente, desde a primeira vez quase nunca), o modelo construído permite montar fácil e facilmente (ou quase) o circuito.Recentemente, um artigo sobre Habré encontrou um artigo sobre o trabalho árduo de cientistas de dados ..., . , , « ». , .. — , / . - .
Vá direto ao ponto. Como base sintática, peguei o TOML desse cidadão .Porque (TOML) é, por um lado, editável por humanos. E por outro lado - traduz 1: 1 em qualquer uma das sintaxes mais comuns: XML, JSON, YAML.Além disso, a implementação que usei no “github.com/BurntSushi/toml”, embora não seja a mais atual (sintaxe atual 1.4), é sintaticamente compatível com o mesmo JSON (“interno”).Ou seja, se desejar, você pode simplesmente dizer "vá pela floresta com esse seu TOML, eu quero XXX" e "remende" o código com apenas uma linha.Portanto, se você deseja escrever algumas janelas (definitivamente não eu) para configurar o xswitcher, não há problemas "com essa sua porra de configuração".Para todas as outras sintaxes com base em "key = value" (e literalmente em algumas opções mais complexas, como = [a, então a matriz]) acreditaintuitivamente conveniente.,
«» ( 2013 ). , , TOML .
, .
Em geral, utilizamos o TOML (muito semelhante ao antigo INI do Windows). E temos uma configuração na qual descrevemos como conectar uma série de ganchos, dependendo do conjunto dos códigos de verificação mais recentes do teclado. Abaixo em pedaços - o que aconteceu no momento. E a explicação do que eu decidi.0. Abstrações básicas
- -. - , - ( loloswitcher).
«ecodes.go» «golang-evdev» ( , ). () . «LEFTBRACE» → «L_BRACE». - « ». . ( . «» .)
- «» . , «»=2 .
1.
[Templates]
"WORD" = "([0-9A-Z`;']|[LR]_BRACE|COMMA|DOT|SLASH|KP[0-9])"
Em que consiste uma palavra da linguagem humana com uma notação fonética (ou é um grafema conhecido como "hieróglifo") ? Algum tipo de "folha" terrível. Portanto, eu imediatamente coloquei o conceito de "modelo".2. O que fazer quando algo é pressionado (o próximo código de digitalização chegou)
[ActionKeys]
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 = ["ESC", "-", "TAB", "ENTER", "KPENTER", "LINEFEED..POWER"]
StateKeys = ["L_CTRL", "L_SHIFT", "L_ALT", "L_META", "CAPS", "N_LOCK", "S_LOCK",
"R_CTRL", "R_SHIFT", "R_ALT", "R_META"]
Test = ["F1..F10", "ZENKAKUHANKAKU", "102ND", "F11", "F12",
"RO..KPJPCOMMA", "SYSRQ", "SCALE", "HANGEUL..YEN",
"STOP..SCROLLDOWN", "NEW..MAX"]
São fornecidos um total de 768 códigos. (Mas, apenas no caso, eu inseri uma captura de "surpresas" no código do xswitcher).No interior, pintei preenchendo a matriz com links para as funções "o que fazer". No golang, (de repente) acabou sendo conveniente e óbvio.- "Largar" neste local pretendo reduzir ao mínimo. A favor de um processamento mais flexível (mostrarei abaixo).
3. Etiqueta de classe da janela
[[WindowClasses]]
Regex = "^VirtualBox"
Actions = ""
[[WindowClasses]]
Regex = "^konsole"
MouseClickDrops = 0
Actions = "Actions"
[[WindowClasses]]
MouseClickDrops = 1
Actions = "Actions"
As linhas da tabela estão entre colchetes duplos com seu nome. Mais fácil de ir não funcionou. Dependendo da janela ativa atual, você pode escolher as opções:- « » «Actions = …». / — .
- «MouseClickDrops» — . xswitcher « », - . () ( ).
4. ( )
[Actions]
SeqLength = 8
NewWord = [ "OFF:(CTRL|ALT|META) SEQ:(((BACK)?SPACE|[LR]_SHIFT):[01],)*(@WORD@:1)",
"SEQ:(@WORD@:2,@WORD@:0)",
"SEQ:((KP)?MINUS|(KP)?ENTER|ESC|TAB)" ]
NewSentence = [ "SEQ:(ENTER:0)" ]
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)" ]
"Action.Respawn" = [ "OFF:(CTRL|ALT|META|SHIFT) SEQ:(S_LOCK:2,S_LOCK:0)" ]
"Action.Layout0" = [ "OFF:(CTRL|ALT|META|R_SHIFT) SEQ:(L_SHIFT:1,L_SHIFT:0)" ]
"Action.Layout1" = [ "OFF:(CTRL|ALT|META|L_SHIFT) SEQ:(R_SHIFT:1,R_SHIFT:0)" ]
"Action.Hook1" = [ "OFF:(CTRL|R_ALT|META|SHIFT) SEQ:(L_ALT:1,L_ALT:0)" ]
Ganchos são divididos em dois tipos. Incorporado, com nomes "falantes" (NewWord, NewSentence, Compose) e programável.Os nomes programáveis começam com "Ação". Porque TOML v1.4, os nomes pontilhados devem estar entre aspas.Uma seção com o mesmo nome deve ser descrita abaixo para cada um .Para não explodir o cérebro das pessoas com regulares "nus" (na experiência, um em cada dez profissionais pode escrevê- los ), eu imediatamente apresento uma sintaxe adicional.- «OFF:» ( «ON:») regexp ( ) ( ).
«» . "|". "[LR]_SHIFT" ( ). - «SEQ:» ( ), «» .
^W «regexp». pcre («perl compatible»). - «_1: 1, _2: 2» .., -.
- «» , "$" .
- «». , . - .
- «SeqLength = 8» , . .. ( ) .
5. ,
[Action.RetypeWord]
Action = [ "Action.CyclicSwitch", "RetypeWord" ]
[Action.CyclicSwitch]
Action = [ "Switch" ]
Layouts = [0, 1]
[Action.Layout0]
Action = [ "Layout" ]
Layout = 0
[Action.Layout1]
Action = [ "Layout" ]
Layout = 1
[Action.Respawn]
Action = [ "Respawn" ]
[Action.Hook1]
Action = [ "Exec" ]
Exec = "/path/to/exec -a -b --key_x"
Wait = 1
SendBuffer = "Word"
O principal aqui é "Ação = [Matriz]" . Semelhante à seção anterior, há um conjunto limitado de ações internas. E, em princípio, ilimitada a possibilidade de atracar (escreva "Action.XXX" e não tenha preguiça de pintar outra seção) .Em particular, a palavra redigitação no layout corrigido é dividida em duas partes: “alterar o layout conforme definido lá” e “redigitar” (“RetypeWord”) .Os parâmetros restantes são gravados no "dicionário" ("mapa" em golang) para esta ação, sua lista depende do que está escrito em "Ação".Várias ações diferentes podem ser descritas em uma pilha (seção) . E você pode separá-lo. Como mostrei acima.Coloque imediatamente a ação "Exec" - execute um script externo. Com a opção de enviar o buffer escrito para o stdin.- “Wait = 1” - aguarde a conclusão do processo em execução.
- Provavelmente, "para a pilha" vai querer colocar no ambiente extra. informações como o nome da classe de janela da qual é interceptada.
"Quer ligar seu manipulador?" Para você aqui.
Ufa (exalado). Parece não ter esquecido nada.Opa! Sim, eu não esqueci ...? -́? :
[ScanDevices]
Test = "/dev/input/event0"
Respawn = 30
Search = "/dev/input/event*"
Bypass = "(?i)Video|Camera"
E onde eu esqueci / cometi um erro (sem isso - de jeito nenhum) , realmente espero que os leitores atentos não tenham preguiça de cutucar o nariz.Boa sorte