Для Mac OS X существует специальный пакет Growl, позволяющий выводить оповещения пользователю в виде всплывающих окошек, что может быть часто полезным для различных видов уведомлений, например, о событиях org-mode.
После некоторого поиска, я нашел информацию о том, как можно достаточно просто реализовать оповещения, используя AppleSript интерфейс Growl. Реализация состоит из двух частей: сначала необходимо зарегистрировать приложение и типы уведомлений, которые оно может посылать, а затем уже отправлять эти уведомления.
Для регистрации приложения нам понадобится следующий скрипт, который объявляет типы уведомлений и регистрирует их и приложение в Growl:1
tell application "GrowlHelperApp" -- Объявить список типов уведомлений set the allNotificationsList to {"Emacs Notification"} -- Объявить список активных уведомлений. Если активированы не все -- то это можно сделать позже через панель настройки Growl set the enabledNotificationsList to {"Emacs Notification"} -- Зарегистрировать наше приложение в Growl. register as application "Aquamacs Emacs" all notifications allNotificationsList \ default notifications enabledNotificationsList \ icon of application "Aquamacs Emacs" end tell
Этот скрипт можно выполнить с помощью команды osascript
в командной строке, или ввести
этот текст в Script Editor
и выполнить оттуда. После регистрации, пользователь может
настроить внешний вид зарегистрированного уведомления, выбрав нужное приложение в разделе
Applications
панели настройки Growl в системных настройках Mac OS X.
После регистрации, пользователь может отправлять уведомления с помощью следующего скрипта, который и будет служить основой для нашего интерфейса уведомлений.
tell application "GrowlHelperApp" notify with name "Emacs Notification" title "Emacs alert" \ description "Message!!!" application name "Aquamacs Emacs" end tell
Этот скрипт также можно выполнять с помощью команды osascript
и он будет выводить
сообщение Message!!!
с заголовком Emacs alert
, но существует одна особенность, связанная с
тем, что AppleScript требует чтобы не-Latin1 символы были закодированы специальным
образом, так что нам придется добавить специальный код, который будет перекодировать
строки в формат, воспринимаемый AppleScript.
Для взаимодействия с AppleScript из Emacs можно было бы воспользоваться функцией
do-applescript
, но обнаружилось, что она неправильно обрабатывает многобайтовые символы «
и »
, которые нужны для указания текста в многобайтовой кодировке. Поэтому, пришлось
сначала формировать скрипт во временном файле, выполнять его с помощью osascript
и удалять
временный файл. Это делается с помощью следующей функции:
(defun output-to-growl (msg) (let ((fname (make-temp-file "/tmp/growlXXXXXX"))) (with-temp-file fname (setq coding-system-for-write 'utf-16) (insert (format "tell application \"GrowlHelperApp\" notify with name \"Emacs Notification\" title \"Emacs alert\" \ description «data utxt%s» as Unicode text \ application name \"Aquamacs Emacs\" end tell" (osd-text-to-utf-16-hex msg)))) (shell-command (format "osascript %s" fname)) (delete-file fname)))
Для правильного вывода строк, содержащих русские и другие не-Latin1 символы, AppleScript
требует, чтобы данные были указаны в кодировке UTF-16, и закодированы в виде строки data
utxtXXXXXX
, где utxtXXXXXXX
— шестнадцетеричные представления соответствующих байтов
строки в UTF-16. Для этого, была написана osd-text-to-utf-16-hex
функция, которая
вызывается из функции output-to-growl
:
(defun osd-text-to-utf-16-hex (text) (let* ((utext (encode-coding-string text 'utf-16)) (ltext (string-to-list utext))) (apply #'concat (mapcar (lambda (x) (format "%02x" x)) ltext))))
Вот и все. Теперь функцию output-to-growl
можно использовать из любого нужного места. Я
пользуюсь ею для получения уведомлений от org-mode.
1. Стоит отметить, что длинные строки разорваны с помощью знаков \
только для улучшения
читабельности, в скрипте они должны быть соединены вместе!
Last change: 05.03.2013 16:54