Вопрос
Я хотел бы создать пользовательский интерфейс в виде всплывающего меню , всплывающего меню, аналогичного используемому в Magit .
особенности
Определение всплывающих окон
Всплывающее окно в контексте этого вопроса означает небольшое временное окно, которое содержит коллекцию пунктов меню, чтобы пользователь мог выбрать один и только один из этих элементов.
Положение на экране
Допускается показ всплывающего окна в любой части экрана, но желательно, чтобы оно было достаточно очевидным, и поэтому оно должно отображаться рядом с текущим активным окном.
Содержимое Popup Buffer
Элементы должны отображаться в виде красивой таблицы. Pretty - контекст вопроса означает визуально привлекательный, этого эффекта легче всего достичь, поместив пункты меню в прямые строки, см.,
complete--insert-string
Например. Этот параграф служит для дополнительного разъяснения, вы можете сделать это по-своему, это не сделает ваш ответ неверным.
Выбор пункта меню
Ожидается, что выбор будет выполнен одним нажатием клавиши или, возможно, мышью (хотя это не так важно, поэтому ответы, содержащие предложения, которые не поддерживают мышь, являются законными). Если вы предлагаете решение, которое поддерживает мышь, обратите внимание, что пользователь должен иметь возможность выбирать пункт меню интуитивно понятным способом, то есть, щелкая левой кнопкой мыши по желаемому выбору.
NB мышь можно использовать по-разному, и приветствуются альтернативные способы указания выбора.
Устранение Popup
Как только пользователь выбрал пункт меню способом, описанным выше, буфер и, следовательно, его окно должны быть исключены из вида, а также уничтожены. Окно, которое было активным до вызова всплывающего меню, должно снова получить фокус (то есть стать активным).
Возвращаемое значение и аргументы
Предпочтительно, это следствие действий должно привести к возвращению объекта Lisp. Объект Лиспа может быть:
nil
- это означает, что пользователь отменил всплывающее меню, нажав C-gили каким-либо другим способом †.string
- строка (разрешено использовать символ) должна указыватьstring-equal
на одну из строк, представленных во всплывающем меню, как набор фактических элементов.
Альтернативные способы сообщить остальной программе выбор пользователя или, возможно, его отсутствие, являются приемлемыми. Однако, если неясно, как еще это можно сделать, я прошу всех ответчиков импровизировать и не просить меня прояснить этот аспект.
Это все для возвращаемого значения. Что касается входных параметров, они должны по крайней мере включать коллекцию строк, которые представляют возможные варианты выбора (то есть пункты меню).
Приемлемые ответы
Ожидаемый ответ может иметь следующие формы:
Достаточный фрагмент кода, который позволяет образованному читателю написать функцию, подобную описанной выше; это не ожидается или необходимо писать всю рабочую функцию. Однако, чтобы избежать неопределенности (можно ли пропустить значительную часть кода?), Я должен отметить, что недостающие части фрагмента должны быть описаны в текстовом компоненте ответа.
Ссылка на существующую библиотеку, которая реализует аналогичные функции. Чтобы избежать неопределенности, я должен отметить, что подобное в нашем случае означает, что библиотека может использоваться для создания всплывающего окна (см. Определение выше), которое имеет как минимум 2 или 3 функции, описанные выше. Если предлагаемая библиотека отличается от точки, в которой ранее указанное условие не может быть выполнено, каждый такой случай будет оцениваться независимо и всегда будет поддерживаться, если OP сочтет это полезным.
Описание встроенных функций Emacs или сторонних, которые могут быть использованы для реализации любой функции, описанной в разделе «Функции», см. Выше. Чтобы избежать неопределенности, пожалуйста, четко укажите, как ваш ответ может быть полезен для будущих читателей, которые хотят реализовать всплывающее , всплывающее меню, подобное тому, которое используется в Magit .
† Альтернативные способы отмены всплывающего меню могут включать следующее (но не ограничиваясь этим):
щелкнув за пределами окна всплывающего меню;
уничтожение буфера, содержащего всплывающее окно, без выбора.
magit-popup
. Новый пакет называетсяtransient
, и это то, что используется в текущих версияхmagit
. Смотрите magit.vc/manual/transient для документации.