lazygit icon indicating copy to clipboard operation
lazygit copied to clipboard

Make the commit message panel non-modal

Open stefanhaller opened this issue 6 months ago • 10 comments

I'm always frustrated when I press c to commit, start typing a message, and then realize I need to look at some parts of the staged changes (in order to describe them in the message) that are currently not visible, either because they are behind the modal commit message panel, or in a file that is currenly not selected.

For committing this is not a huge deal because I can cancel the commit, look at the changes (maybe copy some function name to the clipboard), and then hit c again to resume. Since lazygit remembers the commit message, I can continue typing where I left off. It's still a bit cumbersome though, and also this is not an option when rewording a commit.

To improve this, it would be nice if the commit message panel was non-modal, like in git gui or in VS Code. Here's a rough mockup of what this could look like:

Image

The idea is that pressing c (or r in the commits panel) temporarily replaces the Command Log pane with a Commit Message pane. This could allow browsing the staged files (or the current commit in case of a reword) while the panel is showing.

Challenges

  1. It's unclear how to navigate away from the commit message panel to one of the side panels. The global navigation keys are tab, left/right, or 1-5, and these all do different things when the commit message is focused (tab switches between message and description). Clicking with the mouse in another panel would work, but for users who prefer the keyboard I don't have a great idea.
  2. If we do find a way to navigate away, then it's unclear under which conditions it should stay open, or when it should auto-close. I think it would be a bit weird if the only way to get the Command Log back is to hit Esc in the commit message; I feel it should auto-close under certain conditions, but I'm not sure what those are. For example, for committing the panel could stay open if you navigate to the Files panel, but auto-close when you focus any other side panel. For rewording it could stay open only if you switch to the Commits panel, but auto-close for any other panel. But I'm not sure this is the best rule.
  3. What if you start to reword a commit, and then while the commit message panel is showing you go to the Commits panel and rebase the branch (i.e. drop the commit). If you then go back to the panel and hit enter, the reword will work because the original commit still exists (until it is garbage-collected), but you are then rewording a commit that you don't see, which could be confusing.

I suppose there are probably many other issues that I'm not seeing yet, and it is probably a pretty large amount of work to implement this. But I'm interested in giving it a try.

stefanhaller avatar Jun 06 '25 18:06 stefanhaller

Related discussion: #4433 (but as @stefanhaller mentioned in that discussion: Discussion should continue in this issue)

linkarzu avatar Jun 06 '25 18:06 linkarzu

I started a "discussion" in a YouTube post. And I know what one of the first comments will be: "In case this is implemented, can it be made optional?"

I think there's a few folks that like the way it works right now, and other folks that would love this new idea. Leaving a link here to the YouTube post for reference, in case it helps http://youtube.com/post/UgkxOaTqFESLngLVeo0QFT8SJNgful80N81y?si=K4y7cfA69kxNGjxH

Personally, I would love to temporarily replace the Command Log pane, and I do understand that this is a lot of work, so anything that you're willing to put your time on, works for me, as long as I can see my Unstaged changes pane

linkarzu avatar Jun 06 '25 18:06 linkarzu

