Cara membuat perintah shell benar-benar diam (mencegahnya untuk membelah jendela atau membuka bingkai / jendela baru dll)

8

Apakah mungkin menjalankan perintah shell secara diam-diam (di latar belakang)? Saat saya gunakan async-shell-command, emacs membagi windows. Saya ingin agar perintah shell tertentu benar-benar di latar belakang (tanpa efek visual).

Sebagai contoh eksplisit, saya memiliki kode berikut (dipinjam dari https://emacs.stackexchange.com/a/7932 ). Ini membuka versi pdf dari file tex yang saya kerjakan. Ketika menjalankannya, ia membelah jendela, saya ingin mencegahnya dari perilaku ini dalam situasi khusus ini.

 (defun my-view-pdf ()
  (interactive)
  (async-shell-command
    (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))
Nama
sumber
3
Bukan tentang pertanyaan abstrak, tetapi kasus penggunaan spesifik: Apakah Anda menggunakan AUCTeX? Adakah alasan khusus Anda tidak menggunakan TeX-view( C-c C-v)?
Dan
@Dan masalahnya adalah ketika saya C-c C-vtidak melakukan apa - apa terjadi. Saya tidak mengerti mengapa. Jika Anda tahu kustomisasi sederhana untuk .emacsmembuat C-c C-vkarya, saya akan senang menggunakannya. OS saya adalah Windows dan penampil PDF saya terletak di C:\Program Files\SumatraPDF\sumatrapdf.exe. Dalam tautan itu daftar hukum telah menyediakan tautan yang komprehensif. Saya hanya tertarik untuk membuat karya TeX-viewer.
Nama
Bukan pada Windows, jadi tidak bisa mengatakan mengapa Anda mengalami masalah. Anda mungkin mencoba bekerja dengannya TeX-view-program-list.
Dan
Pertanyaan ini memiliki jawaban yang sangat bagus sehingga saya akan benci untuk ini ditutup. Tapi ini duplikat dari pertanyaan ini: emacs.stackexchange.com/q/5553/115
Kaushal Modi

Jawaban:

8

save-window-excursionadalah makro untuk menjalankan sepotong kode tanpa mengubah konfigurasi jendela. Sesuatu seperti ini seharusnya bekerja:

 (defun my-view-pdf ()
  (interactive)
  (save-window-excursion
   (async-shell-command
     (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf"))))
legoscia
sumber
Makro yang bagus, saya mengkonfirmasi bahwa solusi Anda berfungsi.
Sebutkan
2
@legoscia yang Anda cari save-window-excursion, yang hampir identik dengan implementasi Anda.
Bhag
@ bmag Saya tertarik untuk mengetahui perbedaan antara save-window-excursiondan save-window-configuration. Tampaknya keduanya berfungsi dalam situasi ini.
Nama
1
@Name Tidak ada perbedaan, kecuali yang save-window-excursionmenggunakan beberapa praktik terbaik makro untuk menghindari memasukkan variabel ke lingkungan tubuh. Juga, save-window-excursionbuilt-in untuk Emacs. Saya mencari makro itu, tetapi tidak menemukannya, jadi saya menulis versi saya sendiri. Untungnya bmag tahu yang asli.
legoscia
8

Jika Anda hanya ingin menelurkan proses di latar belakang Anda tidak perlu semua lonceng peluit yang menyediakan fungsi perintah shell.

Sebagai gantinya, Anda dapat menggunakan fungsi ini call-process. Sebagai contoh:

(call-process
 "a_command"
 nil
 0                                  ; <- Discard and don't wait
 nil
 "arg1"
 "arg2")

Konkretnya, ini berarti bahwa Anda dapat mengimplementasikan perintah Anda sebagai:

(defun my-view-pdf ()
    (interactive)
    (call-process "SumatraPDF" nil 0 nil
                  (concat (file-name-base (buffer-file-name)) ".pdf")))
Lindydancer
sumber
Saya mencoba menerapkan saran Anda untuk contoh spesifik saya, (defun my-pdf-viewer () (interactive) (call-process (async-shell-command (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")) nil 0 ; <- Discard and don't wait nil "arg1" "arg2") )saya mendapatkan kesalahan `Argumen tipe salah: stringp, comint-output-filter`. Saya tidak yakin apakah sintaks yang saya gunakan sudah benar.
Nama
Anda harus jatuhkan async-shell-commandsemuanya. Seharusnya seperti itu (defun my-pdf-viewer () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf")).
Lindydancer
1
Terima kasih, solusi Anda bekerja sempurna, hanya ada penjepit hilang, sehingga kode yang benar harus: (defun my-view-pdf () (interactive) (call-process "SumatraPDF" nil 0 nil (concat (file-name-base (buffer-file-name)) ".pdf"))) .
Nama
@Name, terima kasih, saya telah memperbarui jawaban untuk menyertakan fungsi konkret.
Lindydancer
7

Gunakan display-buffer-alistdengan display-buffer-no-windowjika Anda menggunakan Emacs 24.4 atau lebih baru.

(setq display-buffer-alist '(("\\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))

Atau, gunakan belenggu :

(setq shackle-rules '(("*Async Shell Command*" :ignore t)))
wasamasa
sumber
Menggunakan (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window)))saya mendapatkan kesalahan apply: Wrong type argument: sequencep, display-buffer-no-window.
Sebutkan
Oh benar, display-buffer-no-windowdiperkenalkan di Emacs 24.4, jadi itu tidak akan berhasil. Paket saya di sisi lain harus bekerja pada 24.3.
wasamasa
Backporting display-buffer-no-windowadalah opsi ketiga, cukup masukkan (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail))dalam konfigurasi Emacs Anda.
wasamasa
Saya mencoba menerapkan komentar terakhir Anda dengan menyatukan semuanya (defun display-buffer-no-window (_buffer alist) (when (cdr (assq 'allow-no-window alist)) 'fail)) (setq display-buffer-alist '(("\`\\*Async Shell Command\\*\\'" display-buffer-no-window))) (defun my-view-pdf () (interactive) (progn (async-shell-command (concat "SumatraPDF " (file-name-base (buffer-file-name)) ".pdf")))) . Tetapi setelah dieksekusi my-view-pdf, emacs membagi jendela dan *Async Shell Command*ditampilkan.
Nama
Saya mengkonfirmasi bahwa solusi Anda berfungsi dengan baik untuk versi 24.4 atau yang lebih baru.
Nama