使用emacs擴展synctex以支援多個開啟的pdf?

使用emacs擴展synctex以支援多個開啟的pdf?

使用這個答案 我已經能夠讓 emacs、syntex 和 evince 幾乎完美地協同工作,以支援正向搜尋(tex 檔案 -> pdf)和反向搜尋(pdf -> tex 檔案)。我缺少的一件事是支援從多個開啟的 pdf 副本中進行搜尋。

更詳細地說,我在撰寫技術論文時習慣打開多個 pdf 副本(在 evince 中使用 ctrl+n 打開副本),但當我這樣做時,打開的副本不再連結回 emacs。也就是說,ctrl+click 在從 emacs 打開的原始 pdf 中起作用,而 ctrl+click 在打開的副本(透過在 evince 中執行 ctrl+n 創建)中不起作用。

我的猜測是,這可能比 emacs 的問題更明顯,但我的問題是我怎麼能做到這一點,以便從第二個 pdf 進行反向搜尋?

答案1

這是受到ttb自己解決方案的啟發。將 emacs 註冊到 dbus 訊號的程式碼位於函數中TeX-source-correlate-mode,如下所示:

(dolist (de-app '(("gnome" "evince") ("mate" "atril") ("x" "reader")))     
  (when (TeX-evince-dbus-p (car de-app) (cadr de-app))                     
    (dbus-register-signal                                                  
     :session nil (format "/org/%s/%s/Window/0" (car de-app) (cadr de-app))
     (format "org.%s.%s.Window" (car de-app) (cadr de-app))                
     "SyncSource"                                                          
     'TeX-source-correlate-sync-source)))

因此(作為一種駭客解決方案),您可以運行相同的程式碼,並將0其替換為您認為同時開啟的視窗i數量。i

因此,我總共將以下內容放入我的.emacs文件中:

(defun my/add-ten-more-synctex-windows ()
  (dotimes (i 10)
    (dolist (de-app '(("gnome" "evince") ("mate" "atril") ("x" "reader")))
      (when (TeX-evince-dbus-p (car de-app) (cadr de-app))
        (dbus-register-signal
         :session nil (format "/org/%s/%s/Window/%d" (car de-app) (cadr de-app) (1+ i))
         (format "org.%s.%s.Window" (car de-app) (cadr de-app))
         "SyncSource"
         'TeX-source-correlate-sync-source)))))                              
   
(add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)                                                                                      
(add-hook 'LaTeX-mode-hook 'my/add-ten-more-synctex-windows)

答案2

我透過編輯 atril 的程式碼解決了這個問題。請注意,可能還存在一個尚未找到的基於 emacs 的解決方案。

關於 emacs <--> atril 互動如何在 pdf -> tex 搜尋方面工作的一些背景知識。在emacs中,我們在dbus路徑「/org/mate/atril/Window/0」上監聽訊息,atril在dbus路徑「/org/mate/atril/Window/N」上傳送訊息,其中N是window_id文件(每次按Ctrl+N 開啟副本時,window_id 都會遞增)。

因此,問題在於副本在 emacs 未偵聽的 dbus 路徑上發送訊息。讓它工作的一種駭客方法是讓 atril 始終在路徑「/org/mate/atril/Window/0」上發送synctex命令,而不管window_id如何。

為此:找到ev-window.c 中的 ,然後修改該函數中出現的函數呼叫ev_window_sync_source的參數。g_dbus_connection_emit_signal具體來說,替換window->priv->dbus_object_path為就足夠了g_strdup_printf (EV_WINDOW_DBUS_OBJECT_PATH, 0)。 (這適用於 github 上提供的 atril 1.18.5 程式碼)

答案3

Joj 上述的解決方案非常好。但它是單向的,即多個證據視窗指向多個 emacs 緩衝區。是否可以將解決方案擴展到相反的方向,即如果我單擊特定的 emacs 緩衝區,它會轉到特定的 evince 視窗。現在,當我單擊任一 emacs 緩衝區時,它只會轉到原始 evince 窗口,而不是 evince 窗口的副本。 [抱歉:這是一個問題/評論,而不是答案]

相關內容