GNU EMACS для технических писателей
285 subscribers
11 photos
19 files
87 links
Настройка, использование, хаки
Download Telegram
display-fill-column-indicator-mode — встроенный режим, который отображает в буфере линию, показывающую достижение строкой предельного значения. На многих проектах есть жёсткие требования к длине строк, например, 80 или 120 знаков. В этом случае порядок действий такой:

1. Добавьте в init.el код активации display-fill-column-indicator-mode в нужных режимах:

(require 'display-fill-column-indicator)
(add-hook 'emacs-lisp-mode-hook 'display-fill-column-indicator-mode)
(add-hook 'yaml-mode-hook 'display-fill-column-indicator-mode)


2. Создайте в каталоге проекта файл .dir-locals.el, в котором укажите максимально допустимую длину строки:

((emacs-lisp-mode . ((fill-column . 80))
(yaml-mode . ((fill-column . 120)))))


Да, вы можете сделать нужные настройки и в init.el, используя функцию setq-local, но лучше всё-таки настраивать отдельно для каждого проекта.

Если вдруг вы захотите изменить значение fill-column "на лету":

1. Нажмите [C-x f].
2. Введите допустимую длину строки.
3. Нажмите [RET].

display-fill-column-indicator-mode это именно что индикатор, а не жёсткий ограничитель. Emacs не будет дробить ваши слишком длинные строки автоматически. Но в целом — этот режим может быть весьма полезен. Сам пользуюсь при работе с YAML, init.el ну и ещё в нескольких режимах, по необходимости.
👍41🔥1
Раньше мы настраивали y и n вместо yes и no так:

(defalias 'yes-or-no-p 'y-or-n-p)


Сейчас всё стало немного проще, достаточно присвоить настройке use-short-answers значение t:

(customize-set-variable 'use-short-answers t "y и n вместо yes и no")
👍3
Вы не просили, но я вам покажу начало своего init.el:


(custom-set-variables
'(compilation-scroll-output t "Автоматическая прокрутка буфера *compilation*")
'(create-lockfiles nil "Не создавать lock-файлы")
'(cursor-type 'bar "Курсор в виде вертикальной черты")
'(default-input-method "russian-computer" "Метод ввода по умолчанию")
'(default-transient-input-method "russian-computer")
'(delete-by-moving-to-trash t "Удалять файлы в Корзину")
'(gc-cons-threshold (* 50 1000 1000) "Увеличить размер памяти для сборщика мусора")
'(indent-tabs-mode nil "Отключить `indent-tabs-mode'.")
'(inhibit-startup-screen t "Не показывать приветственный экран")
'(initial-scratch-message nil "Пустой буфер *scratch*")
'(load-prefer-newer t "Если есть файл elc, но el новее, загрузить el-файл.")
'(read-file-name-completion-ignore-case t "Игнорировать регистр при вводе имён файлов")
'(ring-bell-function 'ignore "Отключить звуковое сопровождение событий")
'(save-place-forget-unreadable-files t "Если файл нельзя открыть, то и помнить о нём ничего не надо")
'(scroll-bar-mode nil "Отключить полосы прокрутки")
'(scroll-conservatively 101 "TODO: проверить что это такое")
'(scroll-margin 4 "Отступ от верхней и нижней границ буфера")
'(show-trailing-whitespace t "Подсветка висячих пробелов")
'(standard-indent 4 "Отступ по умолчанию")
'(tab-always-indent 'complete "Если можно — выровнять текст, иначе — автодополнение.")
'(truncate-lines 1 "Обрезать длинные строки")
'(use-dialog-box nil "Диалоговые окна ОС не нужны")
'(use-short-answers t "Краткие ответы вместо длинных")
'(user-full-name "Dunaevsky Maxim" "Имя пользователя")
'(user-mail-address "dunmaksim@yandex.ru" "Адрес электронной почты")
'(vc-follow-symlinks t "Переходить по ссылкам без лишних вопросов")
'(visible-bell t "Мигать буфером при переходе в него"))
👍2
Если вы используете Emacs в режиме сервера, то он может загрузиться как до SSH Agent, так и после (так называемое неопределённое поведение). В первом случае пакеты, использующие SSH, будут каждый раз требовать у вас пароли от приватных ключей. Ну, например, Magit будет просить ввести пароль ключа при каждом git push (вы же работаете с репозиториями через SSH, верно?). Чтобы такого не было, нужно немного поменять параметры службы emacs.service.

