-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Add command to open a popup as a new buffer #9311
base: master
Are you sure you want to change the base?
Conversation
For now, starting from a popup, this opens a new buffer with a preset title and content. This compiles fine. |
I am trying to understand the structure of the classes that would be involved in getting this to work, and if changes should be made, what is the best way. Looking in particular into https://github.com/helix-editor/helix/blob/master/helix-term/src/ui/lsp.rs#L50 and related. So it looks like the popup I see 2 ways further then:
pub struct ContentAsString {
title: String,
body: String,
language: String,
}
pub struct Popup<T: Component> {
contents: T,
position: Option<Position>,
margin: Margin,
size: (u16, u16),
child_size: (u16, u16),
position_bias: Open,
scroll: usize,
auto_close: bool,
ignore_escape_key: bool,
id: &'static str,
has_scrollbar: bool,
// fields used in case the Popup can be opened in a new buffer; e.g., lsp documentation
content_as_strings: Option<ContentAsStrings>,
} and then this With this information, it would be trivial to open for example doc popups in a new buffer. Would this make sense from an architecture point of view? Is it worth to give it a try? |
This is now able to open doc into a new markdown buffer :) . |
This now has the following functionality:
The main things I do not manage to get at the current time:
Any advice on these 2 points (and the general draft of course :) ) would be welcome; @the-mikedavis any advice? :) |
(of course refactoring, supporting splits etc, will come soon, just trying to find how to do the last "blocker actions" before refactoring and extending :) ). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't intend on properly looking at or merging this feature until #5505 is possible. With #5505 we could make this possible only on popups where this makes sense, like hover, and we could cleanly downcast the type to a concrete Popup<Markdown>
, where we would be able to read the contents. Without it we need to duplicate the contents and store it on the Popup as you have here with StringsContent
which IMO is too hacky.
// put a meaningful title | ||
// TODO: get a meaningful buffer title | ||
let stringified_buffername = Some(Path::new(&stringified_buffername)); | ||
doc.set_path(stringified_buffername); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The path of a buffer isn't meant to be a name - this should be left as a scratch buffer instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree / understand this is hacky... But at the same time, I would like to have a more illustrative buffer name than "scratch", so that if I have several docs open, I can navigate easily between them. I.e. instead of having "scratch", "scratch", "scratch", I would find it much easier to navigate between several docs named "doc_NAME1", "doc_NAME2", "doc_NAME3". Any idea / recommendation / "non hacky way" you would do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, these docs shouldn't be opened for very long if they're just being used for reference anyways so I think scratch is fine
cx.editor.new_file(Action::Replace); | ||
|
||
// TODO: how can we meaningfully stringify the content of a Popup? for now dummy | ||
// TODO: is this an un-necessary copy? ... | ||
// put the content in the new buffer | ||
let (view, doc) = current!(cx.editor); | ||
paste_impl( | ||
&[stringified_body], | ||
doc, | ||
view, | ||
Paste::Before, | ||
1, | ||
cx.editor.mode, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new document should be created with Document::from
and then added to the editor with Editor::new_file_from_document
(which is currently private but could be pub
). That will remove the need to modify the selection, jumplist and last-saved-revision.
doc.set_last_saved_revision(1); | ||
// make readonly | ||
// TODO: this does not make really readonly from helix viewpoint, why? | ||
doc.readonly = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is set for files that have readonly permissions. A readonly "mode" for buffers that prevents editing isn't implemented yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so I guess we could consider implementing some form of "make readonly" function? Should I open a new issue / PR to discuss? Any recommended direction to implement something like this? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #7128. I suspect that it would be a large change and it needs some design before anyone goes about making a PR that attempts it
// close the popup since we just opened it in a new buffer | ||
let _ = self.contents.handle_event(event, cx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This passes the C-o
event to the contained component (a Markdown
in hover's case) which isn't necessary. The popup is handling the event so it shouldn't pass it down. Closing the popup is done below by returning Some(close_fun)
Interesting; is there already some "machinery" / tooling in place for this downcast + getting the contents from it (could you point me to it if so), or is it something that would be implemented following #5505 , or something to be implemented after it? :) |
Here's a block that finds and downcasts a component in the compositor into a helix/helix-term/src/ui/picker.rs Lines 477 to 482 in 2661e05
The compositor uses |
closes #8748
The idea is to make it possible to press
ctrl-o
to open the popup content in a new buffer. Once this work, I can easily addctrl-h
andctrl-v
to open in horizontal and vertical splits :) .This is still an early WIP; what remains to be done:
I will look into this more in the days to come :) .