четверг, 22 апреля 2010 г.

Гестуры в xwem

Совсем забыл про классную фукнциональность в xwem — гестуры aka strokes. Это когда рисуешь что-нибудь на экране, а у тебя выполняется какая-нибудь команда. В родном (S)XEmacs есть поддержка, но она конечно далека от идела с точки зрения пользовательского интерфейса, зато дало нужную функциональность для реализации гестур в xwem.

Вот список гестур, которыми я пользуюсь:

global strokes

Глобальные гестуры

xemacs strokes

Гестуры локальные для xemacs фреймов

gv strokes

Гестуры локальные для ghostview приложений

opera strokes

Гестуры локальные для бравзера opera

firefox strokes

Гестуры локальные для бравзера firefox

Скачать эти гестуры можно тут.

Как видно из скринов, гестуры в xwem достаточно прокаченные: они могут запускать команды, произвольные e-lisp выражения, эмулировать нажатия кнопок, а также вводить в текущее приложение всякие строки (на скринах нет такого варианта гестуры).

суббота, 3 апреля 2010 г.

SXEmacs живёт

После некоторого затишья проект SXEmacs продолжил развитие. Появились merge-requestы и что-то всё таки делается. Залили мои патчи к FFI, которые реализуют новый тип safe-string в помощь дядьке, который пишет FFI к libdbus. Так же в Wand-mode я добавил поддержку модного liquid scale, кто не знает, то это выглядит вот так

Кстати, я наконец-то придумал как можно использовать wand-button в стандартном customize!

воскресенье, 7 февраля 2010 г.

Интеграция SXEmacs с Mac OS

Немного сомневаюсь, хочу посоветоваться с пользователями GNU Emacs под Mac OS. Есть идея и возможность реализовать в SXEmacs FFI к libobjc. Только не очень представляю как его потом можно полезно использовать.

Вообще я хочу сделать чтобы эпловский multitouch мог работать в SXEmacs (конкретно в Wand-mode). Я не представляю как реализован multitouch и что нужно для того, чтобы он работал. Просветите пожалуйста если кто в курсе.

Ещё хотел бы посоветоваться какая именно интеграция с Mac OS была бы полезна в Emacs? Мне пока на ум приходит только использование нативных виджетов для M-x customize RET, чтобы выглядело как настройки у других приложений под Mac OS. Само собой ещё growl и голос.

Ещё хотелось бы, чтобы Slife.app каким-нибудь образом брал данные из запущенного Emacs (потому что отчёты Slife.app типа "95% времени работает приложение X11.app" меня как-то не возбуждают), но как это сделать вообще без понятия.

Если наработается хоть пусть и небольшая интеграция с Mac OS, то это будет очень большим подспорьем для привлечения нужных людей (возможно даже из проекта GNU Emacs ;))) к реализации нативного redisplay в SXEmacs под Mac OS.

среда, 16 декабря 2009 г.

Генератор кнопок

В (S)XEmacs есть классный package, называется xpm-button.el. Он умеет на лету генерировать картинку с кнопкой. Всё вроде бы хорошо, но «красота» сгенерированных кнопок повергает в уныние. Решил написать достаточно гибкий генератор красивых кнопок используя Wand-mode. По мере написания генератора, добавлял необходимый функционал в Wand-mode. Вот что в итоге получилось:

(wand-button 150 32 "Wand Button"
             :bg "cornflowerblue" :fg "white"
             :round 8.0 :depth 1 :yoff 8 ; :type 'pressed
             :wand-font (make-wand-font :family "Zapfino"))

button1

(wand-button 100 20 "Wand Button"
             :bg "gray80" :fg "black" :round 10.0
             :contrast 0.5 :depth 2 ; :type 'pressed
             :wand-font (make-wand-font :family "Copperplate"))

button2

