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

helix-term/commands: implement buffer-close (bc, bclose) #1035

Merged
merged 17 commits into from
Nov 15, 2021

Conversation

cole-h
Copy link
Contributor

@cole-h cole-h commented Nov 9, 2021

This behaves the same as Kakoune's delete-buffer / db command:

  • With 3 files opened by the user with :o ab, :o cd, and :o ef:
    • buffer-close once closes ef and switches to cd
    • buffer-close again closes cd and switches to ab
    • buffer-close again closes ab and switches to a scratch buffer
  • With 3 files opened from the command line with hx -- ab cd ef:
    • buffer-close once closes ab and switches to cd
    • buffer-close again closes cd and switches to ef
    • buffer-close again closes ef and switches to a scratch buffer
  • With 1 file opened (ab):
    • buffer-close once closes ab and switches to a scratch buffer
    • buffer-close again closes the scratch buffer and switches to a new
      scratch buffer

Closes #851.

I'm new to the codebase (as you can see by this being my first contribution...), so I may have done some things "wrong". Please correct me on everything, no matter how small.

Note that I publicized the jumps field of the JumpList struct in helix-view/src/view.rs in order to ensure that no references to the now-removed buffer exist anywhere. I took a naive approach at validating this: I simply used the debug formatter to print the compositor::Context struct and looked for any references to the now-removed document's ID.

If you'd prefer, I could instead make a method that would give access (mutable and not) to this field.

Also note that I named the command buffer-close instead of only bclose (but I did add this and bc as an alias) or close in order to pave the way for potentially more buffer-specific actions. Namespacing is easier at implementation time than at some point in the future where we wished we had done this.

@cole-h
Copy link
Contributor Author

cole-h commented Nov 9, 2021

Just realized I should probably also implement buffer-close! (force buffer close).

Copy link
Member

@archseer archseer left a comment

Choose a reason for hiding this comment

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

Hey, great work! Always amazing to see NixOS folks over here 👋🏻

I just have a few minor comments, looks good otherwise

helix-term/src/commands.rs Show resolved Hide resolved
helix-term/src/commands.rs Outdated Show resolved Hide resolved
helix-term/src/commands.rs Show resolved Hide resolved
helix-view/src/view.rs Outdated Show resolved Hide resolved
@archseer
Copy link
Member

archseer commented Nov 9, 2021

(Invited you to the Matrix Space too)

@cole-h cole-h force-pushed the buffer-close branch 2 times, most recently from 1e9c14b to e51386c Compare November 9, 2021 16:38
@cole-h cole-h requested a review from archseer November 9, 2021 16:40
helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
According to archseer, this was never implemented or used properly. Now
that we have a proper "buffer close" function, we can get rid of this.
This behaves the same as Kakoune's `delete-buffer` / `db` command:

* With 3 files opened by the user with `:o ab`, `:o cd`, and `:o ef`:
  * `buffer-close` once closes `ef` and switches to `cd`
  * `buffer-close` again closes `cd` and switches to `ab`
  * `buffer-close` again closes `ab` and switches to a scratch buffer
* With 3 files opened from the command line with `hx -- ab cd ef`:
  * `buffer-close` once closes `ab` and switches to `cd`
  * `buffer-close` again closes `cd` and switches to `ef`
  * `buffer-close` again closes `ef` and switches to a scratch buffer
* With 1 file opened (`ab`):
  * `buffer-close` once closes `ab` and switches to a scratch buffer
  * `buffer-close` again closes the scratch buffer and switches to a new
    scratch buffer
Namely, if you have a document open in multiple splits, all the splits
will  be closed at the same time, leaving only splits without that
document focused (or a scratch buffer if they were all focused on that
buffer).
@cole-h
Copy link
Contributor Author

cole-h commented Nov 12, 2021

OK, I think I've got this in a good place (functionality-wise) now. That said, I feel like the code can be improved -- I just don't know how, yet.

For the most part, I've taken inspiration from how nvim handles splits (at least, in my neovim with its various plugins.....) -- namely, that closing a buffer that's visible in multiple splits will also close those splits. However, if this adds too much complexity, it can easily be removed / saved for another, more focused PR.

Copy link
Member

@archseer archseer left a comment

Choose a reason for hiding this comment

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

It's getting there! Some ideas on how to simplify:

helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
}

if view.doc == doc_id {
let new_id = if let Some(alt) = view.last_accessed_doc {
Copy link
Member

Choose a reason for hiding this comment

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

For the most part, I've taken inspiration from how nvim handles splits (at least, in my neovim with its various plugins.....) -- namely, that closing a buffer that's visible in multiple splits will also close those splits.

This actually doesn't seem to do that but instead tries to display a different document in the split? Might be a bit better actually since it keeps the layout intact.

If you'd like to keep the vim behaviour on the other hand, then this code can be simplified: simply self.close all the views where view.doc == doc_id, then remove the document from self.documents. If you're left with an empty view tree but !self.documents.is_empty(), then push a new view and set it to self.documents.iter().first()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The last_accessed_doc was so that we could switch to that doc if it was Some(...), since it's more likely that the user wants to see the document they were looking at before closing their current one, than it is that they want to see the first document...

By unconditionally closing the view, we can't check the last_accessed_doc and switch to that if it exists... So opening ab, cd, and ef, then closing ef will bring you to ab instead of (as previously) cd. This seems weird to me.

helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
helix-view/src/editor.rs Outdated Show resolved Hide resolved
Copy link
Member

@archseer archseer left a comment

Choose a reason for hiding this comment

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

Looks good! 🎉

@archseer archseer merged commit c638b6b into helix-editor:master Nov 15, 2021
@cole-h cole-h deleted the buffer-close branch November 15, 2021 16:12
@VuiMuich
Copy link
Contributor

Thanks! I was tremendously stuck with my attempt to implement this.

@cole-h
Copy link
Contributor Author

cole-h commented Nov 15, 2021

Just a note that the commit body is now wrong -- we decided to go a simpler route, so closing a buffer will bring you to the first document in the list, not the last accessed document, or the document before it in the list.

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.

[feature] Close Buffer
4 participants