Базовая настройка сервера Emacs под OSX

Базовая настройка сервера Emacs под OSX

Недавно я купил свой первый Mac за десятилетие и сейчас настраиваю его. Я пользователь Emacs и решил, что хочупросто обычный Emacsне Aquamacs, чтобы я мог использовать свою существующую конфигурацию из других операционных систем. Я пытался следовать многим инструкциям, которые я нашел в сети (например,Вот этот,Вот этотиэто с сайта, с которого я скачал Emacs), и пробовал комбинировать части разными способами, но так и не смог добиться состояния, хотя бы отдаленно напоминающего то, к чему я привык/на что надеюсь:

  1. Демон Emacs начинает работать либопри запускеиликак только мне это понадобится; любой из них хорош. Любые новые фреймы Emacs поддерживаются тем же сервером.
  2. Когда я открываю текстовый файл из Finder, файл открывается в Emacs, по возможности в существующем графическом фрейме.
  3. Если я запускаю Emacs.app, система повторно использует демон emacs, работающий в фоновом режиме, вместо того, чтобы запускать новый экземпляр и открывать в нем новое окно.подсказка)
  4. Когда я запускаю Emacs из терминала, терминал продолжает работу, не дожидаясь, пока я закончу работу с Emacs (если я не использую '-nw')
  5. Насколько мне известно, ни в какой момент во время описанных выше операций Emacs не должен оказаться в состоянии («режим редактирования сервера?»), в котором он ждет, пока я наберу текст C-x #, хотя у меня нет глубокого понимания этого.
  6. (Я бы расценил это как бонус) У меня есть способ вызвать Emacs из терминала, чтобы Emacs повторно использовал существующий фрейм, если это возможно.

Как мне настроить Emacs так, чтобы он вел себя подобным образом?

Меня особенно озадачивает, как заставить Finder открывать файлы в Emacs так, как мне нужно (№2), поскольку руководства, которые я нашел, обычно создают ряд псевдонимов, скриптов Applescript, bash-скриптов и т. д., и я не уверен, какой из них использовать в Finder для открытия текстовых файлов.

Спасибо!

А.@lawlist спрашивает: «Открывается ли новый фрейм по умолчанию при открытии нового файла из терминала, даже если уже есть существующий фрейм?» Ответ таков: если я запускаю сервер при запуске, как описаноздесь, открыть фрейм, а затем открыть файл, набрав /Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n <whatever>, я могу заставить файл открыться в существующем фрейме. Если в данный момент нет открытого фрейма, мне приходится использовать "-nc", или когда я пытаюсь открыть файл, ничего не происходит.

Б.@lawlist спрашивает: «Хотите ли вы, чтобы демон запускался при входе в систему, или будет достаточно загрузить Emacs вручную после входа в систему?» Запуск вручную будет вполне приемлемым.

решение1

Чтобы Emacs.app открывал файлы в существующем фрейме, а не в новом, добавьте (setq ns-pop-up-frames nil)в файл конфигурации, например ~/.emacs.

Вы можете открыть файл из терминала с помощью open -a emacs fileили emacsclient -n file. Если Emacs.app не открыт, но есть Emacs --daemonпроцесс, по какой-то причине emacsclient -n fileне работает, но emacsclient -nc fileработает.

Убедитесь, что вы используете emacsclientдвоичный файл, входящий в состав используемой вами версии Emacs, например /Applications/Emacs.app/Contents/MacOS/bin/emacsclient, или /usr/local/bin/emacsclientесли вы установили Emacs с помощью Homebrew.

Чтобы запустить сервер Emacs при входе в систему, например, сохраните этот plist как ~/Library/LaunchAgents/my.emacsdaemon.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>my.emacsdaemon</string>
  <key>ProgramArguments</key>
  <array>
    <string>/Applications/Emacs.app/Contents/MacOS/Emacs</string>
    <string>--daemon</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <true/> <!-- run the program again if it terminates -->
</dict>
</plist>

Файл plist загрузится автоматически при следующем входе в систему, но вы можете загрузить его немедленно, запустив launchctl load ~/Library/LaunchAgents/my.emacsdaemon.plist.

Редактировать: Я все еще не знаю, почему люди связывают типы файлов с приложением AppleScript, а не просто с Emacs.app. Скрипт в ответе kuzzooroo также может быть написан как скрипт оболочки:

macos=/Applications/Emacs.app/Contents/MacOS
if pgrep -qf 'Emacs.*--daemon'; then
  [[ $($macos/bin/emacsclient -e '(<= 2 (length (visible-frame-list)))') = t ]] && args=-nc || args=-n
else
  $macos/Emacs --daemon
  args=-nc
fi
$macos/bin/emacsclient $args "$@"
open -a /Applications/Emacs.app

Вы можете использоватьУтконосчтобы сохранить скрипт как приложение:

Я только что начал использовать Emacs, но у меня совершенно другая настройка. Я создал собственное приложение Emacs, сделав копию iTerm.app, изменив CFBundleIdentifier в Info.plist так, чтобы приложение использовало другой файл настроек, и установив команду по умолчанию на . /usr/local/bin/emacsЯ добавил и открываю пользовательское приложение Emacs при входе в систему. Я использовал Platypus для создания работающего приложения и сделал его приложением по умолчанию для текстовых файлов.(server-start)~/.emacsemacsclient -n "$@";open -b my.emacs

решение2

Решение Лаури в сочетании с предложениями из комментариев в значительной степени устранило мои проблемы. Ниже я вставил немного Applescript, который я сшил из того, что нашел в сети. Скрипт помогает сгладить некоторые оставшиеся морщины, например, его поведение немного лучше, если нет текущего фрейма Emacs.

EDIT: цель скрипта — связать его с файлами .txt в Finder.

-- http://superuser.com/questions/457484/how-to-open-emacs-from-macs-finder
-- https://gist.github.com/ambethia/304964#comment-799519
on run {input}
    set filepath to quoted form of POSIX path of input
    tell application "Terminal"
        try
            -- we look for <= 2 because Emacs --daemon seems to always have an entry in visibile-frame-list even if there isn't
            set frameVisible to do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -e '(<= 2 (length (visible-frame-list)))'"
            if frameVisible is "t" then
                do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -n " & filepath
            else
                -- there is a not a visible frame, launch one
                do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -n " & filepath
            end if
        on error
            -- daemon is not running, start the daemon and open a frame     
            do shell script "/Applications/Emacs.app/Contents/MacOS/Emacs --daemon"
            do shell script "/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c -n"
        end try
    end tell

    -- bring the visible frame to the front
    tell application "Emacs" to activate

    return input
end run

Связанный контент