मैगिट में प्रयुक्त पॉपअप मेनू के समान कैसे लागू करें


10

सवाल

मैं मैगिट में उपयोग किए जाने वाले पॉपअप मेनू , पॉपअप मेनू के रूप में यूजर इंटरफेस बनाना चाहूंगा

विशेषताएं

पॉपअप की परिभाषा

इस प्रश्न के संदर्भ में पॉपअप का अर्थ है कि थोड़ी अस्थायी विंडो जिसमें मेनू आइटम का संग्रह हो ताकि उपयोगकर्ता इनमें से किसी एक और आइटम का चयन कर सके।

स्क्रीन पर स्थिति

पॉपअप को स्क्रीन के किसी भी भाग में प्रदर्शित होने की अनुमति है, लेकिन यह वांछनीय है कि यह काफी स्पष्ट होना चाहिए और इस प्रकार यह वर्तमान में सक्रिय विंडो के बगल में दिखाई देना चाहिए।

पॉपअप बफर की सामग्री

वस्तुओं को सुंदर तालिका के रूप में प्रदर्शित किया जाना चाहिए। सुंदर प्रश्न का संदर्भ है, नेत्रहीन अपील का अर्थ है, यह प्रभाव मेनू आइटमों को सीधे पंक्तियों में डालकर आसानी से प्राप्त किया जा सकता है, complete--insert-stringउदाहरण के लिए देखें । यह अनुच्छेद अतिरिक्त स्पष्टीकरण के लिए कार्य करता है, आप इसे अपने तरीके से कर सकते हैं, इससे आपका उत्तर गलत नहीं होगा।

मेनू आइटम का चयन

चयन की उम्मीद है कि एक कुंजी दबाकर या, एक माउस के साथ वैकल्पिक रूप से प्रदर्शन किया जा सकता है (हालांकि यह इतना महत्वपूर्ण नहीं है कि प्रस्ताव वाले उत्तर जो माउस का समर्थन नहीं करते हैं कानूनी हैं)। यदि आप माउस का समर्थन करने वाले समाधान का प्रस्ताव करते हैं, तो कृपया ध्यान दें कि उपयोगकर्ता को सहज तरीके से मेनू आइटम का चयन करने में सक्षम होना चाहिए, अर्थात बाईं ओर-बटन वांछित विकल्प पर क्लिक करके।

नायब माउस का उपयोग कई तरीकों से किया जा सकता है और विकल्प को इंगित करने के लिए वैकल्पिक तरीकों का भी स्वागत किया जाता है।

पॉपअप का उन्मूलन

एक बार जब उपयोगकर्ता ने ऊपर वर्णित तरीके से मेनू आइटम का चयन किया है, तो बफर और इस तरह इसकी खिड़की को देखने के साथ-साथ मार दिया जाना चाहिए। पॉपअप मेनू के आह्वान से पहले सक्रिय हुई विंडो को फ़ोकस (यानी सक्रिय हो जाना) फिर से प्राप्त करना चाहिए।

लौटाया गया मूल्य और तर्क

अधिमानतः, कार्यों के इस परिणाम के परिणामस्वरूप एक लिस्प ऑब्जेक्ट लौटाया जाना चाहिए। लिस्प ऑब्जेक्ट या तो हो सकता है:

  • nil- यह इंगित करता है कि उपयोगकर्ता ने पॉपअप मेनू को दबाकर C-gया किसी अन्य तरीके से has को निरस्त कर दिया है ।

  • string- स्ट्रिंग (यह एक प्रतीक का उपयोग करने की अनुमति है) string-equal वास्तविक वस्तुओं के संग्रह के रूप में पॉपअप मेनू को आपूर्ति की गई तार में से एक होना चाहिए ।

बाकी कार्यक्रमों को उपयोगकर्ता की पसंद को बताने के वैकल्पिक तरीके, या, संभवतः, इसकी अनुपस्थिति स्वीकार्य हैं। हालांकि, अगर यह स्पष्ट नहीं है कि इसे और कैसे किया जा सकता है तो मैं सभी उत्तरदाताओं को सुधारने के लिए कहता हूं और मुझसे इस पहलू को स्पष्ट करने के लिए नहीं कहता।

