toaster -w conflict with the default saving file behavior in vim #47

Closed
zx1986 opened this Issue Nov 22, 2012 · 29 comments

Projects

None yet

3 participants

@zx1986
zx1986 commented Nov 22, 2012

2012-12-11

I thought there was vim environment problem, NOT a coffee-toaster bug. so, I rename the title.



here is the error output:

[14:17:01] File deleted, stop watching /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/timer.coffee
[14:17:01] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:1200
              file.item.getinfo();
                  ^
TypeError: Cannot read property 'item' of null
    at __t.Builder.Builder.watch (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:1200:19)
    at __t.FnUtil.FnUtil.proxy (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:348:19)
    at StatWatcher.__t.FsUtil.FsUtil.watch_file (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:530:51)
    at StatWatcher.EventEmitter.emit (events.js:99:17)
    at StatWatcher._handle.onchange (fs.js:889:10)

### after restart toaster without modify my coffee file, everything goes fine again.

zx1986@mfc66:~/work/log-watcher-gts$ toaster -w
[14:18:48] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:18:50] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/timer.coffee
[14:18:50] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

here is the offee file, timer.coffee:

get_time = (holder_id) ->
    s = $("##{holder_id} p:last-child").text().split(' ')
    time = s[4] + s[1] + s[2] + s[3] 
    console.log time 

In file.item.getinfo(), the file means that file which has been watched ?
I ran guard + livereload + toaster at same time, will that cause this problem ?

@arboleya arboleya was assigned Nov 23, 2012
@arboleya
Owner

The same happens when will run Toaster alone, without the Livereload / Guard?

Seeing the stack trace you pasted I suspect it's the same of a previous issue (theoretically fixed #37).

If it happens even when you run Toaster without the others players, tell me how to reproduce it and which platform it's happening so I can take a closer look.

Thanks

p.s.: I answered your email at the group in case you didn't see it yet:
https://groups.google.com/forum/?fromgroups=#!topic/coffee-toaster/RC-RS-OMQFU

@arboleya arboleya referenced this issue Nov 25, 2012
Closed

file deletion #37

@zx1986
zx1986 commented Nov 27, 2012

without Guard / Livereload

here is my toaster.coffee:

# => SRC FOLDER
toast 'assets/coffeescripts'

        # EXCLUDED FOLDERS (optional)
        exclude: ['.swp', '.tmp' ]

        # => VENDORS (optional)
        # vendors: ['vendors/x.js', 'vendors/y.js', ... ]

        # => OPTIONS (optional, default values listed)
        # bare: false
        # packaging: true
        # expose: ''
        minify: false

        # => HTTPFOLDER (optional), RELEASE / DEBUG (required)
        httpfolder: ''
        release: 'assets/javascripts/main.js'
        debug: 'assets/javascripts/main-debug.js'

toaster output:

[14:25:15] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:25:31] File deleted, stop watching /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:25:31] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:25:31] New file created /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:25:31] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:25:48] File deleted, stop watching /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/get_elapsed_time.coffee
[14:25:48] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:1200
              file.item.getinfo();
                  ^
TypeError: Cannot read property 'item' of null
    at __t.Builder.Builder.watch (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:1200:19)
    at __t.FnUtil.FnUtil.proxy (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:348:19)
    at StatWatcher.__t.FsUtil.FsUtil.watch_file (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/lib/toaster.js:530:51)
    at StatWatcher.EventEmitter.emit (events.js:99:17)
    at StatWatcher._handle.onchange (fs.js:889:10)

what I did was:

  1. vim alert.coffee
  2. save & exit alert.coffee
  3. vim get_elapsed_time.coffee
  4. saving get_elapsed (in vim, not exit yet)
  5. toaster got error
  6. run "toaster -w" agiain
  7. toaster works again

oh! big point!
the folder is in my dropbox folder, any conflict?

@arboleya
Owner

Hi, is this happening frequently?

