Xswitcher አቀማመጥ አራሚ ለሊኑክስ፡ ደረጃ ሁለት

ጀምሮ ያለፈው እትም (xswitcher በ “የፅንሰ-ሃሳብ ማረጋገጫ” ደረጃ) ብዙ ገንቢ አስተያየቶችን አግኝቷል (ጥሩ ነው), ፕሮጀክቱን በማዘጋጀት ነፃ ጊዜዬን ማሳለፍ ቀጠልኩ. አሁን ከእርስዎ ትንሽ ማጥፋት እፈልጋለሁ ... ሁለተኛው እርምጃ በጣም የተለመደ አይሆንም፡ ስለ ውቅረት ዲዛይን ሀሳብ/ውይይት።

Xswitcher አቀማመጥ አራሚ ለሊኑክስ፡ ደረጃ ሁለት

የሆነ ሆኖ መደበኛ ፕሮግራመሮች እነዚህን ሁሉ መቆጣጠሪያዎች ማዘጋጀት በሚያስደንቅ ሁኔታ አሰልቺ ሆኖ አግኝተውታል።

መሠረተ ቢስ እንዳንሆን ውስጤ የምይዘው ምሳሌ ነው።
በአጠቃላይ በጥሩ ሁኔታ የተፀነሰ (እና በጥሩ ሁኔታ የተተገበረ) Apache Kafka እና ZooKeeper።
- ማዋቀር? ግን አሰልቺ ነው! ደደብ xml ("ከሳጥኑ ውጭ" ስለሆነ)።
- ኦ፣ አንተም ኤሲኤልን ትፈልጋለህ? ግን በጣም አሰልቺ ነው! መታ-blooper... እንደዚህ ያለ ነገር።

ነገር ግን በእኔ ስራ በትክክል ተቃራኒ ነው. ቀኝ (ወዮ ፣ በጭራሽ ለመጀመሪያ ጊዜ ማለት ይቻላል) የተገነባው ሞዴል የበለጠ በቀላሉ እና በተፈጥሮ እንዲቀጥሉ ያስችልዎታል (ማለት ይቻላል) ዲያግራም ሰብስቡ.

ስለ ዳታ ሳይንቲስቶች ትጋት የተሞላበት ስራ በሀበሬ ላይ በቅርቡ አንድ መጣጥፍ አጋጥሞኝ ነበር።
ይህ ጊዜ ለእነሱ ሙሉ በሙሉ እውን ሆኗል ። እና በእኔ ልምምድ, "የብርሃን ስሪት" እንደሚሉት. ባለብዙ-ጥራዝ ሞዴሎች፣ ልምድ ያካበቱ ፕሮግራመሮች ከኦኦፒ ጋር ዝግጁ ሲሆኑ፣ ወዘተ. - ይህ ሁሉ ሲነሳ / ሲነሳ በኋላ ላይ ይታያል. ግን ንድፍ አውጪው እዚህ እና አሁን የሆነ ቦታ መጀመር አለበት.

ወደ ነጥቡ ግባ። ቶኤምኤልን እንደ አገባብ መሰረት ወሰድኩ። ከዚህ ዜጋ.

ምክንያቱም እሱ (TOML) በአንድ በኩል, ሰው-ሊታረም የሚችል. በሌላ በኩል፣ 1፡1 ወደ ማንኛውም በጣም የተለመዱ አገባቦች፡ XML፣ JSON፣ YAML ተተርጉሟል።
ከዚህም በላይ ከ "github.com/BurntSushi/toml" የተጠቀምኩት ትግበራ ምንም እንኳን በጣም ፋሽን ባይሆንም (አሁንም 1.4 አገባብ) ከተመሳሳይ ("የተገነባ") JSON ጋር በአገባብ ይስማማል።

ማለትም፣ ከፈለጉ፣ በቀላሉ "ከዛ ቶኤምኤልህ ጋር ጫካ ውስጥ ሂድ፣ XXX እፈልጋለሁ" እና ኮዱን በአንድ መስመር ብቻ "ፕላች" ማለት ትችላለህ።

ስለዚህ, xswitcher ን ለማዋቀር አንዳንድ መስኮቶችን መጻፍ ከፈለጉ (እርግጠኛ አይደለሁም) “ከዚህ የተረገመ ውቅርህ ጋር” ምንም ችግሮች አይጠበቁም።

ለሌሎች ሁሉ፣ አገባቡ በ"ቁልፍ = እሴት" ላይ የተመሰረተ ነው። (እና በጥሬው ሁለት ይበልጥ የተወሳሰቡ አማራጮች እንደ = [አንዳንድ፣ ያ፣ ድርድር]) እንደምገምተው
በማስተዋል ምቹ።
የሚገርመው ይህ ነው። "ተቃጠለ" በተመሳሳይ ጊዜ (በ2013 አካባቢ)። ብቻ፣ እንደኔ ሳይሆን፣ የTOML ፀሃፊው በተገቢው ሚዛን ነው የገባው።

ስለዚህ, አሁን ለራሴ አተገባበርን ማስተካከል ቀላል ይሆንልኛል, እና በተቃራኒው አይደለም.

