Skip to content

Conversation

@dhruvisompura
Copy link
Contributor

@dhruvisompura dhruvisompura commented Oct 21, 2025

Related to #9713 (the ask to have a mechanism to switch between modes already exists)

This PR is a suggestion for improving the edit to view mode experience for markdown cells.

While playing around with notebooks, I noticed that there was some inconsistency with how markdown cells behaved when using the keyboard vs the cell action bar that caused me a bit of confusion.

When you are in edit mode for a markdown cell, the cell action bar has a chevron icon button that hides the editor for markdown cells. I assumed this action was changing the cell from edit to view mode. The notebook also has a keybinding to exit edit mode that maps to Escape. This command does not do the same thing as the button in the cell action bar. When you press Escape in a markdown cell, focus moves to the markdown cell container and leaves the editor. The markdown editor view stays around with the preview underneath it.

It was unclear that this mismatch in behavior was intentional! I think another reason that the edit to view mode transition in markdown cells is confusing has to do with not having a great visual indicator for being in view mode. We show a focus indicator around the cell when a user is in edit mode, but there isn't anything like that for view mode.

I can close out this PR If we don't want to consolidate the behavior and need it to be different, but I figured I'd see what folks thought. I find the consolidation makes things less confusing.

It turns out we have 2 different commands that address exiting edit mode:

  • positronNotebook.cell.collapseMarkdownEditor -> command for action that shows up in markdown cell action bars
  • positronNotebook.cell.quitEdit -> command to exit edit mode for all cell types that is not contributed to any action bars

I think we still need two separate actions, one that allows us to contribute a button to a cell action bar, and a generic one that we can attach the keybinding to. I just think the behavior for both should be the same!

BEFORE

Screen.Recording.2025-10-21.at.4.29.49.PM.mov

AFTER

Screen.Recording.2025-10-21.at.4.26.51.PM.mov

Release Notes

New Features

  • N/A

Bug Fixes

  • N/A

QA Notes

@:positron-notebooks

@github-actions
Copy link

github-actions bot commented Oct 21, 2025

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:positron-notebooks

readme  valid tags

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just added a bunch of comments here that I thought were helpful

Comment on lines +44 to 48
/**
* POSITRON_NOTEBOOK_CELL_IS_EDITING looks to be a duplicate of POSITRON_NOTEBOOK_CELL_EDITOR_FOCUSED.
* The context key value is set but never actually read anywhere in the codebase. Consider removing it if it's not needed.
*/
export const POSITRON_NOTEBOOK_CELL_IS_EDITING = new RawContextKey<boolean>('positronNotebookCellIsEditing', false);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This key will probably get cleaned up when #9992 is tackled since that will require updating this file.

Copy link
Contributor

@seeM seeM left a comment

Choose a reason for hiding this comment

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

Thanks this is neat! Probably worth discussing this in today's sync.

I believe we were matching Jupyter Lab where the expectation is that you "run" a markdown cell (usually with Shift+Enter) to preview it.

VSCode and PyCharm both use your suggested approach of defaulting to preview and only editing via a user action: pressing enter on the cell or double clicking it.

I think this is more intuitive, and there's already presedence so it shouldn't be too surprising for users.

One issue, maybe to track separately: should it also automatically preview when you click a different cell while editing a markdown cell?

Screen.Recording.2025-10-22.at.09.04.14.mov

