Emacs新手:如何自定义VHDL/Verilog错误格式及编译报错展示
Hey there! Since you're new to Emacs and Elisp, let's break this down step by step to get you set up with custom error parsing and compiler integration for VHDL/Verilog—mirroring that handy autofix workflow you liked in Vim.
Emacs uses compilation-mode to handle compiler output, and the key to making it recognize your VHDL/Verilog errors is adding entries to compilation-error-regexp-alist. This list tells Emacs how to extract file paths, line numbers, and error messages from your tool's output.
Let's use examples for common tools:
For Icarus Verilog (iverilog): Its error output looks like
test.v:12: syntax error, so we can define a regex to match this:(add-to-list 'compilation-error-regexp-alist '(iverilog "^\\([^:]+\\):\\([0-9]+\\): \\(syntax error\\|error\\|warning\\)" 1 2 nil 2))Let's break this down:
^\\([^:]+\\): Captures the filename (group 1):\\([0-9]+\\):: Captures the line number (group 2)\\(syntax error\\|error\\|warning\\): Matches error/warning types- The final numbers:
1= filename group,2= line number group,nil= no column group,2= highlight the error message
For ModelSim VHDL: Errors might look like
** Error: ./src/test.vhd(42): near "end": syntax error, so the regex would be:(add-to-list 'compilation-error-regexp-alist '(modelsim "\\*\\* \\(Error\\|Warning\\): \\([^(:]+\\)(\\([0-9]+\\)): \\(.*\\)" 2 3 nil 1))Here, group 2 is the filename, group 3 is the line number, and group 1 marks error/warning severity.
Next, you need to tell Emacs which compiler to run for VHDL/Verilog files, and link it to your custom error regex.
Add this to your init.el to set buffer-local compile commands for each language mode:
;; For Verilog mode (add-hook 'verilog-mode-hook (lambda () (setq-local compile-command "iverilog -o test_output test.v") ;; Associate our iverilog regex with this buffer's compilation (setq-local compilation-error-regexp-alist '(iverilog)))) ;; For VHDL mode (add-hook 'vhdl-mode-hook (lambda () (setq-local compile-command "vcom -work work src/test.vhd") (setq-local compilation-error-regexp-alist '(modelsim))))
Now, when you open a Verilog/VHDL file and run M-x compile, Emacs will use the right command and parse errors correctly.
Vim's autofix usually lets you jump between errors and apply quick fixes. In Emacs, you can build this with a mix of built-in commands and custom functions:
First, use built-in navigation commands:
M-x compilation-next-error(orC-x) jumps to the next errorM-x compilation-previous-errorjumps to the previous one
To add quick fixes, write a custom function that checks the current error message and applies a fix. For example, fixing a missing semicolon in Verilog:
(defun my-verilog-fix-missing-semicolon () "Quick fix for missing semicolon error in Verilog." (interactive) (end-of-line) (insert ";") (save-buffer) ;; Recompile automatically to check if the fix worked (recompile))
Bind this to a convenient key in Verilog mode:
(add-hook 'verilog-mode-hook (lambda () (local-set-key (kbd "C-c f") 'my-verilog-fix-missing-semicolon)))
For more complex fixes, expand this to check the error message (using compilation-current-error-message) and apply different fixes based on regex matches.
If you want to package this into a proper plugin, here's a minimal structure:
;;; my-vhdl-verilog-fix.el --- Autofix-like workflow for VHDL/Verilog in Emacs ;; Define error regexes (defconst my-iverilog-error-regex "^\\([^:]+\\):\\([0-9]+\\): \\(syntax error\\|error\\|warning\\)" "Regex for Icarus Verilog errors.") (defconst my-modelsim-error-regex "\\*\\* \\(Error\\|Warning\\): \\([^(:]+\\)(\\([0-9]+\\)): \\(.*\\)" "Regex for ModelSim VHDL errors.") ;; Hook into modes (defun my-vhdl-verilog-setup () (interactive) (cond ((eq major-mode 'verilog-mode) (setq-local compile-command "iverilog -o out *.v") (add-to-list 'compilation-error-regexp-alist '(iverilog my-iverilog-error-regex 1 2 nil 2))) ((eq major-mode 'vhdl-mode) (setq-local compile-command "vcom -work work *.vhd") (add-to-list 'compilation-error-regexp-alist '(modelsim my-modelsim-error-regex 2 3 nil 1))))) (add-hook 'verilog-mode-hook 'my-vhdl-verilog-setup) (add-hook 'vhdl-mode-hook 'my-vhdl-verilog-setup) ;; Autofix functions (defun my-fix-missing-semicolon () "Fix missing semicolon in current line." (interactive) (end-of-line) (insert ";") (save-buffer) (message "Added missing semicolon")) (provide 'my-vhdl-verilog-fix) ;;; my-vhdl-verilog-fix.el ends here
Save this as my-vhdl-verilog-fix.el in your Emacs load path, then add (require 'my-vhdl-verilog-fix) to your init.el.
内容的提问来源于stack exchange,提问作者Ishu Gupta