በአጠቃላይ, TOML እንወስዳለን (ከአሮጌው ዊንዶውስ INI ጋር በጣም ተመሳሳይ ነው). እና ከቁልፍ ሰሌዳው የቅርብ ጊዜ የፍተሻ ኮዶች ስብስብ ላይ በመመስረት ተከታታይ መንጠቆዎችን እንዴት ማያያዝ እንደሚቻል የምንገልጽበት ውቅር አለን። ከዚህ በታች፣ ቁርጥራጭ፣ እስካሁን የሆነው ነገር ነው። እና ለምን በዚህ መንገድ እንደወሰንኩ ማብራሪያ.

0. መሰረታዊ ማጠቃለያዎች

  • የኮድ ስያሜዎችን ይቃኙ። በቀላሉ ዲጂታል ኮዶች በሰው ሊነበቡ የማይችሉ ስለሆኑ (ያ እኔ ብቻ ነኝ) በዚህ ላይ በእርግጠኝነት አንድ ነገር መደረግ አለበት። loloswitcher).
    እኔ “ecodes.go”ን ከ “golang-evdev” ነቀነቅኩ (ዋናውን ምንጭ ለማየት በጣም ሰነፍ ነበርኩ፣ ምንም እንኳን ደራሲው በባህላዊ መልኩ ቢጠቁምም)። በጣም የሚያስፈራ ነገርን ትንሽ (ለአሁኑ) አስተካክያለሁ። እንደ "LEFTBRACE" → "L_BRACE"።
  • በተጨማሪም የ "ግዛት ቁልፎች" ጽንሰ-ሐሳብ አስተዋወቀ. ጥቅም ላይ የዋለው መደበኛ ሰዋሰው ረጅም ምንባቦችን ስለማይፈቅድ. (ነገር ግን በአነስተኛ ክፍያ እንዲፈትሹ ይፈቅድልዎታል። "ቀጥታ" ቀረጻ ብቻ የሚጠቀሙ ከሆነ።)
  • የተጫነውን አብሮ የተሰራ "deduplicator" ይኖራል. ስለዚህም ግዛቱ "ድገም" = 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፣ ነጥቦች ያሏቸው ስሞች በጥቅሶች ውስጥ መሆን አለባቸው።

እያንዳንዱ ክፍል ከዚህ በታች መገለጽ አለበት በተመሳሳይ ስም.

የሰዎችን አእምሮ በ "እርቃናቸውን" አዘውትረው ላለመንፋት (ከልምድ ፣ የእነሱ ይፃፉከአስር ውስጥ አንዱ ሊሆን ይችላል። ባለሙያዎች), ወዲያውኑ ተጨማሪ አገባብ ተግባራዊ አደርጋለሁ.

  • "ጠፍቷል:" (ወይም "በርቷል:") ከ regexp (መደበኛ አገላለጽ) በፊት የሚከተሉት አዝራሮች እንዲለቁ (ወይም እንዲጫኑ) ይጠይቃሉ.
    በመቀጠል "ፍትሃዊ ያልሆነ" መደበኛ አገላለጽ አደርጋለሁ. በፓይፕ "|" መካከል ያሉትን ቁርጥራጮች በተለየ መፈተሽ. እንደ "[LR]_SHIFT" ያሉ መዝገቦችን ቁጥር ለመቀነስ (ይህ በግልጽ አስፈላጊ ካልሆነ)።
  • "SEQ:" የቀደመው ሁኔታ ከተሟላ (ወይም ከሌለ) ፣ ከዚያ “የተለመደ” መደበኛ መግለጫን እንፈትሻለን። ለዝርዝር መረጃ፣ ወዲያውኑ ወደ “regexp” ቤተ-መጽሐፍት ወደ ^W ልኬዋለሁ። ምክንያቱም እኔ አሁንም ከምወደው pcre ("ፐርል ተኳሃኝ") ጋር ያለውን የተኳሃኝነት ደረጃ ለማወቅ አልተቸገርኩም።
  • መግለጫው በቅጹ ውስጥ ተጽፏል "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" ብለው ይጻፉ እና ለእሱ ሌላ ክፍል ለመጻፍ በጣም ሰነፍ አይሁኑ).
በተለይም በተስተካከለው አቀማመጥ ውስጥ የቃሉን እንደገና መተየብ በሁለት ይከፈላል። "እዚያ እንደተገለጸው አቀማመጡን ቀይር" и "እንደገና ይተይቡ" ("እንደገና ይተይቡ").

የተቀሩት መለኪያዎች ወደ “መዝገበ-ቃላት” ተጽፈዋል። ("ካርታ" በጎላንግ ውስጥ) ለአንድ ተግባር, ዝርዝራቸው በ "ድርጊት" ውስጥ በተጻፈው ላይ የተመሰረተ ነው.

በአንድ ክምር ውስጥ ብዙ የተለያዩ ድርጊቶች ሊገለጹ ይችላሉ (ክፍሎች). ወይም ደግሞ መጎተት ይችላሉ. ከላይ እንዳሳየሁት።

ውጫዊውን ስክሪፕት ለማስፈጸም ወዲያውኑ የ "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.

የት ነው የረሳሁት/የተሳሳትኩት? (ከዚህ ውጭ ምንም መንገድ የለም)፣ በትኩረት የሚከታተሉ አንባቢዎች አፍንጫቸውን ለመንጠቅ በጣም ሰነፍ እንደማይሆኑ ተስፋ አደርጋለሁ።

መልካም ዕድል!

ምንጭ: hab.com

አስተያየት ያክሉ