Меню:


Для 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

blog comments powered by Disqus