Comint can't navigate to file
I confirm that...
-
[X] I have searched the issue tracker, documentation, FAQ, Discourse, and Google, in case this issue has already been reported/resolved.
-
[X] I have read "How to Debug Issues", and will use it to provide as much information about this issue as possible.
-
[X] The issue can be reproduced on the latest available commit of Doom.
-
[X] The issue can be reproduced on a stable release of Emacs, such as 27, 28, or 29. (Unstable versions end in .50, .60, or .9x)
Expected behavior
When running compile to build and test angular projects I should be able to select the filenames in the compilation log to open them.
Current behavior
Find file at point cannot find the file at point because it is wrongly including the 'Error: ' as part of the filepath.
Is there a way to work around this?
Steps to reproduce
I assume this works for any node project, build commands are being issues by npm-mode-npm-run.
System Information
https://pastebin.com/gTWcz0C4
Chat-gpt was able to provide this solution but perhaps there's a better way:
(defun my/strip-error-prefix (str)
"Strip the 'Error: ' prefix from STR if present."
(if (string-prefix-p "Error: " str)
(substring str 7)
str))
(defun my/compilation-find-file (orig-fun marker filename directory &rest formats)
"Advice to strip 'Error: ' prefix from FILENAME and DIRECTORY in `compilation-find-file`."
(let* ((clean-filename (my/strip-error-prefix filename))
(clean-directory (my/strip-error-prefix directory))
;; Apply `my/strip-error-prefix` to each format string if formats is not empty.
(clean-formats (if formats
(mapcar #'my/strip-error-prefix formats)
nil))
;; Construct arguments list.
(args (append (list marker clean-filename clean-directory) clean-formats)))
(apply orig-fun args)))
(advice-add 'compilation-find-file :around #'my/compilation-find-file)
This should be a considered a bug with whatever you use to launch those compilation buffers. Comint doesn't automatically recognize files, it needs to be told how to by setting compilation-error-regexp-alist-alist. You can force this on your end with something like:
(after! compile
(add-to-list 'compilation-error-regexp-alist 'angular)
(add-to-list 'compilation-error-regexp-alist-alist '(angular "Error: \\(.+\\)\n\n\\([0-9]+\\) " 1 2)))
I only guessed the regexp so you'll need to tweak it.
I think you may have misunderstood the bug, it's not that the error isn't being detected by comint, it's that I can't navigate to the file because 'Error: ' is included in the filepath when Emacs attempts to navigate to it.
Anyway, I'm using Doom's js module, which uses npm-mode for running build/test commands, which as far as I can tell is just scanning the project for a list of commands to execute and then passing the selection to compile. If I run compile myself there's still random stuff in the buffer being detected as an 'error' i.e. this BuildInfo string:
Ah it’s typescript mode setting to the list but everything seems right there. I assume something else is configured incorrectly? Here's the current value of compilation-error-regexp-alist-alist
((typescript-nglint-warning "WARNING:[[:blank:]]+\\([^(
)]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\) - .*$"
1 2 3 1)
(typescript-nglint-error "ERROR:[[:blank:]]+\\([^(
)]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\) - .*$"
1 2 3 2)
(typescript-tslint "^[[:blank:]]*\\(?:\\(?:ERROR\\|\\(WARNING\\)\\):[[:blank:]]+\\)?\\((.*)[[:blank:]]+\\)?\\([^(
)]+\\)\\[\\([[:digit:]]+\\), \\([[:digit:]]+\\)\\]: .*$"
3 4 5 (1))
(typescript-tsc-pretty "^[[:blank:]]*\\([^(
)]+\\):\\([0-9]+\\):\\([0-9]+\\) - [[:blank:]]*error [[:alnum:]]+: [^
]+$"
1 2 3 2)
(typescript-tsc "^[[:blank:]]*\\([^(
)]+\\)(\\([0-9]+\\),\\([0-9]+\\)):[[:blank:]]+error [[:alnum:]]+: [^
]+$"
1 2 3 2)
(absoft "^\\(?:[Ee]rror on \\|[Ww]arning on\\( \\)\\)?[Ll]ine[ ]+\\([0-9]+\\)[ ]+of[ ]+\"?\\([a-zA-Z]?:?[^\":
]+\\)\"?:"
3 2 nil (1))
(ada "\\(warning: .*\\)? at \\([^
]+\\):\\([0-9]+\\)$"
2 3 nil (1))
(aix " in line \\([0-9]+\\) of file \\([^
]+[^.
]\\)\\.? "
2 1)
(ant "^[ ]*\\(?:\\[[^]
]+\\][ ]*\\)\\{1,2\\}\\(\\(?:[A-Za-z]:\\)?[^:
]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\)?\\( warning\\)?"
1 (2 . 4) (3 . 5) (6))
(bash "^\\([^:
]+\\): line \\([0-9]+\\):"
1 2)
(borland "^\\(?:Error\\|Warnin\\(g\\)\\) \\(?:[FEW][0-9]+ \\)?\\([a-zA-Z]?:?[^:(
]+\\) \\([0-9]+\\)\\(?:[) ]\\|:[^0-9
]\\)"
2 3 nil (1))
(python-tracebacks-and-caml "^[ ]*File \\(\"?\\)\\([^,\"
<>]+\\)\\1, lines? \\([0-9]+\\)-?\\([0-9]+\\)?\\(?:$\\|,\\(?: characters? \\([0-9]+\\)-?\\([0-9]+\\)?:\\)?\\([
]Warning\\(?: [0-9]+\\)?:\\)?\\)"
2 (3 . 4) (5 . 6) (7))
(cmake
"^CMake \\(?:Error\\|\\(Warning\\)\\) at \\(.*\\):\\([1-9][0-9]*\\) ([^)]+):$"
2 3 nil (1))
(cmake-info "^ \\(?: \\*\\)?\\(.*\\):\\([1-9][0-9]*\\) ([^)]+)$" 1 2 nil 0)
(comma "^\"\\([^,\"
]+\\)\", line \\([0-9]+\\)\\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?"
1 2 3 (4))
(msft "^ *\\([0-9]+>\\)?\\(\\(?:[a-zA-Z]:\\)?[^ :(
][^:(
]*\\)(\\([0-9]+\\)\\(?:,\\([0-9]+\\)\\)?) ?: \\(?:see declaration\\|\\(?:warnin\\(g\\)\\|[a-z ]+\\) C[0-9]+:\\)"
2 3 4 (5))
(edg-1 "^\\([^
]+\\)(\\([0-9]+\\)): \\(?:error\\|warnin\\(g\\)\\|remar\\(k\\)\\)"
1 2 nil (3 . 4))
(edg-2 "at line \\([0-9]+\\) of \"\\([^
]+\\)\"$"
2 1 nil 0)
(epc "^Error [0-9]+ at (\\([0-9]+\\):\\([^)
]+\\))"
2 1)
(ftnchek "\\(^Warning .*\\)? line[
]\\([0-9]+\\)[
]\\(?:col \\([0-9]+\\)[
]\\)?file \\([^ :;
]+\\)"
4 2 3 (1))
(gradle-kotlin "^\\(?:\\(w\\)\\|\\([iv]\\)\\|e\\): \\(\\(?:[A-Za-z]:\\)?[^
:]+\\): (\\([[:digit:]]+\\), \\([[:digit:]]+\\)): "
3 4 5 (1 . 2))
(gradle-android "^ *ERROR:\\(?1:[^
:]+\\):\\(?2:[[:digit:]]+\\): "
1 2)
(iar
"^\"\\(.*\\)\",\\([0-9]+\\)\\s-+\\(?:Error\\|Warnin\\(g\\)\\)\\[[0-9]+\\]:" 1
2 nil (3))
(ibm "^\\([^(
]+\\)(\\([0-9]+\\):\\([0-9]+\\)) : \\(?:warnin\\(g\\)\\|informationa\\(l\\)\\)?"
1 2 3 (4 . 5))
(irix "^[-[:alnum:]_/ ]+: \\(?:\\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*: \\)?\\([^,\"
]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):"
3 4 nil (1 . 2))
(java "^\\(?:[ ]+at \\|==[0-9]+== +\\(?:at\\|b\\(y\\)\\)\\).+(\\([^()
]+\\):\\([0-9]+\\))$"
2 3 nil (1))
(javac "^\\(\\(?:[A-Za-z]:\\)?[^
:]+\\):\\([0-9]+\\): \\(warning: \\)?.*
.*
*\\^$"
1 2 current-column (3))
(jikes-file "^\\(?:Found\\|Issued\\) .* compiling \"\\(.+\\)\":$" 1 nil nil 0)
(maven "^\\(?:\\[\\(?:ERROR\\|\\(?1:WARNING\\)\\|\\(?2:INFO\\)\\)] \\)?\\(?3:[^
[]\\(?:[^
:]\\| [^
/-]\\|:[^
[]\\)*\\):\\[\\(?4:[[:digit:]]+\\),\\(?5:[[:digit:]]+\\)] "
3 4 5 (1 . 2))
(jikes-line "^ *\\([0-9]+\\)\\.[ ]+.*
+\\(<-*>
\\*\\*\\* \\(?:Error\\|Warnin\\(g\\)\\)\\)"
nil 1 nil 2 0 (2 (compilation-face '(3))))
(clang-include "^In file included from \\([^
:]+\\):\\([0-9]+\\):$"
1 2 nil 0)
(gcc-include "^\\(?:In file included \\| \\| \\)from \\([0-9]*[^0-9
]\\(?:[^
:]\\| [^-/
]\\|:[^
]\\)*?\\):\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?\\(?:\\([:,]\\|$\\)\\)?"
1 2 3 (nil . 4))
(ruby-Test::Unit "^ [[ ]?\\([^ (].*\\):\\([1-9][0-9]*\\)\\(\\]\\)?:in " 1 2)
(lua "^[^
]+?: \\([^
]+?\\):\\([0-9]+\\): .+
stack traceback:
"
1 2 nil 2 1)
(lua-stack "^ \\(?:\\[C]:\\|\\([^
]+?\\):\\(?:\\([0-9]+\\):\\)?\\) in "
1 2 nil 0 1)
(gmake ": \\*\\*\\* \\[\\(\\(.+?\\):\\([0-9]+\\): .+\\)\\]" 2 3 nil 0 1) (gnu "^\\(?:[[:alpha:]][.[:alnum:]-]+: ?\\| +|\\)?\\(?1:\\(?:[^
0-9]\\|[0-9]+[^
0-9]\\)\\(?:[^
:]\\| [^
/-]\\|:[^
]\\)*?\\): ?\\(?2:[0-9]+\\)\\(?:-\\(?4:[0-9]+\\)\\(?:\\.\\(?5:[0-9]+\\)\\)?\\|[.:]\\(?3:[0-9]+\\)\\(?:-\\(?:\\(?4:[0-9]+\\)\\.\\)?\\(?5:[0-9]+\\)\\)?\\)?:\\(?: *\\(?6:\\(?:FutureWarning\\|RuntimeWarning\\|W\\(?::\\|arning\\)\\|warning\\)\\)\\| *\\(?7:\\(?:I\\(?::\\|nfo\\(?:rmation\\(?:al\\)?\\)?\\)\\|Note\\|in\\(?:fo\\(?:rmation\\(?:al\\)?\\)?\\|stantiated from\\)\\|note\\|required from\\)\\|\\[ skipping .+ ]\\)\\| *\\(?:[Ee]rror\\)\\|[0-9]?\\(?:[^
0-9]\\|$\\)\\|[0-9][0-9][0-9]\\)"
1
(2
.
4)
(3
.
5)
(6
.
7))
(cucumber
"\\(?:^\\(?:cucumber\\(?: -p [^[:space:]]+\\)?\\| \\)\\|#\\) \\([^(].*\\):\\([1-9][0-9]*\\)"
1 2)
(lcc "^\\(?:E\\|\\(W\\)\\), \\([^(
]+\\)(\\([0-9]+\\),[ ]*\\([0-9]+\\)"
2 3 4 (1))
(makepp
"^makepp\\(?:\\(?:: warning\\(:\\).*?\\|\\(: Scanning\\|: [LR]e?l?oading makefile\\|: Imported\\|log:.*?\\) \\|: .*?\\)`\\(\\(\\S +?\\)\\(?::\\([0-9]+\\)\\)?\\)['(]\\)"
4 5 nil (1 . 2) 3
(0
(progn
(save-match-data
(compilation-parse-errors (match-end 0) (line-end-position)
`
("`\\(\\(\\S +?\\)\\(?::\\([0-9]+\\)\\)?\\)['(]"
2 3 nil
,(cond ((match-end 1) 1) ((match-end 2) 0)
(t 2))
1)))
(end-of-line) nil)))
(mips-1 " (\\([0-9]+\\)) in \\([^
]+\\)"
2 1)
(mips-2 " in \\([^()
]+\\)(\\([0-9]+\\))$"
1 2)
(omake "^\\*\\*\\* omake: file \\(.*\\) changed" 1 nil nil nil nil
(0 (progn (compilation--flush-file-structure (match-string 1)) nil)))
(oracle
"^\\(?:Semantic error\\|Error\\|PCC-[0-9]+:\\).* line \\([0-9]+\\)\\(?:\\(?:,\\| at\\)? column \\([0-9]+\\)\\)?\\(?:,\\| in\\| of\\)? file \\(.*?\\):?$"
3 1 2)
(perl " at \\([^
]+\\) line \\([0-9]+\\)\\(?:[,.]\\|$\\| during global destruction\\.$\\)"
1 2)
(php "\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)" 2
3 nil nil)
(rxp "^\\(?:Error\\|Warnin\\(g\\)\\):.*
.* line \\([0-9]+\\) char \\([0-9]+\\) of file://\\(.+\\)"
4 2 3 (1))
(shellcheck "^In \\(.+\\) line \\([0-9]+\\):" 1 2)
(sparc-pascal-file
"^\\w\\w\\w \\w\\w\\w +[0-3]?[0-9] +[0-2][0-9]:[0-5][0-9]:[0-5][0-9] [12][09][0-9][0-9] +\\(.*\\):$"
1 nil nil 0)
(sparc-pascal-line "^\\(\\(?:E\\|\\(w\\)\\) +[0-9]+\\) line \\([0-9]+\\) - "
nil 3 nil (2) nil (1 (compilation-face '(2))))
(sparc-pascal-example "^ +\\([0-9]+\\) +.*
\\(\\(?:e\\|\\(w\\)\\) [0-9]+\\)-+"
nil 1 nil (3) nil (2 (compilation-face '(3))))
(sun
": \\(?:ERROR\\|WARNIN\\(G\\)\\|REMAR\\(K\\)\\) \\(?:[[:alnum:] ]+, \\)?File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
3 4 5 (1 . 2))
(sun-ada "^\\([^,
]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., (-]"
1 2 3)
(watcom "^[ ]*\\(\\(?:[a-zA-Z]:\\)?[^ :(
][^:(
]*\\)(\\([0-9]+\\)): ?\\(?:\\(Error! E[0-9]+\\)\\|\\(Warning! W[0-9]+\\)\\):"
1 2 nil (4))
(4bsd "\\(?:^\\|:: \\|\\S ( \\)\\(/[^
()]+\\)(\\([0-9]+\\))\\(?:: \\(warning:\\)?\\|$\\| ),\\)"
1 2 nil (3))
(gcov-file "^ *-: *\\(0\\):Source:\\(.+\\)$" 2 1 nil 0 nil)
(gcov-header
"^ *-: *\\(0\\):\\(?:Object\\|Graph\\|Data\\|Runs\\|Programs\\):.+$" nil 1 nil
0 nil)
(gcov-nomark "^ *-: *\\([1-9]\\|[0-9]\\{2,\\}\\):.*$" nil 1 nil 0 nil
(0 'default) (1 compilation-line-face))
(gcov-called-line "^ *\\([0-9]+\\): *\\([0-9]+\\):.*$" nil 2 nil 0 nil
(0 'default) (1 compilation-info-face)
(2 compilation-line-face))
(gcov-never-called "^ *\\(#####\\): *\\([0-9]+\\):.*$" nil 2 nil 2 nil
(0 'default) (1 compilation-error-face)
(2 compilation-line-face))
(perl--Pod::Checker "^\\*\\*\\* \\(?:ERROR\\|\\(WARNING\\)\\).* \\(?:at\\|on\\) line \\([0-9]+\\) \\(?:.* \\)?in file \\([^
]+\\)"
3 2 nil (1))
(perl--Test "^# Failed test [0-9]+ in \\([^
]+\\) at line \\([0-9]+\\)"
1 2)
(perl--Test2 "^\\(.*NOK.*\\)?# Test [0-9]+ got:.* (\\([^
]+\\) at line \\([0-9]+\\)\\( fail #[0-9]+\\)?)"
2 3)
(perl--Test::Harness "^.*NOK.* \\([^
]+\\) at line \\([0-9]+\\)"
1 2)
(weblint "^\\([^
(]+\\) (\\([0-9]+\\):\\([0-9]+\\)) "
1 2 3)
(guile-file "^In \\(.+\\..+\\):
"
1 nil nil 0)
(guile-line "^ *\\([0-9]+\\): *\\([0-9]+\\)" nil 1 2) (typescript-tsc-plain "^\\([^
()][^
()]*\\)(\\([0-9]+\\),\\([0-9]+\\)): error [0-9A-Z]+: "
1 2
3 2)
(typescript-tsc-pretty "^\\([^
()][^
()]*\\):\\([0-9]+\\):\\([0-9]+\\) - error [0-9A-Z]+: "
1 2 3 2))