На Tech Writer Days 2 ни одного доклада про Emacs. Но если бы он был, вы бы пошли?
Anonymous Poll
63%
Да
38%
Нет
Пакет Counsel делает очень простую вещь: ускоряет выбор из списков. Он не заменяет собой Ivy, а работает на его основе.
Допустим, как работает обычная команда
Counsel предоставляет замену стандартной команде —
Попробуем найти все команды со словом
1. [M-x counsel-M-x RET].
2. Удалите
3. Введите слово
Обратите внимание на то, сколько ещё возможных вариантов предлагает Emacs. В моём случае всего 47 команд, содержащих слово "compile" в своём названии.
Перемещение между записями классическое — [C-n], [C-p].
В Counsel есть не только
Допустим, как работает обычная команда
[M-x]
? Вы вводите название команды, помогая себе с помощью [TAB]. То есть вам нужно знать с какого слова начинается название нужной команды.Counsel предоставляет замену стандартной команде —
counsel-M-x
. Эта команда использует регулярные выражения для фильтрации записей. А это значит, что вы не обязаны знать с каких слов начинается название нужной команды: достаточно помнить хотя бы одну из частей, а Counsel сделает всё остальное.Попробуем найти все команды со словом
compile
в названии:1. [M-x counsel-M-x RET].
2. Удалите
^
, т. к. этот символ в регулярных выражениях означает "начало строки". Другими словами, пока ^
находится в начале строки, Counsel интерпретирует команды так: "найди всё, что начинается с указанной строки", т. е. реализует обычное поведение Emacs.3. Введите слово
compile
.Обратите внимание на то, сколько ещё возможных вариантов предлагает Emacs. В моём случае всего 47 команд, содержащих слово "compile" в своём названии.
Перемещение между записями классическое — [C-n], [C-p].
В Counsel есть не только
counsel-M-x
, но и другие команды. Рекомендую:;; 📦 COUNSEL
;; https://elpa.gnu.org/packages/counsel.html
;; Автодополнение на основе Ivy
(use-package counsel
:ensure t
:bind
(:map global-map
("C-c c" . counsel-compile)
("C-c g" . counsel-git)
("C-h f" . counsel-describe-function)
("C-h l" . counsel-find-library)
("C-h v" . counsel-describe-variable)
("C-x 8 RET" . counsel-unicode-char)
("C-x C-f" . counsel-find-file)
("M-x" . counsel-M-x)
("M-y" . counsel-yank-pop)))
👍8
Кто давно читает этот канал, обратил внимание, что я вставляю в код символ 📦, а в книге можно увидеть такую конструкцию:
Это небольшая хитрость, которую я подсмотрел у кого-то из активных пользователей Emacs: то ли Bozhidar Batsov, то ли Protesilaos Stavrou, уже не помню. Этот маркер не является частью синтаксиса и ни на что не влияет. Зато он позволяет быстро найти нужную настройку в
1. Нажмите [M-s o].
2. Введите 📦 или
3. Нажмите [RET].
В буфере
-->
. К чему это всё?Это небольшая хитрость, которую я подсмотрел у кого-то из активных пользователей Emacs: то ли Bozhidar Batsov, то ли Protesilaos Stavrou, уже не помню. Этот маркер не является частью синтаксиса и ни на что не влияет. Зато он позволяет быстро найти нужную настройку в
init.el
.1. Нажмите [M-s o].
2. Введите 📦 или
-->
(смотря чем вы пользуетесь).3. Нажмите [RET].
В буфере
*Occur*
вы увидите все нужные строки. Если вы переключитесь на этот буфер [C-x o], то сможете быстро перейти к нужной настройке.А некоторые комментарии ещё как часть синтаксиса и имеют особое значение! Я про то, что написано в книге в главе "File Local Variables".
Допустим, у вас есть файл на Python, и вы хотите для переменной
При открытии файла Emacs извлечёт значение этой переменной из комментария и задаст настройке указанное значение.
Лучший способ добавлять такие комментарии — использовать команду
Допустим, у вас есть файл на Python, и вы хотите для переменной
fill-column
(переменной Emacs!) задать значение 120
. Добавьте в конец файла такие строки:# Local Variables:
# fill-column: 120
# End:
При открытии файла Emacs извлечёт значение этой переменной из комментария и задаст настройке указанное значение.
Лучший способ добавлять такие комментарии — использовать команду
add-file-local-variable
. Однако, я советую вам воздержаться от этого и всё-таки задавать значения настроек на уровне файлов .dir-locals.el
.👍6
Не обновляйте
Посидите пока на старой версии пакета.
tree-sitter-langs
до версии 0.12.268
, там ошибка:⛔️ Error (use-package): tree-sitter-langs/:catch: Eager macro-expansion failure: (error "Error calling (tar -xvzf tree-sitter-grammars.x86_64-unknown-linux-gnu.v0.12.268.tar.gz), exit code is 2")
Посидите пока на старой версии пакета.
👍3
В Emacs 29 разработчики добавили функцию
setopt
. Она работает так же, как customize-set-variable
, но пишется значительно короче. Большого смысла в использовании setopt
я не вижу, разве что ваш init.el
усыпан setq
: тогда, разумеется, лучше сделать замену. Про проблему setq
я уже писал: она не вызывает сеттер, если он есть. А без этого значения многих настроек не применяются.Добрый день, друзья!
Работа над книгой продолжается, недавно на Boosty вышла новая версия. Также часть контента доступна на моём сайте: я добавил описание настроек, которые предоставляет встроенный пакет
Работа над книгой продолжается, недавно на Boosty вышла новая версия. Также часть контента доступна на моём сайте: я добавил описание настроек, которые предоставляет встроенный пакет
rst.el
: https://dunaevsky-ms.ru/emacs/emacs/packages/builtin/rst.html👍5
Давайте поговорим про
Тут есть пара неочевидных свойств:
1. В
2. Нужно ли туда что-то добавлять вручную? Сейчас будет срыв покровов: во многих примерах в этом канале я писал ерунду, и многие примеры кода можно было бы сократить, убрав значения, предусмотренные авторами пакетов.
Допустим, у нас есть
Даю подсказку: надо посмотреть код самого
Ничего себе! Это регулярное выражение сложное, но включает не только
ВЫВОД: заполнение блока
auto-mode-alist
. Это такой ассоциированный список, где слева — регулярное выражение для имени файла, а справа — название основного режима. Благодаря auto-mode-alist
Emacs понимает, какой режим надо использовать при открытии файлов.Тут есть пара неочевидных свойств:
1. В
auto-mode-alist
уже есть какие-то значения. Как их посмотреть? describe-variable
: [M-x describe-variable RET auto-mode-alist RET].2. Нужно ли туда что-то добавлять вручную? Сейчас будет срыв покровов: во многих примерах в этом канале я писал ерунду, и многие примеры кода можно было бы сократить, убрав значения, предусмотренные авторами пакетов.
Допустим, у нас есть
yaml-mode
. Надо ли писать так?(use-package yaml-mode
:ensure t
:mode
(("\\.yml\\'"
"\\.yaml\\'") . yaml-mode))
Даю подсказку: надо посмотреть код самого
yaml-mode
, а именно найти строку с переменной auto-mode-alist
. Смотрим:;;;###autoload
(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode))
Ничего себе! Это регулярное выражение сложное, но включает не только
.yml
и .yaml
! А значит, нам и делать ничего не нужно, всё будет работать само собой.ВЫВОД: заполнение блока
:mode
в use-package
или ручное добавление элементов в auto-mode-alist
в императивном стиле имеет смысл только в том случае, когда нужное регулярное выражение не добавлено автором пакета. Например, нужно ассоциировать ruby-mode
с файлами Vagrantfile
, а вот с расширением .rb
— не нужно.🔥4👍1
Поскольку глава про регулярные выражения ещё не написана, сейчас сделаю разбор выражения, приведённого в предыдущем посте:
1.
2.
2.1.
2.2.
3.
4.
Что имеем по итогу? Данному регулярному выражению удовлетворяет целый список расширений:
1.
2.
3.
4.
5.
\\.\\(e?ya?\\|ra\\)ml\\'
1.
\\.
означает символ точки, буквально. Т. е. речь идёт о расширении.2.
(e?ya?\\|ra\\)
— одно из двух:2.1.
e?ya?
— символ e
может стоять в первой позиции, но это не обязательно; символ y
обязателен, символ a
опционален.2.2.
ra
— буквально;3.
ml
— буквально;4.
\\'
— конец имени файла.Что имеем по итогу? Данному регулярному выражению удовлетворяет целый список расширений:
1.
.yml
2.
.eyml
3.
.yaml
4.
.eyaml
5.
.raml
👍2
Ещё одна причина изучать Emacs: он не зависит от воли отдельных людей или корпораций. Стоило интересам компании Microsoft вступить в конфликт с интересами пользователей и других разработчиков...
https://www.opennet.ru/opennews/art.shtml?num=63139
https://www.opennet.ru/opennews/art.shtml?num=63139
www.opennet.ru
В Microsoft C/C++ Extension включена блокировка работы в форках VS Code
Компания Microsoft внесла в бинарные сборки расширения Microsoft C/C++ Extension (ms-vscode.cpptools) изменение, блокирующее работу в форках открытого редактора кода VS Code (Visual Studio Code). Расширение является проприетарным и используется для добавления…
👍8
Про парсинг.
Чтобы подсветить ключевые слова как ключевые, а ссылки оформить как ссылки редакторы и IDE используют парсинг — текст программы (в нашем случае — доки) разбирается на отдельные части, а уже они оформляются как нужно.
Существуют разные способы разбора исходного кода. Самый широко распространённый — использование регулярных выражений. Сейчас так работают примерно все IDE и редакторы, и Emacs в том числе. Недостатков у этого подхода море:
1. При изменении одной строки нужно выполнять парсинг всего файла. Разработчики используют различные хитрости, чтобы сузить область для повторного разбора, но работает это плохо.
2. Сложность создания регулярных выражений. Без комментариев.
3. Сложность разбора регулярных выражений. Попробуйте открыть JSON-файл размером ну хотя бы в 5 МБ. Уверен, ваш редактор или IDE подвиснет на несколько секунд.
Автор TreeSitter предложил решение этой проблемы — он создал парсер, который создаёт абстрактное синтаксическое дерево открытого файла, где части исходного кода — это ветви и листья этого дерева. При изменении небольшого фрагмента нет необходимости перестраивать всё дерево — достаточно внести изменения только в нужный фрагмент.
В итоге оказалось, что TreeSitter работает (читай: открывает и раскрашивает файлы) быстрее, чем стандартный парсинг регулярных выражений. Не то чтобы TreeSitter не использовал регулярки (он использует), просто принцип работы там сильно другой.
Сейчас TreeSitter внедряют везде где могут, в том числе в Emacs. Для старых версий есть пакет
Общий порядок установки такой:
1. Установите компиляторы C, C++ и, возможно, Rust. Они нужны для сборки библиотек, которые будут разбирать грамматику ваших файлов.
2. Укажите в настройках
3. Установите и скомпилируйте нужные грамматики.
4. Замените название режима на почти такое же, только с суффиксом
Звучит просто, но на самом деле всё довольно сложно. Например, так выглядит код настройки в моём
Чтобы подсветить ключевые слова как ключевые, а ссылки оформить как ссылки редакторы и IDE используют парсинг — текст программы (в нашем случае — доки) разбирается на отдельные части, а уже они оформляются как нужно.
Существуют разные способы разбора исходного кода. Самый широко распространённый — использование регулярных выражений. Сейчас так работают примерно все IDE и редакторы, и Emacs в том числе. Недостатков у этого подхода море:
1. При изменении одной строки нужно выполнять парсинг всего файла. Разработчики используют различные хитрости, чтобы сузить область для повторного разбора, но работает это плохо.
2. Сложность создания регулярных выражений. Без комментариев.
3. Сложность разбора регулярных выражений. Попробуйте открыть JSON-файл размером ну хотя бы в 5 МБ. Уверен, ваш редактор или IDE подвиснет на несколько секунд.
Автор TreeSitter предложил решение этой проблемы — он создал парсер, который создаёт абстрактное синтаксическое дерево открытого файла, где части исходного кода — это ветви и листья этого дерева. При изменении небольшого фрагмента нет необходимости перестраивать всё дерево — достаточно внести изменения только в нужный фрагмент.
В итоге оказалось, что TreeSitter работает (читай: открывает и раскрашивает файлы) быстрее, чем стандартный парсинг регулярных выражений. Не то чтобы TreeSitter не использовал регулярки (он использует), просто принцип работы там сильно другой.
Сейчас TreeSitter внедряют везде где могут, в том числе в Emacs. Для старых версий есть пакет
tree-sitter.el
. Начиная с Emacs 29 доступен встроенный пакет treesit.el
. При этом авторы tree-sitter.el
рекомендуют использовать treesit.el
!Общий порядок установки такой:
1. Установите компиляторы C, C++ и, возможно, Rust. Они нужны для сборки библиотек, которые будут разбирать грамматику ваших файлов.
2. Укажите в настройках
treesit.el
, откуда загружать библиотеки, нужные для разбора файлов на том или ином языке.3. Установите и скомпилируйте нужные грамматики.
4. Замените название режима на почти такое же, только с суффиксом
-ts
. Т. е. было python-mode
, а станет python-ts-mode
.Звучит просто, но на самом деле всё довольно сложно. Например, так выглядит код настройки в моём
init.el
:
;; 📦 TREESIT
;; Встроенный пакет для работы с TreeSitter
(use-package treesit
:init
(progn
;; Создадим каталог для хранения so-файлов с грамматиками
(defvar init-el-tree-sitter-dir (expand-file-name "tree-sitter" user-emacs-directory))
(unless (file-directory-p init-el-tree-sitter-dir)
(make-directory init-el-tree-sitter-dir)))
:config
(add-to-list 'treesit-language-source-alist '(asciidoc "https://github.com/cathaysia/tree-sitter-asciidoc.git" "v0.3.0" "tree-sitter-asciidoc/src/"))
(add-to-list 'treesit-language-source-alist '(bash "https://github.com/tree-sitter/tree-sitter-bash.git" "v0.23.3"))
(add-to-list 'treesit-language-source-alist '(css "https://github.com/tree-sitter/tree-sitter-css.git" "v0.23.2"))
(add-to-list 'treesit-language-source-alist '(dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile" "v0.2.0" "src/"))
(add-to-list 'treesit-language-source-alist '(html "https://github.com/tree-sitter/tree-sitter-html.git" "v0.23.2"))
(add-to-list 'treesit-language-source-alist '(javascript "https://github.com/tree-sitter/tree-sitter-javascript.git" "v0.23.1"))
(add-to-list 'treesit-language-source-alist '(json "https://github.com/tree-sitter/tree-sitter-json.git" "v0.24.8"))
(add-to-list 'treesit-language-source-alist '(make "https://github.com/tree-sitter-grammars/tree-sitter-make.git" "v1.1.1" "src/"))
(add-to-list 'treesit-language-source-alist '(markdown "https://github.com/tree-sitter-grammars/tree-sitter-markdown.git" "v0.3.2" "tree-sitter-markdown/src/"))
(add-to-list 'treesit-language-source-alist '(python "https://github.com/tree-sitter/tree-sitter-python.git" "v0.23.6"))
(add-to-list 'treesit-language-source-alist '(ruby "https://github.com/tree-sitter/tree-sitter-ruby.git" "v0.23.1"))
(add-to-list 'treesit-language-source-alist '(rust "https://github.com/tree-sitter/tree-sitter-rust.git" "v0.23.2"))
(add-to-list 'treesit-language-source-alist '(rst "https://github.com/stsewd/tree-sitter-rst.git" "v0.1.0" "src/"))
(add-to-list 'treesit-language-source-alist '(typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src"))
(add-to-list 'treesit-language-source-alist '(xml "https://github.com/tree-sitter-grammars/tree-sitter-xml.git" "v0.7.0" "xml/src/"))
(add-to-list 'treesit-language-source-alist '(yaml "https://github.com/tree-sitter-grammars/tree-sitter-yaml.git" "v0.7.0" "src/"))
(add-to-list 'major-mode-remap-alist '(dockerfile-mode . dockerfile-ts-mode))
(add-to-list 'major-mode-remap-alist '(html-mode . html-ts-mode))
(add-to-list 'major-mode-remap-alist '(ruby-mode . ruby-ts-mode))
(add-to-list 'major-mode-remap-alist '(yaml-mode . yaml-ts-mode))
(add-to-list 'major-mode-remap-alist '(typescript-mode . typescript-ts-mode)))
Из всего многообразия я чаще всего использую
yaml-ts-mode
и ruby-ts-mode
. Настроить asciidoc-ts-mode
пока не удалось 😊👍2
Про иконочные шрифты.
Раньше автор каждого пакета или библиотеки предпочитал иметь всё своё. Но постепенно этот подход заменил другой: пишем только уникальный код, а общие компоненты выносим в библиотеки. Так появились DLL / so-файлы.
В Emacs авторы многих пакетов пошли тем же путём: «Зачем писать собственную поддержку иконок, если можно использовать другой пакет?»
Раньше для иконок использовали файлы формата ICO. Потом JPG и PNG. В какой-то момент все перешли в вектор – SVG. Однако, самый мощный прорыв случился в момент появления иконочных шрифтов. Вместо букв и цифр их глифы рисуют картинки. Вроде бы сейчас даже появилась спецификация, позволяющая раскрашивать эти картинки разными цветами, а не основным цветом шрифта. Впрочем, вернёмся к Emacs.
Основные «киты» – это пакетывы не поверите
Раньше автор каждого пакета или библиотеки предпочитал иметь всё своё. Но постепенно этот подход заменил другой: пишем только уникальный код, а общие компоненты выносим в библиотеки. Так появились DLL / so-файлы.
В Emacs авторы многих пакетов пошли тем же путём: «Зачем писать собственную поддержку иконок, если можно использовать другой пакет?»
Раньше для иконок использовали файлы формата ICO. Потом JPG и PNG. В какой-то момент все перешли в вектор – SVG. Однако, самый мощный прорыв случился в момент появления иконочных шрифтов. Вместо букв и цифр их глифы рисуют картинки. Вроде бы сейчас даже появилась спецификация, позволяющая раскрашивать эти картинки разными цветами, а не основным цветом шрифта. Впрочем, вернёмся к Emacs.
Основные «киты» – это пакеты
all-the-icons
и nerd-icons
. В обоих есть команды для загрузки нужных шрифтов – all-the-icons-install-fonts
и nerd-icons-install-fonts
. В Windows эти шрифты потом надо ещё и установить. В Linux достаточно обновить кеш шрифтов.👍4
Нужна ли книга "Git простым языком"? Без неё читать главу про Magit сложновато, как мне кажется.
Anonymous Poll
80%
Да
20%
Нет
Как увеличить размер окна по высоте (при условии, что есть куда)? Очень просто: [C-x ^].
Но эта команда увеличивает высоту окна только на один символ! А как увеличить на 5?
Простое и брутальное решение: [C-u 5 C-x ^].
А попроще можно? Конечно! Включите глобальный дополнительный режим
Что он делает? После первого вызова некоторых команд он переходит в режим повтора. Это значит, что в минибуфере будет выводиться подсказка с названием доступных клавиш, и нажатие каждой из них будет работать так, будто вы нажали всю последовательность целиком.
Ещё раз, попроще. Для изменения размера окна используются эти последовательности:
[C-x ^] — выше
[C-x v] — ниже
[C-x }] — шире
[C-x {] — уже
Но теперь после нажатия любой из этих последовательностей Emacs перейдёт в режим повтора, и для изменения размеров активного окна нужно будет нажать не последовательность, а всего одну клавишу:
[^] — выше
[v] — ниже
[}] — шире
[{] — уже
И пока вы не нажмёте [C-g] или клавишу, не входящую в список для повтора, это поведение будет работать. В следующем посте будет GIF, демонстрирующий это поведение.
Кстати, при изменении размера шрифта
Но эта команда увеличивает высоту окна только на один символ! А как увеличить на 5?
Простое и брутальное решение: [C-u 5 C-x ^].
А попроще можно? Конечно! Включите глобальный дополнительный режим
repeat-mode
!(use-package repeat
:config (repeat-mode 1))
Что он делает? После первого вызова некоторых команд он переходит в режим повтора. Это значит, что в минибуфере будет выводиться подсказка с названием доступных клавиш, и нажатие каждой из них будет работать так, будто вы нажали всю последовательность целиком.
Ещё раз, попроще. Для изменения размера окна используются эти последовательности:
[C-x ^] — выше
[C-x v] — ниже
[C-x }] — шире
[C-x {] — уже
Но теперь после нажатия любой из этих последовательностей Emacs перейдёт в режим повтора, и для изменения размеров активного окна нужно будет нажать не последовательность, а всего одну клавишу:
[^] — выше
[v] — ниже
[}] — шире
[{] — уже
И пока вы не нажмёте [C-g] или клавишу, не входящую в список для повтора, это поведение будет работать. В следующем посте будет GIF, демонстрирующий это поведение.
Кстати, при изменении размера шрифта
repeat-mode
тоже крайне полезен!👍8❤1
magit.pdf
150.2 KB
Добрый день, мои чюваки!
Я решил переписать с нуля главу про Magit. Выкладываю её на всеобщее обозрение для оценки читаемости и понятности.
Подписчики на Boosty чуть позже получат книгу, где эта глава будет переписана с учётом ваших замечаний и предложений. Так же там будет множество примеров использования Magit для выполнения типовых операций.
Я решил переписать с нуля главу про Magit. Выкладываю её на всеобщее обозрение для оценки читаемости и понятности.
Подписчики на Boosty чуть позже получат книгу, где эта глава будет переписана с учётом ваших замечаний и предложений. Так же там будет множество примеров использования Magit для выполнения типовых операций.
🔥9👍1
Операции Git, которые должны быть описаны в главе про Magit:
Anonymous Poll
67%
commit
67%
pull
67%
push
56%
rebase
72%
merge
61%
cherry-pick
56%
checkout
56%
branch
72%
stash
11%
Свой вариант в комментарии
🔥2
На Boosty опубликована новая версия книги. Глава про Magit переписана с нуля на основе ваших комментариев. Надеюсь, стало попроще.
Пока не описаны
Пока не описаны
cherry-pick
, stash
и некоторые варианты, предложенные в комментариях. Это на следующее обновление.boosty.to
v25.05.17 - Максим Дунаевский
Очередное обновление книги "GNU Emacs для технических писателей". Глава про Magit переписана с нуля!
❤5