LINUX.ORG.RU

Emacs - как открыть новый файл в существующем процессе emacs (не создавать новый процесс)

 


1

2

Вопрос: как можно открывать txt-файлы Nautilus'ом без создания новой сессии Emacs, как если бы они были открыты через C-x C-f.
- emacs установлен редатором по умолчанию, таким образом текстовые файлы открываются имеенно в нем.
- проблема в том, что текстовые файлы, открываемые через Nautilus, каждый раз запускают новую сессию Emacs.
- хотелось бы решить проблему без использования emacsclient!
- в файле /usr/share/applications/emacs.desktop:

Exec=emacs %f
вероятно нужно добавить какой-то аргумент, чтобы не создавать новую сессию, если есть уже открытая.
Возможно вообще это?
P.S. кстати emacsclient тоже открывает файл каждый раз в новом графическом фрейме. А нужно в уже имеющемся!
P.P.S. Почему без клиент-серверного режима нужно - потому что для windows тоже нужно аналогичное решение.
P.P.P.S. Запуск emacs в режиме --daemon (в linux) плюс emacsclient также не решает проблему.



Последнее исправление: volodlebedev (всего исправлений: 11)

В init.el прописать

(server-mode 1)

Для запуска я использую такой скрипт:

#!/bin/sh

if [ -z "$DISPLAY" ]; then
    vim $@
else
    if [ -e "/tmp/emacs1000/server" ]; then
        emacsclient -q -n $@
    else
        emacs $@ 2>/dev/null &
    fi
fi

Если emacs не запущен, запускается. Если запущен, файл передается ему через emacsclient. Под виндой наверное тоже можно настроить подобным образом.

Без emacsclient, боюсь, это не решить.

Puzan ★★★★★
()
Последнее исправление: Puzan (всего исправлений: 2)

Не готовое решение, а идея для грязного хака:

#!/bin/bash
echo "(find-file \"$1\")" >> ~/.emacs.d/cmdfile

В emacs периодически дергается

(defun read-cmd-file ()
  (load-file "~/.emacs.d/cmdfile")
  (delete-file "~/.emacs.d/cmdfile"))

