Gọi emacsclient từ một chương trình được gọi bởi Emacs


9

Tôi đã gặp vấn đề khi xem các tệp tài liệu pdf với AucTex. Tôi sử dụng pdf-toolsđể xem các tệp PDF từ bên trong Emacs và tôi đã đặt emacsclient -nlàm trình xem pdf mặc định của mình (thông qua xdg-mime trên Debian Linux). Điều này hoạt động tốt trong hầu hết các trường hợp, nhưng nó phá vỡ (Tex-documentation-texdoc ...)chức năng của Auctex ( C-c ?).

Tôi đã thu hẹp vấn đề xuống một dòng mã. Khi tôi cố gắng xem tài liệu cho listingsgói, TeX-documentation-texdocbiến nó thành sexp sau:

(shell-command-to-string "texdoc --view  listings")

texdoclần lượt gọi emacsclientđể thực sự mở tệp (dựa trên cách tôi đã cấu hình máy tính để bàn của mình qua xdg). Tuy nhiên, tại thời điểm này, Emacs bị treo và tôi cần phải thoát ( C-g) để lấy lại quyền kiểm soát. Sau đó, không có pdf mới được mở. Điều tương tự cũng xảy ra nếu tôi cố gắng gọi trực tiếp emacsclient:

(shell-command-to-string "emacsclient -n tmp.pdf")

Cả hai lệnh làm việc tại dòng lệnh (nghĩa là emacsclient -n tmp.pdftexdoc --view listings.

Câu hỏi của tôi là, trong một trường hợp như thế này, làm thế nào để tôi gọi emacsclient từ bên trong Emacs? (và tôi biết rằng tôi chỉ có thể mở tệp pdf bằng find-file; đó không phải là một tùy chọn ở đây vì tôi cần gọi một quy trình bên ngoài (texdoc) để tìm tệp, và quá trình đó sau đó gọi emacsclient).


Tại sao không chỉ sử dụng texdoc -M --list listingsđể tìm tập tin, và sau đó sử dụng find-file?
Quarky

@suvayu Chỉ cần tiện lợi. Một cách khác là chuyển sang một thiết bị đầu cuối để gọi texdoc --viewvà sau đó chuyển trở lại Emacs khi nó mở tệp. Nhưng tôi nghĩ nên có một cách để làm điều này trong một bước duy nhất từ ​​Emacs?
Tyler

1
Có thể (async-shell-command "emacsclient -n tmp.pdf")giải quyết vấn đề?
Tên

1
@ Tên thú vị - (async-shell-command "emacsclient -n tmp.pdf")hoạt động, nhưng (async-shell-command "texdoc --view listings")không. Vì vậy, đó là một đầu mối hữu ích.
Tyler

1
C-u C-c ?hoạt động không? Đầu tiên, nó hiển thị danh sách các tài liệu liên quan đến gói, sau đó mở trình xem với (call-process "texdoc" nil 0 nil "--just-view" doc).
giordano

Câu trả lời:


5

Giải pháp là chạy texdoctrong một quy trình không đồng bộ.

Cách tốt nhất để làm điều đó có lẽ là sử dụng start-file-processthay vì shell-command-to-string(đó là một chức năng tiện lợi cho mã nhanh & bẩn khi việc viết một tập lệnh shell nhỏ hơn so với mã Elisp tương ứng, nhưng tốt hơn là nên tránh theo kinh nghiệm của tôi).

Nhưng nó sẽ yêu cầu thay đổi đáng kể cho mã xung quanh, vì start-file-processkhông trả lại trực tiếp đầu ra của quy trình, thay vào đó, nó cho phép bạn chỉ ra bộ đệm nào để đặt đầu ra và sau đó bạn phải sử dụng set-process-sentinelchức năng gọi lại lấy đầu ra từ bộ đệm đó và "bất cứ điều gì cần phải được thực hiện với nó" khi lệnh kết thúc.


Trong trường hợp cụ thể khi chạy texdoctrong AocateeX, tôi thấy việc sử dụng Sentinel hơi quá mức, vì đây không phải là một tính năng cơ bản (giống như nó là mở trình xem cho tài liệu đầu ra, trong trường hợp đó chúng tôi sử dụng trọng điểm).
giordano

Tôi không biết tại sao hàm "-to-string" được sử dụng, vì vậy tôi không biết những gì được thực hiện với đầu ra của lệnh. Nếu đầu ra này là cần thiết (như được đề xuất bởi việc sử dụng ...-to-string), thì một giải pháp không đồng bộ sẽ cần một bộ lọc quy trình hoặc một proces-sentinel. Nếu không, sau đó mã có thể sử dụng một cái gì đó như (shell-command "texdoc --view listings &").
Stefan

Nó được giải thích trong các ý kiến ​​về TeX-documentation-texdoc: ...-to-stringbiến thể được sử dụng để hiển thị cho người dùng thông báo lỗi có thể xảy ra (ví dụ: khi không tìm thấy tài liệu nào). Ngoài ra, texdoc nonexistingpackagetrả về 0, nhưng sentinel có thể được sử dụng để phân tích đầu ra.
giordano

Sau đó, một sentinel dường như là lựa chọn tốt nhất.
Stefan

Tôi không thể tìm thấy một lời mời start-file-processnào thực sự hoạt động ở đây. (start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")tạo bộ đệm *texdoc*, được chèn vào "Quá trình texdoc kết thúc" và pdf không bao giờ mở. Điều tương tự cũng xảy ra khi tôi đặt trình xem pdf xdg-mime để thể hiện.
Tyler

1

Nếu bạn chỉ cần gửi lại yêu cầu cho Emacs, không cần chờ câu trả lời, thì bạn có thể chạy emacsclienttrong nền. Trong các hệ điều hành kiểu Unix (Linux, macOS, Cygwin, cám):

emacsclient … &

Trong Windows gốc:

start emacsclient …

Chắc chắn, nhưng trong trường hợp cụ thể này, tôi cần gọi một chương trình (texdoc) mà sau đó gọi (emacsclient). Mức độ chuyển hướng bổ sung đang gây ra vấn đề.
Tyler

@Tyler texdockhông đồng bộ (nghĩa là bạn không đợi nó hoàn thành), phải không? Vì vậy, bạn có thể áp dụng nguyên tắc tương tự: chạy texdoc … &như lệnh shell.
Gilles 'SO- ngừng trở nên xấu xa'

Chúng tôi đã cố gắng lên trong các ý kiến ​​dưới câu hỏi của tôi; Nó hoạt động khi gọi emacsclienttrực tiếp, nhưng không phải khi gọi texdoc.
Tyler
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.