Làm thế nào tôi có thể trả lời một dấu nhắc nhỏ từ elisp?


10

Thỉnh thoảng tôi thấy mình sử dụng các chức năng tương tác bên trong một chức năng mà tôi đang viết cho mục đích sử dụng của riêng tôi. Nếu một hàm yêu cầu một số thông tin (ví dụ: "Tệp xuất: ~ /") thì có một cách chung chung để thêm văn bản vào bộ thu nhỏ và sau đó nhấn enter để người dùng không phải làm như vậy không?

Ví dụ, giả sử rằng tôi muốn chạy org-latex-export-to-pdfbên trong hàm nhưng tôi không muốn người dùng phải chỉ định tên tệp. Chạy (org-latex-export-to-pdf)sẽ di chuyển điểm đến xe buýt nhỏ, nhưng đặt một cái gì đó như (insert "filename.tex")trên dòng tiếp theo dường như không hoạt động.


3
Thông thường, một chức năng tương tác sẽ nhắc cho thông tin đó trong interactivemệnh đề của nó . Khi được gọi từ elisp, bạn sẽ có thể truyền thông tin dưới dạng đối số hàm. Tất nhiên, điều này không giúp ích gì cho bạn, trong trường hợp chức năng bạn đang cố gắng gọi không theo thiết kế này.
Lindydancer 30/03/2015

Vâng, tôi đã thấy rằng đó cũng là trường hợp thường xảy ra (tiếc là không phải lúc này), đó có thể là lý do tại sao câu trả lời cho điều này rất khó tìm. Bạn có biết nếu có một lý do thiết kế để thực sự muốn người dùng gõ câu trả lời cho lời nhắc từ xe buýt nhỏ không?
Seth Rothschild

Nhận xét của bạn không rõ ràng, với tôi. Bạn có muốn người dùng được truy vấn và trả lời hay không? Nếu không, sau đó lập trình đưa ra các giá trị đối số (tên tệp đầu ra) mà bạn muốn / cần và chuyển chúng cho hàm. Tôi đề nghị bạn hiển thị một số mã hoặc theo một cách khác làm cho cụ thể và rõ ràng vấn đề & câu hỏi của bạn là gì , hoặc các rủi ro câu hỏi được đóng lại là không rõ ràng.
vẽ

Tôi không muốn người dùng (tôi) truy vấn. Tôi có thể làm rõ câu hỏi. Sau khi đọc một phần của một chuỗi email liên quan đến bạn từ một vài năm trước về việc kéo xe buýt nhỏ, tôi nghĩ rằng tôi biết làm thế nào để làm điều này. Nếu tôi làm cho nó hoạt động tôi sẽ viết nó lên.
Seth Rothschild

1
Vui lòng gửi một ví dụ cụ thể về chức năng tương tác mà bạn muốn sử dụng khi viết chức năng của riêng mình, để người tham gia diễn đàn khác có thể trình bày cách truyền đối số cho chức năng và bỏ qua hoàn toàn bộ thu nhỏ.
luật

Câu trả lời:


3

Vấn đề thú vị. Có vẻ như trình soạn thảo chạy post-command-hookmỗi khi nó vào một vòng lệnh mới, tức là a recursive-edit. Nhưng chúng ta có thể bắt đầu với minibuffer-setup-hook, nó thực thi một chức năng sau khi vào xe buýt nhỏ. Mặc dù điều này cho phép chèn đầu vào, nhưng quá sớm để thoát khỏi bộ thu nhỏ, bởi vì sản phẩm khai thác chưa được thiết lập.

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

Đó là chúng ta cần phải bọc 'đối số' trong 'vòng lệnh' của chính chúng ta, được thực thi mỗi khi chúng ta nhập vào recursive-edit, tại đó nó sẽ bật một đối số và ném lên một cấp, thông qua exit-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

Tôi đã viết một macro cho cái này được gọi with-simulated-input, mà bạn có thể nhận được ở đây . Nó cho phép bạn cung cấp đầu vào tùy ý cũng như thực hiện các hình thức lisp tùy ý để mô phỏng tương tác của người dùng.

Ví dụ:

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

sẽ trở lại "hello world", với "xin chào" được chèn bởi chuỗi đầu tiên, "thế giới" được chèn thông qua mã lisp và cuối cùng là "RET" để hoàn tất việc nhập.

Nó đi kèm với một bộ thử nghiệm mà bạn có thể xem xét để biết thêm các ví dụ sử dụng.


0

Có vẻ như sử dụng run-with-timervới insertsẽ hoàn thành công việc.

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

Lệnh insertkhi được đặt sau đó sẽ xuất hiện quá nhanh. Nó cố gắng chèn chuỗi trước khi có một nơi để chèn nó.


Tôi khuyên bạn nên sửa đổi câu hỏi của mình để tìm kiếm sự trợ giúp bằng cách lập trình một tên tệp org-export-output-file-namekhi sử dụng org-latex-export-to-pdfđể người dùng không được nhắc tên tệp. Bạn có thể đặt nỗ lực của mình vào câu hỏi - ví dụ, run-with-timerv.v. - tuy nhiên, đó không phải là một giải pháp tốt (theo ý kiến ​​của tôi). Giải pháp tốt hơn là truyền đúng tên tệp theo chương trình để bộ thu nhỏ không bao giờ mở ở vị trí đầu tiên. Tôi khuyên bạn nên xóa câu trả lời này để bạn có được giải pháp tốt hơn bởi người có nhiều elispkinh nghiệm hơn .
luật

@lawlist câu hỏi làm thế nào để chuyển một tên tệp org-latex-export-to-pdfkhông phải là tên tôi quan tâm. Đây là một ví dụ vì bạn dường như có ý định cho tôi thêm một tên. Câu hỏi tôi hỏi là câu tôi muốn nói: có cách nào để trả lời một cách đáng tin cậy một dấu nhắc xe buýt thông qua elisp. Một giải pháp theo từng trường hợp là rất nhiều không phải những gì tôi đang tìm kiếm. Từ nhận xét của bạn, tôi có thể suy luận rằng nó không được khuyến khích.
Seth Rothschild
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.