1. Откройте файл ~/.config/systemd/user/emacs.service.
2. Приведите его к такому виду:

[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/

[Service]
Type=notify
ExecStart=/usr/bin/emacs --fg-daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"

# Emacs will exit with status 15 after having received SIGTERM, which
# is the default "KillSignal" value systemd uses to stop services.
SuccessExitStatus=15

# The location of the SSH auth socket varies by distribution, and some
# set it from PAM, so don't override by default.
Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure
TimeoutSec=600

[Install]
WantedBy=default.target


3. Перезапустите сервер Emacs:

systemctl --user restart emacs.service


С этой секунды Emacs и SSH Agent — друзья на век, и пароли от ключей у вас никто спрашивать не будет.
Настройки в Emacs условно можно разделить на 2 уровня: настройки пакетов и настройки ядра. Отличие в том, что настройки пакетов, даже встроенных, описаны в файлах .el. При необходимости можно обратиться к этим файлам и почитать описание "из первых рук". Также можно использовать команду describe-variable:

1. [C-h v].
2. Введите название настройки.
3. [RET]. В открывшемся буфере будет описание.

Для некоторых настроек (настроек ядра) эта команда работать не будет, если Emacs не будет знать, где лежит его исходный код. В этом случае делайте так:

0. Выясните версию Emacs, которым пользуетесь: [M-x emacs-version RET].
1. Идите на сервер GNU.
2. Загрузите архив с исходным кодом используемой версии Emacs.
3. Распакуйте архив в нужный каталог. Если у вас DEB-based дистрибутив, рекомендую разместить исходный код в каталоге /usr/share/emacs/<версия>/src/. По умолчанию Emacs ищет свой исходный код там. Если не найдёт — добавьте в init.el код, задающий значение настройки source-directory:


;; Определение пути к каталогу с исходным кодом
(when (string-equal system-type "gnu/linux")
(message "Используется ОС на базе GNU/Linux")
(defvar init-el-emacs-source-path "Путь к каталогу с исходным кодом Emacs")
(setq init-el-emacs-source-path
(format "/usr/share/emacs/%d.%d/src/"
emacs-major-version
emacs-minor-version))
(if (file-exists-p init-el-emacs-source-path)
;; Каталог существует
(if (directory-empty-p init-el-emacs-source-path)
;; Каталог пуст
(message (format "Каталог %s пуст." init-el-emacs-source-path))
;; Каталог не пуст
(progn
(customize-set-variable 'source-directory init-el-emacs-source-path)
(message (format "Исходный код обнаружен в каталоге %s" init-el-emacs-source-path))))
;; Каталог не существует
(message (format "Каталог %s не существует." init-el-emacs-source-path))))


4. Попробуйте получить описание настройки use-short-answers. Теперь вместо сообщения о том, что исходный код не найден, Emacs выведет красивую справку:

use-short-answers is a variable defined in ‘src/fns.c’.

Its value is t
Original value was nil

Non-nil means ‘yes-or-no-p’ uses shorter answers "y" or "n".
When non-nil, ‘yes-or-no-p’ will use ‘y-or-n-p’ to read the answer.
We recommend against setting this variable non-nil, because ‘yes-or-no-p’
is intended to be used when users are expected not to respond too
quickly, but to take their time and perhaps think about the answer.
The same variable also affects the function ‘read-answer’.

This variable was introduced, or its default value was changed, in
version 28.1 of Emacs.
You can customize this variable.

[back]


Обратите внимание на то, что эта настройка хранится в файле с расширением .c, а не .el, то есть является частью ядра.
🔥1
Как часто вы используете регулярные выражения?
Anonymous Poll
21%
Каждый день
15%
1-2 раза в неделю
36%
1-2 раза в месяц
27%
Каво?
gnu-emacs-for-technical-writers-v24.10.pdf
3.3 MB
Вот старая версия книги. А в новой, которая скоро будет выложена на Boosty, добавлю раздел про регулярные выражения.
👍6
Загадка на эти выходные: что делают эти две команды?

1.

find ./ -name "*.<ext>" -exec grep -e "[A-Za-z][А-Яа-яЁё]" {} \;


2.

find ./ -name "*.<ext>" -exec grep -e "[А-Яа-яЁё][A-Za-z]" {} \;


Вместо <ext> подставьте расширение файлов, в которых хранится код ваших проектов: md для Markdown, rst для ReStructured Text, adoc для AsciiDoc, tex для LaTeX и так далее.
👍1
Теперь ответ на приведённую выше задачу.

Утилита find используется для поиска файлов. В данном случае выполняется поиск по части имени.
Найденные файлы передаются в утилиту grep, которая выполняет поиск нужной строки. Только вместо строки у нас регулярное выражение, которое в первом случае означает "Найди места, где после символов латиницы идут символы кириллицы", а во втором случае — наоборот, "Найди места, где сначала идёт кириллица, а потом латиница".

При желании можно объединить эти две команды в одну, подправив регулярное выражение. Однако, при этом пострадает простота понимания. Регулярные выражения сложны сами по себе, поэтому не усложняйте их без веской причины.
👍1
Команда find-grep в Emacs запускает утилиту find, её вывод перенаправляет в grep, а его вывод отображает в буфере. По умолчанию команда find запускается с такими аргументами:

find . -type f -exec grep


Эта запись означает следующее: искать только файлы (не каталоги и не символические ссылки), начиная с текущего каталога, а найденное передавать в grep.

Что там разбирает grep пока опустим. Лучше подкрутим аргументы find. Вряд ли вы хотите, чтобы утилита искала совпадения во всех файлах проекта, поэтому давайте добавим аргумент -name, например:

find . -type f -name "*.rst" -exec grep


#find #grep #поиск
👍4
На выходных поработал с интерпретатором Python в интерактивном режиме. VIM опять никому не нужен, а вот сочетания Emacs вполне себе работают: [C-a], [C-e], [M-f], [M-b], [C-f], [C-b] и ещё некоторые. Возможно, даже стоит написать статью на Хабр, где рассказать, что сочетания из Emacs можно использовать в Python и GNOME Terminal, а сочетания из VIM только в самом VIM.
👍1
По мотивам поста про бесячий автокомплит просто выложу свой код настройки company-mode:

;; 📦 COMPANY-MODE
;; https://company-mode.github.io/
;; Автодополнение
(use-package company
:ensure t
:init
(unless (package-installed-p 'company)
(package-vc-install '(company
:url "https://github.com/company-mode/company-mode.git"
:branch "1.0.2")))
:delight ""
:demand t
:custom
(company-idle-delay 0.5 "Задержка вывода подсказки — полсекунды")
(company-minimum-prefix-length 2 "Минимум 2 знака, чтобы company начала работать")
(company-show-quick-access t "Показывать номера возле потенциальных кандидатов")
(company-tooltip-align-annotations t "Выровнять текст подсказки по правому краю")
(company-tooltip-limit 15 "Ограничение на число подсказок")
:hook ((adoc-mode
css-mode
dockerfile-mode
emacs-lisp-mode
html-mode
latex-mode
lisp-data-mode
minibufer-mode
nxml-mode
org-mode
python-mode
rst-mode
ruby-mode
web-mode
) . company-mode)
:bind
(:map company-active-map
("TAB" . company-complete-common-or-cycle)
("M-/" . company-complete)
("M-." . company-show-location)))


Теперь описание.

1. Если пакет не установлен, package-vc-install сделает это, при чём поставит фиксированную версию 1.0.2, а не нестабильную из MELPA.
2. В строке состояния ничего не выводится. Для этого я использую Delight. Код установки и инициализации в моём init.el размещается выше.
3. Пакет company загружается не сразу, а в фоне. Прямо после запуска он мне не нужен, поэтому :demand t.
4. Настройки — самое интересное. То, о чём написано в ОП-посте, решается через правку company-idle-delay и, при необходимости, company-minimum-prefix-length.
5. Всё остальное уже вкусовщина, настраивайте по своему усмотрению.
👍1🔥1
Главная проблема 9 каналов из 10, касающихся Emacs, заключается в том, что там обсуждают не Emacs. org-mode, DooM Emacs, Emacs Prelude, Evil, ошибки при работе фрагментов кода, взятых со StackOverflow, и хорошо если не из вопроса, а из ответов...
По возможности избегайте чтения таких каналов: может сложиться впечатление, что Emacs состоит из одних только проблем.
👌7🙈3
Если вы до сих пор не используете Counsel, то самое время попробовать:


;; 📦 COUNSEL
;; https://elpa.gnu.org/packages/counsel.html
;; Автодополнение на основе Ivy
(use-package counsel
:ensure t
:bind
(:map global-map
("M-x" . counsel-M-x)
("C-x C-f" . counsel-find-file)
("M-y" . counsel-yank-pop)
("C-h f" . counsel-describe-function)
("C-h v" . counsel-describe-variable)
("C-h l" . counsel-find-library)
("C-c c" . counsel-compile)
("C-c g" . counsel-git)
("C-x 8 RET" . counsel-unicode-char)))


В Counsel встроено множество команд, заменяющих собой стандартные команды. Главное удобство заключается в поиске. Например, counsel-M-x фильтрует записи по регулярному выражению прямо во время ввода команды!

Если вы ранее настроили Helm, не забудьте отключить часть его функций, чтобы не было конфликтов.

#counsel
Пакет colorful-mode.el обновился до стабильной версии 1.1.0. Он используется для отображения цветов в буферах. Если вы часто работаете с CSS или HTML-кодом, то вам этот пакет будет полезен тем, что фон строки с кодом цвета типа #FF2200 будет иметь именно этот оттенок красного! Также пакет распознаёт коды типа cyan, red, black и тому подобное.
Техписам тоже будет полезен при настройке тем AsciiDoc или Sphinx.


;; 📦 COLORFUL-MODE
;; https://github.com/DevelopmentCool2449/colorful-mode
;; Отображение цветов прямо в буфере. Наследник `raibow-mode.el'.
(use-package colorful-mode
:ensure t
:hook ((css-mode
emacs-lisp-mode
web-mode) . colorful-mode))


https://github.com/DevelopmentCool2449/colorful-mode
CSS-файл с активным colorful-mode.
👍4
А вы знали, что для ReStructured Text и Sphinx существует LSP-сервер? А он есть и называется Esbonio. Сегодня мне удалось его настроить вопреки инструкциям с сайта разработчиков, поэтому в ближайшем обновлении книги на Boosty будет целая глава про это. Всем остальным придётся ждать 3 месяца 😊
hl-line.el — это встроенный пакет. Всё, что он делает — подсвечивает активную строку. Конечно, у нас есть Pulsar и Beacon, но hl-line-mode не конфликтует с ними, а образует симбиоз. Единственное, что могу посоветовать — выбирайте тему оформления так, чтобы в ней подсвеченная строка нормально читалась. Например, в doom-monokai-pro приходилось напрягать глаза, зато в ef-autumn всё в порядке.

(require 'hl-line)
(global-hl-line-mode 1)


Впрочем, с use-package тоже можно:

(use-package hl-line
:config (global-hl-line-mode 1))
👍2