لينڪس لاءِ Xswitcher ترتيب درست ڪندڙ: ٻه قدم

کان اڳوڻي اشاعت (xswitcher "تصور جو ثبوت" اسٽيج تي) ڪافي تعميري موٽ ملي ٿي (جيڪو سٺو آهي)، مان پنهنجي مفت وقت کي پروجيڪٽ جي ترقي ۾ خرچ ڪرڻ جاري رکيو. هاڻي مان توهان جو ٿورو خرچ ڪرڻ چاهيان ٿو ... ٻيو مرحلو بلڪل معمولي نه ٿيندو: ٺاھ جوڙ جي تجويز/ بحث.

لينڪس لاءِ Xswitcher ترتيب درست ڪندڙ: ٻه قدم

ڪنهن نه ڪنهن طرح اهو ظاهر ٿئي ٿو ته عام پروگرامر انهن سڀني ڪنٽرولن کي ترتيب ڏيڻ لاء ناقابل اعتماد حد تائين بورنگ ڳوليندا آهن.

بي بنياد نه ٿيڻ لاءِ، اندر هڪ مثال آهي جنهن سان مان معاملو ڪري رهيو آهيان.
مجموعي طور تي شاندار طور تي تصور ڪيو ويو (۽ چڱي طرح لاڳو ٿيل) Apache Kafka ۽ ZooKeeper.
- ٺاھ جوڙ؟ پر اهو بورنگ آهي! گونگا xml (ڇاڪاڻ ته اهو "باڪس کان ٻاهر" آهي).
- اوهين، ڇا توهان پڻ هڪ ACL چاهيو ٿا؟ پر اهو تمام بورنگ آهي! ٽيپ-بلوپر... ڪجهه اهڙو.

پر منهنجي ڪم ۾ ان جي بلڪل ابتڙ آهي. ساڄو (افسوس، تقريبن ڪڏهن به پهريون ڀيرو) تعمير ٿيل ماڊل توهان کي وڌيڪ آساني سان ۽ قدرتي طور تي جاري رکڻ جي اجازت ڏئي ٿو (تقريبن) هڪ خاڪو گڏ ڪرڻ.

مون تازو ئي ڊيٽا سائنسدانن جي محنت جي باري ۾ Habré تي هڪ مضمون آيو ...
اهو ظاهر ٿيو ته هي لمحو انهن لاء مڪمل طور تي محسوس ڪيو ويو آهي. ۽ منهنجي عمل ۾، جيئن اهي چون ٿا، "روشن ورزن". ملٽي حجم جا ماڊل، تيار ڪيل او او پي سان تجربيڪار پروگرامر وغيره. - اهو سڀ ڪجهه بعد ۾ ظاهر ٿيندو جڏهن/جيڪڏهن اهو بند ٿئي. پر ڊزائنر کي هتي ۽ هاڻي شروع ڪرڻ جي ضرورت آهي.

نقطي تي وڃو. مون هڪ نحوي بنياد طور TOML ورتو هن شهري کان.

ڇاڪاڻ ته هو (TOML) هڪ طرف، انساني قابل تدوين. ٻئي طرف، اهو ترجمو ڪيو ويو آهي 1: 1 ڪنهن به وڌيڪ عام نحو ۾: XML، JSON، YAML.
ان کان علاوه، عمل درآمد مون "github.com/BurntSushi/toml" مان استعمال ڪيو، جيتوڻيڪ سڀ کان وڌيڪ فيشني نه آهي (اڃا تائين 1.4 نحو)، ساڳئي ("بلٽ-ان") JSON سان مطابقت رکندڙ آهي.

اھو آھي، جيڪڏھن توھان چاھيو، توھان صرف چئي سگھو ٿا "جبل ۾ وڃو توھان جي TOML سان، مون کي XXX گھرجي" ۽ "پيچ" ڪوڊ صرف ھڪڙي لائن سان.

ان ڪري، جيڪڏھن توھان لکڻ چاھيو ٿا ڪجھ ونڊوز کي ترتيب ڏيڻ لاءِ xswitcher (مون کي پڪ ناهي) ڪنهن به مسئلي جي توقع ناهي "توهان جي هن لات واري ترتيب سان."

