أوضاع إيماكس:"حاول الأمر استخدام minibuffer أثناء وجوده في minibuffer"

StackOverflow https://stackoverflow.com/questions/812135

  •  03-07-2019
  •  | 
  •  

سؤال

سيناريو:

  • أبدأ في كتابة M-x لكتابة أمر
  • قمت بالتبديل إلى نافذة/مخزن مؤقت آخر لـ emacs لأنني أدركت أنني أقوم بتنفيذ الأمر في النافذة الخاطئة
  • أبدأ في كتابة M-x مرة أخرى لتنفيذ الأمر في النافذة الصحيحة

نتيجة:أحصل على الرسالة المخيفة "حاول الأمر استخدام المخزن المؤقت الصغير أثناء وجوده في المخزن المؤقت الصغير"

يحدث هذا لي عدة مرات في اليوم أثناء استخدام إيماكس، وليس فقط في هذا السيناريو.يعتبر هذا السلوك معاديًا للغاية للمستخدم (المرجع.الأوضاع والأوضاع الزائفة في The Humane Interface بقلم جيف راسكين)

هل هناك طريقة لتخصيص سلوك emacs بحيث بدلاً من إعطاء هذا الخطأ، يقوم فقط بإلغاء المخزن المؤقت الأول واستبداله بآخر جديد؟

هل كانت مفيدة؟

المحلول

في الواقع فإن "ميزة" emacs هذه عدوانية ومزعجة.لقد وجدت أن هذا هو الحل الصحيح للمشكلة. على الأرجح أنك فقدت التركيز على المخزن المؤقت الصغير لأنك قمت بتبديل النوافذ باستخدام الماوس وليس أمر المخزن المؤقت الصغير.لذا، كلما فقدت التركيز باستخدام الماوس، سيتم مسح المخزن المؤقت الصغير.تحقق من هذا المنصب.إنه يعمل بالنسبة لي وهو أفضل بكثير من المخازن المؤقتة الصغيرة العودية التي تسبب الصداع

http://trey-jackson.blogspot.com/2010/04/emacs-tip-36-abort-minibuffer-when.html

نصائح أخرى

يمكنك ضبط المتغير enable-recursive-minibuffers, ، مما سيمنع ظهور رسالة الخطأ هذه.ولكنه يتيح فقط إجراء مكالمات متعددة إلى المخزن المؤقت الصغير - ولا يعيد توجيه أمر المخزن المؤقت الحالي إلى المخزن المؤقت الجديد.يمكنك تجربة ذلك، ولكن أعتقد أنه سيكون أكثر إرباكًا لأن الإجراء الأصلي لا يزال معلقًا...

M-x لا بد منه 'execute-extended-command, وإعادة الاستضافة (تغيير المخزن المؤقت الأصلي) لهذا الأمر تشبه البرمجة مع الاستمرار.أي.يمكنك استدعاء روتين فرعي من الموقع X، ولكن بدلاً من العودة إلى X عند الانتهاء، يمكنك العودة إلى Y.أنا شخصياً أعتقد أنه سيفتح المزيد من الارتباك أكثر مما سيحل.لكنني أتفهم الإحباط (وأعرف آخرين لديهم نفس الإحباط).

لست متأكدًا مما إذا كان هناك مثل هذا التخصيص، لكن الطريقة التي أتجنب بها ذلك هي الضرب كنترول-ز لإلغاء الأمر كنت في منتصف الكتابة في المخزن المؤقت.

نظرًا لأن إجابتي الأولى لا تمنحك ما تريد بشكل مباشر، فقد اعتقدت أنني سأتوصل إلى حل حقيقي.هذا ما لدي:

(defvar my-execute-extended-command-source-buffer nil
  "var holding the buffer to which the extended-execute-command should apply")
(defvar in-my-execute-extended-command nil
  "internal use - indicates whether we're in a 'recursive edit' of sorts")
(defun my-execute-extended-command (command)
  "home-grown version of execute-extended-command that supports re-hosting the buffer"
  (interactive (list (if in-my-execute-extended-command
                   nil
                 (let ((in-my-execute-extended-command t))
                   (setq my-execute-extended-command-source-buffer (current-buffer))
                   (completing-read "My-x " obarray 'commandp t nil 'extended-command-history nil nil)))))
  (if in-my-execute-extended-command
      (progn (setq my-execute-extended-command-source-buffer (current-buffer))
             (select-window (minibuffer-window)))
    (switch-to-buffer my-execute-extended-command-source-buffer)
    (call-interactively (symbol-function (intern command)))))

لقد اختبرت ذلك بهذه الطريقة.لقد ربطته بالمفتاح (F10 في حالتي ب/ج لم أكن أريد أن أخسر M-x).بعد ذلك، مع فتح نافذتين، تعرض كل منهما مخزنًا مؤقتًا مختلفًا (على سبيل المثال A وB):

  1. من النافذة التي تظهر المخزن المؤقت A: F10 isearch-for
  2. قم بالتبديل من المخزن المؤقت الصغير إلى النافذة التي تظهر A: C-x o
  3. التبديل من النافذة التي تظهر A إلى النافذة التي تظهر B: C-x o
  4. "إعادة استضافة" الأمر من المخزن المؤقت B: F10
  5. الآن عد إلى المخزن المؤقت الصغير، قم بإنهاء الأمر ward RET

عندما بدأت في كتابة مصطلح بحث، تم تطبيق البحث على المخزن المؤقت B.

هذا يحل محل فقط M-x الوظائف، وليس الأوامر التي يتم استدعاؤها منها M-x.كما أن هذا الإصدار لا يدعم وسيطة البادئة.

نأمل أن يكون هذا ما تريد.

هل يمكن لأي شخص تحسين ما يلي؟

لقد استسلمت وأريد فقط تعيين \C-w لإلغاء أي مخزن مؤقت صغير سابق قبل فتح مخزن جديد (مثل القيام \C-g\C-w)

حتى الآن بفضل Trey حصلت على:

(defun cancel-completing-read ()
  (if (> (minibuffer-depth) 0) (exit-minibuffer))
   (completing-read "My-x " obarray 'commandp t nil 'extended-command-history nil nil))

(defun cancel-and-execute-command (command)
  (interactive (list (cancel-completing-read)))
  (call-interactively (symbol-function (intern command))))

(global-set-key "\M-x" 'cancel-and-execute-command)

ما الأمر الذي يجب أن أستخدمه بدلاً من exit-minibuffer فوق؟

لقد حاولت

keyboard-escape-quit
exit-minibuffer
keyboard-quit

ها أنت ذا:

;; automatically cancel the minibuffer when you switch to it, to avoid
;; "attempted to use minibuffer" error.
;; cy was here

(provide 'cancel-minibuffer)

(defun cancel-minibuffer-first (sub-read &rest args)
    (let ((active (active-minibuffer-window)))
        (if active
                (progn
                    ;; we have to trampoline, since we're IN the minibuffer right now.
                    (apply 'run-at-time 0 nil sub-read args)
                    (abort-recursive-edit))
            (apply sub-read args))))

(advice-add 'read-from-minibuffer :around #'cancel-minibuffer-first)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top