jyp / dante

392 stars 51 forks source link

dante + flycheck + git-emacs: "HEAD:src/: no such directory" #101

Closed conal closed 5 years ago

conal commented 5 years ago

The set-up recommended in the readme when used with git-emacs leads to errors like "HEAD:src/: no such directory" for Haskell source files when I use git-diff-head (C-x g d RET). The problem appears to be in the invocation of dante-mode in order to prettify a copy of the source buffer for the diff, as in the following Emacs Lisp stack trace:

Debugger entered--Lisp error: (error "HEAD:src/: no such directory")
  signal(error ("HEAD:src/: no such directory"))
  #[257 "\300 \210\301@A\"\207" [flycheck-report-failed-syntax-check signal] 4 "\n\n(fn ERR)"]((error "HEAD:src/: no such directory"))
  funcall(#[257 "\300 \210\301@A\"\207" [flycheck-report-failed-syntax-check signal] 4 "\n\n(fn ERR)"] (error "HEAD:src/: no such directory"))
  flycheck-buffer()
  flycheck-select-checker(haskell-dante)
  dante-mode()
  run-hooks(change-major-mode-after-body-hook prog-mode-hook haskell-mode-hook)
  apply(run-hooks (change-major-mode-after-body-hook prog-mode-hook haskell-mode-hook))
  run-mode-hooks(haskell-mode-hook)
  haskell-mode()
  set-auto-mode-0(haskell-mode nil)
  set-auto-mode()
  (let ((buffer-file-name buffer-name)) (set-auto-mode))
  (save-current-buffer (set-buffer buffer) (setq buffer-read-only nil) (erase-buffer) (let ((buffer-file-name buffer-name)) (set-auto-mode)) (apply (function git--exec-buffer) "cat-file" args) (setq buffer-read-only t) (goto-char (point-min)) (if (looking-at "^\\([Ff]atal\\|[Ff]ailed\\|[Ee]rror\\):") (progn (let ((msg (buffer-string))) (kill-buffer nil) (setq buffer nil) (error "%s" (git--trim-tail msg))))))
  (let ((buffer (get-buffer-create buffer-name))) (save-current-buffer (set-buffer buffer) (setq buffer-read-only nil) (erase-buffer) (let ((buffer-file-name buffer-name)) (set-auto-mode)) (apply (function git--exec-buffer) "cat-file" args) (setq buffer-read-only t) (goto-char (point-min)) (if (looking-at "^\\([Ff]atal\\|[Ff]ailed\\|[Ee]rror\\):") (progn (let ((msg (buffer-string))) (kill-buffer nil) (setq buffer nil) (error "%s" (git--trim-tail msg)))))) buffer)
  git--cat-file("HEAD:src/Fun.hs" "blob" "HEAD:src/Fun.hs")
  (setq buf2 (git--cat-file (if (equal rev ":") (concat "<index>" filerev) filerev) "blob" filerev))
  (let ((filerev (concat rev (file-relative-name abspath)))) (setq buf2 (git--cat-file (if (equal rev ":") (concat "<index>" filerev) filerev) "blob" filerev)))
  (let ((abspath (expand-file-name file)) (filename nil)) (cd (git--get-top-dir (file-name-directory abspath))) (let ((filerev (concat rev (file-relative-name abspath)))) (setq buf2 (git--cat-file (if (equal rev ":") (concat "<index>" filerev) filerev) "blob" filerev))))
  (progn (let ((abspath (expand-file-name file)) (filename nil)) (cd (git--get-top-dir (file-name-directory abspath))) (let ((filerev (concat rev (file-relative-name abspath)))) (setq buf2 (git--cat-file (if (equal rev ":") (concat "<index>" filerev) filerev) "blob" filerev)))))
  (unwind-protect (progn (let ((abspath (expand-file-name file)) (filename nil)) (cd (git--get-top-dir (file-name-directory abspath))) (let ((filerev (concat rev (file-relative-name abspath)))) (setq buf2 (git--cat-file (if (equal rev ":") (concat "<index>" filerev) filerev) "blob" filerev))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((abspath (expand-file-name file)) (filename nil)) (cd (git--get-top-dir (file-name-directory abspath))) (let ((filerev (concat rev ...))) (setq buf2 (git--cat-file (if ... ... filerev) "blob" filerev))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((abspath (expand-file-name file)) (filename nil)) (cd (git--get-top-dir (file-name-directory abspath))) (let ((filerev ...)) (setq buf2 (git--cat-file ... "blob" filerev))))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (let* ((buf1 (find-file-noselect file)) (buf2 nil) (config (current-window-configuration))) (let ((temp-buffer (generate-new-buffer " *temp*"))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (let ((abspath ...) (filename nil)) (cd (git--get-top-dir ...)) (let (...) (setq buf2 ...)))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))) (if (eq 0 (compare-buffer-substrings buf1 nil nil buf2 nil nil)) (progn (kill-buffer buf2) (error "No differences vs. %s" (or (car-safe (split-string rev ":" t)) "index")))) (set-buffer (ediff-buffers buf1 buf2 (append (if before-ediff-hook (progn (list before-ediff-hook)))))) (add-hook (quote ediff-quit-hook) (let ((--cl-saved-config-- (make-symbol "--saved-config--")) (--cl-saved-after-ediff-hook-- (make-symbol "--saved-after-ediff-hook--"))) (progn (let* ((v --cl-saved-config--)) (set v config)) (let* ((v --cl-saved-after-ediff-hook--)) (set v after-ediff-hook))) (list (quote lambda) (quote (&rest --cl-rest--)) (list (quote apply) (list (quote quote) (function (lambda ... ...))) (list (quote quote) --cl-saved-after-ediff-hook--) (list (quote quote) --cl-saved-config--) (quote --cl-rest--)))) nil t))
  git--diff("/Users/conal/Documents/Convolution/src/Fun.hs" "HEAD:")
  git-diff-head()
  funcall-interactively(git-diff-head)
  call-interactively(git-diff-head nil nil)
  command-execute(git-diff-head)

The value of haskell-mode-hook is (flycheck-mode dante-mode haskell-auto-insert-module-template my-haskell-mode-hook interactive-haskell-mode). If I swap the first two hooks, the problem vanishes.

To fix this issue, I've modified my dante setup to be the following:

(use-package dante
  :ensure t
  :after haskell-mode
  :commands 'dante-mode
  :init
  (add-hook 'haskell-mode-hook 'flycheck-mode)
  ;; OR:
  ;; (add-hook 'haskell-mode-hook 'flymake-mode)
  ;; Git-emacs chokes if flycheck-mode comes after dante-mode, e.g.,
  ;; "HEAD:src/: no such directory"
  (add-hook 'haskell-mode-hook 'dante-mode)
  )