Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing and simplifying New Chat keybindings logic #6514

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

arafatkatze
Copy link
Collaborator

@arafatkatze arafatkatze commented Jan 3, 2025

Solves linear issue

Loom Video

Test plan

Open the debugger and just test all things chat with alt+l command which is very simple or select something and try the shift+alt+l to add to chat

Changelog

@@ -608,57 +608,16 @@
"when": "!cody.activated"
},
{
"command": "cody.chat.toggle",
"command": "cody.chat.simpleNewChat",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the words "simple" and "new" are in my deny-list of names to use in code. The "new" thing always eventually becomes old, and the "simple" is almost never simple in the end.

},
{
"command": "cody.mention.selection",
"key": "shift+alt+l",
"when": "cody.activated && editorTextFocus && editorHasSelection"
},
{
"command": "cody.mention.selection",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should aim to keep some basic compatibility with older commands where possible. One option is to keep the command IDs, but they are just aliases for the main chat command. People may have configured custom shortcuts for these IDs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One option is to keep the command IDs, but they are just aliases for the main chat command. People may have configured custom shortcuts for these IDs.

Yeah I suppose we can keep them(so that's what I will do). Personally I think we probably shouldn't have introduced so much optionality in the first place. Too many options is too much confusion but I suppose we should just keep these things to maintain compatibility.

@@ -15,7 +15,7 @@ import type { SyntaxNode } from 'web-tree-sitter'
import { execQueryWrapper } from '../tree-sitter/query-sdk'

const EDIT_SHORTCUT_LABEL = isMacOS() ? 'Opt+K' : 'Alt+K'
const CHAT_SHORTCUT_LABEL = isMacOS() ? 'Opt+L' : 'Alt+L'
const CHAT_SHORTCUT_LABEL = isMacOS() ? 'Shift+Opt+L' : 'Shift+Alt+L'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional to require the shift modifier here? Our primary chat shortcut should ideally only be option+l or command+l

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically I have two two different chat shortcuts here.

  1. New chat which is Alt+L
  2. Add to chat when you select some text and that is Shift+Alt+L

See https://www.loom.com/share/5e306ff626b145c891e79c1fa016d9e4 for explaination

}
),
vscode.commands.registerCommand('cody.chat.simpleNewChat', async () => {
await this.panel.clearAndRestartSession()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not tested this locally, but this seems to unconditionally clear the session, which is not the desired behavior. We should only restart the session when 1) the sidebar is focused and 2) when the text input is non-empty. We also need to handle the modality here, and I'm not fully sure what to do there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should only restart the session when 1) the sidebar is focused

So when the sidebar is NOT focused on you press keybindings for new chat you move to a chat but you don't Actually start the new chat? isn't that moot then?

  1. when the text input is non-empty.

So this one will require some webview manipulation because instead of checking "text is non-empty" we check if history is non empty and we could do that but I am not entirely sure if that's a good idea. The new chat keybindings should be very simple. Whenever you press then you either move to the new chat view that's just an empty chat or you start a new chat.

We also need to handle the modality here

I would disagree because that's the essence of the confusion. When you have editor chat do X and when you have sidebar chat do Y is just bad confusing behavior which was what you pointed out in the original slack thread.

Can't we get rid of it all and just do new chat= sidebar's new chat

Copy link
Member

@olafurpg olafurpg Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposal here had clear instructions on the desired behavior, and it includes testing things like whether the chat input is empty or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we get rid of it all and just do new chat= sidebar's new chat

I am OK with this, and it's roughly what I alluded to on Slack. Chat editors are a great feature but for the Option+L shortcut I think it simplifies a lot if it only works with the sidebar. When you expand a chat into the editor then this chat goes out of the shortcut "system"

