diff --git a/test-hdl b/test-hdl
index 127f4ad..f5e819f 160000
--- a/test-hdl
+++ b/test-hdl
@@ -1 +1 @@
-Subproject commit 127f4add50d1a08388b73d36500549ae4e3934be
+Subproject commit f5e819fb256b1d959609d8b8e8814db4b8e57d68
diff --git a/verilog-ext-beautify.el b/verilog-ext-beautify.el
index 19b4b7b..7031bb3 100644
--- a/verilog-ext-beautify.el
+++ b/verilog-ext-beautify.el
@@ -23,7 +23,7 @@
;; Indent, align parameters and ports:
;; - Interactively for module at point
;; - Interactively for current buffer
-;; - In batch for files of current directory
+;; - In batch for list of files and files of current directory
;;; Code:
@@ -136,7 +136,8 @@ FILES is a list of strings containing the filepaths."
(dolist (file files)
(with-temp-file file
(insert-file-contents file)
- (verilog-mode)
+ (verilog-ext-with-no-hooks
+ (verilog-mode))
(verilog-ext-beautify-current-buffer)))))
(defun verilog-ext-beautify-dir-files (dir)
diff --git a/verilog-ext-block-end-comments.el b/verilog-ext-block-end-comments.el
index cc40a67..02df338 100644
--- a/verilog-ext-block-end-comments.el
+++ b/verilog-ext-block-end-comments.el
@@ -20,7 +20,7 @@
;;; Commentary:
-;; Block end comments to names mode
+;; Convert block end comments to names.
;;; Code:
diff --git a/verilog-ext-compile.el b/verilog-ext-compile.el
index c30870f..354382a 100644
--- a/verilog-ext-compile.el
+++ b/verilog-ext-compile.el
@@ -20,25 +20,29 @@
;;; Commentary:
-;; Compilation related SystemVerilog functions.
+;; Compilation-related SystemVerilog functions.
;;
;; This file provides functions to perform compilations with syntax highlighting
-;; and jump to error based on `compilation-mode'.
+;; and jump to error based on `compilation-mode':
;;
-;; Some usage examples:
-;; - (verilog-ext-compile-verilator (concat "verilator --lint-only " buffer-file-name))
-;; - (verilog-ext-compile-iverilog (concat "iverilog " buffer-file-name))
-;; - (verilog-ext-compile-verible (concat "verible-verilog-lint " buffer-file-name))
-;; - (verilog-ext-compile-slang (concat "slang --color-diagnostics=false " buffer-file-name))
-;; - (verilog-ext-compile-svlint (concat "svlint -1 " buffer-file-name))
-;; - (verilog-ext-compile-surelog (concat "surelog -parseonly " buffer-file-name))
+;; - Interactive functions examples:
+;; - `verilog-ext-compile-makefile': prompt to available Makefile targets and compile
+;; - `verilog-ext-compile-project': compile using :compile-cmd of `verilog-ext-project-alist'
+;;
+;; - Non-interactive function usage examples:
+;; - (verilog-ext-compile-verilator (concat "verilator --lint-only " buffer-file-name))
+;; - (verilog-ext-compile-iverilog (concat "iverilog " buffer-file-name))
+;; - (verilog-ext-compile-verible (concat "verible-verilog-lint " buffer-file-name))
+;; - (verilog-ext-compile-slang (concat "slang --color-diagnostics=false " buffer-file-name))
+;; - (verilog-ext-compile-svlint (concat "svlint -1 " buffer-file-name))
+;; - (verilog-ext-compile-surelog (concat "surelog -parseonly " buffer-file-name))
;;
;; It also includes a function to preprocess current buffer: `verilog-ext-preprocess'
;;; Code:
(require 'verilog-mode)
-(require 'verilog-ext-template)
+(require 'verilog-ext-utils)
(require 'make-mode)
@@ -59,100 +63,6 @@
:group 'verilog-ext-compile)
-;;;; Preprocess
-(defun verilog-ext-preprocess ()
- "Preprocess current file.
-Choose among different available programs and update `verilog-preprocessor'
-variable."
- (interactive)
- (let ((tools-available (seq-filter (lambda (bin)
- (executable-find bin))
- '("verilator" "iverilog" "vppreproc"))))
- (pcase (completing-read "Select tool: " tools-available)
- ;; Verilator
- ("verilator" (setq verilog-preprocessor "verilator -E __FLAGS__ __FILE__"))
- ;; Verilog-Perl
- ("vppreproc" (setq verilog-preprocessor "vppreproc __FLAGS__ __FILE__"))
- ;; Icarus Verilog: `iverilog' command syntax requires writing to an output file (defaults to a.out).
- ("iverilog" (let* ((filename-sans-ext (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))
- (iver-out-file (concat (temporary-file-directory) filename-sans-ext "_pp_iver.sv")))
- (setq verilog-preprocessor (concat "iverilog -E -o" iver-out-file " __FILE__ && "
- "echo \"\" && " ; Add blank line between run command and first preprocessed line
- "cat " iver-out-file)))))
- (verilog-preprocess)
- (pop-to-buffer "*Verilog-Preprocessed*")))
-
-
-;;;; Makefile
-(defun verilog-ext-makefile-create ()
- "Create Iverilog/Verilator Yasnippet based Makefile.
-Create it only if in a project and the Makefile does not already exist."
- (interactive)
- (let ((project-root (verilog-ext-buffer-proj-root))
- file)
- (if project-root
- (if (file-exists-p (setq file (file-name-concat project-root "Makefile")))
- (error "File %s already exists!" file)
- (find-file file)
- (verilog-ext-template-insert-yasnippet "verilog"))
- (error "Not in a project!"))))
-
-(defun verilog-ext-makefile-compile ()
- "Prompt to available Makefile targets and compile.
-Compiles them with various verilog regexps."
- (interactive)
- (let ((makefile (file-name-concat (verilog-ext-buffer-proj-root) "Makefile"))
- (makefile-need-target-pickup t) ; Force refresh of makefile targets
- target cmd)
- (unless (file-exists-p makefile)
- (error "%s does not exist!" makefile))
- (with-temp-buffer
- (insert-file-contents makefile)
- (makefile-pickup-targets)
- (setq target (completing-read "Target: " makefile-target-table)))
- (setq cmd (concat "cd " (verilog-ext-buffer-proj-root) " && make " target))
- (compile cmd)))
-
-
-(defmacro verilog-ext-compile-define-mode (name &rest args)
- "Macro to define a compilation derived mode for a Verilog error regexp.
-
-NAME is the name of the created compilation mode.
-
-ARGS is a property list with :desc, :docstring, :compile-re and :buf-name."
- (declare (indent 1) (debug 1))
- (let ((desc (plist-get args :desc))
- (docstring (plist-get args :docstring))
- (compile-re (plist-get args :compile-re))
- (buf-name (plist-get args :buf-name)))
- `(define-compilation-mode ,name ,desc ,docstring
- (setq-local compilation-error-regexp-alist (mapcar #'car ,compile-re))
- (setq-local compilation-error-regexp-alist-alist ,compile-re)
- (when ,buf-name
- (rename-buffer ,buf-name))
- (setq truncate-lines t)
- (goto-char (point-max)))))
-
-(defmacro verilog-ext-compile-define-fn (name &rest args)
- "Macro to define a function to compile with error regexp highlighting.
-
-Function will be callable by NAME.
-
-ARGS is a property list."
- (declare (indent 1) (debug 1))
- (let ((docstring (plist-get args :docstring))
- (buf (plist-get args :buf))
- (comp-mode (plist-get args :comp-mode)))
- `(defun ,name (command)
- ,docstring
- (when (and ,buf (get-buffer ,buf))
- (if (y-or-n-p (format "Buffer %s is in use, kill its process and start new compilation?" ,buf))
- (kill-buffer ,buf)
- (user-error "Aborted")))
- (compile command)
- (,comp-mode))))
-
-
;;;; Compilation-re
(defconst verilog-ext-compile-filename-re "[a-zA-Z0-9-_\\.\\/]+")
@@ -207,14 +117,52 @@ ARGS is a property list."
(surelog-info2 ,(concat "^\\[\\(?1:INF:\\(?2:[A-Z0-9]+\\)\\)\\]\\s-+") nil nil nil 0 nil (1 compilation-info-face) (2 verilog-ext-compile-msg-code-face)))
"Surelog regexps.")
-(defvar verilog-ext-compile-verilator-buf "*verilator*")
-(defvar verilog-ext-compile-iverilog-buf "*iverilog*")
-(defvar verilog-ext-compile-verible-buf "*verible*")
-(defvar verilog-ext-compile-slang-buf "*slang*")
-(defvar verilog-ext-compile-svlint-buf "*svlint*")
-(defvar verilog-ext-compile-surelog-buf "*surelog*")
+(defconst verilog-ext-compile-verilator-buf "*verilator*")
+(defconst verilog-ext-compile-iverilog-buf "*iverilog*")
+(defconst verilog-ext-compile-verible-buf "*verible*")
+(defconst verilog-ext-compile-slang-buf "*slang*")
+(defconst verilog-ext-compile-svlint-buf "*svlint*")
+(defconst verilog-ext-compile-surelog-buf "*surelog*")
+
+;;;; Compilation-modes and macros
+(defmacro verilog-ext-compile-define-mode (name &rest args)
+ "Macro to define a compilation derived mode for a Verilog error regexp.
+
+NAME is the name of the created compilation mode.
+
+ARGS is a property list with :desc, :docstring, :compile-re and :buf-name."
+ (declare (indent 1) (debug 1))
+ (let ((desc (plist-get args :desc))
+ (docstring (plist-get args :docstring))
+ (compile-re (plist-get args :compile-re))
+ (buf-name (plist-get args :buf-name)))
+ `(define-compilation-mode ,name ,desc ,docstring
+ (setq-local compilation-error-regexp-alist (mapcar #'car ,compile-re))
+ (setq-local compilation-error-regexp-alist-alist ,compile-re)
+ (when ,buf-name
+ (rename-buffer ,buf-name))
+ (setq truncate-lines t)
+ (goto-char (point-max)))))
+
+(defmacro verilog-ext-compile-define-fn (name &rest args)
+ "Macro to define a function to compile with error regexp highlighting.
+
+Function will be callable by NAME.
+
+ARGS is a property list."
+ (declare (indent 1) (debug 1))
+ (let ((docstring (plist-get args :docstring))
+ (buf (plist-get args :buf))
+ (comp-mode (plist-get args :comp-mode)))
+ `(defun ,name (command)
+ ,docstring
+ (when (and ,buf (get-buffer ,buf))
+ (if (y-or-n-p (format "Buffer %s is in use, kill its process and start new compilation?" ,buf))
+ (kill-buffer ,buf)
+ (user-error "Aborted")))
+ (compile command)
+ (,comp-mode))))
-;;;; Compilation-modes and functions
(verilog-ext-compile-define-mode verilog-ext-compile-verilator-mode
:desc "Verilator"
:docstring "Verilator Compilation mode."
@@ -282,8 +230,24 @@ ARGS is a property list."
:comp-mode verilog-ext-compile-surelog-mode)
-(defun verilog-ext-compile ()
- "Compile using command of :compile-cmd of `verilog-ext-project-alist' project.
+;;;; Compilation interactive functions
+(defun verilog-ext-compile-makefile ()
+ "Prompt to available Makefile targets and compile."
+ (interactive)
+ (let ((makefile (file-name-concat (verilog-ext-buffer-proj-root) "Makefile"))
+ (makefile-need-target-pickup t) ; Force refresh of makefile targets
+ target cmd)
+ (unless (file-exists-p makefile)
+ (error "%s does not exist!" makefile))
+ (with-temp-buffer
+ (insert-file-contents makefile)
+ (makefile-pickup-targets)
+ (setq target (completing-read "Target: " makefile-target-table)))
+ (setq cmd (mapconcat #'identity `("cd" ,(verilog-ext-buffer-proj-root) "&&" "make" ,target) " "))
+ (compile cmd)))
+
+(defun verilog-ext-compile-project ()
+ "Compile using :compile-cmd of `verilog-ext-project-alist' project.
Depending on the command, different syntax highlight will be applied.
@@ -318,10 +282,37 @@ set the appropriate mode."
;; For the rest use the provided command
(t
compile-cmd)))
- (cmd (concat "cd " (verilog-ext-buffer-proj-root proj) " && " cmd-processed)))
+ (cmd (mapconcat `("cd" ,(verilog-ext-buffer-proj-root proj) "&&" ,cmd-processed) " ")))
(funcall fn cmd)))
+;;;; Preprocess
+(defun verilog-ext-preprocess ()
+ "Preprocess current file.
+
+Choose among available programs and update `verilog-preprocessor' variable.
+
+Supports verilator, vppreproc and iverilog."
+ (interactive)
+ (let ((tools-available (seq-filter (lambda (bin)
+ (executable-find bin))
+ '("verilator" "iverilog" "vppreproc"))))
+ (pcase (completing-read "Select tool: " tools-available)
+ ;; Verilator
+ ("verilator" (setq verilog-preprocessor "verilator -E __FLAGS__ __FILE__"))
+ ;; Verilog-Perl
+ ("vppreproc" (setq verilog-preprocessor "vppreproc __FLAGS__ __FILE__"))
+ ;; Icarus Verilog: `iverilog' command syntax requires writing to an output file (defaults to a.out).
+ ("iverilog" (let* ((filename-sans-ext (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))
+ (iver-out-file (concat (temporary-file-directory) filename-sans-ext "_pp_iver.sv")))
+ (setq verilog-preprocessor (concat "iverilog -E -o" iver-out-file " __FILE__ && "
+ "echo \"\" && " ; Add blank line between run command and first preprocessed line
+ "cat " iver-out-file)))))
+ (verilog-preprocess)
+ (pop-to-buffer "*Verilog-Preprocessed*")))
+
+
+
(provide 'verilog-ext-compile)
;;; verilog-ext-compile.el ends here
diff --git a/verilog-ext-flycheck.el b/verilog-ext-flycheck.el
index f811ca1..e981df6 100644
--- a/verilog-ext-flycheck.el
+++ b/verilog-ext-flycheck.el
@@ -85,7 +85,7 @@ https://chipsalliance.github.io/verible/lint.html"
(defcustom verilog-ext-flycheck-svlint-include-path nil
"List of include paths for svlint linter.
-Variables is needed since svlint doesn't allow both source and -f command file
+Variable is needed since svlint doesn't allow both source and -f command file
at the same time."
:type '(repeat directory)
:group 'verilog-ext-flycheck)
diff --git a/verilog-ext-font-lock.el b/verilog-ext-font-lock.el
index aeb51b1..2e2cf37 100644
--- a/verilog-ext-font-lock.el
+++ b/verilog-ext-font-lock.el
@@ -683,6 +683,7 @@ Similar to `verilog-match-translate-off' but including
;;; Setup
(defun verilog-ext-font-lock-setup ()
"Setup syntax highlighting of SystemVerilog buffers.
+
Add `verilog-ext-mode' font lock keywords before running
`verilog-mode' in order to populate `font-lock-keywords-alist'
before `font-lock' is loaded."
diff --git a/verilog-ext-hierarchy.el b/verilog-ext-hierarchy.el
index 0ee7b9a..7b39f83 100644
--- a/verilog-ext-hierarchy.el
+++ b/verilog-ext-hierarchy.el
@@ -83,11 +83,12 @@ Used to navigate definitions with `verilog-ext-hierarchy-twidget-nav-open'.")
(defvar verilog-ext-hierarchy-internal-alist nil
"Per project flat hierarchy alist.
Used by builtin and tree-sitter backends.")
+
(defvar verilog-ext-hierarchy-current-flat-hier nil
"Current flat hierarchy.
Used by `verilog-ext-hierarchy-extract--internal',
-`verilog-ext-hierarchy-ghdl-extract' and their subroutines.
+`verilog-ext-hierarchy-vhier-extract' and their subroutines.
Needed since `verilog-ext-hierarchy-extract--childrenfn' can only
have one argument (item).")
@@ -126,7 +127,7 @@ Arg ITEM are hierarchy nodes."
(defun verilog-ext-hierarchy-extract--internal (module)
"Construct hierarchy struct for MODULE.
-Entities and instances will be analyzed from corresponding entry in
+Modules and instances will be analyzed from corresponding entry in
`verilog-ext-hierarchy-current-flat-hier'. These entries will have an
associated project present `verilog-ext-project-alist' and will be of the form:
\(module instance1:NAME1 instance2:NAME2 ...\).
@@ -295,7 +296,10 @@ Used for hierarchy.el frontend to visit file of module at point."
(defun verilog-ext-hierarchy-vhier-extract (module)
"Extract hierarchy of MODULE using Verilog-Perl vhier as a backend.
-Return hierarchy as an indented string."
+
+With current prefix, force refreshing of hierarchy database for active project.
+
+Return populated `hierarchy' struct."
(unless (executable-find "vhier")
(error "Executable vhier not found"))
(let* ((proj (verilog-ext-buffer-proj))
@@ -338,6 +342,7 @@ Return hierarchy as an indented string."
(setq hierarchy-string (buffer-substring-no-properties (point-min) (point-max))))
;; Convert indented string to alist for caching and default hierarchy.el displaying
(setq hierarchy-alist (verilog-ext-hierarchy--convert-string-to-alist hierarchy-string))
+ ;; Update variables and cache
(verilog-ext-proj-setcdr proj verilog-ext-hierarchy-vhier-alist hierarchy-alist)
(verilog-ext-hierarchy-build-module-alist proj-files proj)
(setq verilog-ext-hierarchy-current-flat-hier hierarchy-alist)
@@ -545,7 +550,7 @@ If OTHER-WINDOW is non-nil, open definition in other window."
(verilog-ext-hierarchy-outshine-jump-to-file :other-window))
(define-minor-mode verilog-ext-hierarchy-outshine-nav-mode
- "Instance navigation frontend for Verilog-Perl `vhier'.
+ "Instance navigation frontend with `outshine'.
Makes use of processed output under `outline-minor-mode' and `outshine'."
:lighter " vH"
:keymap
@@ -605,7 +610,8 @@ Expects HIERARCHY to be a indented string."
(goto-char (point-min))
(open-line 1)
(insert "// Hierarchy generated by `verilog-ext'\n")
- (verilog-mode)
+ (verilog-ext-with-no-hooks
+ (verilog-mode))
(verilog-ext-hierarchy-outshine-nav-mode))
(pop-to-buffer buf)))
@@ -665,13 +671,13 @@ With prefix arg, clear cache for ALL projects."
"Construct hierarchy for MODULE depending on selected backend."
(cond (;; Verilog-Perl vhier
(eq verilog-ext-hierarchy-backend 'vhier)
- (verilog-ext-hierarchy-vhier-extract module)) ; Returns indented string
+ (verilog-ext-hierarchy-vhier-extract module))
(;; Tree-sitter
(eq verilog-ext-hierarchy-backend 'tree-sitter)
- (verilog-ext-hierarchy-tree-sitter-extract module)) ; Returns populated hierarchy struct
+ (verilog-ext-hierarchy-tree-sitter-extract module))
(;; Built-in
(eq verilog-ext-hierarchy-backend 'builtin)
- (verilog-ext-hierarchy-builtin-extract module)) ; Returns populated hierarchy struct
+ (verilog-ext-hierarchy-builtin-extract module))
;; Fallback
(t (error "Must set a proper extraction backend in `verilog-ext-hierarchy-backend'"))))
diff --git a/verilog-ext-hs.el b/verilog-ext-hs.el
index 6226bc6..2a2c968 100644
--- a/verilog-ext-hs.el
+++ b/verilog-ext-hs.el
@@ -20,7 +20,7 @@
;;; Commentary:
-;; Basic hideshow configuration
+;; `hideshow' configuration for code folding.
;;; Code:
@@ -62,7 +62,7 @@
"\\)" "\\)")))
(defun verilog-ext-hs-setup ()
- "Configure hideshow."
+ "Configure `hideshow'."
(dolist (mode '((verilog-mode . verilog-forward-sexp-function)
(verilog-ts-mode . verilog-ts-forward-sexp)))
(add-to-list 'hs-special-modes-alist `(,(car mode)
@@ -72,7 +72,11 @@
,(cdr mode)))))
(defun verilog-ext-hs-toggle-hiding (&optional e)
- "Wrapper for `hs-toggle-hiding' with proper syntax table.
+ "Wrapper for `hs-toggle-hiding' depending on current Verilog `major-mode'.
+
+For `verilog-mode' use a modified syntax table. For `verilog-ts-mode' use
+existing one.
+
Toggle hiding/showing of a block.
See `hs-hide-block' and `hs-show-block'.
Argument E should be the event that triggered this action."
diff --git a/verilog-ext-imenu.el b/verilog-ext-imenu.el
index 182b2fa..876e211 100644
--- a/verilog-ext-imenu.el
+++ b/verilog-ext-imenu.el
@@ -30,6 +30,12 @@
(require 'verilog-ext-nav)
+(defconst verilog-ext-imenu-class-item-face 'verilog-ext-imenu-class-item-face)
+(defface verilog-ext-imenu-class-item-face
+ '((t nil))
+ "Face for class items."
+ :group 'verilog-ext)
+
(defconst verilog-ext-imenu-top-re "^\\s-*\\(?1:connectmodule\\|m\\(?:odule\\|acromodule\\)\\|p\\(?:rimitive\\|rogram\\|ackage\\)\\)\\(\\s-+automatic\\)?\\s-+\\(?2:[a-zA-Z0-9_.:]+\\)")
(defconst verilog-ext-imenu-localparam-re "^\\s-*localparam\\(?1:\\s-+\\(logic\\|bit\\|int\\|integer\\)\\s-*\\(\\[.*\\]\\)?\\)?\\s-+\\(?2:[a-zA-Z0-9_.:]+\\)")
(defconst verilog-ext-imenu-define-re "^\\s-*`define\\s-+\\([a-zA-Z0-9_.:]+\\)")
@@ -50,6 +56,7 @@
(defun verilog-ext-imenu-find-module-instance-index ()
"Create imenu entries of modules and instances.
+
Placing this outside of `imenu--generic-function' avoids running it if
`which-func' is enabled. It also allows to conditionally disable the index
building if file cannot contain instances."
@@ -93,7 +100,7 @@ Group the ones that belong to same external method definitions."
(defun verilog-ext-imenu--format-class-item-label (type name modifiers)
"Return Imenu label for single node using TYPE, NAME and MODIFIERS."
- (let* ((prop-name (propertize name 'face '(:foreground "goldenrod" :weight bold)))
+ (let* ((prop-name (propertize name 'face verilog-ext-imenu-class-item-face))
(short-type (pcase type
("task" " [T]")
("function" " [F]")
@@ -156,6 +163,7 @@ Find recursively tasks and functions inside classes."
(defun verilog-ext-imenu-index ()
"Index builder function for Verilog Imenu.
+
Makes use of `verilog-ext-imenu-generic-expression' for everything but classes
and methods. These are collected with `verilog-ext-imenu-classes-index'."
(append (verilog-ext-imenu-find-module-instance-index)
diff --git a/verilog-ext-nav.el b/verilog-ext-nav.el
index 706c175..ecd6845 100644
--- a/verilog-ext-nav.el
+++ b/verilog-ext-nav.el
@@ -24,9 +24,13 @@
;;; Code:
+(require 'ag)
+(require 'ripgrep)
+(require 'xref)
(require 'verilog-ext-utils)
+;;;; Custom
(defgroup verilog-ext-nav nil
"Verilog-ext navigation."
:group 'verilog-ext)
@@ -38,6 +42,8 @@ Either `rg' or `ag' are implemented."
(const :tag "ripgrep" "rg"))
:group 'verilog-ext-nav)
+
+;;;; Defuns
(defconst verilog-ext-block-re
(eval-when-compile
(regexp-opt
@@ -79,6 +85,7 @@ Move backward ARG words."
(defun verilog-ext-find-function-task (&optional limit bwd interactive-p)
"Search for a Verilog function/task declaration or definition.
+
Allows matching of multiline declarations (such as in some UVM source files).
If executing interactively show function/task name in the minibuffer.
@@ -302,6 +309,7 @@ Bound search to LIMIT in case optional argument is non-nil."
(defun verilog-ext-find-function-task-class (&optional limit bwd interactive-p)
"Find closest declaration of a function/task/class.
+
Return alist with data associated to the thing found.
Search bacwards if BWD is non-nil.
@@ -580,7 +588,7 @@ Bound search to LIMIT in case it is non-nil."
(when (called-interactively-p 'interactive)
(message "Could not find any instance backwards"))))))
-(defun verilog-ext-find-module-instance-bwd-2 ()
+(defun verilog-ext-find-module-instance-bwd-1 ()
"Search backwards for a Verilog module/instance.
The difference with `verilog-ext-find-module-instance-bwd' is that it
moves the cursor to current instance if pointing at one."
@@ -694,103 +702,6 @@ If REF is non-nil show references instead."
(verilog-ext-jump-to-module-at-point :ref))
-;;;; Jump to parent module
-(defvar verilog-ext-jump-to-parent-module-point-marker nil
- "Point marker to save the state of the buffer where the search was started.
-Used in ag/rg end of search hooks to conditionally set the xref marker stack.")
-(defvar verilog-ext-jump-to-parent-module-name nil)
-(defvar verilog-ext-jump-to-parent-module-dir nil)
-(defvar verilog-ext-jump-to-parent-trigger nil
- "Variable to run the post ag/rg command hook.
-Runs only when the ag/rg search was triggered by
-`verilog-ext-jump-to-parent-module' command.")
-(defvar verilog-ext-jump-to-parent-module-starting-windows nil
- "Variable to register how many windows are open when trying to jump-to-parent.")
-
-(defun verilog-ext-jump-to-parent-module ()
- "Find current module/interface instantiations via `ag'/`rg'.
-
-Configuration should be done so that `verilog-ext-navigation-ag-rg-hook' is run
-after the search has been done."
- (interactive)
- (let* ((proj-dir (verilog-ext-buffer-proj-root))
- (module-name (or (verilog-ext-select-file-module buffer-file-name)
- (error "No module/interface found @ %s" buffer-file-name)))
- (module-instance-pcre ; Many thanks to Kaushal Modi for this PCRE
- (concat "^\\s*\\K" ; Initial blank before module name. Do not highlighting anything till the name
- "\\b(" module-name ")\\b" ; Module name identifier
- "(?=" ; Lookahead to avoid matching
- "(\\s+|(" ; Either one or more spaces before the instance name, or...
- "(\\s*\#\\s*\\((\\n|.)*?\\))+" ; ... hardware parameters, '(\n|.)*?' does non-greedy multi-line grep
- "(\\n|.)*?" ; Optional newline/space before instance name/first port name
- "([^.])*?" ; Do not match more than 1 ".PARAM (PARAM_VAL),"
- "))" ; Close capture groups before matching identifier
- "\\b(" verilog-identifier-re ")\\b" ; Instance name
- "(?=[^a-zA-Z0-9_]*\\()" ; Nested lookahead (space/newline after instance name and before opening parenthesis)
- ")"))) ; Closing lookahead
- ;; Check we are in a project
- (unless proj-dir
- (user-error "Not in a Verilog project buffer"))
- ;; Update variables used by the ag/rg search finished hooks
- (setq verilog-ext-jump-to-parent-module-name module-name)
- (setq verilog-ext-jump-to-parent-module-dir proj-dir)
- (setq verilog-ext-jump-to-parent-module-starting-windows (length (window-list)))
- ;; Perform project based search
- (cond
- ;; Try ripgrep
- ((and (string= verilog-ext-jump-to-parent-module-engine "rg")
- (executable-find "rg"))
- (let ((rg-extra-args '("-t" "verilog" "--pcre2" "--multiline" "--stats")))
- (setq verilog-ext-jump-to-parent-module-point-marker (point-marker))
- (setq verilog-ext-jump-to-parent-trigger t)
- (ripgrep-regexp module-instance-pcre proj-dir rg-extra-args)))
- ;; Try ag
- ((and (string= verilog-ext-jump-to-parent-module-engine "ag")
- (executable-find "ag"))
- (let ((ag-arguments ag-arguments)
- (extra-ag-args '("--verilog" "--stats")))
- (dolist (extra-ag-arg extra-ag-args)
- (add-to-list 'ag-arguments extra-ag-arg :append))
- (setq verilog-ext-jump-to-parent-module-point-marker (point-marker))
- (setq verilog-ext-jump-to-parent-trigger t)
- (ag-regexp module-instance-pcre proj-dir)))
- ;; Fallback
- (t
- (error "Did not find `rg' nor `ag' in $PATH")))))
-
-(defun verilog-ext-navigation-ag-rg-hook-cleanup ()
- "Handle buffer killing depending on the number of active windows."
- (if (> verilog-ext-jump-to-parent-module-starting-windows 1)
- (kill-buffer (current-buffer))
- (other-window 1)
- (delete-window)))
-
-(defun verilog-ext-navigation-ag-rg-hook ()
- "Jump to the first result and push xref marker if there were any matches.
-Kill the buffer if there is only one match."
- (when verilog-ext-jump-to-parent-trigger
- (let ((module-name (propertize verilog-ext-jump-to-parent-module-name 'face '(:foreground "green")))
- (dir (propertize verilog-ext-jump-to-parent-module-dir 'face '(:foreground "light blue")))
- (num-matches))
- (save-excursion
- (goto-char (point-min))
- (re-search-forward "^\\([0-9]+\\) matches\\s-*$" nil :noerror)
- (setq num-matches (string-to-number (match-string-no-properties 1))))
- (cond ((eq num-matches 1)
- (xref-push-marker-stack verilog-ext-jump-to-parent-module-point-marker)
- (next-error)
- (verilog-ext-navigation-ag-rg-hook-cleanup)
- (message "Jump to only match for [%s] @ %s" module-name dir))
- ((> num-matches 1)
- (xref-push-marker-stack verilog-ext-jump-to-parent-module-point-marker)
- (next-error)
- (message "Showing matches for [%s] @ %s" module-name dir))
- (t
- (verilog-ext-navigation-ag-rg-hook-cleanup)
- (message "No matches found")))
- (setq verilog-ext-jump-to-parent-trigger nil))))
-
-
;;;; Defun movement
(defun verilog-ext-goto-begin-up ()
"Move point to start position of current begin."
@@ -892,13 +803,14 @@ If in a module/interface look for instantiations.
Otherwise look for functions/tasks."
(interactive)
(if (verilog-ext-scan-buffer-modules)
- (call-interactively #'verilog-ext-find-module-instance-bwd-2)
+ (call-interactively #'verilog-ext-find-module-instance-bwd-1)
(call-interactively #'verilog-ext-defun-level-up)))
(defun verilog-ext-nav-beg-of-defun-dwim ()
"Context based search upwards.
-If in a module/interface look for instantiations.
-Otherwise look for functions/tasks."
+If in a module/interface look for blocks (e.g modules, always, initial,
+function, generate, property...)
+Otherwise look for functions, tasks or classes."
(interactive)
(if (verilog-ext-scan-buffer-modules)
(call-interactively #'verilog-ext-find-block-bwd)
@@ -906,8 +818,9 @@ Otherwise look for functions/tasks."
(defun verilog-ext-nav-end-of-defun-dwim ()
"Context based search upwards.
-If in a module/interface look for instantiations.
-Otherwise look for functions/tasks."
+If in a module/interface look for blocks (e.g modules, always, initial,
+function, generate, property...)
+Otherwise look for functions, tasks or classes."
(interactive)
(if (verilog-ext-scan-buffer-modules)
(call-interactively #'verilog-ext-find-block-fwd)
@@ -936,6 +849,103 @@ Otherwise move to previous paragraph."
(backward-paragraph)))
+;;;; Jump to parent module
+(defvar verilog-ext-jump-to-parent-module-point-marker nil
+ "Point marker to save the state of the buffer where the search was started.
+Used in ag/rg end of search hooks to conditionally set the xref marker stack.")
+(defvar verilog-ext-jump-to-parent-module-name nil)
+(defvar verilog-ext-jump-to-parent-module-dir nil)
+(defvar verilog-ext-jump-to-parent-trigger nil
+ "Variable to run the post ag/rg command hook.
+Runs only when the ag/rg search was triggered by
+`verilog-ext-jump-to-parent-module' command.")
+(defvar verilog-ext-jump-to-parent-module-starting-windows nil
+ "Variable to register how many windows are open when trying to jump-to-parent.")
+
+(defun verilog-ext-jump-to-parent-module ()
+ "Find current module/interface instantiations via `ag'/`rg'.
+
+Configuration should be done so that `verilog-ext-navigation-ag-rg-hook' is run
+after the search has been done."
+ (interactive)
+ (let* ((proj-dir (verilog-ext-buffer-proj-root))
+ (module-name (or (verilog-ext-select-file-module buffer-file-name)
+ (error "No module/interface found @ %s" buffer-file-name)))
+ (module-instance-pcre ; Many thanks to Kaushal Modi for this PCRE
+ (concat "^\\s*\\K" ; Initial blank before module name. Do not highlighting anything till the name
+ "\\b(" module-name ")\\b" ; Module name identifier
+ "(?=" ; Lookahead to avoid matching
+ "(\\s+|(" ; Either one or more spaces before the instance name, or...
+ "(\\s*\#\\s*\\((\\n|.)*?\\))+" ; ... hardware parameters, '(\n|.)*?' does non-greedy multi-line grep
+ "(\\n|.)*?" ; Optional newline/space before instance name/first port name
+ "([^.])*?" ; Do not match more than 1 ".PARAM (PARAM_VAL),"
+ "))" ; Close capture groups before matching identifier
+ "\\b(" verilog-identifier-re ")\\b" ; Instance name
+ "(?=[^a-zA-Z0-9_]*\\()" ; Nested lookahead (space/newline after instance name and before opening parenthesis)
+ ")"))) ; Closing lookahead
+ ;; Check we are in a project
+ (unless proj-dir
+ (user-error "Not in a Verilog project buffer"))
+ ;; Update variables used by the ag/rg search finished hooks
+ (setq verilog-ext-jump-to-parent-module-name module-name)
+ (setq verilog-ext-jump-to-parent-module-dir proj-dir)
+ (setq verilog-ext-jump-to-parent-module-starting-windows (length (window-list)))
+ ;; Perform project based search
+ (cond
+ ;; Try ripgrep
+ ((and (string= verilog-ext-jump-to-parent-module-engine "rg")
+ (executable-find "rg"))
+ (let ((rg-extra-args '("-t" "verilog" "--pcre2" "--multiline" "--stats")))
+ (setq verilog-ext-jump-to-parent-module-point-marker (point-marker))
+ (setq verilog-ext-jump-to-parent-trigger t)
+ (ripgrep-regexp module-instance-pcre proj-dir rg-extra-args)))
+ ;; Try ag
+ ((and (string= verilog-ext-jump-to-parent-module-engine "ag")
+ (executable-find "ag"))
+ (let ((ag-arguments ag-arguments)
+ (extra-ag-args '("--verilog" "--stats")))
+ (dolist (extra-ag-arg extra-ag-args)
+ (add-to-list 'ag-arguments extra-ag-arg :append))
+ (setq verilog-ext-jump-to-parent-module-point-marker (point-marker))
+ (setq verilog-ext-jump-to-parent-trigger t)
+ (ag-regexp module-instance-pcre proj-dir)))
+ ;; Fallback
+ (t
+ (error "Did not find `rg' nor `ag' in $PATH")))))
+
+(defun verilog-ext-navigation-ag-rg-hook-cleanup ()
+ "Handle buffer killing depending on the number of active windows."
+ (if (> verilog-ext-jump-to-parent-module-starting-windows 1)
+ (kill-buffer (current-buffer))
+ (other-window 1)
+ (delete-window)))
+
+(defun verilog-ext-navigation-ag-rg-hook ()
+ "Jump to the first result and push xref marker if there were any matches.
+Kill the buffer if there is only one match."
+ (when verilog-ext-jump-to-parent-trigger
+ (let ((module-name (propertize verilog-ext-jump-to-parent-module-name 'face '(:foreground "green")))
+ (dir (propertize verilog-ext-jump-to-parent-module-dir 'face '(:foreground "light blue")))
+ (num-matches))
+ (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^\\([0-9]+\\) matches\\s-*$" nil :noerror)
+ (setq num-matches (string-to-number (match-string-no-properties 1))))
+ (cond ((eq num-matches 1)
+ (xref-push-marker-stack verilog-ext-jump-to-parent-module-point-marker)
+ (next-error)
+ (verilog-ext-navigation-ag-rg-hook-cleanup)
+ (message "Jump to only match for [%s] @ %s" module-name dir))
+ ((> num-matches 1)
+ (xref-push-marker-stack verilog-ext-jump-to-parent-module-point-marker)
+ (next-error)
+ (message "Showing matches for [%s] @ %s" module-name dir))
+ (t
+ (verilog-ext-navigation-ag-rg-hook-cleanup)
+ (message "No matches found")))
+ (setq verilog-ext-jump-to-parent-trigger nil))))
+
+
(provide 'verilog-ext-nav)
;;; verilog-ext-nav.el ends here
diff --git a/verilog-ext-tags.el b/verilog-ext-tags.el
index 5926ff7..e80748a 100644
--- a/verilog-ext-tags.el
+++ b/verilog-ext-tags.el
@@ -19,9 +19,25 @@
;; along with this program. If not, see .
;;; Commentary:
-
+;;
;; Tag collection for jump to definition/reference and semantic completion.
-
+;;
+;; `verilog-ext-tags-get-async' relies on emacs-async: https://github.com/jwiegley/emacs-async:
+;;
+;; - Limitations with async tag collection:
+;;
+;; - The `async' library has limitations with hash-tables:
+;; - async-start returns hash tables as lists: https://github.com/jwiegley/emacs-async/issues/164
+;; - Since the # is stripped (https://github.com/jwiegley/emacs-async/issues/145) and it's needed to
+;; properly represent hash-tables, the result is that this implementation requires a workaround
+;; - Solution:
+;; - Reading/writing to/from stored cached files
+;;
+;; - Injecting the environment with the value of large hash tables (e.g. `verilog-ext-tags-defs-table') in
+;; `async-start' via `async-inject-variables' takes a long time in the parent process
+;; - Solution:
+;; - Reading environment from stored cached files
+;;
;;; Code:
(require 'async)
@@ -184,7 +200,7 @@ project."
;;;; Builtin
(cl-defun verilog-ext-tags-table-push-defs (&key tag-type file start limit parent)
- "Push definitions of TAG-TYPE inside hash table TABLE.
+ "Push definitions of TAG-TYPE inside tags hash table.
FILE might be specified for the cases when a temp-buffer without an associated
file is being parsed.
@@ -314,7 +330,7 @@ PARENT is the module where TAG is defined/instantiated for dot completion."
(defun verilog-ext-tags-table-push-refs (file)
"Push references inside hash table TABLE.
-FILE can be provided for the case when references are fetched from a
+FILE must be provided for the case when references are fetched from a
temp-buffer."
(let (tag begin line)
(save-match-data
@@ -506,7 +522,7 @@ Steps:
(FILE-WAS-REMOVED should be non-nil)
- Check current file hash and compare to previous stored ones to check if it
has changed
- - If it did, consider 3 different scenarios:
+ - Consider 3 different scenarios:
- File did not change: skip that file and check next one
- File changed: remove previous file locs, collect new file tags and update
tables and file hashes
diff --git a/verilog-ext-template.el b/verilog-ext-template.el
index 8c3b3a2..4e0cd1a 100644
--- a/verilog-ext-template.el
+++ b/verilog-ext-template.el
@@ -44,7 +44,7 @@
(defconst verilog-ext-template-snippets-dir
(expand-file-name "snippets" (file-name-directory (or load-file-name (buffer-file-name))))
- "Yasnippet verilog-ext snippets directory.")
+ "Yasnippet `verilog-ext' snippets directory.")
(defmacro with-verilog-ext-template (&rest body)
@@ -363,39 +363,39 @@ If ASYNC is non-nil create an asynchronous reset."
;;;; Instances
-(defvar verilog-ext-template-inst-auto-header "// Beginning of Verilog AUTO_TEMPLATE")
-(defvar verilog-ext-template-inst-auto-footer "// End of Verilog AUTO_TEMPLATE")
+(defconst verilog-ext-template-inst-auto-header "// Beginning of Verilog AUTO_TEMPLATE")
+(defconst verilog-ext-template-inst-auto-footer "// End of Verilog AUTO_TEMPLATE")
(defun verilog-ext-template-inst-auto (template)
"Insert header and footer to TEMPLATE strings for instantiation."
(concat "\n" verilog-ext-template-inst-auto-header " " template " " verilog-ext-template-inst-auto-footer "\n"))
-(defvar verilog-ext-template-inst-auto-conn-ports
+(defconst verilog-ext-template-inst-auto-conn-ports
(verilog-ext-template-inst-auto "
/* AUTO_TEMPLATE (
.\\(.*\\) (\\1),
); */")
"Template with connected ports (same signal name as the port).")
-(defvar verilog-ext-template-inst-auto-disc-ports
+(defconst verilog-ext-template-inst-auto-disc-ports
(verilog-ext-template-inst-auto "
/* AUTO_TEMPLATE (
.\\(.*\\) (),
); */")
"Template with disconnected ports.")
-(defvar verilog-ext-template-inst-auto-conn-ports-ss
+(defconst verilog-ext-template-inst-auto-conn-ports-ss
(verilog-ext-template-inst-auto "
/* AUTO_TEMPLATE (
.\\(.*\\) (\\1[]),
); */")
"Template with connected ports and subscripts.")
-(defvar verilog-ext-template-inst-auto-simple "\
+(defconst verilog-ext-template-inst-auto-simple "\
(/*AUTOINST*/);
")
-(defvar verilog-ext-template-inst-auto-params "\
+(defconst verilog-ext-template-inst-auto-params "\
# (/*AUTOINSTPARAM*/) (/*AUTOINST*/);
")
@@ -693,7 +693,7 @@ Files will be created at {BASE-DIR}/{NAME} directory."
(save-buffer)
(kill-buffer)))))
-;;;; Yasnippet/Hydra
+;;;; Yasnippet
(defun verilog-ext-template-insert-yasnippet (snippet)
"Insert SNIPPET programatically."
(insert snippet)
@@ -704,6 +704,22 @@ Files will be created at {BASE-DIR}/{NAME} directory."
(add-to-list 'yas-snippet-dirs verilog-ext-template-snippets-dir)
(yas-reload-all))
+;;;; Makefile
+(defun verilog-ext-template-makefile ()
+ "Create iverilog/verilator `yasnippet' based Makefile.
+
+Create it only if in a project and the Makefile does not already exist."
+ (interactive)
+ (let ((project-root (verilog-ext-buffer-proj-root))
+ file)
+ (if project-root
+ (if (file-exists-p (setq file (file-name-concat project-root "Makefile")))
+ (error "File %s already exists!" file)
+ (find-file file)
+ (verilog-ext-template-insert-yasnippet "verilog"))
+ (error "Not in a project!"))))
+
+;;;; Hydra
(defhydra verilog-ext-hydra (:color blue
:hint nil)
("aa" (verilog-ext-template-insert-yasnippet "aa") "always" :column "A-C")
diff --git a/verilog-ext-time-stamp.el b/verilog-ext-time-stamp.el
index 9672d70..e5827af 100644
--- a/verilog-ext-time-stamp.el
+++ b/verilog-ext-time-stamp.el
@@ -1,4 +1,4 @@
-;;; verilog-ext-time-stamp.el --- Verilog-ext Timestamp -*- lexical-binding: t -*-
+;;; verilog-ext-time-stamp.el --- Verilog-ext Time-stamp -*- lexical-binding: t -*-
;; Copyright (C) 2022-2023 Gonzalo Larumbe
@@ -20,7 +20,7 @@
;;; Commentary:
-;; Timestamp setup
+;; `time-stamp' setup.
;;; Code:
@@ -34,17 +34,17 @@
:group 'verilog-ext-time-stamp)
(defcustom verilog-ext-time-stamp-regex "^// Last modified : "
- "Timestamp regexp."
+ "`time-stamp' regexp."
:type 'string
:group 'verilog-ext-time-stamp)
(defcustom verilog-ext-time-stamp-pattern (concat verilog-ext-time-stamp-regex "%%$")
- "Timestamp pattern. See `time-stamp-pattern'."
+ "`time-stamp' pattern. See `time-stamp-pattern'."
:type 'string
:group 'verilog-ext-time-stamp)
(defcustom verilog-ext-time-stamp-format "%:y/%02m/%02d"
- "Timestamp format. See `time-stamp-format'."
+ "`time-stamp' format. See `time-stamp-format'."
:type 'string
:group 'verilog-ext-time-stamp)
diff --git a/verilog-ext-typedef.el b/verilog-ext-typedef.el
index 4c44e5d..f9caf76 100644
--- a/verilog-ext-typedef.el
+++ b/verilog-ext-typedef.el
@@ -44,7 +44,7 @@
(defun verilog-ext-typedef--var-find (regex &optional limit)
"Search for REGEX and bound to LIMIT.
-Match data is expected to fits that one of
+Match data is expected to fit that one of
`verilog-ext-typedef-var-decl-single-re' or
`verilog-ext-typedef-var-decl-multiple-re'."
(let (found pos type)
@@ -126,7 +126,7 @@ I.e: populate `verilog-ext-typedef-align-words-current-proj'."
(verilog-ext-typedef--typedef-buffer-update verilog-ext-typedef-generic-re))
(defun verilog-ext-typedef-get (&optional verbose)
- "Scan all (System)Verilog FILES and udpate typedef list.
+ "Scan all (System)Verilog files of current project and udpate typedef list.
It will return the updated value of
`verilog-ext-typedef-align-words-current-proj', which can be used later along
diff --git a/verilog-ext-utils.el b/verilog-ext-utils.el
index 46c5f22..8f71b4f 100644
--- a/verilog-ext-utils.el
+++ b/verilog-ext-utils.el
@@ -20,30 +20,28 @@
;;; Commentary:
-;; Utils
+;; Common utils used in different features.
;;; Code:
(require 'verilog-mode)
-(require 'xref)
-(require 'ag)
-(require 'ripgrep)
;;;; Custom
(defcustom verilog-ext-file-extension-re "\\.s?vh?\\'"
- "(SystemVerilog) file extensions.
+ "(System)Verilog file extension regexp.
Defaults to .v, .vh, .sv and .svh."
:type 'string
:group 'verilog-ext)
(defcustom verilog-ext-cache-enable t
- "Enable use of cache files if set to non-nil."
+ "If set to non-nil enable use of cache files."
:type 'boolean
:group 'verilog-ext)
(defcustom verilog-ext-cache-do-compression t
"If set to non-nil compress cache files.
-Requires having \"gzip\" and \"gunzip\" in the PATH."
+
+Requires having \"gzip\" and \"gunzip\" in the $PATH."
:type 'boolean
:group 'verilog-ext)
@@ -59,7 +57,7 @@ of the project and their cdr a property list with the following properties:
- :ignore-dirs - directories to ignore (list of strings)
- :files - files to be used for the project, keep in order for vhier
hierarchy extraction (list of strings)
- - :ignore-files - files to be ignored for project (list of stings)
+ - :ignore-files - files to be ignored for project (list of strings)
Compilation:
- :compile-cmd - command used to compile current project (string)
@@ -83,17 +81,11 @@ Vhier:
;;;; Consts/Vars
+;;;;; Regexps
(defconst verilog-ext-keywords-re
(eval-when-compile
(regexp-opt verilog-keywords 'symbols)))
-(defconst verilog-ext-compiler-directives
- (eval-when-compile
- (mapcar (lambda (directive)
- (substring directive 1 nil))
- verilog-compiler-directives))
- "List of Verilog compiler directives, without the tick.")
-
(defconst verilog-ext-top-instantiable-re
(concat "\\<\\(?1:module\\|interface\\)\\>\\(\\s-+\\\\)?\\s-+\\(?3:" verilog-identifier-sym-re "\\)"))
(defconst verilog-ext-task-re
@@ -108,12 +100,6 @@ Vhier:
(defconst verilog-ext-class-re (concat "\\(?1:\\\\)\\s-+\\(?3:" verilog-identifier-sym-re "\\)"))
(defconst verilog-ext-top-re (concat "\\<\\(?1:package\\|program\\|module\\|interface\\)\\>\\(\\s-+\\\\)?\\s-+\\(?3:" verilog-identifier-sym-re "\\)"))
-(defvar verilog-ext-buffer-list nil)
-(defvar verilog-ext-dir-list nil)
-(defvar verilog-ext-file-list nil)
-(defvar-local verilog-ext-file-allows-instances nil
- "Non nil if current file includes a module or interface block.")
-
(defconst verilog-ext-range-optional-re
(concat "\\(\\s-*" verilog-range-re "\\)?"))
(defconst verilog-ext-range-or-class-params-optional-re
@@ -138,10 +124,7 @@ type_t foo1, foo2 , foo4, foo6[], foo7 [25], foo8 ;")
(defconst verilog-ext-typedef-generic-re (concat "^\\s-*typedef\\s-+\\(?1:\\<" verilog-identifier-re "\\>\\)"
"\\(" verilog-ext-typedef-class-params-optional-re "\\|" verilog-ext-range-optional-re "\\)"
"\\s-*\\(?2:\\<" verilog-identifier-re "\\>\\)"))
-
-(defconst verilog-ext-cache-dir (file-name-concat user-emacs-directory "verilog-ext")
- "The directory where verilog-ext cache files will be placed at.")
-
+;;;;; LSP
(defconst verilog-ext-server-lsp-list
'((ve-hdl-checker . ("hdl_checker" "--lsp"))
(ve-svlangserver . "svlangserver")
@@ -149,14 +132,28 @@ type_t foo1, foo2 , foo4, foo6[], foo7 [25], foo8 ;")
(ve-svls . "svls")
(ve-veridian . "veridian"))
"Verilog-ext available LSP servers.")
+(defconst verilog-ext-server-lsp-ids (mapcar #'car verilog-ext-server-lsp-list))
-(defconst verilog-ext-server-lsp-ids
- (mapcar #'car verilog-ext-server-lsp-list))
+;;;;; Misc
+(defvar verilog-ext-buffer-list nil)
+(defvar verilog-ext-dir-list nil)
+(defvar verilog-ext-file-list nil)
+(defvar-local verilog-ext-file-allows-instances nil
+ "Non nil if current file includes a module or interface block.")
+
+(defconst verilog-ext-cache-dir (file-name-concat user-emacs-directory "verilog-ext")
+ "The directory where verilog-ext cache files will be placed at.")
+(defconst verilog-ext-compiler-directives
+ (eval-when-compile
+ (mapcar (lambda (directive)
+ (substring directive 1 nil))
+ verilog-compiler-directives))
+ "List of Verilog compiler directives, without the tick.")
;;;; Macros
(defmacro verilog-ext-with-no-hooks (&rest body)
- "Execute BODY without running any Verilog related hooks."
+ "Execute BODY without running any additional Verilog hooks."
(declare (indent 0) (debug t))
`(let ((prog-mode-hook nil)
(verilog-mode-hook '(verilog-ext-mode))
@@ -166,10 +163,9 @@ type_t foo1, foo2 , foo4, foo6[], foo7 [25], foo8 ;")
(defmacro verilog-ext-proj-setcdr (proj alist value)
"Set cdr of ALIST for current PROJ to VALUE.
-ALIST is an alist and its keys are projects in `verilog-ext-project-alist' as
-strings.
+If current VALUE is nil remove its key from ALIST.
-If current VALUE is nil remove its key from the alist ALIST."
+ALIST keys are strings that define projects in `verilog-ext-project-alist'."
(declare (indent 0) (debug t))
`(setf (alist-get ,proj ,alist nil 'remove 'string=) ,value))
@@ -230,11 +226,11 @@ If current VALUE is nil remove its key from the alist ALIST."
(down-list)))
(defun verilog-ext-skip-identifier-backwards ()
- "Return non-nil if point skipped backwards verilog identifier chars."
+ "Return non-nil if point skipped backwards Verilog identifier chars."
(< (skip-chars-backward "a-zA-Z0-9_") 0))
(defun verilog-ext-skip-identifier-forward ()
- "Return non-nil if point skipped forward verilog identifier chars."
+ "Return non-nil if point skipped forward Verilog identifier chars."
(> (skip-chars-forward "a-zA-Z0-9_") 0))
(defmacro verilog-ext-when-t (cond &rest body)
@@ -245,7 +241,7 @@ Same function `when' from subr.el but returning t if COND is nil."
(defmacro verilog-ext-while-t (cond &rest body)
"Execute BODY while COND is non-nil.
-Same function `while' but returning t after last condition for use in ands."
+Same function `while' but returning t after last condition."
(declare (indent 1) (debug t))
`(progn
(while ,cond
@@ -341,7 +337,6 @@ Expand with respect to REL-DIR if non-nil."
(expand-file-name file rel-dir))
file-list))
-
;;;; File modules
(defun verilog-ext-scan-buffer-modules ()
"Find modules in current buffer.
@@ -382,7 +377,8 @@ Return list with found modules or nil if not found."
(when debug
(clone-indirect-buffer-other-window "*debug*" t))
(insert-file-contents file)
- (verilog-mode)
+ (verilog-ext-with-no-hooks
+ (verilog-mode))
(verilog-ext-scan-buffer-modules)))))
(defun verilog-ext-select-file-module (&optional file)
@@ -398,8 +394,7 @@ Return nil if no module was found."
;;;; Block at point / point inside block
(defun verilog-ext-class-declaration-is-typedef-p ()
- "Return non-nil if point is at a class declaration.
-Ensure it is not a typedef class declaration."
+ "Return non-nil if point is at a typedef class declaration."
(save-excursion
(save-match-data
(and (looking-at verilog-ext-class-re)
@@ -409,7 +404,7 @@ Ensure it is not a typedef class declaration."
(defun verilog-ext-looking-at-class-declaration ()
"Return non-nil if point is at a class declaration (i.e. not a typedef).
-Also updates `match-data' with that of `verilog-ext-class-re'."
+Updates `match-data' with matches of `verilog-ext-class-re'."
(and (looking-at verilog-ext-class-re)
(not (verilog-ext-class-declaration-is-typedef-p))))
@@ -422,7 +417,7 @@ Also updates `match-data' with that of `verilog-ext-class-re'."
(match-string-no-properties 2)))) ; Match 2 corresponds to class name classifier
(defun verilog-ext-point-inside-multiline-define ()
- "Return non-nil if point is inside a multilin define.
+ "Return non-nil if point is inside a multiline define.
Check `verilog-indent-ignore-p'."
(save-match-data
(or (save-excursion
@@ -577,8 +572,10 @@ Return alist with block type, name and boundaries."
(defun verilog-ext-block-at-point (&optional return-pos)
"Return current block type and name at point.
+
If RETURN-POS is non-nil, return also the begin and end positions for the block
at point.
+
Do not reuse `verilog-ext-point-inside-block' implementation to improve
efficiency and be able to use it for features such as `which-func'."
(let ((start-pos (point))
@@ -719,8 +716,10 @@ Optional ARG sets number of words to kill."
(defun verilog-ext-indent-region (start end &optional column)
"Wrapper for `indent-region'.
+
Prevents indentation issues with compiler directives with a modified syntax
table.
+
Pass the args START, END and optional COLUMN to `indent-region'."
(cond ((eq major-mode 'verilog-mode)
(let ((table (make-syntax-table verilog-mode-syntax-table)))
@@ -734,9 +733,11 @@ Pass the args START, END and optional COLUMN to `indent-region'."
(defun verilog-ext-tab (&optional arg)
"Run corresponding TAB function depending on `major-mode'.
+
If on a `verilog-mode' buffer, run `electric-verilog-tab' with original
`verilog-mode' syntax table. Prevents indentation issues with compiler
directives with a modified syntax table.
+
If on a `verilog-ts-mode' buffer, run `indent-for-tab-command' with ARG."
(interactive "P")
(cond ((eq major-mode 'verilog-mode)
@@ -753,7 +754,7 @@ If on a `verilog-ts-mode' buffer, run `indent-for-tab-command' with ARG."
;;;; Project
(defun verilog-ext-aget (alist key)
"Return the value in ALIST that is associated with KEY.
-If KEY is not found, then nil is returned."
+If KEY is not found return nil."
(cdr (assoc key alist)))
(defun verilog-ext-buffer-proj ()
@@ -786,7 +787,7 @@ If KEY is not found, then nil is returned."
(expand-file-name cmd-file root))))
(defun verilog-ext-proj-lib-search-path (&optional project)
- "Return current PROJECT lib search path for vhier."
+ "Return current PROJECT vhier lib search path."
(let ((proj (or project (verilog-ext-buffer-proj))))
(when proj
(plist-get (verilog-ext-aget verilog-ext-project-alist proj) :lib-search-path))))
@@ -884,8 +885,6 @@ Compress cache files if gzip is available."
(read (buffer-string)))))))
-
-
(provide 'verilog-ext-utils)
;;; verilog-ext-utils.el ends here
diff --git a/verilog-ext-which-func.el b/verilog-ext-which-func.el
index 6d2a109..5932f09 100644
--- a/verilog-ext-which-func.el
+++ b/verilog-ext-which-func.el
@@ -20,7 +20,7 @@
;;; Commentary:
-;; Basic `which-func' setup
+;; `which-func' integration.
;;; Code:
diff --git a/verilog-ext-xref.el b/verilog-ext-xref.el
index 202410d..13439c3 100644
--- a/verilog-ext-xref.el
+++ b/verilog-ext-xref.el
@@ -20,12 +20,14 @@
;;; Commentary:
-;; Find definitions and references builtin backend.
+;; Find definitions and references `xref' backend.
;;; Code:
+(require 'xref)
(require 'verilog-ext-tags)
+
(defgroup verilog-ext-xref nil
"Verilog-ext xref customization."
:group 'verilog-ext)
@@ -97,12 +99,13 @@ Still experimental. Removes the rest of xref backends."
(defun verilog-ext-xref-set (&optional disable)
"Setup `verilog-ext' to use builtin `xref' backend.
+
If optional arg DISABLE is provided, remove the hook that enabled the backend.
-Still experimental:
-- Removes the rest of xref backends by being a hook for `verilog-ext-mode'
-instead of to `verilog-mode', since the first one is loaded later and overwrites
-the hook value. Otherwise, hooks are not ran in a specific order, and rely on
-the priority argument."
+
+Removes the rest of xref backends by being a hook for `verilog-ext-mode' instead
+of to `verilog-mode', since the first one is loaded later and overwrites the
+hook value. Otherwise, hooks are not ran in a specific order, and rely on the
+priority argument."
(if disable
(remove-hook 'verilog-ext-mode-hook #'verilog-ext-xref-backend-enable)
(add-hook 'verilog-ext-mode-hook #'verilog-ext-xref-backend-enable)))
diff --git a/verilog-ext.el b/verilog-ext.el
index 5f078b5..8499931 100644
--- a/verilog-ext.el
+++ b/verilog-ext.el
@@ -133,19 +133,19 @@ FEATURES can be a single feature or a list of features."
(require 'verilog-ext-hs)
(require 'verilog-ext-time-stamp)
(require 'verilog-ext-block-end-comments)
-(require 'verilog-ext-compile)
(require 'verilog-ext-utils)
+(require 'verilog-ext-compile)
(require 'verilog-ext-nav)
(require 'verilog-ext-font-lock)
(require 'verilog-ext-imenu)
(require 'verilog-ext-which-func)
(require 'verilog-ext-ports)
-(require 'verilog-ext-tags)
-(require 'verilog-ext-typedef)
-(require 'verilog-ext-capf)
-(require 'verilog-ext-hierarchy)
(require 'verilog-ext-beautify)
(require 'verilog-ext-template)
+(require 'verilog-ext-typedef)
+(require 'verilog-ext-hierarchy)
+(require 'verilog-ext-tags)
+(require 'verilog-ext-capf)
(require 'verilog-ext-xref)
(require 'verilog-ext-formatter)
(require 'verilog-ext-flycheck)
@@ -161,7 +161,7 @@ FEATURES can be a single feature or a list of features."
(verilog-ext-when-feature 'formatter
(define-key map (kbd "C-c C-l") 'verilog-ext-formatter-run))
(verilog-ext-when-feature 'compilation
- (define-key map (kbd "C-c ") 'verilog-ext-compile)
+ (define-key map (kbd "C-c ") 'verilog-ext-compile-project)
(define-key map (kbd "C-c C-p") 'verilog-ext-preprocess))
(verilog-ext-when-feature 'flycheck
(define-key map (kbd "C-c C-f") 'verilog-ext-flycheck-mode))