إيماكس:كيف يمكنك تخزين المعلمة الأخيرة التي قدمها المستخدم كإعداد افتراضي؟
سؤال
أنا أكتب وظيفة تفاعلية أود أن أتذكر الوسيطة الأخيرة التي قدمها المستخدم واستخدامها كإعداد افتراضي.
(defun run-rake (param)
(interactive "sTask: ")
(shell-command (format "rake %s" task)))
في المرة الأولى التي يتم فيها استدعاء الوظيفة، أريدها أن تتذكر الوسيطة التي قدمها المستخدم بحيث في المرة التالية التي يقومون فيها باستدعاء الوظيفة، يمكنهم فقط الضغط على زر الإدخال وستستخدم القيمة التي قدموها في المرة السابقة.
لا يمكنني العثور على هذا في الوثائق - كيف يمكنك القيام بذلك في elisp؟
المحلول
يمكنك أن ترى كيف compile
الأمر يفعل هذا.أظهر نص التعليمات لأمر الترجمة باستخدام C-h f compile
, ، حرك المؤشر فوق اسم الملف الذي يحتوي على الوظيفة، ثم اضغط على RETURN
.سيؤدي هذا إلى إظهار الملف المصدر لـ compile
.
في الأساس، هناك متغير ديناميكي/عالمي compile-command
الذي يحمل أمر الترجمة الأخير.Emacs هو نظام مستخدم واحد ومؤشر ترابط واحد، لذا ليست هناك حاجة حقًا إلى المزيد.ضع في اعتبارك أيضًا أن Elisp عبارة عن مدرسة Lisp قديمة جدًا، وأن المتغيرات لها نطاق ديناميكي (مكدس الاستدعاءات)، وليس نطاقًا معجميًا.ومن الطبيعي في مثل هذا النظام:
(let ((compile-command "gcc -o foo foo.c frobnicate.c"))
...
(compile)
...)
يتحدث عن compile
الأمر، هل حاولت استخدامه بدلا من الخاص بك run-rake
وظيفة؟
نصائح أخرى
read-from-minibuffer
هو ما تريد استخدامه.أنه يحتوي على مكان لمتغير التاريخ.
إليك بعض نماذج الشفرة:
(defvar run-rake-history nil "History for run-rake")
(defun run-rake (cmd)
(interactive (list (read-from-minibuffer "Task: " (car run-rake-history) nil nil 'run-rake-history)))
(shell-command (format "rake %s " cmd)))
من الواضح تخصيص لاحتياجاتك.إن "run-rake-history" هو ببساطة متغير يستخدم لتخزين السجل الخاص باستدعاء "read-from-minibuffer".هناك خيار آخر يتمثل في استخدام "إكمال القراءة - ولكن هذا يفترض أن لديك قائمة من الاختيارات التي تريد تقييد المستخدم على استخدامها (وهو ما لا ينطبق عادةً على الأوامر المشابهة لـ Shell).
لقد اكتشفت كيفية القيام بذلك يدويًا باستخدام defvar (عام)، ولكن هذا يبدو وكأنه نوع الشيء الذي يجب أن توفره المكتبة الأساسية بالفعل (نوع من معلمات الإنشاء الخاصة بالمخطط).يبدو هذا وكأنه المزيد من التعليمات البرمجية ودليل أكثر مما ينبغي:
(defvar *editconf-ruby-run-rake-last-rake-task* nil)
(defun editconf-ruby-run-rake-last-rake-task (&optional new-val)
(when new-val
(setf *editconf-ruby-run-rake-last-rake-task* new-val))
*editconf-ruby-run-rake-last-rake-task*)
(defun editconf-ruby-run-rake (task-name)
"Execute rake `task-name'. See
`krb-ruby-get-rakefile-path-for-current-buffer' for how the
Rakefile is located.."
(interactive
(let* ((rakefile (krb-ruby-get-rakefile-path-for-current-buffer))
(rake-tasks (krb-ruby-get-rake-tasks rakefile))
(default-task (or (editconf-ruby-run-rake-last-rake-task)
(editconf-ruby-run-rake-last-rake-task (car rake-tasks)))))
(list
(read-string (format "Task [%s|%s]: "
rake-tasks
default-task)
nil nil default-task))))
(editconf-ruby-run-rake-last-rake-task task-name)
(let ((cmd (format "cd %s; rake %s"
(krb-lisp-strip-path-suffix rakefile 1)
task-name)))
(message "editconf-ruby-run-rake: cmd='%s'" cmd)
(shell-command cmd)))