Дата — это просто!
об автоматизации
В это сложно поверить, но компьютер может подчиняться пользователю, а не наоборот.
Было у меня вчера, к ночи ближе, просветление.
Я до вчерашнего дня в файлах для этого сайта дату вручную выставлял. Это несложно, в общем-то, но неудобно, и чем дальше, тем больше напрягает, как камешек в ботинке.
Исходники страниц для Hugo — файлы Markdown, а служебная информация, вроде той же даты публикации, добавляется в начало файла «нашлёпкой» TOML (можно YAML или даже JSON, по вкусу), в терминах Hugo это называется «Front Matter». Например, начало файла с вот этой вот записью выглядит так:
+++
title = "Дата — это просто!"
subtitle = "об автоматизации"
date = 2020-06-05T11:39:46+03:00
tags = ["linux", "hugo", "чему не учат в школе"]
categories = ["IT"]
+++
> В это сложно поверить, но компьютер может[...]
Дата, как видите, строкой в формате ISO 8601. И набирать вот эту строку каждый раз руками очень лень. Надо сделать, чтобы текущая дата (нужна-то, как правило, именно текущая) вставлялась сама. Но как?
Просто брать дату коммита из Git (раз уж всё равно всё это в Git сохраняется) — не вариант: тогда дата будет обновляться при каждом исправлении опечаток или форматирования1.
Встроенный в Hugo механизм решения этой проблемы — шаблоны для создаваемых файлов. Можно сделать, чтобы по команде
$ hugo new /posts/2020/date.md
создавался файл сразу с заполненной во Front Matter текущей датой (и другими полями, если хочется). Этот вариант в целом годится для коротких заметок, но пост, даже не очень длинный, может писаться долго2, и хочется, чтобы в нём стояла дата (и время), когда он был закончен, а не когда он был задуман и файл создан.
Я уже стал было поглядывать в сторону плагина для Vim, который, в числе прочего, умеет вставлять дату в нужном формате. Беда в том, что мне неудобно писать посты в Vim3, а в ReText, которым я пользуюсь для написания этого вот поста, плагины не предусмотрены.
Вчера меня, наконец, осенило:
А что, собственно, мешает вставлять текущую дату средствами системы?!
У меня ж тут вроде бы Linux, в котором вроде бы возможно всё — и ещё немножко. Так неужто нельзя организовать вставку текущей даты в формате ISO 8601 в любое место по желанию? А ведь можно же!
Как и в любом приличном системном интерфейсе, в KDE, которым пользуюсь я, есть возможности назначить выполнение любой команды на сочетание клавиш. Например, на Ctrl-Alt-D
. Надо только понять, как должна выглядеть команда, которая вставит текущую дату. И куда вставит-то, кстати?
Найти сходу команду, которая вставляла бы произвольный текст в позицию курсора в любое окно, я не смог. Зато есть утилита xsel
для работы с буфером обмена, можно вставить текущую дату туда. Надо попробовать:
date -Is | tr -d "\n" | xsel -b -i
Работает!4 Текущая дата в нужном формате появляется в буфере, потом можно нажать ‘Ctrl-V’ (или ‘Shift-Ins’, кому что удобно) — и дата вставится куда пожелаешь. Но на это уходит два сочетания клавиш, и буфер обмена при этом перезаписывается — неаккуратненько как-то это всё. Хочется, чтобы в одно нажатие и без манипуляций с буфером…
Гугл подсказал, что есть утилита xdotool
, которая умеет печатать за пользователя. Интересно, она заработает по сочетанию клавиш? Заведём-ка что-нибудь вроде
xdotool type "test"
на сочетание Ctrl-Shift-T
и попробуем в текстовом редакторе… Упс! В редакторе открылось окно «сохранить как». Что за чертовщина?!
Оказывается, xdotool
-то печатает, но клавиатура-то при этом ввод даёт тоже, а у меня же в этот момент нажаты Ctrl и Shift! Поэтому редактор (а это в тесте был Kate) не получил Ctrl-Shift-T
(его перехватила система), но получил Ctrl-Shift-E
(на которое никакого действия не предусмотрено), а потом Ctrl-Shift-S
(«сохранить как»), и повторное Ctrl-Shift-T
уже игнорировал.
Так не пойдёт! Благо, для xdotool
есть опция --clearmodifiers
, которая «отпускает» перед началом печати все нажатые клавиши (включая CapsLock, например), а после окончания печати восстанавливает состояние в исходное. Пробуем…
Уже лучше. Правда, зачем-то xdotool
«отпустил» ещё и T, поэтому первая буква пропала, а потом «нажал обратно» Ctrl и Shift (и редактор вёл себя очень странно, пока я не догадался нажать это сочетание снова). Но это всё уже не проблема: буква D, которая у меня будет входить в сочетание для даты, в дате не встречается, а «отпустить» клавиши, «нажатые обратно», можно заставить сам xdotool
:
xdotool type --clearmodifiers $(date -Is | tr -d "\n") && xdotool keyup ctrl alt d
Нажимаем Ctrl-Alt-D
…
Вот и славно! Работает где угодно, хоть в консоли, хоть в ReText, хоть в том же Vim…
Конечно, на то, чтобы разобраться (особенно с xdotool
) ушло время5. Конечно, кто-то назовёт это «ненужным красноглазием». Но мой компьютер теперь делает то, что я хочу, и так, как я хочу. Для чего, собственно, компьютер-то и нужен по-хорошему…
Мне думается, таким вещам надо обязательно в школе учить.
-
Это можно использовать (и использую) для показа даты обновления. Например, вот этот пост написан в июле прошлого года, а месяц назад я чуть скорректировал ошибки, возникшие при импорте из Known, поэтому в заголовке июль 2019 (из Front Matter), а в нижней части, над тэгами — май 2020 (дата последнего коммита этого файла в Git). ↩︎
-
Что-то пишется урывками в свободное время, что-то обдумывается подолгу. Можно было бы писать в отдельном файле, а перед публикацией вставлять в новосозданный, но к чему эти лишние телодвижения… ↩︎
-
Это тема для отдельного поста. Я с удовольствием пользуюсь Vim для правки конфигов, написания скриптов на bash и кода на Go, но мне жутко неудобно писать в нём связный текст на человеческом языке — changelog ещё могу, а вот readme уже тяжко. ↩︎
-
date -Is
даёт дату в нужном формате,tr -d "\n"
убирает из полученной строки символ конца строки (условный «Enter», которыйdate
зачем-то добавляет в конец), аxsel -b -i
записывает полученную строку в системный буфер обмена. ↩︎
Ответы
Реакции
Ejitsu