To reproduce this I had to keep typing "ESC + : + w + ENTER" with the file opened in VIM in an INSANELY fast way I didn't know I was capable of. The error rises both inside and outside the Dropbox folder.

Basically, at some point the file stats gets 'nlink=0' which means the file was deleted. To go further, I also put another check of 'fs.existsSync' and it incredibly also returned 'false'. This is beyond Toaster.

In other hand the stack trace you pasted suggets it's happening EVERYTIME you save a file (:x and :w).

Is that correct? You're running linux right? Which distro?

@arboleya
Owner

Hi, I've made an attempt to reduce this problems with "deleted files" that was not actually deleted.
92ddafb

Please update to the latest version 0.6.5 and tell me if something changes.

@zx1986
zx1986 commented Nov 28, 2012

To reproduce this I had to keep typing "ESC + : + w + ENTER" with the file opened in VIM in an INSANELY fast way I didn't know I was capable of.

that was exactly what I did!
you are so right!

I am running Ubuntu 12.04 i386 with nodejs v0.8.14:

/home/zx1986/nvm/v0.8.14/lib
├── coffee-script@1.4.0
├─┬ coffee-toaster@0.6.5
│ ├── coffee-script@1.3.3
│ ├── colors@0.5.1
│ ├── growl@1.2.1
│ ├─┬ optimist@0.2.8
│ │ └── wordwrap@0.0.2
│ ├── uglify-js@1.1.1
│ └─┬ vows@0.6.4
│   ├── diff@1.0.4
│   └── eyes@0.1.8