(run-with-idle-timer 1 t 'read-cmd-file)
good_riddance
()

Теоретически можно накостылять через dbus.

no-such-file ★★★★★
()
Ответ на: комментарий от Puzan

Puzan, попробовал, каждый новый файл открывается в новом фрейме. А нужно в одном - как если бы файл через dired открывался или через C-x C-f

volodlebedev
() автор топика
Ответ на: комментарий от good_riddance

good_riddance, реально грязный хак ))) нужно решение поизящней, неужели штатных средств не предусмотрено в emacs для этого?! :-(

volodlebedev
() автор топика
Ответ на: комментарий от volodlebedev

да не предусмотрено, потому-что подразумевается что это ОСь и ты все делаешь из него. А ОСь может быть только одна как-ты понимаешь, отсюда и server-mode, хотя мне он тоже не нравится

bismi
()
Последнее исправление: bismi (всего исправлений: 1)
Ответ на: комментарий от volodlebedev

Точно прописал (server-mode 1)?

Я только что проверил на пустом init.el, всё работает, открывает в одном окне (фрейме).

Puzan ★★★★★
()

Долго думал - зачем? Открытие/закрытие фреймов в emacsclient происходит мгновенно, дешево как для системы, так и для самого емакса.

emacsclient --eval '(with-current-buffer (find-file "/etc/fstab"))' 

P.S. ненужно

lazyklimm ★★★★★
()
Последнее исправление: lazyklimm (всего исправлений: 2)
Ответ на: комментарий от Puzan

вот ты костылятор

EMACSCLIENT(1)       
...

 -a, --alternate-editor=EDITOR
              if the Emacs server is not running, run the specified editor instead.  This can also be specified via the `ALTERNATE_EDITOR' environment variable.  If the value of EDITOR is the empty  string,
              run `emacs --daemon' to start Emacs in daemon mode, and try to connect to it.


lazyklimm ★★★★★
()
Ответ на: комментарий от Puzan

Puzan, поясните пожалуйста Ваше решение, файлы нужно через скрипт запускать? И что значит пустой unit.el?

anonymous
()
Ответ на: комментарий от Puzan

и, да, «emacs --daemon» при старте системы (через инит-скрипт или пользовательский crontab) запускать гораздо удобнее, имхо.

lazyklimm ★★★★★
()
Ответ на: комментарий от lazyklimm

вот ты костылятор

Так у меня проблема - при использовании emacsclient --alternate-editor=«» emacs запускается в терминале (в котором я работаю), а не в своем иксовом окне. А если просто запустить emacs, то всё в порядке.

Может ты знаешь, в чем трабла?

Puzan ★★★★★
()
Ответ на: комментарий от lazyklimm

А можно узнать чем?

Перезапускать ось иногда приходится, мне проще жмакнуть крестик а потом иконку на панельке

bismi
()
Ответ на: комментарий от bismi

Перезапускать ось иногда приходится, мне проще жмакнуть крестик а потом иконку на панельке

M-x kill-emacs или что-нибудь типа того и запуск (у меня шорткат) emacsclient -c -a «»

lazyklimm ★★★★★
()
Ответ на: комментарий от Puzan

Тогда даже хз, у меня всё запускается как надо. параметр "-t/-nw/-tty" не передаёшь?

Если что, запускаю сам емакс через --daemon.

lazyklimm ★★★★★
()
Ответ на: комментарий от lazyklimm

Вот и я не понял, почему не работает. Пришлось накостылить скрипт.

Как нибудь попробую разобраться.

Puzan ★★★★★
()
Ответ на: комментарий от Puzan

Попробуй --daemon запускать отдельно, а не через

 (server-mode 1)

у меня так:

crontab -l | grep emacs                                                                                                                             
@reboot emacs --daemon

запускается при старте системы, можно юзать хоть из консоли (а не запускать ненужный vim), хоть так

lazyklimm ★★★★★
()
Ответ на: комментарий от lazyklimm

Изначально было на дебиане. Сейчас арч и то-же самое. На работе дебиан и там так же.

Puzan ★★★★★
()
Последнее исправление: Puzan (всего исправлений: 1)

у меня в арче так:

в init.el

(require 'server)
(unless (server-running-p) (server-start))

и в dolphin просто привязка к типу файла для запуска через emacsclient без аргументов. Из терминала emacsclient <filename> тоже открывает в запущенной копии emacs'a.

hope13 ★★★
()
Ответ на: комментарий от good_riddance

Во, как-то так, в .emacs:

(defvar emacs-command-file-name "/tmp/emacs-cmd")
(defvar emacs-command-buffer (or (find-buffer-visiting emacs-command-file-name)
                                 (with-current-buffer (find-file-noselect emacs-command-file)
                                   (save-buffer)
                                   (current-buffer))))
(with-current-buffer emacs-command-buffer
  (add-hook 'after-revert-hook
            #'(lambda ()
                (let ((files (split-string
                              (with-current-buffer emacs-command-buffer
                                (let ((ret (buffer-string)))
                                  (erase-buffer)
                                  ret))
                              "\n" t "[ \t\n]"))))
                (mapc #'find-file files))
            nil t)
  (auto-revert-mode))
Ну и соответственно editor.sh
#!/bin/bash
echo "$1\" >> ~/.emacs.d/cmdfile

Ну или с евалом можно.

Bad_ptr ★★★★★
()
Последнее исправление: Bad_ptr (всего исправлений: 3)
Ответ на: комментарий от Bad_ptr

рабочая версия 1.0

(defvar emacs-files-to-find-file-name "/tmp/emacs-files-to-find")
(defvar emacs-files-to-find-buffer (or (find-buffer-visiting emacs-files-to-find-file-name)
                                       (with-current-buffer (find-file-noselect emacs-files-to-find-file-name)
                                         (save-buffer)
                                         (rename-buffer " *emacs-files-to-find-buf*")
                                         (current-buffer))))

(defun find-files-from-buffer-and-erase (buffer-or-name)
  (let ((files (split-string
                (with-current-buffer buffer-or-name
                  (let ((ret (buffer-string)))
                    (erase-buffer)
                    ret))
                "\n" t "[ \t\n]")))
    (mapc #'find-file files)))

(with-current-buffer emacs-files-to-find-buffer
  (add-hook 'after-revert-hook
            #'(lambda ()
                (find-files-from-buffer-and-erase emacs-files-to-find-buffer))
            nil t)
  (auto-revert-mode))


#!/bin/bash
echo "$1" >> /tmp/emacs-files-to-find

Bad_ptr ★★★★★
()
Последнее исправление: Bad_ptr (всего исправлений: 1)
Ответ на: комментарий от hope13

Из терминала emacsclient <filename> тоже открывает в запущенной копии emacs'a.

А если еще нет запущеной копии, то где запускает?

Puzan ★★★★★
()
Ответ на: комментарий от Puzan

Puzan

Точно прописал (server-mode 1)?

да, только не в init.el прописывал, а в ~/.emacs (разницы ведь нет)
да и потом, режим daemon пришел в новых версиях на смену режиму server-mode (это ведь почти одно и то же?), так что, раз с daemon не получилось, то неудивительно что и с server-mode не получится..

Я только что проверил на пустом init.el, всё работает, открывает в одном окне (фрейме).

очень странно.. я уже склоняюсь к тому, что это вообще невозможно :))

volodlebedev
() автор топика
Ответ на: комментарий от lazyklimm

lazyklimm

EMACSCLIENT(1) ...

-a, --alternate-editor=EDITOR
if the Emacs server is not running, run the specified editor instead. This can also be specified via the `ALTERNATE_EDITOR' environment variable. If the value of EDITOR is the empty string,
run `emacs --daemon' to start Emacs in daemon mode, and try to connect to it.

и что?))

и, да, «emacs --daemon» при старте системы (через инит-скрипт или пользовательский crontab) запускать гораздо удобнее, имхо.

ну не знаю, что может быть проще запуска через .desktop файл. :)

