haskell / haskell-mode

Emacs mode for Haskell
http://haskell.github.io/haskell-mode/
GNU General Public License v3.0
1.33k stars 344 forks source link

Linting failure when reloading file that is not current buffer #1757

Closed sirlensalot closed 3 years ago

sirlensalot commented 3 years ago

Problem is in haskell-process-errors-warnings when comparing current buffer file name to the warning result:

https://github.com/haskell/haskell-mode/blob/98ba3922360199d5260d47f417f096730ad057c5/haskell-load.el#L547-L548

When an error appears in a different file than the currently-loaded one, ghci outputs a relative file name. Thus, if "/var/project/src/Foo/Bar.hs" is loaded but user is looking at "/var/project/src/Baz/Quux.hs", an error in Baz.Quux will print for "src/Baz/Quux.hs"; whereas if it was in the loaded file, it gets a full/absolute path.

The problem occurs when default-directory does not match the session directory: with a relative path, file-truename simply appends default directory. For our example, that would be "/var/project/src/Baz", resulting in the erroneous value of "/var/project/src/Baz/src/Baz/Quux.hs", which will obviously fail the comparison above.

The workaround is to overwrite default-directory with the session current-dir:

  (when (and module-buffer haskell-process-show-overlays)
          (set-variable 'default-directory (haskell-session-current-dir session)) ;; <- workaround
          (haskell-check-paint-overlay
           module-buffer
           (string= (file-truename (buffer-file-name module-buffer))
                    (file-truename file))
           line error-msg file type nil col1))

This resolves the issue, at the cost of setting default-directory for the buffer to the session directory, which is probably not great.

sirlensalot commented 3 years ago

If there's some with-XXX or save-excursion trick to set default-directory only in that scope then I think the workaround could be principled.

purcell commented 3 years ago

You can locally bind default-directory to whatever you want within a let form.