and you were right again: I used :x to save file
but when I test in version 0.6.5, I just create a test.coffee, and then :w
and toaster crash again :-(


and I test in Ubuntu 10.04 i386 with nodejs v0.8.15:

/home/zx1986/nvm/v0.8.15/lib
├── coffee-script@1.4.0
├─┬ coffee-toaster@0.6.5
│ ├── coffee-script@1.3.3
│ ├── colors@0.5.1
│ ├── growl@1.2.1
│ ├─┬ optimist@0.2.8
│ │ └── wordwrap@0.0.2
│ ├── uglify-js@1.1.1
│ └─┬ vows@0.6.4
│   ├── diff@1.0.4
│   └── eyes@0.1.8

the same result, when I vim test.coffee and :w:

console.log 'hi'

toaster crash :-(

[10:18:29] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[10:18:31] File deleted, stop watching /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/b.coffee
[10:18:31] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

/opt/nvm/v0.8.15/lib/node_modules/coffee-toaster/lib/toaster.js:1185
              file.item.getinfo();
                  ^
TypeError: Cannot read property 'item' of null
    at __t.Builder.Builder.watch (/opt/nvm/v0.8.15/lib/node_modules/coffee-toaster/lib/toaster.js:1185:19)
    at __t.FnUtil.FnUtil.proxy (/opt/nvm/v0.8.15/lib/node_modules/coffee-toaster/lib/toaster.js:348:19)
    at StatWatcher.__t.FsUtil.FsUtil.watch_file (/opt/nvm/v0.8.15/lib/node_modules/coffee-toaster/lib/toaster.js:530:51)
    at StatWatcher.EventEmitter.emit (events.js:99:17)
    at StatWatcher._handle.onchange (fs.js:889:10)

my toaster.coffee:

# => SRC FOLDER
toast 'assets/coffeescripts'

    # EXCLUDED FOLDERS (optional)
    exclude: ['.swp', '.tmp' ]

    # => VENDORS (optional)
    # vendors: ['vendors/x.js', 'vendors/y.js', ... ]

    # => OPTIONS (optional, default values listed)
    # bare: false
    # packaging: true
    # expose: ''
    minify: false

    # => HTTPFOLDER (optional), RELEASE / DEBUG (required)
    httpfolder: ''
    release: 'assets/javascripts/main.js'
    debug: 'assets/javascripts/main-debug.js'

it got worse at toaster v0.6.5, so I got back to v0.6.4 now ...

@arboleya
Owner

Ok, I'm in the middle of a big refactor from the ground up aiming to solve all this problems concerning filesystem in Windows.

I'll take advantage of the moment and build up an Ubuntu vm as well so I can hopefully fix it for everyone across all platforms (osx, windows and linux).

@zx1986
zx1986 commented Nov 28, 2012

if you need to do any test in Ubuntu, I could do it for you.
maybe you have the testing steps ?


I tried to use ZZ in vim to save file, and toaster -w got no response with ZZ action.
but failed with :x or :w, otherwise toaster -c works fine.

@arboleya
Owner
arboleya commented Dec 8, 2012

@zx1986 Hi, I've detached the fs-utils class from Toaster and completely rewrite it into a fresh new package. So far the tests are passing in ubuntu as well.

Can you pls check it out and tells me if it (finally) worked?

npm install -g git://github.com/serpentem/coffee-toster#cross-platform-refactor
@arboleya
Owner
arboleya commented Dec 9, 2012

Ops there was a typo, again:

npm install -g git://github.com/serpentem/coffee-toaster#cross-platform-refactor
@zx1986
zx1986 commented Dec 10, 2012

sorry for so late to reply!

YOU are such a sweet DEVELOPER! 💯
you even testing in a Dropbox directory too. 👍

but when I testing Ubuntu 12.10 i386, I got something wrong ....


I got a firewall out of my control, it doesn't allow me to use git protocol (TCP 22 port),
so what I did is:

git clone http://github.com/serpentem/coffee-toaster.git
cd coffee-toaster
git checkout -b cross remotes/origin/cross-platform-refactor
cd ..
tar zcvf coffee-toaster.tar.gz coffee-toaster/
npm install -g coffee-toaster.tar.gz

then I got:

$ npm list -g

/home/zx1986/nvm/v0.8.14/lib
├── coffee-script@1.4.0
├─┬ coffee-toaster@0.6.6
│ ├── coffee-script@1.3.3
│ ├── colors@0.5.1
│ ├── fs-util@0.3.2
│ ├── growl@1.2.1
│ ├─┬ optimist@0.2.8
│ │ └── wordwrap@0.0.2
│ ├── uglify-js@1.1.1
│ └─┬ vows@0.6.4
│   ├── diff@1.0.4
│   └── eyes@0.1.8

toaster-coffee commit

commit 9291fb40149cae13b350c93238961a6e73a6d7a3
Author: arboleya <anderson@arboleya.me>
Date:   Sun Dec 9 23:06:33 2012 -0200

    Updating `fs-util` version in `package.json`.

when I open a coffee file, then :w, I got:

toaster -w

[09:38:56] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[09:39:06] File deleted, stop watching /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[09:39:06] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[09:39:06] New file created /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee~
[09:39:06] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

fs.js:837
    throw errnoException(errno, 'watch');
          ^
Error: watch ENOENT
    at errnoException (fs.js:806:11)
    at FSWatcher.start (fs.js:837:11)
    at Object.fs.watch (fs.js:861:11)
    at FileWatcher.watch (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:170:22)
    at new FileWatcher (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:151:12)
    at DirWatcher.onchange (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:298:46)
    at FSWatcher.__bind (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:4:61)
    at FSWatcher.EventEmitter.emit (events.js:99:17)
    at FSEvent._handle.onchange (fs.js:826:12)

when I open a coffee file, do nothing, then ZZ or :x, it was fine.
but if I modified the file, then ZZ or :x will get the same error above. 🎱

may I know what is your ubuntu version ?
perhaps my env got something chaos ...

I will test again when I get home, my PC at home is Ubuntu 12.10 i386,
the same version as my PC in my office.

@arboleya
Owner

Hell, all my attempts to fix all the shits around the File System across platforms turns into a nightmare. Oh my god.

Ok, lets do it one more time, I noticed this weird line in the stack you pasted:

[09:39:06] New file created /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee~

It's so weird, because a file ending with .coffee~ shouldn't be catch by Toaster, I'll check this.

It's a kind of temporary file in Linux? Vim saves the .swp, right? Maybe this .coffee~ can be possibly something related with Dropbox?

Well, in this meanwhile can you pls run the tests suite for me and paste the results here?

git clone git://github.com/serpentem/fs-util
cd fs-util && npm install && make test

Btw, my ubuntu is 12.04.1 i386. I couldn't install the 12.10 in Virtual Box because of a real painful slowness, the system seems to have driver issues in Virtual Box, so I switched to 12.04 thinking that would be enough.

@arboleya
Owner

Ops, I think I got it here, here and here.

Dumb mistake, a simple if, now it should be ok. I've assumed that the problem was only the *.coffee~ files being wrongly collected.

Please update Toaster again and see if it (god have mercy) works now:

npm install -g git://github.com/serpentem/coffee-toaster#cross-platform-refactor

If you're behind firewall, use this (simpler) snippet, will save you some lines and seconds. 👌

git clone --branch=cross-platform-refactor http://github.com/serpentem/coffee-toaster
cd coffee-toaster && npm install && npm link
@zx1986
zx1986 commented Dec 11, 2012

Reinstall

cd /tmp
git clone --branch=cross-platform-refactor http://github.com/serpentem/coffee-toaster
cd coffee-toaster
npm install -g
npm list -g
/home/zx1986/nvm/v0.8.14/lib
├── coffee-script@1.4.0
├─┬ coffee-toaster@0.6.6
│ ├── coffee-script@1.3.3
│ ├── colors@0.5.1
│ ├── fs-util@0.3.3
│ ├── growl@1.2.1
│ ├─┬ optimist@0.2.8
│ │ └── wordwrap@0.0.2
│ ├── uglify-js@1.1.1
│ └─┬ vows@0.6.4
│   ├── diff@1.0.4
│   └── eyes@0.1.8

Testing

  1. toaster -w
  2. vim assets/coffeescripts/alert.coffee
  3. using :w to save file in vim
[14:32:52] File deleted, stop watching /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:32:52] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:32:52] New file created /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:32:52] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

