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

unable to watch file edits by vim #247

Closed
haoyu0015 opened this issue Mar 4, 2020 · 12 comments
Closed

unable to watch file edits by vim #247

haoyu0015 opened this issue Mar 4, 2020 · 12 comments

Comments

@haoyu0015
Copy link

System details

  • OS/Platform name and version: ubuntu 18.04

  • Rust version (if building from source): rustc --version: 1.40.0

  • Notify version (or commit hash if building from git): the newest one(5.0.0-pre.2)

  • If you're coming from a project that makes use of Notify, what it is, and a link to the downstream issue if there is one:

  • Filesystem type and options:

  • On Linux: Kernel version: Linux wlan16 4.15.0-72-generic Watch only new directories in the monitor example #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

  • On Windows: version and if you're running under Windows, Cygwin (unsupported), Linux Subsystem:

  • If you're running as a privileged user (root, System): yeah, is root.

  • If you're running in a container, details on the runtime and overlay:

  • If you're running in a VM, details on the hypervisor:

What I did

I use the example in the git repository and want to hot watch a single file changed. I create a project and the src code is the same as the example:
https://github.com/notify-rs/notify/blob/main/examples/monitor_raw.rs

I create a singe file in the path "/root/watcher/aaa", then I run the process with argument "/root/watcher/aaa", then I use vim to write "www" into the file "aaa" twice times, only the first time have notfication, and the second times was ignored.

The log of first times I changed the file like that:
watching /root/watcher/aaa
changed: Event { kind: Modify(Name(From)), paths: ["/root/watcher/aaa"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }
changed: Event { kind: Modify(Metadata(Any)), paths: ["/root/watcher/aaa"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }
changed: Event { kind: Remove(File), paths: ["/root/watcher/aaa"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }

The second times I changed the file no any log

@superlou
Copy link

superlou commented Mar 8, 2020

I see the same behavior with 5.0.0-pre.2 on Linux Mint 19.3 when watching a single file. If I watch a directory, I continue to see updates.

Edit: This also happens on 4.0.13.

@f8122dac
Copy link

The same behavior with 5.0.0-pre.2 on 1.43.0-nightly (c20d7eecb 2020-03-11) on Arch Linux 5.5.8.arch1-1, using the same example code. I'm changing a text file with neovim.

When I use stdout and filepipe to update the file, I do get messages:

echo hello world >> PATH_TO_TEXT_FILE
changed: Event { kind: Modify(Data(Any)), paths: ["PATH_TO_TEXT_FILE"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }
changed: Event { kind: Access(Close(Write)), paths: ["PATH_TO_TEXT_FILE"], attr:tracker: None, attr:flag: None, attr:info: None, attr:source: None }

@f8122dac
Copy link

I think this is related to how vim handles writing. Temp file gets created and it is moved to the original file when writing is issued.

@tomsmeding
Copy link

This is indeed because of how vim handles file writing. In particular, the responsible vim option is backupcopy, which is set to auto by default.

  • If it is set to yes, vim writes to the file as usual and this notify crate picks everything up as usual.
  • If backupcopy is set to something else, like it is by default, then vim first writes the buffer content to a separate, temporary file, and then renames this temorary file over the file in question. In the lower-level file system watching API's, both on macOS and on Linux (I don't know about Windows), this results in a "remove" event, followed by a "create" event of a file with a new inode. Since watching a "file" really means watching an inode on those systems, the file system watching backend "loses" the file in the process, and therefore this notify crate also loses the file.

@0xpr03 0xpr03 changed the title watch a single file failed unable to watch file edits by vim Jun 15, 2020
@0xpr03
Copy link
Member

0xpr03 commented Jun 15, 2020

I edited the title in hopes of making it easier to find. @haoyu0015 are there still questions, or can this be closed ?

@haoyu0015
Copy link
Author

@0xpr03 I know the root cause of this issue , but could this issue be fixed in this crate ? I still need it to watch a single file change which edited by vim

@tomsmeding
Copy link

@haoyu0015 The way to track a file across rename tricks like vim does, is to watch the directory that contains the file. Then, you will still get a "remove" event first, but then you will get a "create" event for the new file as well. In your application code, you can observe these two and conclude that something like this happened.

This should probably not be added in the low-level API that notify offers; it could, however, be added as an abstraction layer on top. For example, notify could add a new method on Watcher called watch_file_tracking; or the API could be modified so that watch gets an additional argument.

I don't know if an existing crate already implements this.

@0xpr03
Copy link
Member

0xpr03 commented Jun 15, 2020

Another problem is how different Windows/Linux/MacOS report events about files. IIRC this can also be a big problem. If notify-rs would just try to abstract this for one of them, many issues could be fixed or features added in a much easier way/time. I'm not saying I'm against it, I just know how fragile this whole thing can be.

@tomsmeding
Copy link

I would definitely be a proponent of a crate that abstracts over all this platform-specific mess. It might even need to be notify, since it already joins together multiple event providers like inotify, FSEvents, etc. But even if for some reason it shouldn't be notify, it would be great for some abstraction layer to exist.

@haoyu0015
Copy link
Author

haoyu0015 commented Jun 15, 2020

Never mind. If you are not going to add something to fix it, you can close this issue. But if plan to add some extra abstraction layer to solved it, may keep this issue and let me know if done. Thank you

@oren0e
Copy link

oren0e commented Jul 7, 2022

@haoyu0015 you can add these lines to your .vimrc, then upon a file write in vim you'll get the usual NoticeWrite followed by Write events.
Lines to add:

set nobackup
set nowritebackup

@tombh
Copy link

tombh commented Sep 20, 2024

Old thread, but it helped me out ❤️

I'll describe my problem for the search engines, in case there's more like me. I had a notify-based build daemon watching some files I was editing in Neovim on Linux. The odd thing is that the first edit was always detected, but the second and all subsequent edits weren't. With @oren0e's tip I added to my editor config:

vim.opt.backup = false
vim.opt.writebackup = false

and everything worked as normal 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants