Add function for alignment of signal declarations.
This commit is contained in:
@@ -8,6 +8,7 @@ Align SystemVerilog ANSI-style port declarations in a contiguous block around po
|
|||||||
- Works on the contiguous block of port declarations above and below point.
|
- Works on the contiguous block of port declarations above and below point.
|
||||||
- Stops at the first non-port line (including blank lines).
|
- Stops at the first non-port line (including blank lines).
|
||||||
- Aligns named port connections in module instantiations via `verilog-align-ports-instantiation`.
|
- Aligns named port connections in module instantiations via `verilog-align-ports-instantiation`.
|
||||||
|
- Aligns signal declarations via `verilog-align-ports-declarations`.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -26,6 +27,11 @@ For module instantiations:
|
|||||||
1. Place point on a named port connection line (e.g., `.clk_i (clk)` or `.full_o,`).
|
1. Place point on a named port connection line (e.g., `.clk_i (clk)` or `.full_o,`).
|
||||||
2. Run `M-x verilog-align-ports-instantiation`.
|
2. Run `M-x verilog-align-ports-instantiation`.
|
||||||
|
|
||||||
|
For signal declarations:
|
||||||
|
|
||||||
|
1. Place point on a declaration line (e.g., `logic foo;` or `wire [3:0] bar;`).
|
||||||
|
2. Run `M-x verilog-align-ports-declarations`.
|
||||||
|
|
||||||
Example input:
|
Example input:
|
||||||
|
|
||||||
```systemverilog
|
```systemverilog
|
||||||
|
|||||||
@@ -140,6 +140,68 @@
|
|||||||
(beginning-of-line)
|
(beginning-of-line)
|
||||||
(should (not (verilog-align-ports-instantiation)))))
|
(should (not (verilog-align-ports-instantiation)))))
|
||||||
|
|
||||||
|
(ert-deftest verilog-align-ports-declarations-aligns-block ()
|
||||||
|
(let* ((input (concat
|
||||||
|
(mapconcat
|
||||||
|
#'identity
|
||||||
|
'("logic wr_en_i; // write enable"
|
||||||
|
"logic [DataWidth-1:0] d_i; // data input"
|
||||||
|
"logic full_o;"
|
||||||
|
"logic [WrDataCountW-1:0] wr_data_count_o; // data count"
|
||||||
|
"wire rd_en_i; // read enable"
|
||||||
|
"logic [DataWidth-1:0] d_o;"
|
||||||
|
"reg empty_o;// empty flag"
|
||||||
|
"logic valid_o;")
|
||||||
|
"\n")
|
||||||
|
"\n"))
|
||||||
|
(expected (concat
|
||||||
|
(mapconcat
|
||||||
|
#'identity
|
||||||
|
(list
|
||||||
|
(concat "logic" (make-string 20 ?\s)
|
||||||
|
"wr_en_i;" (make-string 9 ?\s)
|
||||||
|
"// write enable")
|
||||||
|
(concat "logic" " " "[DataWidth-1:0]" (make-string 4 ?\s)
|
||||||
|
"d_i;" (make-string 13 ?\s)
|
||||||
|
"// data input")
|
||||||
|
(concat "logic" (make-string 20 ?\s) "full_o;")
|
||||||
|
(concat "logic" " " "[WrDataCountW-1:0]" " "
|
||||||
|
"wr_data_count_o;" " " "// data count")
|
||||||
|
(concat "wire" (make-string 21 ?\s)
|
||||||
|
"rd_en_i;" (make-string 9 ?\s)
|
||||||
|
"// read enable")
|
||||||
|
(concat "logic" " " "[DataWidth-1:0]" (make-string 4 ?\s)
|
||||||
|
"d_o;")
|
||||||
|
(concat "reg" (make-string 22 ?\s)
|
||||||
|
"empty_o;" (make-string 9 ?\s)
|
||||||
|
"// empty flag")
|
||||||
|
(concat "logic" (make-string 20 ?\s) "valid_o;")
|
||||||
|
)
|
||||||
|
"\n")
|
||||||
|
"\n")))
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert input)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(search-forward "logic full_o")
|
||||||
|
(beginning-of-line)
|
||||||
|
(should (verilog-align-ports-declarations))
|
||||||
|
(should (string= (buffer-string) expected)))))
|
||||||
|
|
||||||
|
(ert-deftest verilog-align-ports-declarations-returns-nil-outside ()
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert (concat
|
||||||
|
(mapconcat
|
||||||
|
#'identity
|
||||||
|
'("module foo;"
|
||||||
|
"logic a;"
|
||||||
|
"endmodule")
|
||||||
|
"\n")
|
||||||
|
"\n"))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(search-forward "module foo")
|
||||||
|
(beginning-of-line)
|
||||||
|
(should (not (verilog-align-ports-declarations)))))
|
||||||
|
|
||||||
(provide 'verilog-align-ports-test)
|
(provide 'verilog-align-ports-test)
|
||||||
|
|
||||||
;;; verilog-align-ports-test.el ends here
|
;;; verilog-align-ports-test.el ends here
|
||||||
|
|||||||
@@ -26,6 +26,17 @@
|
|||||||
"^\\s-*\\.\\(\\\\[^[:space:]]+\\|[A-Za-z_][A-Za-z0-9_$]*\\)\\b"
|
"^\\s-*\\.\\(\\\\[^[:space:]]+\\|[A-Za-z_][A-Za-z0-9_$]*\\)\\b"
|
||||||
line))))
|
line))))
|
||||||
|
|
||||||
|
(defun verilog-align-ports--line-decl-p (pos)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char pos)
|
||||||
|
(let ((line (buffer-substring-no-properties
|
||||||
|
(line-beginning-position)
|
||||||
|
(line-end-position))))
|
||||||
|
(and (string-match-p
|
||||||
|
"^\\s-*\\(logic\\|wire\\|reg\\)\\b"
|
||||||
|
line)
|
||||||
|
(verilog-align-ports--parse-decl-line line)))))
|
||||||
|
|
||||||
(defun verilog-align-ports--split-comment (line)
|
(defun verilog-align-ports--split-comment (line)
|
||||||
(let ((pos (string-match "//" line)))
|
(let ((pos (string-match "//" line)))
|
||||||
(if pos
|
(if pos
|
||||||
@@ -115,6 +126,26 @@
|
|||||||
(setq end (line-beginning-position))
|
(setq end (line-beginning-position))
|
||||||
(cons start end)))))
|
(cons start end)))))
|
||||||
|
|
||||||
|
(defun verilog-align-ports--decl-bounds ()
|
||||||
|
(save-excursion
|
||||||
|
(and (verilog-align-ports--line-decl-p (line-beginning-position))
|
||||||
|
(let ((start (line-beginning-position))
|
||||||
|
(end nil))
|
||||||
|
(while (and (not (bobp))
|
||||||
|
(save-excursion
|
||||||
|
(forward-line -1)
|
||||||
|
(verilog-align-ports--line-decl-p
|
||||||
|
(line-beginning-position))))
|
||||||
|
(forward-line -1)
|
||||||
|
(setq start (line-beginning-position)))
|
||||||
|
(goto-char start)
|
||||||
|
(while (and (not (eobp))
|
||||||
|
(verilog-align-ports--line-decl-p
|
||||||
|
(line-beginning-position)))
|
||||||
|
(forward-line 1))
|
||||||
|
(setq end (line-beginning-position))
|
||||||
|
(cons start end)))))
|
||||||
|
|
||||||
(defun verilog-align-ports--collect (start end)
|
(defun verilog-align-ports--collect (start end)
|
||||||
(let (entries)
|
(let (entries)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
@@ -185,6 +216,50 @@
|
|||||||
:comma comma
|
:comma comma
|
||||||
:comment comment)))))
|
:comment comment)))))
|
||||||
|
|
||||||
|
(defun verilog-align-ports--parse-decl-line (line)
|
||||||
|
(let* ((split (verilog-align-ports--split-comment line))
|
||||||
|
(code (string-trim-right (car split)))
|
||||||
|
(comment (cdr split)))
|
||||||
|
(when (string-match
|
||||||
|
"^\\(\\s-*\\)\\(logic\\|wire\\|reg\\)\\b\\s-*\\(.*\\)$"
|
||||||
|
code)
|
||||||
|
(let* ((indent (match-string 1 code))
|
||||||
|
(kind (match-string 2 code))
|
||||||
|
(rest (string-trim (match-string 3 code)))
|
||||||
|
(name nil)
|
||||||
|
(tail nil)
|
||||||
|
(type-rest "")
|
||||||
|
(range "")
|
||||||
|
(before ""))
|
||||||
|
(when (string-match
|
||||||
|
"\\(\\\\[^[:space:]]+\\|[A-Za-z_][A-Za-z0-9_$]*\\)\\s-*\\(?:\\(=[^;]*\\)\\)?;\\s-*$"
|
||||||
|
rest)
|
||||||
|
(setq name (match-string 1 rest))
|
||||||
|
(setq tail (when (match-string 2 rest)
|
||||||
|
(string-trim (match-string 2 rest))))
|
||||||
|
(setq before
|
||||||
|
(string-trim-right (substring rest 0 (match-beginning 1))))
|
||||||
|
(setq before (string-trim before))
|
||||||
|
(unless (string-match-p "," before)
|
||||||
|
(if (and (not (string-empty-p before))
|
||||||
|
(string-match "\\(\\[[^][]+\\]\\)\\s-*$" before))
|
||||||
|
(progn
|
||||||
|
(setq range (match-string 1 before))
|
||||||
|
(setq type-rest
|
||||||
|
(string-trim-right
|
||||||
|
(substring before 0 (match-beginning 1)))))
|
||||||
|
(setq type-rest before)
|
||||||
|
(setq range ""))
|
||||||
|
(let ((type (if (string-empty-p type-rest)
|
||||||
|
kind
|
||||||
|
(concat kind " " type-rest))))
|
||||||
|
(list :indent indent
|
||||||
|
:type type
|
||||||
|
:range range
|
||||||
|
:name name
|
||||||
|
:tail tail
|
||||||
|
:comment comment))))))))
|
||||||
|
|
||||||
(defun verilog-align-ports--inst-collect (start end)
|
(defun verilog-align-ports--inst-collect (start end)
|
||||||
(let (entries)
|
(let (entries)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
@@ -199,6 +274,20 @@
|
|||||||
(forward-line 1)))
|
(forward-line 1)))
|
||||||
(nreverse entries)))
|
(nreverse entries)))
|
||||||
|
|
||||||
|
(defun verilog-align-ports--decl-collect (start end)
|
||||||
|
(let (entries)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char start)
|
||||||
|
(while (< (point) end)
|
||||||
|
(let* ((line (buffer-substring-no-properties
|
||||||
|
(line-beginning-position)
|
||||||
|
(line-end-position)))
|
||||||
|
(entry (verilog-align-ports--parse-decl-line line)))
|
||||||
|
(when entry
|
||||||
|
(push entry entries)))
|
||||||
|
(forward-line 1)))
|
||||||
|
(nreverse entries)))
|
||||||
|
|
||||||
(defun verilog-align-ports--max-lengths (entries)
|
(defun verilog-align-ports--max-lengths (entries)
|
||||||
(let ((max-dir 0)
|
(let ((max-dir 0)
|
||||||
(max-type 0)
|
(max-type 0)
|
||||||
@@ -295,6 +384,48 @@
|
|||||||
left)))
|
left)))
|
||||||
entries left-parts)))
|
entries left-parts)))
|
||||||
|
|
||||||
|
(defun verilog-align-ports--decl-format-lines (entries)
|
||||||
|
(let* ((base-indent (plist-get (car entries) :indent))
|
||||||
|
(max-type 0)
|
||||||
|
(max-range 0)
|
||||||
|
(has-comment nil)
|
||||||
|
left-parts
|
||||||
|
(max-left 0))
|
||||||
|
(dolist (entry entries)
|
||||||
|
(setq max-type (max max-type (length (plist-get entry :type))))
|
||||||
|
(setq max-range (max max-range (length (plist-get entry :range))))
|
||||||
|
(when (plist-get entry :comment)
|
||||||
|
(setq has-comment t)))
|
||||||
|
(let ((has-range (> max-range 0)))
|
||||||
|
(dolist (entry entries)
|
||||||
|
(let* ((type (plist-get entry :type))
|
||||||
|
(range (plist-get entry :range))
|
||||||
|
(name (plist-get entry :name))
|
||||||
|
(tail (plist-get entry :tail))
|
||||||
|
(type-pad (verilog-align-ports--pad max-type (length type)))
|
||||||
|
(range-pad (when has-range
|
||||||
|
(verilog-align-ports--pad max-range (length range))))
|
||||||
|
(left (concat base-indent
|
||||||
|
type
|
||||||
|
type-pad
|
||||||
|
(when has-range range)
|
||||||
|
(when has-range range-pad)
|
||||||
|
name
|
||||||
|
(when tail (concat " " tail))
|
||||||
|
";")))
|
||||||
|
(push left left-parts)
|
||||||
|
(setq max-left (max max-left (length left)))))
|
||||||
|
(setq left-parts (nreverse left-parts))
|
||||||
|
(cl-mapcar
|
||||||
|
(lambda (entry left)
|
||||||
|
(let ((comment (plist-get entry :comment)))
|
||||||
|
(if (and has-comment comment)
|
||||||
|
(concat left
|
||||||
|
(verilog-align-ports--pad max-left (length left))
|
||||||
|
comment)
|
||||||
|
left)))
|
||||||
|
entries left-parts))))
|
||||||
|
|
||||||
(defun verilog-align-ports--apply (start lines)
|
(defun verilog-align-ports--apply (start lines)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char start)
|
(goto-char start)
|
||||||
@@ -331,6 +462,20 @@
|
|||||||
(verilog-align-ports--apply start lines)
|
(verilog-align-ports--apply start lines)
|
||||||
t))))))
|
t))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun verilog-align-ports-declarations ()
|
||||||
|
"Align SystemVerilog signal declarations around point."
|
||||||
|
(interactive)
|
||||||
|
(let ((bounds (verilog-align-ports--decl-bounds)))
|
||||||
|
(and bounds
|
||||||
|
(let* ((start (car bounds))
|
||||||
|
(end (cdr bounds))
|
||||||
|
(entries (verilog-align-ports--decl-collect start end)))
|
||||||
|
(and entries
|
||||||
|
(let ((lines (verilog-align-ports--decl-format-lines entries)))
|
||||||
|
(verilog-align-ports--apply start lines)
|
||||||
|
t))))))
|
||||||
|
|
||||||
(provide 'verilog-align-ports)
|
(provide 'verilog-align-ports)
|
||||||
|
|
||||||
;;; verilog-align-ports.el ends here
|
;;; verilog-align-ports.el ends here
|
||||||
|
|||||||
Reference in New Issue
Block a user