ฉันจะตอบรับคำสั่ง minibuffer จาก elisp ได้อย่างไร


10

ฉันพบว่าตัวเองใช้ฟังก์ชั่นอินเทอร์แอคทีฟภายในฟังก์ชั่นที่ฉันเขียนเพื่อใช้งานเอง หากฟังก์ชั่นขอข้อมูลบางอย่าง (เช่น "ไฟล์ที่ส่งออก: ~ /") มีวิธีการเพิ่มข้อความทั่วไปใน minibuffer แล้วกด enter เพื่อให้ผู้ใช้ไม่ต้องทำเช่นนั้น?

ตัวอย่างเช่นสมมติว่าฉันต้องการเรียกใช้org-latex-export-to-pdfภายในฟังก์ชัน แต่ฉันไม่ต้องการให้ผู้ใช้ต้องระบุชื่อไฟล์ การวิ่ง(org-latex-export-to-pdf)จะย้ายจุดไปที่มินิบัสเกอร์ แต่การวางบางอย่าง(insert "filename.tex")ในบรรทัดถัดไปดูเหมือนจะไม่ทำงาน


3
โดยทั่วไปฟังก์ชั่นแบบโต้ตอบควรแจ้งให้ข้อมูลดังกล่าวในinteractiveข้อของมัน เมื่อถูกเรียกจาก elisp คุณควรจะสามารถส่งผ่านข้อมูลเป็นอาร์กิวเมนต์ของฟังก์ชันได้ แน่นอนว่าสิ่งนี้ไม่ได้ช่วยคุณในกรณีที่ฟังก์ชั่นที่คุณพยายามโทรไม่เป็นไปตามการออกแบบนี้
Lindydancer

ใช่ฉันพบว่าเป็นเรื่องปกติเช่นกัน (น่าเสียดายที่ไม่ใช่ในขณะนี้) ซึ่งอาจเป็นสาเหตุที่คำตอบของเรื่องนี้หายากมาก คุณรู้หรือไม่ถ้ามีเหตุผลที่ออกแบบจริงๆต้องการผู้ใช้สามารถพิมพ์คำตอบที่จะแจ้งจาก minibuffer หรือไม่
เซ ธ รอ ธ ไชลด์

ความคิดเห็นของคุณไม่ชัดเจนสำหรับฉัน คุณต้องการให้ผู้ใช้สอบถามและตอบกลับหรือไม่? หากไม่ได้โดยทางโปรแกรมจะมีค่าอาร์กิวเมนต์ (ชื่อไฟล์เอาต์พุต) ที่คุณต้องการ / ต้องการและส่งผ่านไปยังฟังก์ชัน ฉันขอแนะนำให้คุณแสดงรหัสหรือวิธีอื่นให้เจาะจงและชัดเจนว่าปัญหา & คำถามของคุณคืออะไรหรือความเสี่ยงของคำถามถูกปิดอย่างไม่ชัดเจน
Drew

ฉันไม่ต้องการผู้ใช้ (ฉัน) สอบถาม ฉันสามารถชี้แจงคำถาม หลังจากอ่านหัวข้ออีเมลที่เกี่ยวข้องกับคุณเมื่อไม่กี่ปีที่ผ่านมาเกี่ยวกับการส่งไปยังรถมินิบัสฉันคิดว่าฉันรู้วิธีการทำเช่นนี้ ถ้าฉันทำให้มันใช้งานได้ฉันจะเขียนมันขึ้นมา
เซ ธ รอ ธ ไชลด์

1
โปรดโพสต์ตัวอย่างเฉพาะของฟังก์ชั่นอินเทอร์แอคทีฟที่คุณต้องการใช้เมื่อเขียนฟังก์ชั่นของคุณเองเพื่อให้ผู้เข้าร่วมฟอรั่มคนอื่นสามารถสาธิตวิธีส่งอาร์กิวเมนต์ไปยังฟังก์ชั่น
ฏหมาย

คำตอบ:


3

ปัญหาที่น่าสนใจ ดูเหมือนว่าบรรณาธิการทำงานทุกครั้งที่มันเข้ามาใหม่คำสั่งห่วงเช่นpost-command-hook recursive-editแต่เราสามารถเริ่มต้นด้วยminibuffer-setup-hookการทำงานของฟังก์ชั่นหลังจากเข้าสู่ minibuffer ในขณะที่สิ่งนี้ช่วยให้การแทรกของอินพุตมันเร็วเกินไปที่จะออกจาก minibuffer เพราะจับยังไม่ได้ติดตั้ง

