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

Рубрика "Секреты Вим". Всплывающие окна

Привет, коллеги. Вим развивается, и в версии 9 появились всплывающие окна. В оконной версии они уже давно есть, а теперь вот и в консоли тоже. Это временные окна, всплывающие поверх других окон и закрываемые автоматически (по времени), по щелчку мыши на кнопке закрытия, просто по щелчку мыши или клавиши, вызовом функции (из скрипта, который окно открыл, или пользователем), вызовом функции, закрывающей все такие окна разом. Они могут вывести срочное сообщение, задать вопрос, выводить какую-то актуальную информацию (наподобие строки информации) и всё в таком роде. Проверьте, доступны ли вам всплывающие окна (popup window), дав команду :echo has('popupwin') Если увидите 1, то доступны, а если 0 - то нет. Вся информация доступна в Справке (конечно, если Вим достаточно новый) по запросу :help popupwin Возможности работы с таким окном ограничены, что и понятно. Доступ к таким окнам весь - через функции: выполнить команду, задать опцию, закрыть, создать окно. В таком окне может быть даже зап

Привет, коллеги. Вим развивается, и в версии 9 появились всплывающие окна. В оконной версии они уже давно есть, а теперь вот и в консоли тоже. Это временные окна, всплывающие поверх других окон и закрываемые автоматически (по времени), по щелчку мыши на кнопке закрытия, просто по щелчку мыши или клавиши, вызовом функции (из скрипта, который окно открыл, или пользователем), вызовом функции, закрывающей все такие окна разом. Они могут вывести срочное сообщение, задать вопрос, выводить какую-то актуальную информацию (наподобие строки информации) и всё в таком роде.

Проверьте, доступны ли вам всплывающие окна (popup window), дав команду

:echo has('popupwin')

Если увидите 1, то доступны, а если 0 - то нет.

Вся информация доступна в Справке (конечно, если Вим достаточно новый) по запросу

:help popupwin

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

В таком окне может быть даже запущен терминал. См. справку.

Предусмотрено много функций для создания, закрытия и управления всплывающими окнами. Например, универсальная popup-create и разновидности для создания окна под курсором (закрывается, когда курсор смещается), для создания диалогов, меню, сообщений и т.п.

Стиль работы у всех общий. Создающие окно функции возвращают его ID, который надо передавать другим функциям, работающим с окном. Создательнице надо передать текст и словарь с настройками. В них может быть очень много всего.

В частности, размеры и положение окна, различные свойства (вроде принадлежности к вкладке или видимость во всех вкладках), внешний вид (рамочка и т.п.), прозрачность (!), приоритет (число, имеющее смысл z-координаты: если одно окно отрисовано поверх другого, то видимо будет то, у которого больше этот параметр), время до автоматического закрытия, другие признаки закрытия (по движению мыши, по движению курсора и какому именно).

Отдельно надо упомянуть вызываемые окном функции, так называемые callbacks (коллбэки?). Если задать такую функцию, то она будет вызвана при закрытии окна и позволит, например, отреагировать на сделанный пользователем выбор. Еще есть filter, который обрабатывает вводимые в окне символы и возвращает 1, если обработал символ сам или 0, если символ ему неинтересен. Это позволит, например, закрыть окно нажатием клавиши Q или сделать что-то ещё.

Посмотрим на примеры.

let winid = popup_create('Just another Vim hacker!', #{
\ pos: 'botleft',
\ border: [],
\ padding: [0,1,0,1],
\ close: 'click',
\ time: 5000,
\ })
Поместите это в файл test.vim и запустите его: :source test.vim

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

Вот пример запроса.

Эта функция просто выводит сообщение, как в предыдущем примере:

function! Msg(text)
let winid = popup_create(a:text, #{
\ pos: 'botleft',
\ border: [],
\ padding: [0,1,0,1],
\ close: 'click',
\ time: 3000,
\ })
return winid
endfunction

А эта вспомогательная, обрабатывает результат. Это коллбэк.
function! CB(_,res)
if a:res == 1
call Msg('Ответ "Да"!')
else
call Msg('Ответ "Нет".')
endif
endfunction

Ну, а это, собственно, запрос:
let winid=popup_dialog('Continue? y/n', #{
\ filter: 'popup_filter_yesno',
\ callback: funcref('CB'),
\ padding: [2, 4, 2, 4],
\ })
Удачи, коллеги!

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