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))