Questão
Gostaria de criar uma interface de usuário na forma de menu pop-up , menu pop-up semelhante ao usado no Magit .
Características
Definição de pop-up
O pop-up no contexto desta pergunta significa uma pequena janela temporária que contém uma coleção de itens de menu para que o usuário possa selecionar um e apenas um desses itens.
Posição na tela
É permitido que o pop-up apareça em qualquer parte da tela, mas é desejável que seja bastante óbvio e, portanto, apareça ao lado da janela ativa no momento.
Conteúdo do buffer pop-up
Os itens devem ser exibidos em forma de tabela bonita. Pretty é contexto da pergunta significa visualmente atraente, esse efeito pode ser alcançado mais facilmente colocando itens de menu em linhas retas, veja,
complete--insert-string
por exemplo. Este parágrafo serve para esclarecimentos adicionais. Você pode fazê-lo à sua maneira. Isso não tornará sua resposta incorreta.
Seleção do item de menu
Espera-se que a seleção seja realizada pressionando uma única tecla ou, opcionalmente, com um mouse (embora não seja tão importante, portanto, as respostas que contêm proposições que não suportam o mouse são legais). Se você propõe uma solução que suporta mouse, observe que o usuário deve poder selecionar um item de menu de maneira intuitiva, ou seja, clicando com o botão esquerdo na opção desejada.
O mouse NB pode ser usado de várias maneiras e maneiras alternativas para indicar uma escolha também são bem-vindas.
Eliminação de pop-up
Depois que o usuário seleciona um item de menu da maneira descrita acima, o buffer e, portanto, sua janela devem ser eliminados da visualização e eliminados. A janela que estava ativa antes da chamada do menu pop-up deve obter o foco (ou seja, tornar-se ativo) novamente.
Valor retornado e argumentos
De preferência, essa consequência de ações deve resultar em um objeto Lisp retornado. O objeto Lisp pode ser:
nil
- isso indica que o usuário cancelou o menu pop-up pressionando C-gou de alguma outra maneira †.string
- string (é permitido usar um símbolo) deve serstring-equal
uma das strings fornecidas no menu pop-up como coleção de itens reais.
Formas alternativas de informar o restante do programa sobre a escolha do usuário ou, possivelmente, sua ausência, são aceitáveis. No entanto, se não estiver claro de que outra forma isso pode ser executado, peço a todos os respondentes que improvisem e não me peçam mais esclarecimentos sobre esse aspecto.
Isso é tudo para o valor retornado. Quanto aos parâmetros de entrada, eles devem incluir pelo menos a coleção de strings que representam possíveis opções (ou seja, itens de menu).
Respostas Aceitáveis
A resposta esperada pode ter as seguintes formas:
Fragmento de código suficiente que permite que o leitor instruído escreva funções como as descritas acima; não é esperado ou necessário escrever toda a função de trabalho. No entanto, para evitar incertezas (partes consideráveis do código podem ser omitidas?), Devo observar que partes ausentes do trecho devem ser descritas no componente textual da resposta.
Um link para a biblioteca existente que implementa funcionalidade semelhante. Para evitar incertezas, devo observar que semelhante em nosso caso significa que a biblioteca pode ser usada para criar pop-up (veja a definição acima) que possui pelo menos 2 ou 3 recursos descritos acima. Se a biblioteca proposta for diferente do ponto em que a condição declarada anteriormente não puder ser atendida, cada um desses casos será julgado de forma independente e sempre será votado se o OP considerar útil.
Descrição das funções internas do Emacs ou de terceiros que podem ser usadas para implementar qualquer recurso descrito na seção «Recursos», veja acima. Para evitar incertezas, indique claramente como sua resposta pode ser útil para futuros leitores que desejam implementar pop-up , menu pop-up semelhante ao usado no Magit .
† Formas alternativas de abortar o menu pop-up podem incluir o seguinte (mas não limitado a estes):
clicar fora da janela do menu pop-up;
morte de buffer contendo o pop-up sem fazer uma escolha.
magit-popup
. O novo pacote é chamadotransient
e é isso que é usado nas versões atuais domagit
. Veja magit.vc/manual/transient para documentação.Hydras são bem simples de escrever:
O Hydra é uma interface centralizada no teclado e, em sua forma básica, não é mais difícil do que
easy-menu-define
(embutida). E é bastante extensível se você quiser fazer coisas mais complexas.Basta olhar para essa interface do twitter, a janela inferior é uma Hydra personalizada, não muito mais difícil de escrever do que a acima:
O código para isso está disponível no wiki , junto com muitos outros exemplos.
fonte
Após algumas pesquisas, encontrei um idioma que pode ser usado para criar uma janela na parte inferior (ou mesmo em qualquer lugar) da janela atualmente ativa. Isso por si só tem efeito de janela auxiliar temporária:
Você pode brincar um pouco com o
action
argumento dewith-current-buffer-window
se deseja que o pop-up apareça em diferentes partes da tela.A função Sair é descrita na sequência de documentos de
with-current-buffer-window
, pode ser usada para obter informações do usuário. Como o @tarsius sugeriu,read-char-choice
é um bom candidato para experimentar.O próprio buffer pop-up pode ser gerado como qualquer outro buffer. Ainda estou pensando nos botões, porque o usuário pode usar o mouse para selecionar um item no menu pop-up, não apenas o teclado. No entanto, isso requer um esforço adicional se você quiser fazê-lo bem.
Se o seu pop-up for um pouco ad-hoc e você não precisar dele mais de uma vez, poderá sair com esta solução. Além disso, dê uma olhada
completion--insert-strings
. Achei bastante útil como um exemplo de como gerar linhas bonitas de itens de menu, você pode até usá-lo inalterado se não precisar de algo especial.fonte
Aqui está uma solução de terceiros, usando Sincelos .
Seu código abre uma janela com os candidatos organizados ordenadamente como um menu. Para saber como, veja abaixo.
Você prefixa cada item de menu com um caractere exclusivo. Por exemplo, a, b, c ... ou 1, 2, 3 ... O usuário pressiona o caractere para escolher o item.
Você vincula algumas variáveis ao redor de uma chamada
completing-read
. Você passa uma lista dos itens de menu. Opcionalmente, você especifica um dos itens como o padrão, escolhido se o usuário clicarRET
.As ligações de variáveis informam
completing-read
para:Você pode deixar os itens do menu tão sofisticados quanto desejar (não mostrado).
mouse-3
menu pop-up, para fazer qualquer coisa com o itemVocê também pode criar menus verdadeiramente de múltipla escolha , ou seja, menus em que um usuário pode escolher vários itens ao mesmo tempo (escolha um subconjunto das opções possíveis).
fonte
Você também pode estar interessado em olhar para o pacote
makey
. Ele tem o objetivo de fornecer funcionalidades semelhantes àsmagit-popup
e é uma bifurcação do predecessor demagit-popup
(magit-key-mode
, mencionado no comentário) de quando ainda não era um pacote disponível separadamentemagit
.Deixe-me mencionar também
discover
: esse é um exemplo de como usarmakey
(e também a sua razão de ser). Esse pacote visa ajudar os recém-chegados a descobrir as ligações do emacs.Referências
makey
ediscover
por seu autor.magit-popup
foi transformado em seu próprio pacote.fonte
O Guide-Key funciona bem para mim em todos os prefixos configurados.
fonte
Com base na resposta de @ Drew (Sincelos), com modificações para separar a implementação do menu dos dados do menu - para que vários menus possam ser definidos, cada um com o seu: (conteúdo, prompt, padrão).
Opcionalmente, ele usa o ivy (quando disponível), que possui recursos mais avançados, como poder ativar itens enquanto mantém o menu aberto.
Pop-up genérico.
Exemplo de uso, atribua algumas ações à tecla f12:
fonte