लौटे मूल्य के लिए यह सब है। इनपुट पैरामीटर्स के लिए, उन्हें कम से कम स्ट्रिंग्स का संग्रह शामिल करना चाहिए जो संभावित विकल्पों का प्रतिनिधित्व करता है (यानी, मेनू आइटम)।

स्वीकार्य जवाब

अपेक्षित उत्तर निम्नलिखित रूपों में से हो सकते हैं:

  • पर्याप्त कोड स्निपेट जो शिक्षित पाठक को ऊपर वर्णित कार्य को लिखने की अनुमति देता है; पूरे कामकाज को लिखने के लिए यह अपेक्षित या आवश्यक नहीं है। हालांकि, अनिश्चितता से बचने के लिए (कोड के काफी हिस्सों को छोड़ा जा सकता है?), मुझे ध्यान देना चाहिए कि स्निपेट के लापता भागों को उत्तर के पाठकीय घटक में वर्णित किया जाना चाहिए।

  • मौजूदा लाइब्रेरी का लिंक जो समान कार्यक्षमता को लागू करता है। अनिश्चितता से बचने के लिए, मुझे ध्यान देना चाहिए कि हमारे मामले में इसी तरह का अर्थ है कि लाइब्रेरी का उपयोग पॉपअप बनाने के लिए किया जा सकता है (ऊपर परिभाषा देखें) जिसमें ऊपर वर्णित कम से कम 2 या 3 विशेषताएं हैं। यदि प्रस्तावित लाइब्रेरी उस बिंदु पर भिन्न है जहां पहले से बताई गई शर्त पूरी नहीं की जा सकती है, तो ऐसे प्रत्येक मामले को स्वतंत्र रूप से आंका जाएगा और यदि ओपी इसे उपयोगी बनाता है तो इसे हमेशा अपग्रेड किया जाएगा।

  • अंतर्निहित Emacs फ़ंक्शन या तृतीय-पक्ष वाले का वर्णन जिनका उपयोग अनुभाग में वर्णित किसी भी सुविधा को लागू करने के लिए किया जा सकता है «विशेषताएँ», ऊपर देखें। अनिश्चितता से बचने के लिए, कृपया स्पष्ट रूप से बताएं कि आपका उत्तर भविष्य के पाठकों के लिए कैसे उपयोगी हो सकता है जो मैगिट में उपयोग किए जाने वाले पॉपअप , पॉपअप मेनू को लागू करना चाहते हैं ।


Menu पॉपअप मेनू को निरस्त करने के वैकल्पिक तरीकों में निम्नलिखित शामिल हो सकते हैं (लेकिन इन तक सीमित नहीं):

  • पॉपअप मेनू विंडो के बाहर क्लिक करना;

  • एक विकल्प बनाने के बिना पॉपअप युक्त बफर की हत्या।

जवाबों:


8

magit-popupयह स्वयं का मैनुअल है ! लेकिन जब तक आप वास्तव में पॉपअप में तर्कों को सेट नहीं करना चाहते हैं जो तब लागू कार्रवाई में पारित हो जाते हैं, तो आप संभवतः hydraइसके बजाय उपयोग करना बेहतर समझते हैं।

यह भी ध्यान दें कि मेरा इरादा आगे विकास करने का नहीं है magit-popup। इसके बजाय मैं खरोंच से एक समान पैकेज लिखूंगा। वर्तमान कार्यान्वयन में सिर्फ आकस्मिक जटिलता है। (लेकिन इसका मतलब यह नहीं है कि magit-popupयह बस गायब हो जाएगा। यह कई नई सुविधाओं को देखने की संभावना नहीं है, लेकिन अगर वर्तमान कार्यान्वयन आप क्या चाहते हैं, तो इसका उपयोग क्यों नहीं करते?)

या जब से आप भी इसे "खरोंच से" करना चाहते हैं, एक नज़र डालें read-char-choiceऔर वहां से जाएं। दृश्य भाग को लागू करने के लिए एक नज़र है lvजो हाइड्रा भंडार का हिस्सा है।