ٻين سڀني لاء، نحو تي ٻڌل آهي "key = قدر" (۽ لفظي طور تي ڪجھ وڌيڪ پيچيده اختيارن، جھڙوڪ = [some, that, array]) منهنجي خيال ۾
intuitively آسان.
دلچسپ ڳالهه اها آهي "سڙي" ساڳئي وقت (2013 جي چوڌاري). صرف، مون جي برعڪس، TOML جو ليکڪ صحيح پيماني تي داخل ٿيو.

تنهن ڪري، هاڻي اهو آسان آهي ته منهنجي لاءِ ان جي عمل درآمد کي ترتيب ڏيڻ لاءِ پاڻ کي ترتيب ڏيو، ۽ نه ان جي برعڪس.

عام طور تي، اسان TOML وٺو (بلڪل ساڳي پراڻي ونڊوز INI). ۽ اسان وٽ هڪ ترتيب آهي جنهن ۾ اسان بيان ڪريون ٿا ته ڪيبورڊ مان جديد اسڪين ڪوڊس جي سيٽ جي بنياد تي ٿلهن جو سلسلو ڪيئن ڳنڍجي. هيٺ، ٽڪرا ٽڪرا ٽڪرا، اهو آهي جيڪو هينئر تائين ٿيو آهي. ۽ هڪ وضاحت ڇو مون هن طريقي سان فيصلو ڪيو.

0. بنيادي خلاصيون

  • اسڪين ڪوڊ نامزدگيون. انهي بابت ڪجهه ضرور ڪرڻ جي ضرورت آهي، ڇاڪاڻ ته صرف ڊجيٽل ڪوڊ بلڪل انساني پڙهڻ جي قابل نه آهن (اهو صرف مان آهيان loloswitcher).
    مون “golang-evdev” مان “ecodes.go” ڪڍي ڇڏيو (آئون اصل ماخذ ڏسڻ ۾ تمام سست هو، جيتوڻيڪ ليکڪ ان کي ثقافتي طور تي اشارو ڪيو آهي). مون ٿورو درست ڪيو (هاڻي لاءِ) ڪجهه جيڪو ڪافي خوفناڪ هو. جهڙوڪ "LEFTBRACE" → "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])"

صوتياتي اشارن سان انساني ٻولي جو لفظ ڇا تي مشتمل آهي؟ (يا ته graphemes جو معاملو عرف "hieroglyphs")؟ ڪجهه قسم جي خوفناڪ "شيٽ". تنهن ڪري، مان فوري طور تي "ٽيمپليٽ" جو تصور متعارف ڪرايو.

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" (جتي اهو واضح طور تي ضروري ناهي).
  • "SEQ:" جيڪڏهن پوئين شرط ملي ٿي (يا غير حاضر)، ته پوءِ اسين ”عام“ باقاعده اظهار جي خلاف چيڪ ڪنداسين. تفصيلن لاءِ، مان فوري طور تي موڪليان ٿو ^W کي ”regexp“ لائبريري. ڇو ته مون اڃا تائين پنهنجي پسنديده پي سي آر سان مطابقت جي درجي کي ڳولڻ جي زحمت نه ڪئي آهي (“perl compatible”).
  • اظهار جي صورت ۾ لکيل آهي "BUTTON_1: CODE1، BUTTON_2: CODE2" وغيره، ترتيب ۾ جنهن ۾ اسڪين ڪوڊ وصول ڪيا ويا آهن.
  • چيڪ هميشه "snugged" تسلسل جي آخر تائين آهي، تنهنڪري دم ۾ “$” شامل ڪرڻ جي ڪا ضرورت ناهي.
  • ھڪڙي لڪير ۾ سڀ چيڪ ھڪ ٻئي کان پوء انجام ڏنا ويا آھن ۽ "I" سان گڏ آهن. پر جيئن ته قدر هڪ صف جي طور تي بيان ڪيو ويو آهي، توهان ڪاما کان پوء هڪ متبادل چيڪ لکي سگهو ٿا. جيڪڏهن اهو ڪنهن سبب جي ضرورت آهي.
  • قدر "SeqLength = 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.

مون ڪٿي وساريو/ غلطي ڪئي؟ (ان کان سواء ڪو به رستو نه آهي)، مون کي اميد آهي ته هوشيار پڙهندڙن کي پنهنجي نڙيءَ کي ڇڪڻ ۾ تمام گهڻو سست نه ٿيندو.

سٺي قسمت!

جو ذريعو: www.habr.com

تبصرو شامل ڪريو