Wystąpił problem z przeglądaniem plików dokumentacji pdf w programie AucTex. Używam pdf-tools
do przeglądania plików PDF z poziomu Emacsa i ustawiłem emacsclient -n
jako domyślną przeglądarkę pdf (przez xdg-mime w systemie Debian Linux). Działa to dobrze w większości przypadków, ale psuje (Tex-documentation-texdoc ...)
funkcję Auctex ( C-c ?
).
Zawęziłem problem do jednego wiersza kodu. Kiedy próbuję przeglądać dokumentację listings
pakietu, TeX-documentation-texdoc
zamienia to w następujący sexp:
(shell-command-to-string "texdoc --view listings")
texdoc
z kolei wezwania emacsclient
do otwarcia pliku (na podstawie tego, jak skonfigurowałem swój pulpit za pomocą xdg). Jednak w tym momencie Emacs zawiesza się i muszę wyjść z ( C-g
), aby odzyskać kontrolę. Po tym nie jest otwierany żaden nowy plik pdf. To samo dzieje się, jeśli spróbuję wywołać emacsclient bezpośrednio:
(shell-command-to-string "emacsclient -n tmp.pdf")
Oba polecenia pracy w linii poleceń (czyli emacsclient -n tmp.pdf
i texdoc --view listings
.
Moje pytanie brzmi: w takim przypadku jak wywołać emacsclient z poziomu Emacsa? (i wiem, że mogłem po prostu otworzyć plik pdf find-file
; nie jest to opcja, ponieważ muszę wywołać proces zewnętrzny (texdoc), aby znaleźć plik, a następnie ten proces wywołuje emacsclient).
źródło
texdoc -M --list listings
aby znaleźć plik, a następnie użyćfind-file
?texdoc --view
a następnie przełączenie z powrotem do Emacsa po otwarciu pliku. Ale myślę, że powinien istnieć sposób na zrobienie tego w jednym kroku od Emacsa?(async-shell-command "emacsclient -n tmp.pdf")
rozwiązać problem?(async-shell-command "emacsclient -n tmp.pdf")
działa, ale nie(async-shell-command "texdoc --view listings")
działa. To przydatna wskazówka.C-u C-c ?
działa Najpierw wyświetla listę dokumentów związanych z pakietem, a następnie otwiera przeglądarkę za pomocą(call-process "texdoc" nil 0 nil "--just-view" doc)
.Odpowiedzi:
Rozwiązaniem jest uruchomienie
texdoc
w ramach procesu asynchronicznego.Najlepszym sposobem na zrobienie tego jest prawdopodobnie użycie
start-file-process
zamiast tegoshell-command-to-string
(jest to przydatna funkcja do szybkiego i brudnego kodu, gdy bardziej celowe jest napisanie małego skryptu powłoki niż odpowiadający mu kod Elisp, ale z mojego doświadczenia wynika, że lepiej go unikać).Będzie to jednak wymagało znacznych zmian w otaczającym kodzie, ponieważ
start-file-process
nie zwraca bezpośrednio wyniku procesu, zamiast tego pozwala wskazać, w którym buforze umieścić dane wyjściowe, a następnie należy użyćset-process-sentinel
funkcji wywołania zwrotnego, która pobiera dane wyjściowe z tego bufora i robi „cokolwiek trzeba z tym zrobić” po zakończeniu polecenia.źródło
texdoc
w AUCTeX uważam, że użycie wartownika jest nieco przesadzeniem, ponieważ nie jest to podstawowa funkcja (jak otwarcie przeglądarki dokumentu wyjściowego, w którym to przypadku używamy strażnik)....-to-string
), wówczas rozwiązanie asynchroniczne będzie wymagało albo filtru procesu, albo czujnika procesu. Jeśli nie, to kod może użyć czegoś takiego(shell-command "texdoc --view listings &")
.TeX-documentation-texdoc
:...-to-string
wariant służy do pokazywania użytkownikom możliwych komunikatów o błędach (na przykład, gdy nie znaleziono żadnej dokumentacji). Ponadtotexdoc nonexistingpackage
zwraca 0, ale wartownika można użyć do parsowania danych wyjściowych.start-file-process
która faktycznie działa tutaj.(start-file-process "texdoc" "*texdoc*" "texdoc" "--view" "listings")
tworzy bufor*texdoc*
, do którego wstawia się „Przetwarzanie texdoc zakończone”, a pdf nigdy się nie otwiera. To samo dzieje się, gdy ustawiam przeglądarkę pdf xdg-mime na ewince.Jeśli musisz tylko przesłać zapytanie do Emacsa, nie czekając na odpowiedź, możesz uruchomić
emacsclient
w tle. Pod systemami uniksowymi (Linux, macOS, Cygwin,…):W natywnym systemie Windows:
źródło
texdoc
jest asynchroniczny (tzn. Nie czekasz na zakończenie), prawda? Możesz więc zastosować tę samą zasadę: uruchomtexdoc … &
jako polecenie powłoki.emacsclient
bezpośrednio, ale nie dzwonisztexdoc
.