fs.js:524
  return binding.stat(pathModule._makeLong(path));
                 ^
Error: ENOENT, no such file or directory '/home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee~'
    at Object.fs.statSync (fs.js:524:18)
    at DirWatcher.onchange (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:295:16)
    at FSWatcher.__bind (/home/zx1986/.nvm/v0.8.14/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:4:61)
    at FSWatcher.EventEmitter.emit (events.js:99:17)
    at FSEvent._handle.onchange (fs.js:826:12)

The vim swap file (filename~)

I thought this is the main problem of mine:

the default "save" behavior of Vim, which is:

  1. write buffer to new file
  2. delete the original file
  3. rename the new file

Reference:
http://vim.wikia.com/wiki/Remove_swap_and_backup_files_from_your_working_directory
http://stackoverflow.com/questions/607435/why-does-vim-save-files-with-a-extension
http://stackoverflow.com/questions/743150/how-to-prevent-vim-from-creating-and-leaving-temporary-files

Modified .vimrc and testing again ( it works! )

" for coffee-toaster
set nobackup       " no backup files
set nowritebackup  " only in case you don't want a backup file while editing
set noswapfile     " no swap files

seem these beautiful output:

toaster -w

[14:55:30] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:55:35] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:55:35] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:55:36] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:55:36] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:55:37] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:55:37] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:55:38] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:55:38] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:55:44] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:55:44] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:55:46] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:55:46] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:56:00] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:56:00] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:56:04] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:56:04] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js
[14:56:07] File changed /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/coffeescripts/alert.coffee
[14:56:07] Compiled /home/zx1986/Dropbox/Projects/log-watcher-gts/assets/javascripts/main.js

oh ~ my dear toaster machine! 🉑

