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")))

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"))))

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")))

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)))

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.