@@ -130,7 +130,7 @@ const HINT_DECORATIONS: Record<
{ text: string; decoration: vscode.TextEditorDecorationType }
> = {
EditOrChat: {
text: `${EDIT_SHORTCUT_LABEL} to Edit, ${CHAT_SHORTCUT_LABEL} to Chat`,
text: `${EDIT_SHORTCUT_LABEL} to Edit, ${CHAT_SHORTCUT_LABEL} to Add to Chat`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"add to" indicates this is a different thing. We should just have a single chat command.

Copy link
Collaborator Author

@arafatkatze arafatkatze Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This for the ghost text which shows when you select something so you want to "add to the existing chat" by adding the user selection as the context so that's what this does.

"add to" indicates this is a different thing

So this is a different thing.

Copy link
Collaborator Author

@arafatkatze arafatkatze Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should just have a single chat command.

So then I can just remove it and go ${CHAT_SHORTCUT_LABEL} to start new Chat and then stop doing this "add to chat" thing but I think its good to have a new chat and then another "add to chat" option. Those are decent choices and its clean.

Try locally and you will see.

@@ -30,7 +30,7 @@ const chatTips: ChatViewTip[] = [
vsCodeOnly: true,
},
{
message: 'Start a new chat with ⇧ ⌥ L or switch to chat with ⌥ /',
message: 'Press ⌥ L to start a new chat or switch to chat view',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keeping the option+L shortcut here but it's shift+option+L above? The "or switch to" reads as a different thing "command does X, or do Y" instead of "command X does A+B".

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I am aware of that. and I mentioned it in the video too but basically I think if I just do Press ⌥ L to start a new chat that would be succinct and do that job.

Copy link
Contributor

@ichim-david ichim-david Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arafatkatze @olafurpg I'm just an user who has made a few contributions to this repo as such my input might not be worth much but I think Options + L should focus on the last input of the existing chat and hitting it again would toggle the panel visibility.

This is how it happens with Windsurf and also to some degree with Cursor (it toggles the panel visibility but starts a new conversation).
In Windsurf hitting shift + option + L starts a new conversation exactly like how Cody did it up to this point and hitting option + L simply focuses in the last input box and toggles the panel visibility.

I would also like to caution against changing the shortcut from option + L to shift + option + L as users might have changed it or have been used to having option + L keyboard shortcut.

The only problem I see in the current behavior is when you select a text and you get the ghost text that lets you know you can edit it with option + k or option + L to chat.
When I press option + L I would expect for what I had selected in the editor to be added to the chat input and currently what it does is to simply focus on the last input from the opened chat panel.
option-l-chat

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ichim-david thank you for your input! The shortcut will remain Option+L, and I left another comment about keeping compatibility with existing command IDs for people who have registered custom shortcuts.

On the exact behavior, I'm torn on the behavior of Option+L when you have a text selection, and I'm curious to hear what you think.

My feeling is that the "add to chat" behavior isn't helpful because chats already include the text selection by default. You end up with duplicate chips. I still think it's useful to display the shortcut in the decoration to make it easier to discover for users.

Copy link
Contributor

@ichim-david ichim-david Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ichim-david thank you for your input! The shortcut will remain Option+L, and I left another comment about keeping compatibility with existing command IDs for people who have registered custom shortcuts.

On the exact behavior, I'm torn on the behavior of Option+L when you have a text selection, and I'm curious to hear what you think.

My feeling is that the "add to chat" behavior isn't helpful because chats already include the text selection by default. You end up with duplicate chips. I still think it's useful to display the shortcut in the decoration to make it easier to discover for users.

Since hitting option + k will only affect the selected text I would expect the same to happen if I hit the shortcut to have it added to the chat input.
Unfortunately, you get the current file chip added before the selection and even if you get rid of it as soon as you modify the selection the current file chip comes back.

Depending on where you are coming from (let us say you don't have the chat window open, hitting option + L and seeing both the full file and the selection added is an anti-pattern as I wouldn't expect that to happen).

See this short screencast for what I mean
https://github.com/user-attachments/assets/63ed9645-337e-4a8c-9dbb-64763ecd0461

A small nit is the fact that if you delete the context and switch between windows nothing happens but I don't expect many users to try this and complain.

Hopefully, this is helpful for you @olafurpg

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for sharing the video! The original motivation to kickstart this PR was that the current behavior is both buggy and confusing, and we want to simplify things so you only need to remember a single simple shortcut like option+L and it does what most people want most of the time. We can optionally expose commands for more narrow use-cases that have no defined shortcuts, which is helpful for power users.

I'm leaning towards that option+L with selected text should "freeze" that selection in the input. We currently have a dynamic chip that updates alongside the text selection. When you trigger the shortcut with text selection, then the dynamic chip is replaced with a hardcoded chip. However, I don't think it's urgent to implement this behavior in the first PR. To start with, we should just make Option+L reliably open the chat.

Copy link
Contributor

@ichim-david ichim-david Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@olafurpg here is one last video where I show how Cody add to chat differs from Windsurf and Cursor, perhaps it might be useful as feedback for you guys for any kind of future considerations.

command-l-behavior.mp4

EDIT:
I forgot to show in the video that repeated use of command + L toggles the chat panel visibility
in the same way it happens with Windsurf.

@arafatkatze
Copy link
Collaborator Author

Hey @olafurpg I updated the implementation with these edge cases

Primary Shortcut Requirements

  • Option+L as primary shortcut
  • Handle all/most chat-related actions in one command

Core Functionality

  • Open chat sidebar when not focused
  • Discard non-empty input and start new chat if sidebar is open

    Note: Required complex implementation to handle unsubmitted content by reaching into React editor component for clearing

  • Hide sidebar when focused with empty chat input

    Blocker: Requires bidirectional communication between backend-webview-backend to check input state

  • Handle selection-to-chat cleanly

    Note: Core functionality working, minor edge cases to be addressed in separate PR

Sidebar and Editor Management

  • Default shortcuts only deal with sidebar chats

Command Palette Integration

  • "New Chat" in command palette matches Option+L behavior
  • Consistent shortcut discovery
  • Clear ghost text indication for new chat actions

Outstanding Issues (To Be Addressed Separately)

  • Managing input state during chat response streaming
  • Fixing black sidebar during streaming responses
  • Edge cases in selection-to-chat behavior

The implementation successfully addresses most core requirements while maintaining a simplified user experience. The remaining unchecked items require additional architectural considerations or will be addressed in separate PRs for better isolation of concerns. Hope this helps

@arafatkatze arafatkatze requested a review from olafurpg January 5, 2025 13:58
@olafurpg
Copy link
Member

olafurpg commented Jan 6, 2025

Thanks @arafatkatze !

Discard non-empty input and start new chat if sidebar is open

I'm unable to reproduce this behavior when I run it locally, the alt-L shortcut has no effect when have a non-empty input. The "New Chat" button also does not work anymore, it has no effect.

@arafatkatze
Copy link
Collaborator Author

arafatkatze commented Jan 6, 2025

Thanks for the feedback @olafurpg! I've fixed the "New Chat" button issue.

Discard non-empty input and start new chat if sidebar is open. I'm unable to reproduce this behavior when I run it locally, the alt-L shortcut has no effect when have a non-empty input

Regarding the alt-L behavior, I have a quick UX question to ensure we implement the right pattern:
When a user presses alt-L with selected text in the editor, which behavior would you prefer?

  1. Always start a fresh new chat
  2. Focus the existing chat and add the selection as context (treating alt-L as "I want to chat about this"). This is current behavior and will NOT clean the unsent chat.

I can implement either approach - just want to make sure we choose the most intuitive one for users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants