Сегодня я собираюсь написать об одном расширении Emacs’а, которое способно изменить ваш распорядок жизни раз и навсегда.

Эта небольшая программа, написанная на EmacsLisp’е, называется org-mode. Она создана, чтобы сделать человеческую жизнь организованной, чтобы не растрачивать зря драгоценные секунды и минуты…​

Вы вольны использовать org-mode в качестве ежедневника, TODO-листа, планировщика проектов или для обычных заметок. Существуют уникумы, которые используют org-mode как табличный редактор, но сейчас я не планирую описывать как это делается.

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

Установка

Вначале нужно установить org-mode. Можно воспользоваться пакетным менеджером дистрибутива, если в репозиториях присутствует пакет с org-mode. А можно просто скачать исходники с сайта расширения (ссылка на него приведена в конце статьи) и скопировать все *.el файлы куда-нибудь в район ~/.emacs.d/elisp/org/. Потом нужно прописать следующие строки в ~/.emacs и перезапустить гхм, …​ текстовый редактор:

(setq load-path (cons "~/.emacs.d/elisp/org/" load-path))
(require 'org-install)
;Ассоциируем файлы с расширением *.org с org-mode
(add-to-list 'auto-mode-alist '("\\\\.org\\\\'" . org-mode))

Использование

Вначале парочка простых примеров…​

Откроем тестовый файл ~/test.org и добавим в его начало следующие строчки:

#+STARTUP:  showall
#+STARTUP: hidestars

Благодаря им, информация отображаемая org’ом в буфере Emacs’а будет более полной и красиво выглядящей.

Нужно убить и открыть буфер заново, чтобы изменения вступили в силу.

Теперь попробуем добавить в наш файл пару простых, многоуровневых списков. При помощи них можно отражать взаимосвязи между иерархическими задачами или чем-нибудь подобным…​

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

* первый уровень вложенности
** элемент второго уровня вложенности
** еще один
** и еще...
*** а это уже третий уровень

Благодаря директиве hidestars в начале файла, наши списки будут выглядеть вот так:

Multilevel lists
Многоуровневые списки

Составим список задач на день, на котором я буду дальше показывать различные фичи org-mode:

Test list

Как видно, элементы первого уровня не несут полезной информации, а выполняют лишь роль тегов. Поэтому …​ сделаем их тегами! Для этого надо добавить в начало org-файла следующую директиву:

#+TAGS: ОБРАЗОВАНИЕ(o) ПРОЕКТЫ(p) ДОМ(h)

…​и снова закрыть и открыть файл. Теперь можно удалить ненужные элементы первого уровня и добавить соответствующие теги элементам бывшего второго уровня.

Чтобы добавить тег (отмечу, что можно добавлять сразу несколько тегов) нужно остановить курсор на соответствующей строке и нажать комбинацию клавиш C-c C-c и затем нажать на клавишу, буква которой стоит в скобках у соответствующего тега (у нас это o, p или h). Должно получиться что-то вроде этого:

Tagged list

Перед обзором оставшихся возможностей org-mode необходимо добавить в ~/.emacs следующие полезные строчки:

(global-set-key "\e\el" 'org-store-link)
(global-set-key "\e\ec" 'org-capture)
(global-set-key "\e\ea" 'org-agenda)
(global-set-key "\e\eb" 'org-iswitchb)

(setq org-agenda-files (quote ("~/.org/")))

;my prefer identation
(setq org-startup-indented t)

;;logging stuff
(setq org-log-done (quote time))
(setq org-log-into-drawer nil)
(setq org-log-redeadline (quote note))
(setq org-log-reschedule (quote time))
;todo keywords
(setq org-todo-keywords
      (quote ((sequence "TODO(t!)" "NEXT(n!)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!/!)" "CANCELLED(c@/!)")
              (sequence "QUOTE(Q!)" "QUOTED(D!)" "|" "APPROVED(A@)" "EXPIRED(E@)" "REJECTED(R@)")
              (sequence "OPEN(O!)" "|" "CLOSED(C!)"))))

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

Вначале рассмотрим как можно задавать время. Для задачи (любого элемента любого уровня) можно задать как временной интервал, на который запланировано выполнение задачи, так и дедлайн, после которого задача обязательно должна быть выполнена. Для первого используется комбинация клавиш C-c C-s, а для второго C-c C-d. Других различий между этими сущностями больше нет.

По нажатию одной из вышеупомянутых комбинаций клавиш откроется окно с календарем и в минибуфер можно будет ввести временные значения или их интервалы.

Calendar

Чтобы задать время выполнения задачи достаточно ввести через двоеточие часы и минуты — в выделенном участке минибуфера (справа) отразится выбранное вами время. Если нужно указать день недели или число — вводите данные примерно в таком формате, как в правой части минибуфера. Временной интервал можно вводить через тире.

Enter подтверждает введенные данные и добавляет в описание задачи сроки ее выполнения или дедлайн.

Setting time
Задаем время выполнения
Setting interval
Задаем временной интервал
Setting time interval with another date
Задаем временной интервал вместе с другой датой

В результате, у нас должно получиться что-то вроде этого:

Result

Теперь перейдем к выставлению статусов для текущих дел.

Если внимательно посмотреть на участок лиспового кода выше, то можно заметить, что в нем уже содержатся статусы, осталось лишь научиться вставлять их в задачи.

Вставка происходит точно так же как и у тегов, лишь только сочетание клавиш другое — C-c C-t.

При вставке или изменении статуса запись об этом событии оказывается в логе задачи — я счел подобное поведение удобным для контроля за исполнением заданных временных интервалов. Если же это не нужно — можно удалить все строки вида *org-log* из конфига.

Вставив и поменяв некоторые статусы мы получим картину вида:

Result

К задачам еще можно добавлять заметки при помощи хоткея C-c C-z (сохранение введенной заметки по хоткею C-c C-c):

Notes

Как видно, при интенсивной смене статусов задач и использовании заметок содержимое org-файла чересчур разрастается и его становится трудно воспринимать на глаз. Чтобы избежать этого — удалите директиву showall в начале файла. Все дополнительные данные по задачам свернутся и развернуть их можно будет клавишей Tab, если конечно возникнет такая необходимость.

Сравните:

Source view
Изначальный вид
After showall delete
После удаления директивы showall

В org-mode удобно составлять отмечаемые чекбоксами списки, например списки покупок или приглашенных друзей. Список должен начинаться с символов - [ ], после которых идет пробел и сам текст элемента списка. Установка или снятие чекбокса на котором сейчас стоит курсор происходит с помощью комбинации клавиш C-c C-c.

Выглядит все это так:

Result

К списку с чекбоксами можно добавлять счетчики, которые показывают сколько чекбоксов уже было помечено. Есть два вида счетчиков — первый показывает соотношение между отмеченными чекбоксами и общим их количеством, а второй — то же соотношение, но уже в процентах. Для установки первого типа счетчиков нужно к описанию списка (которое уровнем выше) добавить символы [/], а для второго — [%]. Счетчики начнут считать только после того, как будет установлен или снят хотя бы один чекбокс.

All checkboxes set
One checkbox clear

Осталась без внимания еще одна часть org-mode, которая может удобно и красиво обрабатывать данные из org-файлов для представления их пользователю — agenda views. Данные могут браться как из открытого буфера с org-файлом, так и из некоторого каталога на диске (у меня это ~/.org), в который сложены все эти org-файлы (смотри в строчки для конфигурационного файла выше).

Для вызова списка доступных agenda views у меня используется сочетание клавиш Esc-Esc-a. О всех элементах данного списка я не расскажу, поскольку сам пользуюсь лишь двумя.

Первый — это распорядок на текущий день или неделю (agenda for current week or day). Отмеченные временными метками задачи выдергиваются из org-файлов, лежащих в каталоге ~/.org и выводятся в виде почасового расписания на текущую неделю.

Agenda for current week or day

Второй, используемый мною элемент — вывод "временной линии" (timeline for current buffer), но лишь для отдельного буфера с org-файлом, открытого в данный момент. Для нашего файла ~/test.org, это будет выглядеть так:

Timeline

emacs