अन्य पाठकों के लिए: ध्यान दें कि @tarsius ने इसके बाद उस प्रतिस्थापन को लिखा और लिखा है magit-popup। नया पैकेज कहा जाता है transient, और वर्तमान संस्करणों में इसका उपयोग किया जाता है magit। प्रलेखन के लिए magit.vc/manual/transient देखें ।
फिल्स

6

हाइड्रस लिखने में बहुत सरल हैं:

(defhydra hydra-launcher (:color blue :columns 2)
   "Launch"
   ("h" man "man")
   ("r" (browse-url "http://www.reddit.com/r/emacs/") "reddit")
   ("w" (browse-url "http://www.emacswiki.org/") "emacswiki")
   ("s" shell "shell")
   ("q" nil "cancel"))

(global-set-key (kbd "C-c r") 'hydra-launcher/body)

हाइड्रा एक कीबोर्ड-केंद्रित इंटरफ़ेस है, और इसके मूल रूप में, यह easy-menu-define(बिल्ट-इन) की तुलना में कठिन नहीं है । और यदि आप इसे और अधिक जटिल चीजें करना चाहते हैं तो यह काफी अधिक है।

बस इस ट्विटर इंटरफ़ेस को देखें, नीचे की खिड़की एक कस्टम हाइड्रा है, ऊपर लिखे एक से लिखने के लिए ज्यादा कठिन नहीं है:

हाइड्रा-twittering.png

इसके लिए कोड विकी पर उपलब्ध है , साथ ही कई और उदाहरण हैं।


महान, मैं निश्चित रूप से इस चीज के बारे में अधिक जानने के लिए समय निकालूंगा!
मार्क कारपोव

1

कुछ शोध के बाद मुझे एक मुहावरा मिला है जिसका उपयोग वर्तमान में सक्रिय विंडो के तल पर (या वास्तव में कहीं भी) एक विंडो बनाने के लिए किया जा सकता है। यह अपने आप में अस्थायी, सहायक खिड़की का प्रभाव है:

(let ((buffer (get-buffer-create "*Name of Buffer*")))
  (with-current-buffer buffer
    (with-current-buffer-window
     ;; buffer or name
     buffer
     ;; action (for `display-buffer')
     (cons 'display-buffer-below-selected
           '((window-height . fit-window-to-buffer)
             (preserve-size . (nil . t))))
     ;; quit-function
     (lambda (window _value)
       (with-selected-window window
         (unwind-protect
             ;; code that gets user input
           (when (window-live-p window)
             (quit-restore-window window 'kill)))))
     ;; Here we generate the popup buffer.
     (setq cursor-type nil)
     ;; …
     )))

यदि आप पॉपअप को स्क्रीन के विभिन्न भाग में दिखाना चाहते हैं तो आप actionतर्क के साथ थोड़ा खेल सकते with-current-buffer-windowहैं।

डॉक-स्ट्रिंग के क्विट फ़ंक्शन का वर्णन किया गया है with-current-buffer-window, इसका उपयोग उपयोगकर्ता से इनपुट प्राप्त करने के लिए किया जा सकता है। जैसा कि @tarsius ने सुझाव दिया, read-char-choiceप्रयोग करने के लिए एक अच्छा उम्मीदवार है।

पॉपअप बफर को किसी भी अन्य बफर की तरह ही उत्पन्न किया जा सकता है। मैं अभी भी वहां बटन के बारे में सोच रहा हूं, क्योंकि उपयोगकर्ता अपने माउस का उपयोग पॉपअप मेनू में एक आइटम का चयन करने के लिए कर सकता है, न कि केवल कीबोर्ड पर। हालाँकि, इसके लिए अतिरिक्त प्रयास की आवश्यकता है यदि आप इसे अच्छी तरह से करना चाहते हैं।

यदि आपका पॉपअप थोड़ा सा तदर्थ है और आपको एक से अधिक बार इसकी आवश्यकता नहीं होगी, तो आप इस समाधान से दूर हो सकते हैं। इसके अलावा, एक नज़र डालें completion--insert-strings। मुझे यह बहुत उपयोगी लगा कि मेनू आइटम की सुंदर पंक्तियों को कैसे उत्पन्न किया जाए, आप इसे बिना उपयोग किए भी उपयोग कर सकते हैं यदि आपको कुछ विशेष की आवश्यकता नहीं है।


4
मुझे लगता है कि आपके दिमाग में जो सवाल है वह अच्छा है; आपके द्वारा लिखा गया प्रश्न स्पष्ट नहीं है, मैं नहीं देखता कि इस तरह के उत्तर के बाद आप किसी को कैसे जान सकते थे।
npostavs

1

यहाँ एक 3-पार्टी समाधान है, इकाल्स का उपयोग करके ।

  • आपका कोड एक मेनू के रूप में बड़े करीने से व्यवस्थित किए गए उम्मीदवारों के साथ एक विंडो पॉप अप करता है। कैसे, के लिए नीचे देखें।

  • आप प्रत्येक मेनू आइटम को एक अद्वितीय चरित्र के साथ उपसर्ग करते हैं। जैसे, a, b, c ... या 1, 2, 3 ... उपयोगकर्ता आइटम को चुनने के लिए चार हिट करता है।

  • आप एक कॉल के चारों ओर कुछ चर बाँधते हैं completing-read। आप इसे अपने मेनू आइटम की सूची से गुजारें। यदि उपयोगकर्ता केवल हिट करता है, तो आप वैकल्पिक रूप से डिफ़ॉल्ट में से एक को निर्दिष्ट करते हैं RET

    परिवर्तनशील बाइंडिंग यह बताती completing-readहै:

    • प्रत्येक मेनू आइटम को एक अलग पंक्ति पर दिखाएं
    • तुरंत मेनू दिखाएँ
    • जब कोई उपयोगकर्ता किसी कुंजी को मारता है, तो उसे तुरंत अपडेट करें
    • यदि उपयोगकर्ता इनपुट केवल एक आइटम से मेल खाता है, तो तुरंत वापस लौटें
    • प्रॉम्प्ट में डिफ़ॉल्ट विकल्प दिखाएं।
  • आप मेनू आइटम को फैंसी के रूप में बना सकते हैं जैसा आप चाहते हैं (दिखाया नहीं गया)।

    • चेहरे के
    • इमेजिस
    • एनोटेशन
    • प्रति आइटम कई लाइनें
    • mouse-3 पॉपअप मेनू, आइटम के साथ कुछ भी करने के लिए
(defvar my-menu '(("a: Alpha It"   . alpha-action)
                  ("b: Beta It"    . beta-action)
                  ("c: Gamma It"   . gamma-action)
                  ("d: Delta It"   . delta-action)
                  ("e: Epsilon It" . epsilon-action)
                  ("f: Zeta It"    . zeta-action)
                  ("g: Eta It"     . eta-action)
                  ("h: Theta It"   . theta-action)
                  ("i: Iota It"    . iota-action)
                  ("j: Kappa It"   . kappa-action)
                  ("k: Lambda It"  . lambda-action)))

(defun my-popup ()
  "Pop up my menu.
User can hit just the first char of a menu item to choose it.
Or s?he can click it with `mouse-1' or `mouse-2' to select it.
Or s?he can hit RET immediately to select the default item."
  (interactive)
  (let* ((icicle-Completions-max-columns               1)
         (icicle-show-Completions-initially-flag       t)
         (icicle-incremental-completion-delay          0.01)
         (icicle-top-level-when-sole-completion-flag   t)
         (icicle-top-level-when-sole-completion-delay  0.01)
         (icicle-default-value                         t)
         (icicle-show-Completions-help-flag            nil)
         (choice  (completing-read "Choose: " my-menu nil t nil nil
                                   "b: Beta It")) ; The default item.
         (action  (cdr (assoc choice my-menu))))

    ;; Here, you would invoke the ACTION: (funcall action).
    ;; This message just shows which ACTION would be invoked.
    (message "ACTION chosen: %S" action) (sit-for 2)))

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


1

आपको पैकेज देखने में भी रुचि हो सकती है makey। इसका उद्देश्य समान कार्यक्षमता प्रदान करना है magit-popup, और यह पूर्ववर्ती magit-popup( magit-key-mode, टिप्पणी में उल्लिखित) का एक कांटा है , जब से यह अभी तक अलग से उपलब्ध पैकेज नहीं था magit

मुझे यह भी उल्लेख करें discover: यह एक उदाहरण है कि कैसे उपयोग किया जाए makey(और इसके raison d'être भी)। यह पैकेज नए लोगों को इमैक बाइंडिंग की खोज करने में मदद करने के लिए है।


संदर्भ


2
@ मर्क मुझे पूरा यकीन नहीं है कि आपने इस जवाब को क्यों स्वीकार किया। यह बिल्कुल भी छोटे भवन ब्लॉकों का उल्लेख नहीं करता है, जो, अगर मुझे सही ढंग से याद है, तो आप क्या थे। यह भी सही नहीं है: मेकी मैगिट-पॉपअप का कांटा नहीं है, यह अपने पूर्ववर्ती मैगिट-की-मोड का कांटा है। यह उन अधिकांश कमियों को विरासत में मिला है जो तब से मैगिट-पॉपअप में संबोधित किए गए हैं। इसलिए आप मैगिट-पॉपअप या हाइड्रा (या अपना खुद का लेखन) का उपयोग करने से बहुत बेहतर हैं।
तारसियस

@tarsius किसी उत्तर की शुद्धता को समझना कठिन हो सकता है। यदि आप जानते हैं कि यह सही नहीं है, तो इसे संपादित करने के लिए स्वतंत्र महसूस करें। मैंने एक संपादन किया, मुझे अभी भी 100% यकीन नहीं है कि यह अभी ठीक है। मैंने "घाटे" का भी उल्लेख नहीं किया क्योंकि यह मुझे विरासत में मिला है क्योंकि मुझे नहीं पता कि वे क्या हैं।
यंगफ्रॉग

0

सभी कॉन्फ़िगर किए गए उपसर्गों के लिए गाइड-की मेरे लिए अच्छा काम है।


0

@ ड्रू के उत्तर (आइकल्स) के आधार पर, मेनू डेटा से अलग मेनू कार्यान्वयन के संशोधनों के साथ - इसलिए कई मेनू को परिभाषित किया जा सकता है, प्रत्येक अपने स्वयं के साथ: (सामग्री, शीघ्र, डिफ़ॉल्ट)।

यह वैकल्पिक रूप से आइवी (जब उपलब्ध हो) का उपयोग करता है, जिसमें अधिक उन्नत विशेषताएं हैं जैसे कि मेनू को खुला रखते हुए आइटम को सक्रिय करने में सक्षम होना।

जेनेरिक पॉपअप।

(defun custom-popup (my-prompt default-index my-content)
  "Pop up menu
Takes args: my-prompt, default-index, my-content).
Where the content is any number of (string, function) pairs,
each representing a menu item."
  (cond
    ;; Ivy (optional)
    ((fboundp 'ivy-read)
      (ivy-read my-prompt my-content
        :preselect
        (if (= default-index -1) nil default-index)
        :require-match t
        :action
        (lambda (x)
          (pcase-let ((`(,_text . ,action) x))
            (funcall action)))
        :caller #'custom-popup))
    ;; Fallback to completing read.
    (t
      (let ((choice (completing-read
                     my-prompt my-content nil t nil nil
                     (nth default-index my-content))))
        (pcase-let ((`(,_text . ,action) (assoc choice my-content)))
          (funcall action))))))

उदाहरण का उपयोग करें, f12 कुंजी के लिए कुछ कार्य असाइन करें:

(defvar
  my-global-utility-menu-def
  ;; (content, prompt, default_index)
  '(("Emacs REPL" . ielm)
    ("Spell Check" . ispell-buffer)
    ("Delete Trailing Space In Buffer" . delete-trailing-whitespace)
    ("Emacs Edit Init" . (lambda () (find-file user-init-file))))

(defun my-global-utility-popup ()
  "Pop up my menu. Hit RET immediately to select the default item."
  (interactive)
  (custom-popup my-global-utility-menu-def "Select: ", 1))

(global-set-key (kbd "<f12>") 'my-global-utility-popup)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.