Найти в Дзене
Блокнот математика

Рубрика "Секреты Вим". Время, дата и напоминания

Привет, коллеги. Сегодня материал для хакеров: как сделать то, что никем для вас не было предусмотрено. А именно, как поместить часы в строку статуса (лучше ее называть информационной строкой) и как сделать напоминалку. Про настройку этой строки материал уже был. Там можно разместить любой текст (подсказки, скажем, как выйти), а также предусмотрено много полей, которые заменяются именем файла, кодом символа под курсором, номером текущей строки, процентом файла выше курсора, признаком наличия несохраненных правок и так далее. Много всего! Но если мы хотим больше? Начнем с даты и времени. Есть функция strftime, которая принимает строку формата и возвращает дату и время в указанном формате. Формат зависит от системы, смотрим справку по системной date, а я буду рассказывать, как у меня в линуксе. Так, strftime('%H:%M') вернет привычное время: 12:42. А "%d %b %Y" даст дату в виде "20 Дек 2021". Полный ответ, дату и время, можно собрать вручную, но есть %c: "Пн 20 дек 2021 23:11:36". Это пе

Привет, коллеги. Сегодня материал для хакеров: как сделать то, что никем для вас не было предусмотрено. А именно, как поместить часы в строку статуса (лучше ее называть информационной строкой) и как сделать напоминалку.

Будем повелевать временем, коллеги! Источник: https://i.ytimg.com/vi/MOlWWWFxBXo/maxresdefault.jpg
Будем повелевать временем, коллеги! Источник: https://i.ytimg.com/vi/MOlWWWFxBXo/maxresdefault.jpg

Про настройку этой строки материал уже был. Там можно разместить любой текст (подсказки, скажем, как выйти), а также предусмотрено много полей, которые заменяются именем файла, кодом символа под курсором, номером текущей строки, процентом файла выше курсора, признаком наличия несохраненных правок и так далее. Много всего! Но если мы хотим больше?

Начнем с даты и времени. Есть функция strftime, которая принимает строку формата и возвращает дату и время в указанном формате. Формат зависит от системы, смотрим справку по системной date, а я буду рассказывать, как у меня в линуксе.

Так, strftime('%H:%M') вернет привычное время: 12:42. А "%d %b %Y" даст дату в виде "20 Дек 2021". Полный ответ, дату и время, можно собрать вручную, но есть %c: "Пн 20 дек 2021 23:11:36".

Это первое. Теперь второй ингредиент: в строке информации можно выполнить любой код: в поле %{}. Вот и всё:

:set statusline+=\ \ %{strftime('%c')}

Кавычки надо одинарные. Формат любой из перечисленных или ваш собственный: только время, с секундами или без, дату, дату и время, с днем недели или без: на ваш вкус! Обратите внимание на два пробела, вставленные через слеш. Можете оставить один, или отделить каким-то символом: всё на ваше усмотрение. Обратите также внимание на команду set+=, которая позволяет добавить что-то к опции. И потом можете аккуратно убрать, не трогая остального, с помощью set-=. И помним, что хотя строка информации обновляется довольно часто (в том окне, в котором работаете!), но гарантий, что время будет обновлено вовремя, нет. Это, скорее, ориентир, а не хронометр.

Не забываем, что надо выставить laststatus=2, чтобы строка была видна всегда, а не только когда окон больше одного (1) или вообще выключена (0).

Давайте усложним задачу и сделаем напоминалку. Заведем команду Rem:

:command -nargs=* Rem call Remember(<f-args>)

Функцию Remember напишем сами:

function! Remember(h, m, ...)
let what = join(a:000)
let t0=(a:h-1)*60+a:m
let t1=(t0+15)%(24*60)
if exists('g:ToDo')
let g:ToDo=g:ToDo+[{'what': what, 't0': t0, 't1': t1}]
else
let g:ToDo=[{'what': what, 't0': t0, 't1': t1}]
endif
endfunc

Мы трактуем первые два аргумента как часы и минуты и переводим их в минуты от начала суток. Затем прибавляем 15 минут и учитываем, что это время может уже выйти на следующие сутки. Далее добавляем к глобальному списку элемент-словарь, в котором лежат два времени и текст сообщения. Текст передается в виде отдельных слов и доступен нам в списке a:000; мы делаем строку из этого списка функцией join. Многоточие и означает "сколько угодно аргументов". "Сколько угодно" - это до 20.

Теперь напишем функцию, которая будет напоминать:

function! CheckReminders()
let h=strftime('%H')
let m=strftime('%M')
let t=(h-1)*60+m
let i=0
for todo in g:ToDo
let L1 = todo['t0'] <= t && todo['t1']>= t
let L2 = todo['t1']>= t && todo['t1']<=15
let L3 = todo['t0']<= t && todo['t0']>=24*60-15
if L1 || L2 || L3
let reminder=todo['what']
unlet g:ToDo[i]
echohl ErrorMsg
echo '!!!' reminder '!!!'
echohl None
return '!!!'.reminder.'!!!'
endif
let i+=1
endfor
return ''
endfunc

Сначала она узнает время (час и минуту) и вычислит число минут, прошедшее от полуночи. Дальше начнет перебирать элементы списка дел. Если назначенное время миновало (но не более 15 минут), то надо дать напоминание. Задержка в 15 минут нужна потому, что строка информации может не обновляться. Если вы, скажем, отошли за кофе. Или просто задумчиво втыкаете в экран, не трогая клавиш. Или переключились в другую программу...

Проверка довольно громоздкая, можно сделать изящнее. Но так зато наглядно. Мы проверяем три возможности: текущее время больше запланированного t0, но меньше t1; текущее время меньше t1, но это первые 15 минут новых суток, то есть t0 было вчера и точно уже прошло; текущее время больше запланированного t0, но от него до полуночи менее 15 минут, так что t1 уже завтра и точно еще не наступило. Обратите внимание на логические связки И (&&) и ИЛИ (||).

Напоминание состоит в следующем. Текст запоминаем, элемент списка удаляем. Удаляем по номеру, поэтому ведем счет элементов в переменной i. Выставляем тревожную раскраску (как для ошибок) и выводим сообщение. Возвращаем сообщение как результат функции, прерывая и цикл. Таким образом, выведется только одно напоминание. При следующем вызове функции выведется следующее (если оно на тот же интервал времени).

Теперь надо привязать функцию к строке информации, чтобы она вызывалась при каждом обновлении:

:set statusline+=\ \ %{CheckReminders()}

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

Можно и цветом выделить, но это другая история.

А сообщение подержится подольше.

Немного оптимизации: можно вычислить выражения вроде 24*60, немного сэкономив работу процессора. Еще мы вводим напоминания самим себе в виде: :Rem 12 42 Do Something. Несложно сделать разбор, чтобы вводить время в привычном виде 12:42. Но это уж сами можете изощряться...

Русский язык работает.

В следующий раз поместим в строку информации статистику по файлу: число слов, символов и все в таком роде.

Удачи, коллеги!

Научно-популярные каналы на Дзене: путеводитель
Новости популярной науки12 марта 2022