(wand-button 100 40 (encode-coding-string "привет" 'utf-8)
             :bg "palegreen" :fg "green" :round 0.0
             :depth 4 :yoff -2 ; :type 'pressed
             :wand-font (make-wand-font :family "Arial Black"
                                        :size 20))

button2

Интересно будет этот функционал внедрить в Emacs widgets, а то кнопки там сделаны через очень большую задницу.

ReST source Скачать оригинал

пятница, 27 ноября 2009 г.

Wand-mode - новые возможности

Wand-mode развивается, с тех пор как я сделал описание, было добавлено несколько интересных возможностей. Их я и опишу.

Имя файла в имени буфера

Откроем какую-нибудь картинку: C-x C-f lg-tree.jpg RET, получаем примерно следующее:

orig image

Замечаем, что в mode-line отображается имя буфера, которое теперь содержит имя оригинального файла. Удобно при переключении с помощью C-x C-b.

Новая операция: modulate

Фотка сама по себе классная, но природа выглядит как-то уныло, немного приукрасим, с помощью команды o modulate RET saturation RET 60 RET, получим результат:

sat inc 60 percents

60% increased saturation

Уже намного лучше.

Поддержка IPTC профиля

Хочется добавить информацию о том, что это там на фотке. Воспользуемся редактором IPTC профиля. Добавим IPTC теги с помощью p caption RET lg climbes trees RET и p keywords RET js-kit, corporative RET, получим:

caption and keywords added

Caption and Keywords added

Pixel color picker

Интересно какого цвета у меня трусы, кликнем на них и увидим:

pixel color picker

Pixel color picker

Видим координаты пикселя, по которому мы кликнули, его цвет и разложение по RGB. Удобно.

Глобальные операции

Иногда нужно просмотреть несколько картинок применяя конкретный набор операций, например увеличение. Для этого теперь есть команда фиксирования операций, по умолчанию висит на O, нажмём её и перейдём к следующей картинке в директории с помощью SPC:

global operations

Global operations applied

Видим список глобальных операций, а также замечаем, что они были автоматически применены к картинке. Однако для этой картинки увеличение saturation не подходит. Отменим с помощью undo (C-/):

operations canceled

Operations canceled

Чтобы сбросить глобальные операции нужно нажать C-u O.

Редактор свойств изображения

Иногда нужно подправить EXIF данные у изображения. Лично я не пользуюсь этой возможностью (мне хватает IPTC профиля), но есть один знакомый фотограф, который попросил эту функциональность в Wand-mode. Мне не сложно за пару пива. Вызвать редактор можно с помощью кнопки e. Он отфильтрует свойства согласно переменной Wand-mode-properties-pattern ("^exif:" по умолчанию).

Новая операция: grayscale

Существует множество методик преобразования картинки в чёрно-белую. Один из них, например, полностью удалить saturation с помощью o modulate RET saturation RET -100 RET, что часто приводит к желаемому результату. Всё же была добавлена возможность поменять colormap на grayscale — o grayscale RET

Новая операция: fit to size

Иногда нужно изменить размеры изображения, чтобы она влазила в определённый размер. Теперь это можно сделать с помощью o fit to size RET. Эта операция запросит ширину, высоту и сохраняя соотношение сторон изменит размер. Есть также пользовательская переменная Wand-mode-scaler, которая отвечает за то, какой преобразователь будет использован. Вы можете создавать свои собственные преобразователи с помощью Wand-make-scaler; неплохой настройкой может быть:

(setq Wand-mode-scaler (Wand-make-scaler :GaussianFilter 1))

Документация к Wand-mode-scaler и Wand-make-scaler содержит исчерпывающую информацию о преобразователях.

ReST source Скачать оригинал

четверг, 12 ноября 2009 г.

Судоку для (S)XEmacs

Не спалось как-то ночью и мягкой подруги не было под рукой. Решил поиграть во что-нибудь. Тетрис слишком активный, сокобан уже прошёл весь, World of Goo перегревает комп — решил погонять в судоку. Зашёл на websudoku.com и начал играть, всё бы хорошо, но это не в SXEmacs и недоступно offline. Решил написать sudoku.el для игры в судоку под SXEmacs. Поискал в инете и нашёл sudoku.el для (X)Emacs. Скачал, запустил и не обрадовался, посмотрел код — вообще расстроился. В итоге ночь провёл за переписыванием sudoku.el, чтобы удовлетворить свои нужды, а именно:

  • Удобный, красивый и информативный интерфейс
  • Возможность скачивания судок с websudoku.com и menneske.no
  • Возможность печати судок
  • Возможность редактирования судок
  • Возможность сохранения/загрузки судок
  • Наличие карандашей для сложных техник и экспериментов
  • Возможность решать только реально сложные задачи, т.е. авто-заполнение (полу)очевидных полей

Пример

Запускаем M-x sudoku RET:

sudoku-mode

Сразу видим кучу очевидных полей для заполнения, например, R5C5 (где курсор) и понятно дело лениво их все заполнять, поэтому нажимаем a, получаем:

autoinsert

Теперь действительно сложная задача, но сразу видно интересность значения 4, поэтому берём карандаш1p (от pencil) и применяем технику Nishio начиная с R8C9, получаем:

pencil
  1. R8C9 -> 4 (начало Nishio)
  2. R2C3 -> 4 (единственное место в C3 где может быть 4)
  3. R3C7 -> 4 (единственное место в R1 где может быть 4)
  4. в восьмом квадрате некуда ставить 4

то есть в R8C9 не может стоять 4. C-u p и отменяем карандаш. Теперь мы знаем, что 4 стоит в R2C9:

won

Хорошая судочка, пожалуй сыну подойдёт, распечатаем её нажав P, на бумаге это выглядит вот так:

printed

Скачать

Скачать можно с http://lgarc.narod.ru/xemacs/sudoku.el

Замечания, баги, фиксы присылайте на lg AT sxemacs.org


1В режиме карандаша авто-заполнение отключается

ReST source Скачать оригинал

среда, 30 сентября 2009 г.

Говорящий SXEmacs

Баловался тут давеча с разными способами более тесной интеграции SXEmacs с Mac OS. Сделал (а точнее стащил из GNU Emacs) интересную функцию, с помощью которой можно запускать различные сценарии AppleScript:

(defun do-applescript (&rest script-lines)
  (let ((script (mapconcat 'identity script-lines "\n"))
        start cmd return)
    (while (string-match "\n" script)
      (setq script (replace-match "\r" t t script)))
    (while (string-match "\"" script start)
      (setq start (+ 2 (match-beginning 0))
            script (replace-match "\\\"" t t script)))
    (setq cmd (concat "osascript -e \"\"\"" script "\"\"\""))
    (setq return (shell-command-to-string cmd))
    (concat "\"" return "\"")))

Применения этой процедуры очевидны. Например можно заставить Growl отображать сообщения SXEmacs:

(defun growl (title message)
  (do-applescript
   "tell application \"GrowlHelperApp\""
   (format "notify with name \"SXEmacs Notification\" title %S description %S application name \"SXEmacs\" image from location \"file:///opt/local/share/sxemacs-22.1.10/etc/sxemacs-icon.png\"" title message)
   "end tell"))

Но, что более интересно, можно научить SXEmacs разговаривать, используя VoiceOver!

(defvar lg-say-voices
  '((agnes . "Agnes") (albert . "Albert") (alex . "Alex")
    (badnews . "BadNews") (bahh . "Bahh") (bells . "Bells")
    (boing . "Boing") (bruce . "Bruce") (bubbles . "Bubbles")
    (cellos . "Cellos") (deranged . "Deranged") (fred . "Fred")
    (goodnews . "GoodNews") (hysterical . "Hysterical") (junior . "Junior")
    (kathy . "Kathy") (organ . "Organ") (princess . "Princess")
    (ralph . "Ralph") (trinoids . "Trinoids") (vicki . "Vicki")
    (victoria . "Victoria") (whisper . "Whisper") (zarvox . "Zarvox")))

(defun lg-say-the-text (text &optional voice)
  (let* ((sv (cdr (assq voice lg-say-voices)))
         (svoice (if sv (format " using %S" sv) ""))
         ;; " -> ' in order to avoid osascript confusion
         (nt (replace-in-string text "\"" "'")))
    (do-applescript (format "say %S%s" nt svoice))
    (growl "Text via VoiceOver" "Done!")))

(defun lg-say-region-or-buffer (arg)
  "Say contents of the buffer or region.
If prefix ARG is specified then use custom voice."
  (interactive "P")
  (let ((voice (and current-prefix-arg
                    (intern
                     (completing-read "Voice: "
                      (mapcar #'(lambda (v)
                                  (list (symbol-name (car v))))
                              lg-say-voices)
                      nil t))))
        (text (if (region-active-p)
                  (buffer-substring (region-beginning) (region-end))
                (buffer-substring))))
    (lg-say-the-text text voice)))

(define-key global-map (kbd "C-c s") 'lg-say-region-or-buffer)

Далее, можно например реализовать процедуру, которая будет читать тело письма в gnus:

(defun lg-gnus-say-article-body ()
  "Say body of the current gnus article."
  (interactive)
  (let ((atxt (with-current-buffer gnus-article-buffer
                (save-restriction
                  (article-goto-body)
                  (buffer-substring (point) (point-max))))))
    (lg-say-the-text atxt)))

Единственная проблема с данной реализацией это то, что SXEmacs блокирует во время выполнения сценария AppleScript. Нужно расширить процедуру do-applescript, чтобы она поддерживала параметр IN-BACKGROUND.

ReST source Скачать оригинал