export const POSITRON_NOTEBOOK_CELL_IS_ONLY = new RawContextKey<boolean>('positronNotebookCellIsOnly', false);
/**
* Context key that is true when the markdown editor of a cell is open for editing.
* This does not necessarily mean the cell is focused, just that the editor is visible.
Copy link
Contributor

Choose a reason for hiding this comment

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

Where could focus be if not in the open editor? Doesn't your PR make it so that an open editor is always focused?

Am I correct that if the editor is open then the cell will definitely be "active" and "selected"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Where could focus be if not in the open editor? Doesn't your PR make it so that an open editor is always focused?

Hah, yes you are right. I added this comment before I made the code change and forgot to change it 🙈. With this code change you can no longer have the editor open without it being focused! I will get this comment updated, thanks for catching that!

Am I correct that if the editor is open then the cell will definitely be "active" and "selected"?

That sounds right to me. We don't really differentiate between the two right now (really only matters for multi-select) but for the purposes of this PR when the editor is open the cell should be "active" and "selected".

@midleman
Copy link
Contributor

Oh! I like this. I've been struggling with this myself and this makes it way more obvious what is happening where. 💛

nstrayer
nstrayer previously approved these changes Oct 22, 2025
Copy link
Contributor

@nstrayer nstrayer left a comment

Choose a reason for hiding this comment

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

I like it. I do think this behavior is more obvious. (Why would someone ever want to have the editor open but not be editing markdown text?)

The pattern does beg the question of if we should make registerCellAction able to do multiple action bar items with non-overlapping when clauses. Could run the risk of burdening the function with too much work though...

@dhruvisompura
Copy link
Contributor Author

@nstrayer

The pattern does beg the question of if we should make registerCellAction able to do multiple action bar items with non-overlapping when clauses. Could run the risk of burdening the function with too much work though...

This crossed my mind and I was wondering if there was a way to consolidate this into one action but it didn't seem worth to effort to do that right now.

I do think a private helper used by both actions would normally be the ideal route to signal these actions are linked together but in this case the helper seemed redundant because of the different parameters that registerCellAction and registerNotebookAction take.

Maybe a comment is what we need in the interim.

@dhruvisompura dhruvisompura requested a review from seeM October 22, 2025 17:01
@dhruvisompura
Copy link
Contributor Author

One issue, maybe to track separately: should it also automatically preview when you click a different cell while editing a markdown cell?

@seeM Ah, great catch! I think it would make sense for it to automatically switch to the preview when you click to a different cell from a usability perspective. I'll see if I can include the change here.

That being said, if others think that the existing behavior makes sense, I can also leave it. I can't really think of a reason as to why we wouldn't want to change this, but please let me know if there is one!

[SelectionState.MultiSelection]: [
SelectionState.MultiSelection, // Modify selection
SelectionState.SingleSelection, // Reduce to single cell
SelectionState.EditingSelection, // Enter edit mode for single cell
Copy link
Contributor Author

Choose a reason for hiding this comment

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

While I was testing these changes I noticed that we didn't handle going from multi selection -> editing which I think we should be doing?

Repro Steps:

  1. Select multiple cells via Shift + arrow keys
  2. double-click on a markdown cell in view mode -> expectation is that all other cells get deselected and the cell that was double-clicked is selected for editing

Here's the before video:

invalid_selection_state_error.mov

Here's the after video:

Screen.Recording.2025-10-22.at.3.41.38.PM.mov

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice catch!

Comment on lines 96 to 105

// Close any open markdown cell editors when clicking on a different cell
// This must happen before any early returns to ensure markdown cells always close
const cells = notebookInstance.cells.get();
for (const otherCell of cells) {
if (otherCell !== cell && otherCell.isMarkdownCell() && otherCell.editorShown.get()) {
otherCell.toggleEditor();
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alrighty, this is the code change that makes it so a markdown cell in edit mode transitions to view mode when a user clicks on a different cell.

I don't love the implementation being here for this (pretty sure there's a better way to do this), will probably undo this and revisit later. Having the cell itself handle closing the editor onBlur makes more sense but its a bit more work than I was expecting.

cc @nstrayer

Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively in the layout effect above you could add the condition:

// If the editor is opened but we're not in editing mode, close the editor
if (cell.isMarkdownCell() && cell.editorShown.get() && selectionStatus !== CellSelectionStatus.Editing) {
	cell.toggleEditor();
}

Which will let the markdown cell itself ensure that it closes its cell. As long as it's commented like this I dont think either one is better than the other though!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this into the layoutEffect and I noticed the UI was a bit snappier when it came to hiding the editor. Thanks for pointing this out!

seeM
seeM previously approved these changes Oct 23, 2025
Copy link
Contributor

@seeM seeM left a comment

Choose a reason for hiding this comment

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

Looks great and ty for the additional improvements! The integration test is unrelated and I think going to be skipped

Co-authored-by: Wasim Lorgat <[email protected]>
Signed-off-by: Dhruvi Sompura <[email protected]>
nstrayer
nstrayer previously approved these changes Oct 23, 2025
Copy link
Contributor

@nstrayer nstrayer left a comment

Choose a reason for hiding this comment

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

Looks great. This is definitely a quality of life improvement to shave away some annoying frictions.

@dhruvisompura dhruvisompura merged commit 209e82e into main Oct 24, 2025
12 checks passed
@dhruvisompura dhruvisompura deleted the bugfix/view-mode-keybinding branch October 24, 2025 21:15
@github-actions github-actions bot locked and limited conversation to collaborators Oct 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants