s-kostyaev / ellama

Ellama is a tool for interacting with large language models from Emacs.
GNU General Public License v3.0
558 stars 38 forks source link

Add transient menu for ellama #162

Closed markokocic closed 1 month ago

markokocic commented 1 month ago

Instead of having to memorize a bunch of keybindings for different options, it would be nice if ellama would come out of the box with a menu bound to key binding. I created one for me, using transient package, and bind in to a C-c e prefix in my config file.

I created this menu system and grouped commands to groups based on prefixed. You may review the menu organization and include it with the base package.

  (transient-define-prefix ellama-transient-code-menu ()
    "Code Commands"
    [["Code Commands"
      ("c" "Complete" ellama-code-complete)
      ("a" "Add" ellama-code-add)
      ("e" "Edit" ellama-code-edit)
      ("i" "Improve" ellama-code-improve)
      ("r" "Review" ellama-code-review)
      ("m" "Generate Commit Message" ellama-generate-commit-message)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-summarize-menu ()
    "Summarize Commands"
    [["Summarize & Session Commands"
      ("s" "Summarize" ellama-summarize)
      ("w" "Summarize Webpage" ellama-summarize-webpage)
      ("c" "Summarize Killring" ellama-summarize-killring)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-session-menu ()
    "Session Commands"
    [["Session Commands"
      ("l" "Load Session" ellama-load-session)
      ("r" "Rename Session" ellama-session-rename)
      ("d" "Remove Session" ellama-session-remove)
      ("a" "Activate Session" ellama-session-switch)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-improve-menu ()
    "Improve Commands"
    [["Improve Commands"
      ("w" "Improve Wording" ellama-improve-wording)
      ("g" "Improve Grammar" ellama-improve-grammar)
      ("c" "Improve Conciseness" ellama-improve-conciseness)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-make-menu ()
    "Make Commands"
    [["Make Commands"
      ("l" "Make List" ellama-make-list)
      ("t" "Make Table" ellama-make-table)
      ("f" "Make Format" ellama-make-format)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-ask-menu ()
    "Ask Commands"
    [["Ask Commands"
      ("i" "Chat" ellama-chat)
      ("l" "Ask Line" ellama-ask-line)
      ("s" "Ask Selection" ellama-ask-selection)
      ("a" "Ask About" ellama-ask-about)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-translate-menu ()
    "Translate Commands"
    [["Translate Commands"
      ("t" "Translate Text" ellama-translate)
      ("b" "Translate Buffer" ellama-translate-buffer)
      ("e" "Enable Translation" ellama-chat-translation-enable)
      ("d" "Disable Translation" ellama-chat-translation-disable)
      ("c" "Text Complete" ellama-complete)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-context-menu ()
    "Context Commands"
    [["Context Commands"
      ("b" "Add Buffer" ellama-context-add-buffer)
      ("f" "Add File" ellama-context-add-file)
      ("s" "Add Selection" ellama-context-add-selection)
      ("i" "Add Info Node" ellama-context-add-info-node)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-provider-menu ()
    "Provider Commands"
    [["Provider Commands"
      ("s" "Select Provider" ellama-provider-select)]
     ["Quit" ("q" "Quit" transient-quit-one)]])

  (transient-define-prefix ellama-transient-main-menu ()
    "Main Menu"
    [["Chat"
      ("a" "Ask" ellama-transient-ask-menu)
      ("c" "Code" ellama-transient-code-menu)]]
    [["Text"
      ("s" "Summarize" ellama-transient-summarize-menu)
      ("i" "Improve" ellama-transient-improve-menu)
      ("t" "Translate" ellama-transient-translate-menu)
      ("m" "Make" ellama-transient-make-menu)]]
    [["System"
      ("S" "Session" ellama-transient-session-menu)
      ("x" "Context" ellama-transient-context-menu)
      ("p" "Provider" ellama-transient-provider-menu)]]
    [["Quit" ("q" "Quit" transient-quit-one)]]))

Once menus are defined, you can bind them to your use-package config like this:

(use-package ellama
  :ensure t :defer t :after transient
  :bind (("C-c e" . ellama-transient-main-menu)
         ("C-c c" . ellama-chat))
s-kostyaev commented 1 month ago

Thank you! It was planned long time ago, but I can't find free time to implement it

markokocic commented 1 month ago

The only thing I'm not sure is the naming. I followed the names and menu structure from the table of all shortcuts in README, but I'm not sure if that's the best hierarchy overall. I can make a PR on Monday and then we can refine it.

markokocic commented 1 month ago

Ok, I created the PR.

Before merging, I think it would make sense to align key bindings and menu structure, so that people end up executing the same command by typing the same keys, regardless if they define ellama prefix to "C-c e" or bind "C-e e" to the ellama-transient-main-menu.

I personally bind "C-c c" to ellama-chat as the most frequently used command, and "C-c e" to the menu.

s-kostyaev commented 1 month ago

maybe we can use better hierarchy. Do you have any ideas?

markokocic commented 1 month ago

I tried to define a new structure for the menu. I regrouped commands a bit. The issue is, submenus need different keys, so I ended up with s for Summarize and S for Session. Also, I'm not sure about "Make", should it be grouped or be in its own menu.

s-kostyaev commented 1 month ago

I don't write transient menus yet. What's the difference between grouping and separated menus?

markokocic commented 1 month ago

I'm also not an expert in transient, was just playing with it to create a menu for ellama to make it more discoverable for me.

You can define one of menu groups in the menu to put together related commands or submenus together. LIke for example in this example I put "System" group which groups "Session", "Context" and "Provider" submenus. You can define group names as you wish, but each submenu shortcut needs to be unique inside a menu.

In this case, those shortcuts just open another submenu, but it would also be possible to have commands assigned to them.

s-kostyaev commented 1 month ago

Let it be submenu then. I think it makes sense.

markokocic commented 1 month ago

All menus and submenus in PR are defined with transient-define-prefix. You can try it out to see what makes the most sense for you.

Nebucatnetzer commented 1 month ago

I gave it a try and I like it a lot, makes it way easier to use. One thing I noticed, is that there is a bit of inconsistency when it comes to the keybindings. However they are coming from ellama itself and not this specific pull request. It just highlights them more.

E.g. C-c e a i says Chat, while maybe "Interactive Chat" would make more sense. Then "Text" has four sub menus while all the actions for code are hidden behind "c". Inside "Text" we have the following two functions but I'm not sure they make sense withing the "Text" context since the function names suggest that they are more related to the interactive chat. I just had a quick look into it so I might be wrong about these findings.

      ("e" "Enable Translation" ellama-chat-translation-enable)
      ("d" "Disable Translation" ellama-chat-translation-disable)
markokocic commented 1 month ago

I based menu system based on keybindings, without knowing what every entry mean. Feel free to reorganise it.

s-kostyaev commented 1 month ago

C-c e a i was "ask interactively" before. I think it should be c at the top level, and code actions should be under C. Probably we can improve it more.

s-kostyaev commented 1 month ago

Translations of chat session should not messing up with text actions. I'm not sure where to put it.

markokocic commented 1 month ago

I updated the menus in PR. Chat moved to top level as "c" Code shortcut changed to "C" Provider selection moved to top level, since it's the only command in own menu.

s-kostyaev commented 1 month ago

I have added a couple comments. But in general LGTM. Address comments and hopefully we will merge it.