@arboleya
Owner

Hi, it's great news. :)

But anyway, the weird thing is that fixed this! I mean, files ending with ~ shouldn't be collected.

That's the current regex filter, there's no space for the ~ at the end.
https://github.com/serpentem/coffee-toaster/blob/cross-platform-refactor/src/toaster/core/builder.coffee#L154

# ...
@watchers.push (watcher = fsu.watch src.path, /.coffee$/m)
# ...
@arboleya
Owner

Just to let you know, I reproduced the (motherfucker) error. Looking into it to fix without any changes to your vim configs. The ideal fix is the only viable fix. 😸

@zx1986
zx1986 commented Dec 13, 2012

But anyway, the weird thing is that fixed this! I mean, files ending with ~ shouldn't be collected.
The ideal fix is the only viable fix.

Indeed!
That's real hackers' way!

reproduced the (motherfucker) error

haha! I think there is a bug in fsu.watch ?
not a problem with coffee-toaster.
just like what you said before.


but I test fs-util with vim, it was just fine, weird ....

Selection_001

@arboleya
Owner

Well, after some research I came to the conclusion that the only way to work reliably with VIM and Toaster is this way you've mentioned.

When you save the file :w, only the first change event is reported for the file. Any further save won't be even noticed for the file. But FsUtil also listens for changes in the parent dir of this file, and this dir gets the change event every time the file is saved with :w. BUT.. guess what, in the moment the event pops up for the dir, the file doesn't exist in the filesystem anymore so the FsUtil reports the file as deleted. lol

It's like VIM deletes it and so creates a new one with the contents coming from the swap, I dont know exactly what happens, but in other words, VIM uses this specific saving-cycle between all these backups, swaps and original files that turns it impossible to have the expected results. There are so much variations and weirdness around this matter that the best option now is makes VIM work as expected -- the way you did -- than trying to understanding it's deepest emotions and childhood behaviors. :)

@arboleya
Owner

Here we go, I just release the 0.6.6, please update and let me know if something weird happens.

Btw, thanks to you I put a note for vim users on the REAME. ;)
https://github.com/serpentem/coffee-toaster#vim-users

@arboleya arboleya closed this Dec 15, 2012
@zx1986
zx1986 commented Dec 17, 2012

that's ok! arboleya!
thanks so much for your effort, you make Coffee-scripts' world better and better! ✌️

@mlen
mlen commented Dec 27, 2012

@arboleya could you explain why this issue is closed? Forcing users to change their setup doesn't look like a good solution.

@arboleya
Owner

@mlen Hi Mateusz, I understand your frustration because I agree a hundred percent wit you. But instead of forcing users to do something, I'm just trying to help them do something if they use VIM and are willing to benefit from Toaster.

As you can see in this thread I digged very deep into this subject with @zx1986 but I ended up with no solution for this. So instead of no solution at all, there's a workaround to make things work as expected.

The FS API of node itself is pretty unstable across different platforms, this made me build a new tool just to have a closer control over fs operations in different platforms (win,mac,linux).

Furthermore, the VIM behaviors is pretty unlikely any other editor. When you hit :w inside some file, multiple changes notificatins popup and worse than that, at this very moment that the notification is rised, your original file do not exist in the file system. It's like VIM deletes your original file and rebuild it with the contents of swap or backup versions.

You'll face the very same problem with all the libraries that do this watch'n'compile thing. VIM, specifically over all other editors I tested, behaviors in a completely different way when it concerns to FS manipulation.

But as I said, I agree with you. So if anything can be done to make this work as expected I'd be happy to do it.

Do you have any suggestion? Did you have a closer contact with filesystem watching? Do you know deeply how VIM works on this matter?

@zx1986
zx1986 commented Dec 28, 2012

hello there!
first of all, you guys are really hackers indeed!

I am using a vim plugin called vim-coffee-script ,
and it had a command named "CoffeeCompile watch", it will watch a coffeescript file and compile it to javascript "almost" immediately.