volodlebedev
() автор топика
Ответ на: комментарий от hope13

hope13

у меня в арче так:

в init.el

(require 'server)
(unless (server-running-p) (server-start))

и в dolphin просто привязка к типу файла для запуска через emacsclient без аргументов. Из терминала emacsclient <filename> тоже открывает в запущенной копии emacs'a.

у меня fedora, при этом emacsclient без аргументов вообще не работает, ошибка, дескать команда запущена без аргумента. Попробовал Ваш рецепт, к сожалению - не работает :(

volodlebedev
() автор топика
Ответ на: комментарий от iVS

iVS

Надеюсь, уже объяснили, что без emacsclient — никак?

да, пофик уже, хоть с emacsclient, хоть с daemon, хоть с server-mode, лишь бы заработало, хочу своими глазами увидеть хоть разок что это вообще возможно. Возможно без рукоблудия конечно, штатными средствами..

volodlebedev
() автор топика
Ответ на: комментарий от volodlebedev

ну не знаю, что может быть проще запуска через .desktop файл

шорткат, ты же емаксер

lazyklimm ★★★★★
()
Ответ на: комментарий от volodlebedev

я выше уже написал, как оно у меня может работать

lazyklimm ★★★★★
()
Ответ на: комментарий от Puzan

Так у меня проблема - при использовании emacsclient --alternate-editor=«» emacs запускается в терминале

Глянь сюда, как запускать.

iVS ★★★★★
()
Ответ на: комментарий от volodlebedev

Puzan, попробовал, каждый новый файл открывается в новом фрейме. А нужно в одном - как если бы файл через dired открывался или через C-x C-f

Emacs - как открыть новый файл в существующем процессе emacs (не создавать новый процесс) (комментарий)

iVS ★★★★★
()

Обнаружил интересную особенность: при запуске emacsclient без опций '-c' или '-t', например так: emacsclient <filename>, появляется процесс с этим <filename>:

[vol@Lenovo ~]$ ps -ax | grep emacs
 4022 ?        Ssl    0:05 /usr/bin/emacs --daemon
 4283 tty2     S+     0:00 emacsclient file1.txt
 4681 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file2.txt
 4685 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file3.txt
 4688 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file4.txt
 4691 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file5.txt
 4694 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file6.txt
 4697 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file7.txt
 4700 tty2     S+     0:00 emacsclient --alternate-editor= /home/vol/Dropbox/_Docs/Docs_Emacs/file8.txt
 4788 tty2     S+     0:00 emacsclient -a  file9.txt
 4790 pts/2    S+     0:00 grep --color=auto emacs
но при этом новых фреймов с файлами file1.txt...file9.txt не открылось ни в иксах, ни в терминале. В списке открытых буферов (C-x C-b из emacsclient) этих файлов тоже нет.
Есть идеи?

volodlebedev
() автор топика
Ответ на: комментарий от volodlebedev

p.s. ну, всмысле, в иксах вообще ничего не создает и не открывает... даже сессия есть. Возможно ноги у этой проблемы растут из изложенного сообщением выше..

volodlebedev
() автор топика
Ответ на: комментарий от volodlebedev
#!/bin/sh

xprop -name emacs >/dev/null 2>/dev/null
if [ "$?" = "1" ]; then
    emacsclient -c -n -a "" "$@"
else
    emacsclient -n -a "" "$@"
fi

вот это будет работать в fedora

ufayan
()
Ответ на: комментарий от ufayan

ufayan

#!/bin/sh

xprop -name emacs >/dev/null 2>/dev/null
if [ "$?" = "1" ]; then
    emacsclient -c -n -a "" "$@"
else
    emacsclient -n -a "" "$@"
fi

вот это будет работать в fedora

итить-колотить!!! И правда работает!!
ufayan, cпасибо огромное! Насколько же просто ларчик оказывается открывался то:
1. получается, опция '-c' нужна только для первого запуска, чтоб создать новый фрейм!
2. без опции '-c' и без открытого фрейма команда не сработает, в чем и заключается главный маразм (на кой хрен тогда режим daemon?!)
3. ну и, без шелл скрипта, получается, не обойтись.
Всем большое спасибо за участие и дельные советы! Тему можно считать закрытой.

volodlebedev
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.