टीएबी से सीआई को अलग कैसे बांधें?


16

मैं Control-iप्रदर्शन करना चाहता हूं indent-region(मूल रूप से Xcode ने उस मांसपेशी मेमोरी को पहले से ही बनाया है)।

मुझे एहसास है कि Control-iऔर tabआसिंकी अर्थ में अप्रभेद्य हैं, लेकिन वे कीकोड अर्थों में हैं।

मैंने स्पष्ट करने की कोशिश की है:

(global-unset-key (kbd "C-i"))
(global-set-key (kbd "C-i") 'indent-region)

कोई फायदा नहीं हुआ - वर्तमान संदर्भ में कुंजी Control-iजो भी करती है उसे अभी भी tabदबाती है। क्या कुछ ऐसा है जिसकी मदद से मैं Emacs टैब बटन को अलग तरह से ट्रीट कर सकता हूं Control-i?

अद्यतन: मुझे लगता है कि जब कोई क्षेत्र चुना जाता है तो tab/ a क्या Control-iदबाता है, इसके लिए एक बराबर परिणाम प्राप्त किया जा सकता है।


1
क्या यह जीयूआई फ्रेम या टर्मिनल फ्रेम से है? मुझे नहीं पता कि आप इसे टर्मिनल के लिए ओवरराइड कर सकते हैं।
dgtized

गुड क्यू, जीयूआई फ्रेम आमतौर पर, लेकिन मैं सर्वरों में रिमोट करता हूं और कभी-कभी टर्मिनल में एमएसीएस का उपयोग करता हूं (जीआईटी-शेयर किए गए एमएसीएसडी कोर्स के साथ :)
मार्क ऑफ़्लिक

जवाबों:


15

मुझे नहीं लगता कि यह एक टर्मिनल से प्राप्त किया जा सकता है, लेकिन GUI मोड में आप यह कोशिश कर सकते हैं:

(define-key input-decode-map [?\C-i] [C-i])
(global-set-key (kbd "<C-i>") 'indent-region)

मैं उसी के साथ काम करता हूं C-mताकि इसे अलग किया जा सकेRET

संपादित करें:

निम्नलिखित कार्य करना चाहिए कि क्या आप GUI या TTY मोड में हैं:

;; Unbind <C-i> from the TAB key and bind it to indent-region.
;; Since TAB and <C-i> cannot be differentiated in TTY emacs,
;; the workaround is to conditionally bind TAB to indent-region
;; when there is an active region selected.
(if (window-system)
  ; IF we are not in a TTY, unbind C-i from TAB
    (progn
      (define-key input-decode-map [?\C-i] [C-i])
      ; ... and remap it to indent-region
      (global-set-key (kbd "<C-i>") 'indent-region))
  ; ELSE IF we are in a TTY, create a replacement for TAB
  (defun my/tab-replacement (&optional START END)
    (interactive "r")
    (if (use-region-p)
      ; IF active region, use indent-region
        (indent-region START END)
      ; ELSE IF no active region, use default tab command
      (indent-for-tab-command)))
  ; Bind our quick-and-dirty TAB replacement to the TAB key
  (global-set-key (kbd "TAB") 'my/tab-replacement))

यह सुंदर नहीं है, लेकिन यह काम करने लगता है। मैं आवश्यक रूप से इस कोड में किसी भी परिशोधन या संपादन का स्वागत करता हूं।


1
अच्छी तरह से काम! ++ फिर से एक emacs stackexchange खरीदेंगे:
मार्क Aufflick

केवल एक छोटी सी समस्या जो मैंने अभी सोची थी कि अब हम एक Emacs के खिलाफ एक टर्मिनल इमैसेकिएंट ला सकते हैं जो एक विंडो सिस्टम (जो मैं कभी-कभी करता हूं) के साथ शुरू किया गया था। अगर मुझे कोई देरी नहीं दिखती है तो मैं सभी मामलों में टैब-रिप्लेसमेंट फंक का उपयोग करूंगा।
मार्क आफ्लिक

1
मैं सिर्फ इतना है कि जोड़ना चाहते हैं <C-i>और [C-i]एक मनमाना पहचानकर्ता हो सकता था, जैसे <foobar>और [foobar], और यह अभी भी काम होगा; बस इसे कॉल न करें tabयाbackspace
xdavidliu

मैं में अपने जवाब पर संपादित कोड टुकड़ा जोड़ लिया है .emacsफ़ाइल लेकिन दोनों TABऔर C-iहै remapped :-( @nispio
alper

@alper, सबसे अधिक संभावना यह है कि आपके लोड होने के समय (window-system)वापस आ गया। ऐसा इसलिए हो सकता है क्योंकि आप Emacs का गैर-ग्राफ़िकल उदाहरण चला रहे हैं, या क्योंकि आप Emacs डेमन चला रहे हैं। nil.emacs
nispio

13

जीयूआई फ्रेम

GUI फ्रेम में (चाहे X11, Windows, OSX,…), Emacs फ़ंक्शन कुंजी के Tabरूप में कुंजी को पढ़ता है tab। हालाँकि, क्योंकि Tabटर्मिनलों की कुंजी पारंपरिक रूप से नियंत्रण^I ( नियंत्रण + I) चरित्र को भेजती है , Emacs tabफ़ंक्शन कुंजी को Control + I वर्ण (वर्ण 9) में अनुवाद करता है, जिसे प्रदर्शित किया जाता है TAB। यह अनुवाद के माध्यम से किया जाता है function-key-map

इसी तरह का अनुवाद कुछ अन्य फ़ंक्शन कुंजियों के साथ होता है। ( Backspaceऔर Deleteएक कांटेदार मामला है जिसके बारे में मैं यहां विस्तार से चर्चा नहीं करूंगा।)

Function key    Translated to character         Notes
                Number  Name  Decomposition
backspace       127     DEL   Ctrl+?            May be translated to C-h instead
tab               9     TAB   Ctrl+I
linefeed         10     LFD   Ctrl+J            Few keyboards have this key
return           13     RET   Ctrl+M
escape           27     ESC   Ctrl+[

यदि आप + को पूरी तरह Tabसे अलग करना चाहते हैं, तो बाइंडिंग को हटा दें :CtrlIfunction-key-map

(define-key function-key-map [tab] nil)

हालाँकि यह बहुत उपयोगी नहीं है, क्योंकि function-key-mapमोड-विशिष्ट कीमैप में बाइंडिंग द्वारा या वैश्विक मानचित्र में प्रविष्टियों को ओवरराइड किया जाता है। इसलिए यदि आप एक अलग बाइंडिंग को परिभाषित करना चाहते हैं tab, तो बस इसे करें (एलिस्प में, अंतःक्रियात्मक रूप से नहीं, क्योंकि कुंजी पढ़ने का संकेत function-key-mapअनुवाद लागू होता है, इसलिए आप रिबंडिंग को समाप्त करेंगे TABऔर नहीं tab):

(global-set-key [tab] '…)
(define-key some-mode-map [tab] '…)

सभी मानक मोड जो Tabकुंजी की क्रिया को संशोधित करते हैं TAB, कुंजी को संशोधित करके करते हैं , जो C-iकुंजी संयोजन Ctrl+ द्वारा उत्पन्न चरित्र के लिए एक उपनाम है I। आप मानक बाइंडिंग को लागू करना चाहते हैं tabके बजाय C-i, छुट्टी function-key-mapऔर मोड keymaps अकेले, और बदले रीडायरेक्ट Ctrl+ Iएक अलग कुंजी के लिए।

(define-key input-decode-map [(control ?i)] [control-i])
(define-key input-decode-map [(control ?I)] [(shift control-i)])
(define-key some-mode-map [control-i] '…)

अब Emacs " Ctrl+ से अनुवादित I" के रूप में रिपोर्ट करेंगे । यह सुंदर नहीं है, लेकिन यह अपरिहार्य है: चरित्र 9 का सुंदर-मुद्रण जैसा कि Emacs स्रोत कोड में बनाया गया है।<control-i>TABTAB

टर्मिनल फ्रेम

टर्मिनल फ्रेम में, समस्या कठिन है और अक्सर असंभव है। टर्मिनल कुंजी को प्रेषित नहीं करते हैं, वे पात्रों को प्रसारित करते हैं (अधिक सटीक रूप से, वास्तव में, वे बाइट्स संचारित करते हैं)। Tabजो नियंत्रण + मैं है, क्या कुंजी संयोजन के रूप में ही - कुंजी टैब वर्ण के रूप में प्रसारित किया जाता है Ctrl+ Iउत्पन्न करता है। फ़ंक्शन कुंजियाँ जिनमें कोई संबंधित वर्ण नहीं है (जैसे कर्सर कुंजियाँ) को भागने के अनुक्रम के रूप में प्रेषित किया जाता है, अर्थात ESC= नियंत्रण + [(जिसके कारण Emacs escapeएक उपसर्ग कुंजी के रूप में परिभाषित होता है - ESCके लिए एक उपसर्ग होना पड़ता है) के अनुक्रमों को परिभाषित करता है । देखें कि कीबोर्ड इनपुट और टेक्स्ट आउटपुट कैसे काम करते हैं? अधिक पृष्ठभूमि के लिए।

कुछ टर्मिनल हैं जिन्हें फ़ंक्शन कुंजियों के लिए अलग-अलग कुंजी अनुक्रम भेजने के लिए कॉन्फ़िगर किया जा सकता है, लेकिन कई नहीं। दोनों लियोनेर्ड के लिबटरमेक / लिबेटिकिट और थॉमस डिके के एक्सटर्म (संस्करण 216 के बाद से) इसका समर्थन करते हैं। Xterm में, सुविधा वैकल्पिक है और modifyOtherKeysसंसाधन के माध्यम से सक्रिय है । हालाँकि, मैं xterm के अलावा किसी भी लोकप्रिय टर्मिनल एमुलेटर के बारे में नहीं जानता जो इसका समर्थन करता है, विशेष रूप से libvte पर निर्मित कई एमुलेटर । कुछ टर्मिनल एमुलेटर आपको सीक्वेंस से बचने के लिए कीचर्ड से उपयोगकर्ता द्वारा परिभाषित पत्राचार के माध्यम से मैन्युअल रूप से ऐसा करने देते हैं।

यह तंत्र कई प्रमुख संयोजनों को प्रतिष्ठित करने की अनुमति देता है, न कि केवल टैब / सीआई, रिटर्न / सीएम और एस्केप / सी- [। अधिक विस्तृत विवरण के लिए टर्मिनल का उपयोग करते समय कीबाइंडिंग के साथ समस्याएं देखें ।

Emacs 24.4 के बाद से बेसिक xterm फीचर को सपोर्ट किया गया है। हालांकि मूल सिद्धांतों (विशेष रूप से Tab, Returnमें Escape, Backspace) अभी भी पारंपरिक नियंत्रण वर्ण भेजते हैं, क्योंकि यही अनुप्रयोग अपेक्षा करते हैं। एक ऐसी विधा है, जहाँ Ctrl+ letterनियंत्रण चरित्र के बजाय एक भागने का क्रम भेजता है। तो CtrlEmacs 24.4 पर संयोजनों से फ़ंक्शन कुंजियों को अलग modifyOtherKeysकरने के लिए, 1 के बजाय संसाधन 2 पर सेट करके इस मोड का उपयोग करने के लिए इसके समर्थन को संशोधित करें।

;; xterm with the resource ?.VT100.modifyOtherKeys: 2
;; GNU Emacs >=24.4 sets xterm in this mode and define
;; some of the escape sequences but not all of them.
(defun character-apply-modifiers (c &rest modifiers)
  "Apply modifiers to the character C.
MODIFIERS must be a list of symbols amongst (meta control shift).
Return an event vector."
  (if (memq 'control modifiers) (setq c (if (or (and (<= ?@ c) (<= c ?_))
                                                (and (<= ?a c) (<= c ?z)))
                                            (logand c ?\x1f)
                                          (logior (lsh 1 26) c))))
  (if (memq 'meta modifiers) (setq c (logior (lsh 1 27) c)))
  (if (memq 'shift modifiers) (setq c (logior (lsh 1 25) c)))
  (vector c))
(defun my-eval-after-load-xterm ()
  (when (and (boundp 'xterm-extra-capabilities) (boundp 'xterm-function-map))
    ;; Override the standard definition to set modifyOtherKeys to 2 instead of 1
    (defun xterm-turn-on-modify-other-keys ()
      "Turn the modifyOtherKeys feature of xterm back on."
      (let ((terminal (frame-terminal)))
        (when (and (terminal-live-p terminal)
                   (memq terminal xterm-modify-other-keys-terminal-list))
          (send-string-to-terminal "\e[>4;2m" terminal))))
    (let ((c 32))
      (while (<= c 126)
        (mapc (lambda (x)
                (define-key xterm-function-map (format (car x) c)
                  (apply 'character-apply-modifiers c (cdr x))))
              '(;; with ?.VT100.formatOtherKeys: 0
                ("\e\[27;3;%d~" meta)
                ("\e\[27;5;%d~" control)
                ("\e\[27;6;%d~" control shift)
                ("\e\[27;7;%d~" control meta)
                ("\e\[27;8;%d~" control meta shift)
                ;; with ?.VT100.formatOtherKeys: 1
                ("\e\[%d;3~" meta)
                ("\e\[%d;5~" control)
                ("\e\[%d;6~" control shift)
                ("\e\[%d;7~" control meta)
                ("\e\[%d;8~" control meta shift)))
        (setq c (1+ c)))))
  (define-key xterm-function-map "")
  t)
(eval-after-load "xterm" '(my-eval-after-load-xterm))

जब आप कहते हैं "Emacs 24.24" क्या आपका मतलब है "Emacs 24.4"?
तारसियस

1
@tarsius मेरी init फ़ाइल से कॉपी किए गए कोड में एक टिप्पणी "24.4" कहती है, इसलिए मुझे लगता है कि यह सही है, और "24.24" पाठ में जो मैंने इस उत्तर के लिए लिखा था वह "24.4" के लिए एक टाइपो था।
गाइल्स का SO- बुराई पर रोक '16
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.