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

[WIP] file watching #588

Closed

Conversation

oberblastmeister
Copy link
Contributor

@oberblastmeister oberblastmeister commented Aug 15, 2021

Currently only the file watching actor is implemented. I am not sure where to put it, is helix-view the right place? I also added rustc_hash because it is faster but less secure, but I don't think we need the security here.

TODO:

  • debouncing
  • handle atomic writes (from editors like vim)
  • reload the file

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.

Oh, there's a way to get rid of the thread and crossbeam_channel altogether:

https://github.com/notify-rs/notify/blob/main/examples/async_monitor.rs#L8-L20

Turn run into an async fn and use tokio channels: async fn run(notifier: NotifyActor, receiver: tokio::mpsc::Receiver<Message>)

Then spawn this via tokio::spawn instead of a thread. This is how we deal with LSP clients too.

helix-view/Cargo.toml Outdated Show resolved Hide resolved
@@ -52,12 +54,14 @@ impl Default for Config {
pub struct Editor {
pub tree: Tree,
pub documents: SlotMap<DocumentId, Document>,
pub path_to_doc: FxHashMap<PathBuf, DocumentId>,
Copy link
Member

Choose a reason for hiding this comment

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

I'd call this documents_by_path and while I think it's useful, you should probably keep the original code which loops through the open documents. This new hashmap doesn't handle possible renames via set_path or set_path + write

@@ -253,6 +256,11 @@ impl Editor {

let id = self.documents.insert(doc);
self.documents[id].id = id;
self.watcher
Copy link
Member

Choose a reason for hiding this comment

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

Now that I think about it, this needs to deal with renaming too, :w somename.txt could set a name for an unnamed file or write an existing file to a new location

helix-view/src/file_watcher.rs Outdated Show resolved Hide resolved

fn new(sender: Sender) -> NotifyActor {
let (tx, rx) = unbounded();
let watcher: RecommendedWatcher = recommended_watcher(move |e| tx.send(e).unwrap()).unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

Return a result and propagate the error here.

Copy link
Member

Choose a reason for hiding this comment

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

I also noticed that v4 supported debounce, but seems like that's removed in v5?

}
}

fn run(mut self, inbox: crossbeam_channel::Receiver<ActorMessage>) {
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 you could merge next_event and run, you construct an enum then immediately deconstruct it.

helix-view/src/file_watcher.rs Show resolved Hide resolved
@oberblastmeister
Copy link
Contributor Author

Do we care about the order of the events after they are coalesced? That is why I have indexmap

@archseer
Copy link
Member

I don't think so, since every event is distinct and handled in isolation. The ordering doesn't matter

@oberblastmeister
Copy link
Contributor Author

How do I reload files?

@archseer
Copy link
Member

archseer commented Aug 18, 2021

There's a doc.reload method. It requires a view_id but you can just pick the first one available under selections.keys I think.

pub fn reload(&mut self, view_id: ViewId) -> Result<(), Error> {

@@ -38,6 +38,8 @@ log = "~0.4"

which = "4.2"

notify = "=5.0.0-pre.11" # check that it builds on NetBSD before upgrading
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason we need to use a pre-release version instead of current stable? (Which I believe is 4.x)

Copy link
Member

Choose a reason for hiding this comment

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

Last time I looked at it, it seemed like they were supporting both versions and 5 seemed stable enough maybe

Comment on lines +106 to +113
) -> anyhow::Result<Self> {
let language_servers = helix_lsp::Registry::new();
let (watcher, watcher_receiver) = {
let (watcher_sender, watcher_receiver) = unbounded_channel();
let watcher = NotifyActor::spawn(Box::new(move |e| watcher_sender.send(e).unwrap()))
.context("Failed to spawn watcher")?;
(Arc::new(watcher), watcher_receiver)
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Unless I'm misunderstanding something, it looks like this API makes it impossible to open an editor unless spawning the file watcher is successful. Presumably, though, we still want to succeed in opening the editor, and just report to the user that file watching isn't active, right? For example, I still want Helix to work even if I'm on a system that doesn't provide the expected notify capabilities.

@archseer
Copy link
Member

Note: debouncing is going to be built in on v5 as well, it's just not implemented yet: notify-rs/notify#286

@archseer archseer linked an issue Nov 18, 2021 that may be closed by this pull request
@the-mikedavis the-mikedavis added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label May 18, 2022
@axdank axdank mentioned this pull request May 31, 2022
@archseer
Copy link
Member

archseer commented Jun 5, 2022

Superseded by #2653

@archseer archseer closed this Jun 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

automatic reload when file changes externally
4 participants