Ignoring Emacs watch files still doesn't work

Hi, I know that there’s the old issue “Hugo server watch should ignore Emacs lock files”. But it seems the Hugo v0.15-429-gdbfc7ea doesn’t honor this.

This is an excerpt from my config.toml:

watch = true
ignoreFiles = [ "\\.#" ]

When I now run hugo server, the last output is:

Web Server is available at http://localhost:1313/ (bind address
Press Ctrl+C to stop

But when I now modify one of the files via emacs -Q impressum.md (the -Q tells Emacs to run totally bare, I wanted to make sure that nothing from my 2200 lines long ~/.emacs/init.el is misbehaving), I see this:

INFO: 2016/03/27 00:05:13 hugo.go:725: Received System Events: ["/home/holger/www.hugo/content/.#impressum.md": CREATE]

Change detected, rebuilding site
2016-03-27 00:05 +0100
INFO: 2016/03/27 00:05:13 site.go:863: rereading /home/holger/www.hugo/content/.#impressum.md

First issue, the ignore system doesn’t ignore files when it comes to triggering rebuilds.

Second issue: live update doesn’t work at all. Because further modifications and save operations of the same file don’t trigger any “Change detect” anymore.

If this is OSX, the second issue is fixed in 0.16.

As to 1:

BTW, this is under Linux, and as there I’m using hugo from Github, checked out today. That’s why I wrote v0.15-429-gdbfc7ea as version number.

BTW, in case you aren’t fluent with emacs, you can do it like this:

  1. emacs -Q content/<some file>
  2. use cursor keys and letters to edit something
  3. Ctrl-X Ctrl-S to save the file
  4. Ctrl-X Ctrl-Q whenever you decide to quit

And for what it’s worth, inotifywait detects this actions:

holger@holger:~/www.hugo$ inotifywait -m -r content
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
content/ CREATE .#impressum.md
content/ MOVED_FROM impressum.md
content/ CREATE impressum.md
content/ OPEN impressum.md
content/ MODIFY impressum.md
content/ CLOSE_WRITE,CLOSE impressum.md
content/ OPEN impressum.md
content/ CLOSE_WRITE,CLOSE impressum.md
content/ DELETE .#impressum.md
content/ ATTRIB impressum.md
content/ ATTRIB impressum.md

I found a mailing list entry “Re: why 4 inotfy events when saving a file?” where someone wrote:

Because that’s what Emacs does when it saves the file, first to the
old version, then to the new. Take a look at the implementation of
write-region, which is the primitive used by save-buffer to write the
buffer to its file, you will see all those operations there.

That primitive are (this may shed a light on why Emacs is doing what it’s doing):

Doing file watching that works cross-platform AND cross-editor is a hard task … I did some work on this to get good OSX suppoert (that is my current dev setup) a while ago, but there still seems to be issues. See https://github.com/fsnotify/fsnotify

I agree.

As far as I understand Emacs, it first writes something to the old file to find out if the file system is writable. Then it writes the new file.

Probably hugo get’s triggered by the first write. Maybe a simple delay would do the job? Or not “eating” the 2nd CLOSE_WRITE,CLOSE event. Because if hugo would get this event, it would again schedule a rebuild, wouldn’t it?

BTW, you can get Emacs also for MacOSX :slight_smile:

I’m a go noob, so I didn’t figure out how to use isNonProcessablePath — my go knowledge isn’t even going so far as that I know how to import something from package filesystem into commands/hugo.go :frowning:

But this will do the trick also:

diff --git a/commands/hugo.go b/commands/hugo.go
index 19fcb57..79b1482 100644
--- a/commands/hugo.go
+++ b/commands/hugo.go
@@ -729,12 +729,14 @@ func NewWatcher(port int) error {

 				for _, ev := range evs {
 					ext := filepath.Ext(ev.Name)
+					base := filepath.Base(ev.Name)
 					istemp := strings.HasSuffix(ext, "~") ||
 						(ext == ".swp") ||
 						(ext == ".swx") ||
 						(ext == ".tmp") ||
 						(ext == ".DS_Store") ||
 						filepath.Base(ev.Name) == "4913" ||
+						strings.HasPrefix(base, ".#") || // Emacs lock files
 						strings.HasPrefix(ext, ".goutputstream") ||
 						strings.HasSuffix(ext, "jb_old___") ||
 						strings.HasSuffix(ext, "jb_bak___")

I’m having the same problem on OSX with trying to get Hugo to ignore LESS files. I’ve got this in config.toml:

ignoreFiles = [ "\\.less$"]

This may or may not be the same problem, depending on where you store your less files. ignoreFiles was added to filter the /content folder, there is an open issue about static.

Ah… that’ll be it then. My .less files are in my theme directory.

Not a big deal anyway. I was just curious as to why it had never worked.