(defmacro with-minibuffer-input (form &rest inputs)
  (declare (indent 1))
  `(minibuffer-with-setup-hook
       (lambda ()
         (minibuffer-input-provider ',inputs))
     ,form))

ที่ของคนเราต้องห่อ 'การขัดแย้งในตัวเอง 'ห่วงคำสั่ง' ของเราซึ่งได้รับการดำเนินการของทุกครั้งที่เราเข้าสู่จุดที่มันปรากฏหนึ่งอาร์กิวเมนต์และพ่นระดับหนึ่งขึ้นผ่านrecursive-editexit-minibuffer

;; -*- lexical-binding: t -*-
(defun minibuffer-input-provider (inputs)
  (let ((hook (make-symbol "hook")))
    (fset hook (lambda ()
                 (remove-hook 'post-command-hook hook)
                 (when inputs
                   (when (= 0 (minibuffer-depth))
                     (error "Too many inputs"))
                   (when (cdr inputs)
                     (add-hook 'post-command-hook hook))
                   (insert (pop inputs))
                   (exit-minibuffer))))
    (add-hook 'post-command-hook hook)))


(with-minibuffer-input (call-interactively 'find-file)
  "/")

(with-minibuffer-input (call-interactively 'occur)
  "\\(foo\\)\\(bar\\)" "\\1");;C-u C-x C-e

;;foobar

(with-minibuffer-input (call-interactively 'replace-string)
  "foo" "bar")

;; foo

3

ผมเขียนแมโครสำหรับการนี้เรียกว่าwith-simulated-inputซึ่งคุณจะได้รับที่นี่ ช่วยให้คุณสามารถป้อนข้อมูลโดยพลการรวมทั้งดำเนินการรูปแบบเสียงกระเพื่อมตามอำเภอใจเพื่อจำลองการโต้ตอบของผู้ใช้

ตัวอย่างเช่น:

(with-simulated-input '("hello SPC" (insert "world") "RET")
  (read-string "Enter greeting: "))

จะกลับมา"hello world"พร้อมกับ "สวัสดี" แทรกโดยสตริงแรกที่ "โลก" แทรกผ่านรหัสเสียงกระเพื่อมและในที่สุดก็ "RET" เพื่อเสร็จสิ้นการป้อนข้อมูล

มันมาพร้อมกับชุดทดสอบที่คุณสามารถดูตัวอย่างการใช้งานเพิ่มเติม


0

ดูเหมือนว่าการใช้run-with-timerด้วยinsertจะทำให้งานเสร็จ

(run-with-timer .2 nil 'insert "filename.tex")
(run-with-timer .3 nil 'execute-kbd-macro (kbd "RET"))
(org-latex-export-to-pdf)

คำสั่งinsertเมื่อวางไว้หลังจากนั้นจะมาเร็วเกินไป มันพยายามที่จะแทรกสตริงก่อนที่จะมีสถานที่ที่จะใส่มัน


ฉันขอแนะนำให้แก้ไขคำถามของคุณเพื่อขอความช่วยเหลือโดยผ่านชื่อไฟล์org-export-output-file-nameโดยทางโปรแกรมเมื่อใช้org-latex-export-to-pdfเพื่อให้ผู้ใช้ไม่ได้รับแจ้งชื่อไฟล์ คุณสามารถใช้ความพยายามของคุณในคำถาม - เช่น, run-with-timerฯลฯ - อย่างไรก็ตามมันไม่ใช่ทางออกที่ดี (ในความคิดของฉัน) ทางออกที่ดีกว่าคือการส่งชื่อไฟล์อย่างเป็นโปรแกรมโดยไม่ต้องเปิดมินิบัสเกอร์ในตอนแรก ฉันขอแนะนำให้ลบคำตอบนี้เพื่อให้คุณได้รับการแก้ไขที่ดีขึ้นโดยคนที่มีelispประสบการณ์มากกว่า
ฏหมาย

@ กฎหมายคำถามของวิธีการส่งชื่อไฟล์org-latex-export-to-pdfไม่ใช่สิ่งที่ฉันสนใจมันเป็นตัวอย่างตั้งแต่คุณดูเหมือนเจตนาที่จะเพิ่มชื่อ คำถามที่ฉันถามคือสิ่งที่ฉันหมายถึง: มีวิธีการที่เชื่อถือได้ตอบรับ minibuffer ผ่าน elisp การแก้ปัญหากรณีและปัญหาเป็นอย่างมากไม่ใช่สิ่งที่ฉันกำลังมองหา จากความคิดเห็นของคุณฉันสามารถอนุมานได้ว่าไม่แนะนำ
เซ ธ รอ ธ ไชลด์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.