23 мая 2007 г.

Tip #2. Быстрое переключение между буферами

Обычно в Emacs'e переключение между буферами производится с помощью сочетания клавиш C-x b, или путем выбора нужного буфера в меню. Однако, при работе с большим количеством файлов, эти методы не совсем удобны. Поэтому, были разработаны пакеты для более удобного переключения между буферами в Emacs'e. Один из таких пакетов - iswitchb, который показывает список буферов, которые соответствуют тому тексту, который вы набираете. Список буферов меняется по мере набора слова или его части, к тому же вы можете набирать любую часть слова, что особенно полезно, если вы имеете много файлов начинающихся с одного префикса. В остальном, iswitchb полностью заменяет стандартные механизмы Emacs. Данный пакет идет в поставке Emacs 22 (текущий CVS), а для предыдуших версий, его можно скачать с emacs-wiki. Настройка пакета тоже проста - надо лишь поместить следующие строки в файл инициализации:
(require 'iswitchb)
(iswitchb-mode 1)
Для того, чтобы не отображались некоторые буфера, их имена можно поместить в список игнорирования, который хранится в переменной iswitchb-buffer-ignore. Вот, например, минимальный список таких буферов:
(add-to-list 'iswitchb-buffer-ignore "*Messages*")
(add-to-list 'iswitchb-buffer-ignore "*Backtrace")
(add-to-list 'iswitchb-buffer-ignore "*Quail Com")
(add-to-list 'iswitchb-buffer-ignore "*Buffer")
(add-to-list 'iswitchb-buffer-ignore "*fsm-debug")
(add-to-list 'iswitchb-buffer-ignore "*Completions")
(add-to-list 'iswitchb-buffer-ignore "^[tT][aA][gG][sS]$")
Для того, чтобы обеспечить кэширование информации, можно использовать пакет filecache, который умеет интегрироваться с iswitchb. Этот пакет также идет в составе Emacs 22. Для его использования поместите в .emacs следующие строки:
(require 'filecache)
(load "iswitchb-fc")
Про другие пакеты, обеспечивающие подобную функциональность, вы можете почитать на Emacs WiKi - в разделе про iswitchb, есть ссылки на них

18 мая 2007 г.

Tip #1

Преамбула

Иногда, находясъ в какой-нибудь функции, требуется быстро перейти на предыдущую или последующую объявленную функцию в коде. Использовать для этого способ, описанный в Tip #0, мне показалось, немного накладно: для этого нужно вызвать команду my-show-functions-list, перейти в буфер *Occur* и выбрать нужную функцию. Гораздо удобнее было бы "скакать" по объявлениям функций, используя определённые клавишные комбинации, оставаясь при этом в текущем буфере.

Задача

Удобное и быстрое перемещение между функциями в текущем буфере, без использования буфера *Occur*.

Решение

Для решения задачи нам потребуются стандартные команды Emacs search-forward-regexp и search-backward-regexp. Как можно догадаться из названий, эти две команды позволяют осуществлять поиск по регулярному выражению в текущем буфере. В качестве аргумента для поиска, мы будем использовать регулярное выражение из Tip #0. Нам также потребуется создать две новые функции с названием my-jump-to-function-forward и my-jump-to-function-backward.

Функции my-jump-to-function-forward и my-jump-to-function-backward

Взяв за основу функцию my-show-functions-list из Tip #0, получаем следуюший Emacs lisp код:


(defun my-jump-to-function-forward()
  (interactive)
  (search-forward-regexp
   "^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)"
   ))

(defun my-jump-to-function-backward()
  (interactive)
  (search-backward-regexp
   "^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)"
   ))

Теперь осталось назначить клавишные комбинации. Для себя я выбрал ^N и ^P.


(global-set-key [(control n)] 'my-jump-to-function-forward)
(global-set-key [(control p)] 'my-jump-to-function-backward)

Всё. Можно наслаждаться быстрыми "прыжками" между функциями, оставаясь при этом в текущем буфере.

17 мая 2007 г.

Tip #0

Задача

Удобное и быстрое перемещение между функциями в текущем буфере.

Решение

В Emacs есть дико полезная команда list-matching-lines. Эта команда принимает, в качестве аргумента, регулярное выражение и возвращает обратно найденые совпадения, в виде списка в отдельный буфер *Occur*. Вот её-то мы и будем использовать для решения задачи.

Подбираем регулярное выражение

Так как я в основом работаю с PHP и Python, то регулярное выражение будет составлено с учётом только этих двух языков.


^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)

Конечно, вся эта бодяга выглядет немного коряво, можно сделать гораздо изящнее. Но это было первое, что пришло мне в голову и оно работает:)

Функция my-show-functions-list

Создав и проверив регулярное выражение, можно заняться созданием специальной функции с последующим размещением её в .emacs (конфигурационный файл редактора). Функцию я обозвал my-show-functions-list. Если вы создаёте новую функцию для Еmacs, советую придумать какой-нибудь префикс (у меня это "my-") и всегда использовать его в начале имени вашей новой функции. Это позволит в дальнейшем удобно отделять ваши собственные команды от стандартных команд Еmacs.


(defun my-show-functions-list()
  (interactive)
  (list-matching-lines "^\t+\\(function\\|public function\\|protected function\\|private function\\|public static\\|protected static\\|private static\\|def\\)"))

Теперь осталось прописать комбинацию клавиш для быстрого вызова нашей новой команды. Я это дело повесил на ^F11 (Control + F11).


(global-set-key [C-f11] 'my-show-functions-list)

Вот собственно и всё. Теперь нужно перегрузить Emacs и открыть какой-нибудь *.php или *.py файл с некоторым кол-вом функций для проверки того, что у нас получилось. При нажатии ^F11 будет открыто новое окно с буфером *Occur*, в котором приведён список всех объявленных в файле функций. Перейдя в буффер *Occur* и выбрав из списка, посредством клавиши Return нужную функцию, вы, тем самым, переместите курсор на строку с объявлением той самой функции в вашем файле.