Saya mengalami masalah saat melihat file dokumentasi pdf dengan AucTex. Saya gunakan pdf-tools
untuk melihat file PDF dari dalam Emacs, dan saya telah menetapkan emacsclient -n
sebagai pdf-viewer default saya (via xdg-mime di Debian Linux). Ini berfungsi dengan baik di sebagian besar keadaan, tetapi itu merusak (Tex-documentation-texdoc ...)
fungsi Auctex ( C-c ?
).
Saya telah mempersempit masalahnya menjadi satu baris kode. Ketika saya mencoba melihat dokumentasi untuk listings
paket, TeX-documentation-texdoc
ubah ini menjadi sexp berikut:
(shell-command-to-string "texdoc --view listings")
texdoc
pada gilirannya panggilan emacsclient
untuk benar-benar membuka file (berdasarkan bagaimana saya mengkonfigurasi desktop saya via xdg). Namun, pada titik ini, Emacs hang dan saya harus berhenti ( C-g
) untuk mendapatkan kontrol kembali. Setelah itu, tidak ada pdf baru dibuka. Hal yang sama terjadi jika saya mencoba memanggil emacsclient secara langsung:
(shell-command-to-string "emacsclient -n tmp.pdf")
Kedua perintah bekerja di baris perintah (yaitu, emacsclient -n tmp.pdf
dan texdoc --view listings
.
Pertanyaan saya adalah, dalam contoh seperti ini, bagaimana saya memanggil emacsclient dari dalam Emacs? (dan saya tahu saya bisa membuka file pdf dengan find-file
; itu bukan pilihan di sini karena saya perlu memanggil proses eksternal (texdoc) untuk menemukan file, dan proses itu kemudian memanggil emacsclient).
sumber
texdoc -M --list listings
untuk mencari file, lalu gunakanfind-file
?texdoc --view
dan kemudian beralih kembali ke Emacs ketika membuka file. Tapi saya pikir harus ada cara untuk melakukan ini dalam satu langkah dari Emacs?(async-shell-command "emacsclient -n tmp.pdf")
memecahkan masalah?(async-shell-command "emacsclient -n tmp.pdf")
berfungsi, tetapi tidak(async-shell-command "texdoc --view listings")
tidak. Jadi itu petunjuk yang berguna.C-u C-c ?
bekerja? Pertama-tama menunjukkan daftar dokumen yang terkait dengan paket, kemudian membuka pemirsa dengan(call-process "texdoc" nil 0 nil "--just-view" doc)
.Jawaban:
Solusinya adalah berjalan
texdoc
dalam proses asinkron.Cara terbaik untuk melakukannya adalah dengan menggunakan
start-file-process
alih-alihshell-command-to-string
(yang merupakan fungsi praktis untuk kode cepat & kotor ketika lebih baik untuk menulis skrip shell kecil daripada kode Elisp yang sesuai, tetapi sebaliknya lebih baik dihindari dalam pengalaman saya).Tapi itu akan membutuhkan perubahan besar pada kode di sekitarnya, karena
start-file-process
tidak mengembalikan output proses secara langsung, sebaliknya ia memungkinkan Anda menunjukkan di mana buffer untuk menempatkan output dan kemudian Anda harus menggunakanset-process-sentinel
fungsi callback yang mengambil output dari buffer itu dan tidak "apa pun yang perlu dilakukan dengan itu" ketika perintah selesai.sumber
texdoc
di AUCTeX saya menemukan penggunaan sentinel sedikit berlebihan, karena ini bukan fitur mendasar (seperti itu adalah pembukaan penampil untuk dokumen output, dalam hal ini kita menggunakan penjaga)....-to-string
), maka solusi async akan membutuhkan proses-filter atau proses-sentinel. Jika tidak, maka kodenya mungkin bisa menggunakan sesuatu seperti(shell-command "texdoc --view listings &")
.TeX-documentation-texdoc
:...-to-string
varian digunakan untuk menunjukkan kepada pengguna kemungkinan pesan kesalahan (misalnya ketika tidak ada dokumentasi yang ditemukan). Selain itu,texdoc nonexistingpackage
mengembalikan 0, tetapi sentinel dapat digunakan untuk mem-parsing output.start-file-process
yang benar-benar berfungsi di sini.(start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")
menciptakan buffer*texdoc*
, yang dimasukkan "Proses texdoc selesai", dan pdf tidak pernah terbuka. Hal yang sama terjadi ketika saya mengatur penampil pdf xdg-mime untuk membuktikan juga.Jika Anda hanya perlu mengumpan balik permintaan ke Emacs, tanpa menunggu jawaban, maka Anda dapat menjalankannya
emacsclient
di latar belakang. Di bawah OS Unix-style (Linux, macOS, Cygwin, ...):Di bawah Windows asli:
sumber
texdoc
asynchronous (artinya Anda tidak menunggu sampai selesai), bukan? Jadi Anda bisa menerapkan prinsip yang sama: jalankantexdoc … &
sebagai perintah shell.emacsclient
langsung, tetapi tidak saat menelepontexdoc
.