2012-12-16 140 views
8

~/.emacs包括打開某些應用程序的某些文件進行以下設置(Ubuntu的12.10; Emacs的24):如何避免在Emacs中彈出* Async Sh​​ell Command *緩衝區?

(setq dired-guess-shell-alist-user 
     '(("\\.pdf\\'" "okular ? &") 
    ("\\.djvu\\'" "okular ? &") 
     ("\\.mp3\\'" "vlc ? &") 
    ("\\.mp4\\'" "vlc ? &") 
    )) 

當我瀏覽到一個PDF中dired-mode和命中!,它在打開的Okular的.PDF ,但是dired緩衝區被分成兩個部分,第二個現在正在像

無用包含內容 *Async Shell Command*緩衝
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig: 
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig: 
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig: 
okular(25393)/kdecore (KConfigSkeleton) KCoreConfigSkeleton::writeConfig: 

我怎樣才能防止被打開這個緩衝區? (除了,也許,如果出現錯誤並且此信息有用)。

我發現相關問題herehere,但他們似乎要處理的,而不是一般*Async Shell Command*與異步執行特定的命令,(如果可能的話,我想改變的行爲一般爲異步進程,不僅對某些文件類型)

+0

查看'.../lisp/simple.el'源文件中的實際函數 - 即'defun shell-command'和'defun async-shell-command'。你甚至可以創建自己的自定義函數和/或使用'defalias'。當使用'start-process'時,第二個參數是輸出緩衝區名稱 - 使用'nil'作爲第二個參數可以防止創建輸出緩衝區。你可以將'set-process-sentinel'和'start-process'結合使用。 – lawlist

+0

'async-shell-command'的文檔字符串表明:'...在Elisp中,通過直接調用'start-process'可以更好地服務,因爲它提供了更多的控制,並且不會強制使用 shell(需要引用參數)。' – lawlist

回答

1

我不能完全肯定這樣做是爲了在普通異步進程,但對於任何通過async-shell-command去,這應該工作:

(defadvice async-shell-command (around hide-async-windows activate) 
     (save-window-excursion 
      ad-do-it)) 
+0

但是,你迫使'async-shell-command'的所有用途丟失緩衝區。我認爲這會過度殺傷;肯定會出現你想看到輸出的情況。改變建議以添加一個指定是否執行'save-window-excursion'的參數不應該太難,但是爲什麼首先使用建議;改用簡單的包裝函數。 – tripleee

+0

......我確實認識到OP特別要求修復'async-shell-command',但應該強調一下與它有關的警告。 – tripleee

+0

這不適合我。我仍然得到異步Shell命令緩衝區。 –

0

一個稍微複雜的咒語小號你會得到你想要的。只需使用shell命令:(okular ? >& /dev/null &)

我還沒有用okular測試過,但我可以做M-!((echo foo; sleep 10; echo bar) >& /dev/null &)和Emacs立即返回而不創建新的緩衝區。

+0

不錯。但是,* Async Sh​​ell Command *緩衝區仍然彈出(現在只是空)。如果我嘗試你的M-! ...'命令,我得到了「沒有輸出的shell命令成功」 –

0

我解決了這個問題,使用這種方法:

;list of programs, corresponding to extensions 
(setq alist-programs 
     '(("pdf" ."okular") 
     ("djvu" . "okular") 
     ("mp3" . "xmms"))) 

(defun my-run-async-command (command file) 
    "Run a command COMMAND on the file asynchronously. 
    No buffers are created" 
    (interactive 
    (let ((file (car (dired-get-marked-files t current-prefix-arg)))) 
    (list 
     ;last element of alist-programs, contains COMMAND 
     (cdr 
     (assoc 
     (file-name-extension file) 
     alist-programs)) 
     file))) 
    ;begin of function body 
    (if command ;command if not nil? 
     (start-process "command" nil command file) 
    ) 
) 

;attach function to <f2> key 
(add-hook 'dired-mode-hook 
     (lambda() 
    (define-key dired-mode-map (kbd "<f2>") 'my-run-async-command))) 
8

發現這個here

(call-process-shell-command "okular&" nil 0) 

爲我工作。沒有stderr gobbledygook。

2

不幸的是,沒有好的方法來避免這個緩衝區,因爲它被'shell-command'函數直接調用('async-shell-command'只是一個包裝器)。

所以,更好的方法是用'start-process'替換'async-shell-command'。 您應該開始處理'set-process-sentinel'以檢測進程發出'退出信號的時刻。然後殺死進程。

1

有人問在2012年,在我寫作的時候,最新的答案是過時的2015年。現在,在2017年,我可以說,答案很簡單:

(add-to-list 'display-buffer-alist (cons "\\*Async Shell Command\\*.*" (cons #'display-buffer-no-window nil)))

0

我捎帶關閉user1404316的答案,但這是實現預期結果的另一種通用方法。

(defun async-shell-command-no-window 
    (command) 
    (interactive) 
    (let 
     ((display-buffer-alist 
     (list 
     (cons 
      "\\*Async Shell Command\\*.*" 
      (cons #'display-buffer-no-window nil))))) 
    (async-shell-command 
    command)))