Pytanie
Chciałbym stworzyć interfejs użytkownika w postaci menu kontekstowego , menu kontekstowego podobnej do tej stosowanej w MAGIT .
funkcje
Definicja wyskakującego okienka
Wyskakujące okienko w kontekście tego pytania oznacza niewielkie tymczasowe okno, które zawiera zbiór elementów menu, dzięki czemu użytkownik może wybrać jeden i tylko jeden z tych elementów.
Pozycja na ekranie
Wyskakujące okienko może pojawiać się w dowolnej części ekranu, ale pożądane jest, aby było dość oczywiste i dlatego powinno się pojawiać obok aktualnie aktywnego okna.
Zawartość Popup Buffer
Przedmioty powinny być wyświetlane w formie ładnego stołu. Ładny jest kontekst pytania oznacza atrakcyjny wizualnie, efekt ten można najłatwiej osiągnąć, umieszczając elementy menu w prostych rzędach, patrz
complete--insert-string
na przykład. Ten akapit służy dodatkowym wyjaśnieniom, możesz to zrobić na swój własny sposób, co nie spowoduje, że twoja odpowiedź będzie niepoprawna.
Wybór pozycji menu
Oczekuje się, że selekcja zostanie przeprowadzona przez naciśnięcie jednego klawisza lub, opcjonalnie, za pomocą myszy (chociaż nie jest to tak ważne, więc odpowiedzi zawierające propozycje, które nie obsługują myszy, są legalne). Jeśli zaproponujesz rozwiązanie, które obsługuje mysz, pamiętaj, że użytkownik powinien być w stanie wybrać element menu w intuicyjny sposób, to znaczy klikając lewym przyciskiem myszy żądany wybór.
Myszy NB można używać na wiele sposobów; mile widziane są również alternatywne sposoby wskazania wyboru.
Eliminacja wyskakującego okienka
Gdy użytkownik wybierze pozycję menu w sposób opisany powyżej, bufor, a tym samym jego okno, należy usunąć z widoku, a także zabić. Okno, które było aktywne przed wywołaniem menu podręcznego, powinno ponownie stać się aktywne (to znaczy stać się aktywne).
Zwrócona wartość i argumenty
Najlepiej, jeśli ta konsekwencja działań powinna spowodować zwrócenie obiektu Lisp. Obiektem Lisp może być:
nil
- oznacza to, że użytkownik przerwał menu podręczne, naciskając C-glub w inny sposób †.string
- ciąg (dozwolone jest użycie symbolu) powinien byćstring-equal
jednym z ciągów dostarczonych do menu podręcznego jako zbiór rzeczywistych elementów.
Dopuszczalne są alternatywne sposoby poinformowania reszty programu o wyborze użytkownika lub ewentualnie jego braku. Jeśli jednak nie jest jasne, jak inaczej można to zrobić, proszę wszystkich improwizujących o improwizację i nie proszę o dalsze wyjaśnienia tego aspektu.
To wszystko dla zwróconej wartości. Jeśli chodzi o parametry wejściowe, powinny one obejmować przynajmniej zbiór ciągów, które reprezentują możliwe wybory (tj. Pozycje menu).
Dopuszczalne odpowiedzi
Oczekiwana odpowiedź może mieć następujące formy:
Wystarczający fragment kodu, który pozwala wykształconemu czytelnikowi pisać funkcje takie jak opisano powyżej; napisanie całej funkcji roboczej nie jest oczekiwane ani konieczne. Aby jednak uniknąć niepewności (czy można pominąć znaczną część kodu?), Należy zauważyć, że brakujące części fragmentu kodu należy opisać w tekstowym składniku odpowiedzi.
Łącze do istniejącej biblioteki, która implementuje podobną funkcjonalność. Aby uniknąć niepewności, należy zauważyć, że podobnie w naszym przypadku oznacza, że biblioteki można użyć do tworzenia wyskakujących okienek (patrz definicja powyżej), która ma co najmniej 2 lub 3 funkcje opisane powyżej. Jeśli proponowana biblioteka różni się od punktu, w którym nie można spełnić wcześniej określonego warunku, każdy taki przypadek będzie oceniany niezależnie i zawsze będzie oceniany, jeśli OP uzna to za przydatne.
Opis wbudowanych funkcji Emacsa lub innych firm, których można użyć do zaimplementowania dowolnej funkcji opisanej w sekcji «Funkcje», patrz wyżej. Niepewności uniknąć należy podać wyraźnie, jak Twoja odpowiedź może być przydatne dla przyszłych czytelników, którzy chcą zaimplementować popup , menu podręczne podobną do tej stosowanej w MAGIT .
† Alternatywne sposoby przerwania menu podręcznego mogą obejmować następujące (ale nie tylko):
kliknięcie poza wyskakującym oknem menu;
zabicie bufora zawierającego wyskakujące okienko bez dokonywania wyboru.
magit-popup
. Wywoływany jest nowy pakiettransient
, który jest używany w aktualnych wersjachmagit
. Zobacz magit.vc/manual/transient dla dokumentacji.Hydry są dość proste do napisania:
Hydra to interfejs zorientowany na klawiaturę, aw swojej podstawowej formie nie jest trudniejszy niż
easy-menu-define
(wbudowany). Jest to dość rozszerzalne, jeśli chcesz sprawić, by robiło bardziej złożone rzeczy.Wystarczy spojrzeć na ten interfejs Twittera, dolne okno to niestandardowa Hydra, niewiele trudniejsza do napisania niż powyższa:
Kod tego jest dostępny na wiki wraz z wieloma innymi przykładami.
źródło
Po kilku badaniach znalazłem idiom, którego można użyć do utworzenia okna na dole (lub w dowolnym miejscu) aktualnie aktywnego okna. To samo ma wpływ na tymczasowe okno pomocnicze:
Możesz zagrać trochę z
action
argumentem,with-current-buffer-window
czy chcesz, aby wyskakujące okienko pojawiało się w innej części ekranu.Funkcja Quit jest opisana w dokumencie doc-string
with-current-buffer-window
, można jej użyć do uzyskania danych wejściowych od użytkownika. Jak sugerował @tarsius,read-char-choice
jest dobrym kandydatem do eksperymentowania.Sam bufor wyskakujący może być generowany tak jak każdy inny bufor. Nadal myślę o przyciskach, ponieważ użytkownik może użyć myszy, aby wybrać element w menu podręcznym, a nie tylko klawiaturę. Wymaga to jednak dodatkowego wysiłku, jeśli chcesz to zrobić dobrze.
Jeśli twoje wyskakujące okienko jest nieco ad-hoc i nie będziesz go potrzebować więcej niż raz, możesz uciec od tego rozwiązania. Zobacz także
completion--insert-strings
. Uznałem, że jest to całkiem przydatne jako przykład generowania ładnych rzędów pozycji menu, możesz nawet używać go bez zmian, jeśli nie potrzebujesz czegoś specjalnego.źródło
Oto rozwiązanie innej firmy, wykorzystujące Icicles .
Twój kod wyskakuje w oknie z kandydatami uporządkowanymi jako menu. Jak to zrobić, patrz poniżej.
Każdą pozycję menu poprzedza się unikalnym znakiem. Np. A, b, c ... lub 1, 2, 3 ... Użytkownik naciska znak, aby wybrać element.
Wiążesz kilka zmiennych wokół wywołania do
completing-read
. Przekazujesz mu listę swoich pozycji menu. Opcjonalnie możesz określić jeden z elementów jako domyślny, wybrany, jeśli użytkownik tylko trafiRET
.Powiązania zmienne nakazują
completing-read
:Możesz sprawić, by elementy menu były tak fantazyjne, jak chcesz (nie pokazano).
mouse-3
menu podręczne, aby zrobić cokolwiek z przedmiotemMożesz także stworzyć naprawdę wielokrotne menu , to znaczy menu, w których użytkownik może wybrać wiele elementów jednocześnie (wybierz podzbiór możliwych wyborów).
źródło
Możesz być także zainteresowany spojrzeniem na pakiet
makey
. Ma on zapewniać podobną funkcjonalność jakmagit-popup
i jest rozwidleniem poprzednikamagit-popup
(magit-key-mode
wspomnianego w komentarzu) z czasów, gdy nie był to jeszcze pakiet dostępny osobnomagit
.Pozwól mi także wspomnieć
discover
: to jest przykład użyciamakey
(a także jego racji bytu). Ten pakiet ma pomóc początkującym odkryć wiązania emacs.Bibliografia
makey
idiscover
autor.magit-popup
zostało zrobione we własnym pakiecie.źródło
Guide-Key działa miło dla wszystkich skonfigurowanych prefiksów.
źródło
Na podstawie odpowiedzi @ Drew (Icicles), z modyfikacjami oddzielającymi implementację menu od danych menu - można więc zdefiniować wiele menu, każde z własnym: (treść, monit, domyślnie).
Opcjonalnie korzysta z bluszczu (jeśli jest dostępny), który ma bardziej zaawansowane funkcje, takie jak możliwość aktywacji przedmiotów przy zachowaniu otwartego menu.
Ogólne wyskakujące okienko.
Przykład użycia, przypisz niektóre akcje do klawisza f12:
źródło