but I thought this plugin just do things in the vim way:
https://github.com/kchmck/vim-coffee-script/blob/master/ftdetect/coffee.vim
unlike Toaster (using FS API) watching files thought the file system way.

check the bottom line in this image: "--No lines in buffer--"
vim-coffee-script
seems vim-coffee-script's "CoffeeScript watch" is watching things in the vim buffer,
and get content from vim buffer thought the vim way.

@arboleya
Owner

That looks awesome! As it seems it's realtime, isn't it? As you type coffee in one side, it automatically compiles it to js on the other. Fabulous.

But I'm afraid it's only possible because it's a VIM plugin, and because of that it runs under the VIM architecture (unlike Toaster). As Toaster isn't a plugin for anything, this can't be that specific.

@mlen
mlen commented Dec 28, 2012

@arboleya thanks for the effort :)

Fortunately I found a better solution than disabling vim functionality (disabling swap files is discouraged by the manual).

There are two strategies for writing files and by default vim decides which one to use (read :h backupcopy for details).
In most cases it renames the original file and after that a new file with updated content is created.
The second strategy is to copy the original file to back it up and overwrite the original with new content.

The line below changes vim behavior to create the backup file by copying the original instead of doing a rename.

set backupcopy=yes

Or even better when combined with autocmd

autocmd BufRead,BufNewFile *.coffee setlocal backupcopy=yes

This still is only a workaround and I think ENOENT should be handled in some way (this is clearly the result of a race condition between vim and toaster) instead of crashing the program.

@arboleya
Owner

@mlen Hi, good news then? Seems much less intrusive than disabling everything. Right @zx1986 ?

What about this ENOENT you mentioned? Well, I'm gonna test it as soon as I can.

Thank you for the tip.

@zx1986
zx1986 commented Dec 31, 2012

I got something pretty weird ........

I comment all the setting for Toaster in .vimrc:

" for coffee-toaster
"autocmd BufRead,BufNewFile *.coffee setlocal backupcopy=yes
"set nobackup       
"set nowritebackup  
"set noswapfile    

then, with Toaster, everything goes fine!
I did a lot of :w and :x, I do not know what to say now ....

here is my env:

Distributor ID: Ubuntu
Description:    Ubuntu 12.10
Release:        12.10
Codename:       quantal

Linux gnome 3.5.0-19-generic #30-Ubuntu SMP Tue Nov 13 17:49:53 UTC 2012 i686 athlon i686 GNU/Linux

├─┬ coffee-toaster@0.6.11
│ ├── coffee-script@1.3.3
│ ├── colors@0.5.1
│ ├── fs-util@0.3.4
│ ├── growl@1.2.1
│ ├─┬ optimist@0.2.8
│ │ └── wordwrap@0.0.2
│ ├── uglify-js@1.1.1
│ └─┬ vows@0.6.4
│   ├── diff@1.0.4
│   └── eyes@0.1.8
@mlen
mlen commented Dec 31, 2012

@zx1986 unfortunately it still doesn't work on OS X.

