Pregunta
Me gustaría crear una interfaz de usuario en forma de menú emergente , menú emergente similar al utilizado en Magit .
Caracteristicas
Definición de ventana emergente
La ventana emergente en el contexto de esta pregunta significa una pequeña ventana temporal que contiene una colección de elementos de menú para que el usuario pueda seleccionar uno y solo uno de estos elementos.
Posición en la pantalla
Se permite que la ventana emergente aparezca en cualquier parte de la pantalla, pero es deseable que sea bastante obvia y, por lo tanto, que aparezca junto a la ventana actualmente activa.
Contenido de Popup Buffer
Los artículos deben mostrarse en forma de bonita mesa. Bonito es el contexto de la pregunta significa visualmente atractivo, este efecto se puede lograr más fácilmente colocando los elementos del menú en filas rectas, ver
complete--insert-string
por ejemplo. Este párrafo sirve para aclaraciones adicionales, puede hacerlo a su manera, esto no hará que su respuesta sea incorrecta.
Selección de elemento de menú
Se espera que la selección se realice presionando una sola tecla u, opcionalmente, con un mouse (aunque no es tan importante, por lo que las respuestas que contienen proposiciones que no admiten mouse son legales). Si propone una solución compatible con el mouse, tenga en cuenta que el usuario debe poder seleccionar un elemento del menú de forma intuitiva, es decir, haciendo clic con el botón izquierdo en la opción deseada.
El mouse NB se puede usar de muchas maneras y también se aceptan formas alternativas para indicar una elección.
Eliminación de Popup
Una vez que el usuario ha seleccionado un elemento del menú de la manera descrita anteriormente, el búfer y, por lo tanto, su ventana deben eliminarse de la vista y eliminarse. La ventana que ha estado activa antes de la invocación del menú emergente debería volver a enfocarse (es decir, volverse activa).
Valor devuelto y argumentos
Preferiblemente, esta consecuencia de las acciones debería dar como resultado un objeto Lisp devuelto. El objeto Lisp puede ser:
nil
- esto indica que el usuario ha abortado el menú emergente presionando C-go de alguna otra manera †.string
- la cadena (está permitido usar un símbolo) debe estarstring-equal
en una de las cadenas suministradas al menú emergente como colección de elementos reales.
Se aceptan formas alternativas para que el resto del programa conozca la elección del usuario o, posiblemente, su ausencia. Sin embargo, si no está claro de qué otra manera se puede realizar, pido a todos los que responden que improvisen y no me piden más aclaraciones sobre este aspecto.
Esto es todo por valor devuelto. En cuanto a los parámetros de entrada, deberían incluir al menos una colección de cadenas que representen posibles opciones (es decir, elementos de menú).
Respuestas Aceptables
La respuesta esperada puede ser de las siguientes formas:
Suficiente fragmento de código que permite al lector educado escribir una función como la descrita anteriormente; No se espera ni es necesario escribir toda la función de trabajo. Sin embargo, para evitar la incertidumbre (¿se pueden omitir partes considerables del código?), Debo tener en cuenta que las partes faltantes del fragmento deben describirse en el componente textual de la respuesta.
Un enlace a la biblioteca existente que implementa una funcionalidad similar. Para evitar la incertidumbre, debo tener en cuenta que similar en nuestro caso significa que la biblioteca se puede utilizar para crear ventanas emergentes (consulte la definición anterior) que tiene al menos 2 o 3 características descritas anteriormente. Si la biblioteca propuesta es diferente al punto en el que no se puede cumplir la condición previamente establecida, cada uno de estos casos se juzgará de forma independiente y siempre se votará si OP lo considera útil.
Descripción de las funciones integradas de Emacs o de terceros que se pueden utilizar para implementar cualquier característica descrita en la sección «Características», ver arriba. Para evitar la incertidumbre, por favor aclara cómo su respuesta puede ser útil para futuros lectores que deseen implementar emergente , menú emergente similar a la utilizada en Magit .
† Las formas alternativas de abortar el menú emergente pueden incluir lo siguiente (pero no limitado a esto):
haciendo clic fuera de la ventana del menú emergente;
Eliminación del búfer que contiene la ventana emergente sin hacer una elección.
magit-popup
. Se llama al nuevo paquetetransient
, y esto es lo que se usa en las versiones actuales demagit
. Consulte magit.vc/manual/transient para obtener documentación.Las hidras son bastante simples de escribir:
Hydra es una interfaz centrada en el teclado y, en su forma básica, no es más difícil que
easy-menu-define
(incorporada). Y es bastante extensible si quieres que haga cosas más complejas.Solo mire esta interfaz de Twitter, la ventana inferior es una Hydra personalizada, no mucho más difícil de escribir que la anterior:
El código para esto está disponible en la wiki , junto con muchos más ejemplos.
fuente
Después de algunas investigaciones, he encontrado un idioma que se puede usar para crear una ventana en la parte inferior (o de hecho en cualquier lugar) de la ventana actualmente activa. Esto mismo tiene efecto de ventana auxiliar temporal:
Puede jugar un poco con el
action
argumento dewith-current-buffer-window
si desea que la ventana emergente aparezca en diferentes partes de la pantalla.La función Salir se describe en la cadena de documentos de
with-current-buffer-window
, se puede usar para obtener información del usuario. Como sugirió @tarsius,read-char-choice
es un buen candidato para experimentar.El búfer emergente en sí se puede generar como cualquier otro búfer. Todavía estoy pensando en botones allí, porque el usuario podría usar su mouse para seleccionar un elemento en el menú emergente, no solo el teclado. Sin embargo, esto requiere un esfuerzo adicional si desea hacerlo bien.
Si su ventana emergente es un poco ad-hoc y no la necesitará más de una vez, puede salirse con la suya. Además, eche un vistazo a
completion--insert-strings
. Lo encontré bastante útil como un ejemplo de cómo generar filas bonitas de elementos de menú, incluso puede usarlo sin modificaciones si no necesita algo especial.fuente
Aquí hay una solución de terceros, usando Icicles .
Su código abre una ventana con los candidatos ordenados como un menú. Para saber cómo, ver más abajo.
Prefijas cada elemento del menú con un personaje único. Por ejemplo, a, b, c ... o 1, 2, 3 ... El usuario toca el carácter para elegir el elemento.
Vincula algunas variables alrededor de una llamada a
completing-read
. Le pasa una lista de los elementos de su menú. Opcionalmente, puede especificar que uno de los elementos sea el predeterminado, elegido si el usuario solo presionaRET
.Los enlaces variables le dicen
completing-read
a:Puede hacer que los elementos del menú sean tan elegantes como desee (no se muestran).
mouse-3
menú emergente, para hacer algo con el elementoTambién puede crear menús verdaderamente de opción múltiple , es decir, menús en los que un usuario puede elegir varios elementos al mismo tiempo (elija un subconjunto de las opciones posibles).
fuente
También podría estar interesado en mirar el paquete
makey
. Su objetivo es proporcionar una funcionalidad similarmagit-popup
y es una bifurcación del predecesor demagit-popup
(magit-key-mode
mencionado en el comentario) de cuando aún no era un paquete disponible por separadomagit
.Permítanme mencionar también
discover
: ese es un ejemplo de cómo usarmakey
(y también su razón de ser). Ese paquete está destinado a ayudar a los recién llegados a descubrir enlaces de emacs.Referencias
makey
ydiscover
por su autor.magit-popup
se hizo en su propio paquete.fuente
Guide-Key funciona bien para mí para todos los prefijos configurados.
fuente
Basado en la respuesta de @ Drew (Icicles), con modificaciones para separar la implementación del menú de los datos del menú, por lo que se pueden definir múltiples menús, cada uno con su propio: (contenido, solicitud, predeterminado).
Opcionalmente, utiliza hiedra (cuando está disponible), que tiene características más avanzadas como la posibilidad de activar elementos mientras se mantiene abierto el menú.
Popup genérico.
Ejemplo de uso, asigne algunas acciones a la tecla f12:
fuente