Concerning the challenges:

  1. Having insert/normal mode (e.g. i/esc as in vim) would allow to use the global navigation keys. Mode would be kept for the whole panel and affect whatever input (message/description) has focus. So you can still use tab to switch between the two inputs, use the mouse, or the usual keys after esc. This could be used for any modal (is there something besides commit message?). Just need an unused global shortcut. 'i' is currently used for different actions depending on the panel (ignore files, interactive rebase, ...). Alternative would be to use '6' to focus the commit message and have it live together with the command log (which would make sense IMO - the only 'mismatch' being that currently all the numbered panels are on the left).
  2. I would have the commit message be a tab next to the command log and allow to switch with ][ like the other panels. Maybe auto-switch back to the command log if there's new output, otherwise just keep the commit panel shown. I have the command panel hidden - I think the most common issue would be an empty commit panel wasting space (most of the time), so maybe auto-hide the panel if the command panel is hidden && commit message/description are empty. More generally, it may make sense to have shift-n toggle visibility of panel n (@ is already used (depending on keyboard layout); idk what else would need to be reassigned).
  3. What happens if you do the same now (reword in lazygit, rebase outside of lazygit)? Does it check every n seconds if the commit is still there? Could have some kind of dirty/detached indicator or a warning message (or try to be smart and match the commit (something like longest common prefix of messages (fixup) or hash of diff w/o message (reword) etc., however, at least when rebasing externally, these are only heuristics - idk how you'd detect squashed commits)).

vogler avatar Jun 08 '25 14:06 vogler

It's unclear how to navigate away from the commit message panel to one of the side panels.

I believe the navigation would definitely benefit from a rework and would personally love to see something close to Vim (for me the most natural way to navigate seems to be vim-tmux-navigator). If something like that would be implemented, then any kind of UI layout (present and future) will just work and things will be easier to extend.

If we do find a way to navigate away, then it's unclear under which conditions it should stay open, or when it should auto-close.

I'd suggest just closing it anytime you navigate away. As mentioned in the discussion linked above, the commit dialog is persistent, so you can close it and return back to it losing no changes, so I see no benefit in keeping it around unless it's focused. The main problem seems to be the fact that it is rendering on top of a diff, so if the popup is non-modal - that solves the problem. Trying to come up with some kind of heuristics on when to keep or auto-close it seems to have nothing to do with the problem at hand and will just add complexity and create new problems.

In regards to the proposed UI change that replaces the Command Log pane with a Commit Message pane, it feels a bit unnatural IMO. The Commit Message is tightly coupled with the Staged Files (what is going to be commited) and the proposed UI kinda moves them as far away from each other as possible. 🤔 Plus, putting it under the Preview also seems counter-intuitive, as that sort of implies that it's related to that Preview instead of the Staged Files.

Can we maybe consider putting it right under Staged Files moving (or maybe even replacing) the Branches, Commit and Stash panes (I can't think of a reason to use any of those 3 panes during commit)? This would keep those 2 relevant elements close together visually. This would look something similar to IntelliJ UI for commit. Image That will, of course, leave less room for the Commit Message pane itself, but I don't think it needs much space anyway.


Btw, looking at IntelliJ, I'd also consider joining "Commit summary" and "Commit description" into one text area, which would free up the "Tab" key to be used for other actions if needed. As far as I know they are just one "commit message" value after-all, isn't it? 🤔 I would assume that majority of the times people don't even use the "Commit description".

TimShilov avatar Jun 10 '25 17:06 TimShilov

@TimShilov I agree with the commit summary and description being joined, but when viewing a commit, I would like to see what I have currently typed (i.e. to see if what I've written makes sense with the changes).

As for the navigation, why don't we have a similar behaviour to now only with the panel being moved? So you hit c to start writing the commit and esc to move focus back to the main panels.

Not sure if there are any conflicts but could c also be a global keybinding to start the writing of the commit from any panel?

JordanllHarper avatar Jun 11 '25 14:06 JordanllHarper

Thanks for all the input so far; responding to some of it below.

  1. Having insert/normal mode (e.g. i/esc as in vim) would allow to use the global navigation keys.

This would only solve it if we make this mode unconditional, and there's no way this is going to happen. I can see how a vim mode could be desirable for vim users, or at least people who are familiar with vim and like it, but for those who don't it would be confusing and annoying. So a vim mode would have to be optional (and I'd say probably opt-in rather than opt-out), and so it doesn't help here.

(Besides, there are more reasons why I think we shouldn't add a vim mode, but that's a topic for another discussion.)

I'd suggest just closing it anytime you navigate away.

But then I don't see the point of making it non-modal in the first place. The main point of doing that is so that you can navigate in the Files panel while still seeing the commit message.

Can we maybe consider putting it right under Staged Files moving (or maybe even replacing) the Branches, Commit and Stash panes

That's a good suggestion, but it doesn't work well because the side panel is too narrow unless you have a pretty large screen. I suppose we could enlarge the side panel to, say, half the window width if the commit message is focused, but that's a bit awkward too. The VS Code commit message panel has the same problem.

I'd also consider joining "Commit summary" and "Commit description" into one text area,

There are good reasons why we made them two separate text fields, and I don't see us changing this back. I like it. 😄

As for the navigation, why don't we have a similar behaviour to now only with the panel being moved? So you hit c to start writing the commit and esc to move focus back to the main panels.

I don't want the commit message panel to be shown permanently. So when hitting esc I would expect to close the panel (or rather, reveal whatever was replaced by it, be that the command log or the branches panel). This is very much related to my question 2. above, to which I haven't seen a convincing suggestion yet.


After the discussion so far, my current feeling is that it's not worth it (opens more problems than it solves). Instead we can address the two underlying problems in different ways:

  • add a config to position the modal commit message panel differently (as suggested in #4433). I could imagine a config that takes an array of positions (e.g. commitMessagePositions: [ middle, bottom-right ]) and a keybinding in the commit message editor that allows to cycle through them (maybe ctrl-p for "position").
  • remember a half-typed commit message also for rewording, and for creating a new commit from a custom patch. We could remember the commit hash that was being reworded, so if you abort a reword and then reword a different commit, we don't reuse it.

I think these would address the problems enough, and don't open the can of worms that a non-modal commit message does.

stefanhaller avatar Jun 11 '25 17:06 stefanhaller

Addressing the command log viewing, I would show it until you write a commit message, then show the commit writing pane(?) until you have committed the changes. Once committed, show the command log again.

This comes with a conflict that if you want to see the command log while writing a commit. In that case, you could view it again with an option behind '@'.

JordanllHarper avatar Jun 12 '25 10:06 JordanllHarper

Addressing the command log viewing, I would show it until you write a commit message, then show the commit writing pane(?) until you have committed the changes. Once committed, show the command log again.

This doesn't answer the question. Of course we would hide the commit message panel when you commit the changes, that's the easy case and there's no question about it. The hard case is when you don't commit the changes, and navigate to some other panel, leaving the commit message panel open.

stefanhaller avatar Jun 12 '25 11:06 stefanhaller

The hard case is when you don't commit the changes, and navigate to some other panel, leaving the commit message panel open.

Hence the option behind the '@' binding, so the user can choose when to see the command log panel again.

JordanllHarper avatar Jun 12 '25 11:06 JordanllHarper

After the discussion so far, my current feeling is that it's not worth it (opens more problems than it solves). Instead we can address the two underlying problems in different ways:

  • add a config to position the modal commit message panel differently (as suggested in https://github.com/jesseduffield/lazygit/discussions/4433). I could imagine a config that takes an array of positions (e.g. commitMessagePositions: [ middle, bottom-right ]) and a keybinding in the commit message editor that allows to cycle through them (maybe ctrl-p for "position").

Personally, I think this makes a lot of sense, because the non-modal mode seems to require a lot of engineering due to the re-design. It can be kept as an idea for the long term future (just my personal opinion)

What if in addition to the position you can pass 2 params, width and height so people can customize the position and also size of the commit message pane, so for example: commitMessagePositions: [ middle 5 10, bottom-right 2 10] (or something along those lines)

I'm suggesting this as I guess there will be folks that will try for the popup to match the size of the commit log pane

Good positions could be: [middle, middle-left, middle-right, top, top-left, top-right, bottom, bottom-left, bottom-right]

linkarzu avatar Jun 12 '25 13:06 linkarzu