@arboleya ENOENT is the error you get, when the file is not found and you want to stat it (see comment #47 (comment)).

I think there is another bug only occurring when I edit toaster.coffee file (without backupcopy=yes).
When I run toaster -w and save the file in vim then I get:

[12:48:19] Compiled ROOT_PATH/release/app.js

ROOT_PATH/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:190
      if (this.curr.mtime > this.prev.mtime) {
                                     ^
TypeError: Cannot read property 'mtime' of null
    at FileWatcher.onchange (ROOT_PATH/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:190:38)
    at FSWatcher.__bind (ROOT_PATH/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:4:61)
    at FSWatcher.EventEmitter.emit (events.js:99:17)
    at FSEvent._handle.onchange (fs.js:826:12)

I'm using OS X 10.7.5 and vim 7.3.762

Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64

├── coffee-script@1.3.3
├─┬ coffee-toaster@0.6.11
│ ├── colors@0.5.1
│ ├── fs-util@0.3.4
│ ├── growl@1.2.1
│ ├─┬ optimist@0.2.8
│ │ └── wordwrap@0.0.2
│ ├── uglify-js@1.1.1
│ └─┬ vows@0.6.4
│   ├── diff@1.0.4
│   └── eyes@0.1.8
├─┬ jasmine-node@1.0.28
│ ├── jasmine-reporters@0.2.1
│ ├── requirejs@2.1.2
│ ├── underscore@1.4.3
│ └── walkdir@0.0.5
└── sugar@1.3.7
@arboleya
Owner

@zx1986 You're kidding. Now I don't know what to say. Maybe VIM was operating with the vars still on?

@mlen I see, well I need to take a closer look to see what happening.

But just te be clear, what is all the differences between the keepbackup=yes set or not?

With it set all goes well, except the `ENOENT``?

Without the backup=yes, the toaster.coffee reports this error you pasted. And everything else just doesn't work as well?

@zx1986
zx1986 commented Jan 2, 2013

To make it simple, I created an virtual machine with Ubuntu 12.10 i386.
Without any vim plugins, run Node v0.8.16 with nvm, installed latest Toaster with npm.
( I don't even run X window. )

Then, I got the error again:

[21:42:33] File deleted, stop watching /home/zx1986/www/coffee/a.coffee
[21:42:33] Compiled /home/zx1986/www/javascripts/main.js
[21:42:33] New file created /home/zx1986/www/coffee/a.coffee

fs.js:524
  return binding.stat(pathModule._makeLong(path));
                 ^
Error: ENOENT, no such file or directory '/home/zx1986/www/coffee/a.coffee~'
    at Object.fs.statSync (fs.js:524:18)
    at Object.exports.ls.ls (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/node_modules/fs-util/lib/fs-util.js:123:15)
    at Builder.__t.Builder.Builder.build_ns_tree (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:847:21)
    at Builder.__t.Builder.Builder.build_namespaces (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:830:14)
    at Builder.__t.Builder.Builder.build (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:743:25)
    at Builder.__bind [as build] (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:27:61)
    at Builder.__t.Builder.Builder.on_fs_change (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:942:21)
    at __bind (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:27:61)
    at Watcher.__t.FnUtil.FnUtil.proxy (/home/zx1986/.nvm/v0.8.16/lib/node_modules/coffee-toaster/lib/toaster.js:367:19)
    at Watcher.EventEmitter.emit (events.js:96:17)

Even after I put autocmd BufRead,BufNewFile *.coffee setlocal backupcopy=yes into .vimrc,
I still got the error sometimes, but without the file delete alert, the output looks like this:

[21:42:33] Compiled /home/zx1986/www/javascripts/main.js
[21:42:33] New file created /home/zx1986/www/coffee/a.coffee

fs.js:524
  return binding.stat(pathModule._makeLong(path));
                 ^
Error: ENOENT, no such file or directory '/home/zx1986/www/coffee/a.coffee~'
......

Things went fine until I put these 3 line back into .vimrc:

set nobackup       
set nowritebackup  
set noswapfile  

I googled something about backupcopy option in vim:

When writing a file and a backup is made, this option tells how it's done.
This is a comma separated list of words.
The main values are:
"yes" make a copy of the file and overwrite the original one
"no" rename the file and write a new one
"auto" one of the previous, what works best

Extra values that can be combined with the ones above are:
"breaksymlink" always break symlinks when writing
"breakhardlink" always break hardlinks when writing

Reference:
http://vimwiki.net/?'backupcopy'
http://vim.wikia.com/wiki/Editing_a_hard_link_to_a_file
http://vimcdoc.sourceforge.net/doc/autocmd.html

I thought the regular file watching way (like FS) has no fitted event for save operating in vim ....
(maybe we need an event like WRITE_CLOSE in inotify/incrond ?)

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