Add function for alignment of named port connections in module instantiations.
This commit is contained in:
@@ -16,6 +16,16 @@
|
||||
(line-end-position))))
|
||||
(string-match-p "^\\s-*\\(input\\|output\\|inout\\)\\b" line))))
|
||||
|
||||
(defun verilog-align-ports--line-inst-port-p (pos)
|
||||
(save-excursion
|
||||
(goto-char pos)
|
||||
(let ((line (buffer-substring-no-properties
|
||||
(line-beginning-position)
|
||||
(line-end-position))))
|
||||
(string-match-p
|
||||
"^\\s-*\\.\\(\\\\[^[:space:]]+\\|[A-Za-z_][A-Za-z0-9_$]*\\)\\b"
|
||||
line))))
|
||||
|
||||
(defun verilog-align-ports--split-comment (line)
|
||||
(let ((pos (string-match "//" line)))
|
||||
(if pos
|
||||
@@ -82,6 +92,26 @@
|
||||
(verilog-align-ports--line-port-p
|
||||
(line-beginning-position)))
|
||||
(forward-line 1))
|
||||
(setq end (line-beginning-position))
|
||||
(cons start end)))))
|
||||
|
||||
(defun verilog-align-ports--inst-bounds ()
|
||||
(save-excursion
|
||||
(and (verilog-align-ports--line-inst-port-p (line-beginning-position))
|
||||
(let ((start (line-beginning-position))
|
||||
(end nil))
|
||||
(while (and (not (bobp))
|
||||
(save-excursion
|
||||
(forward-line -1)
|
||||
(verilog-align-ports--line-inst-port-p
|
||||
(line-beginning-position))))
|
||||
(forward-line -1)
|
||||
(setq start (line-beginning-position)))
|
||||
(goto-char start)
|
||||
(while (and (not (eobp))
|
||||
(verilog-align-ports--line-inst-port-p
|
||||
(line-beginning-position)))
|
||||
(forward-line 1))
|
||||
(setq end (line-beginning-position))
|
||||
(cons start end)))))
|
||||
|
||||
@@ -99,6 +129,76 @@
|
||||
(forward-line 1)))
|
||||
(nreverse entries)))
|
||||
|
||||
(defun verilog-align-ports--find-paren-end (text start)
|
||||
(let ((depth 0)
|
||||
(idx start)
|
||||
(len (length text))
|
||||
(end nil))
|
||||
(while (and (< idx len) (not end))
|
||||
(let ((ch (aref text idx)))
|
||||
(cond
|
||||
((eq ch ?\() (setq depth (1+ depth)))
|
||||
((eq ch ?\))
|
||||
(setq depth (1- depth))
|
||||
(when (eq depth 0)
|
||||
(setq end (1+ idx))))))
|
||||
(setq idx (1+ idx)))
|
||||
end))
|
||||
|
||||
(defun verilog-align-ports--parse-inst-line (line)
|
||||
(let* ((split (verilog-align-ports--split-comment line))
|
||||
(code (string-trim-right (car split)))
|
||||
(comment (cdr split)))
|
||||
(when (string-match
|
||||
"^\\(\\s-*\\)\\.\\(\\\\[^[:space:]]+\\|[A-Za-z_][A-Za-z0-9_$]*\\)\\(.*\\)$"
|
||||
code)
|
||||
(let* ((indent (match-string 1 code))
|
||||
(name (match-string 2 code))
|
||||
(rest (match-string 3 code))
|
||||
(rest (if rest (string-trim-right rest) ""))
|
||||
(pos (string-match "\\S-" rest))
|
||||
(has-conn nil)
|
||||
(conn "")
|
||||
(comma nil))
|
||||
(if (and pos (< pos (length rest)) (eq (aref rest pos) ?\())
|
||||
(let* ((end (verilog-align-ports--find-paren-end rest pos)))
|
||||
(if end
|
||||
(progn
|
||||
(setq has-conn t)
|
||||
(setq conn (string-trim (substring rest (1+ pos) (1- end))))
|
||||
(let ((after (string-trim (substring rest end))))
|
||||
(when (and (> (length after) 0)
|
||||
(eq (aref after 0) ?,))
|
||||
(setq comma ","))))
|
||||
(let ((after (string-trim rest)))
|
||||
(when (and (> (length after) 0)
|
||||
(string-match-p "," after))
|
||||
(setq comma ",")))))
|
||||
(let ((after (string-trim rest)))
|
||||
(when (and (> (length after) 0)
|
||||
(string-match-p "," after))
|
||||
(setq comma ","))))
|
||||
(list :indent indent
|
||||
:name name
|
||||
:has-conn has-conn
|
||||
:conn conn
|
||||
:comma comma
|
||||
:comment comment)))))
|
||||
|
||||
(defun verilog-align-ports--inst-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-inst-line line)))
|
||||
(when entry
|
||||
(push entry entries)))
|
||||
(forward-line 1)))
|
||||
(nreverse entries)))
|
||||
|
||||
(defun verilog-align-ports--max-lengths (entries)
|
||||
(let ((max-dir 0)
|
||||
(max-type 0)
|
||||
@@ -153,9 +253,48 @@
|
||||
(when has-range range-pad)
|
||||
name
|
||||
(when (and has-comment comment) name-pad)
|
||||
(or comment ""))))
|
||||
(or comment ""))))
|
||||
entries)))
|
||||
|
||||
(defun verilog-align-ports--inst-format-lines (entries)
|
||||
(let* ((base-indent (plist-get (car entries) :indent))
|
||||
(max-name 0)
|
||||
(has-comment nil)
|
||||
left-parts
|
||||
(max-left 0))
|
||||
(dolist (entry entries)
|
||||
(let ((name-len (+ 1 (length (plist-get entry :name)))))
|
||||
(setq max-name (max max-name name-len)))
|
||||
(when (plist-get entry :comment)
|
||||
(setq has-comment t)))
|
||||
(dolist (entry entries)
|
||||
(let* ((name (plist-get entry :name))
|
||||
(name-field (concat "." name))
|
||||
(has-conn (plist-get entry :has-conn))
|
||||
(conn (plist-get entry :conn))
|
||||
(comma (plist-get entry :comma))
|
||||
(pad (when has-conn
|
||||
(verilog-align-ports--pad max-name (length name-field))))
|
||||
(left (concat base-indent
|
||||
name-field
|
||||
(when has-conn pad)
|
||||
(when has-conn "(")
|
||||
(when has-conn conn)
|
||||
(when has-conn ")")
|
||||
(when comma ","))))
|
||||
(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)
|
||||
(save-excursion
|
||||
(goto-char start)
|
||||
@@ -169,12 +308,26 @@
|
||||
"Align SystemVerilog port declarations around point."
|
||||
(interactive)
|
||||
(let ((bounds (verilog-align-ports--bounds)))
|
||||
(and bounds
|
||||
(let* ((start (car bounds))
|
||||
(end (cdr bounds))
|
||||
(entries (verilog-align-ports--collect start end)))
|
||||
(and entries
|
||||
(let ((lines (verilog-align-ports--format-lines entries)))
|
||||
(verilog-align-ports--apply start lines)
|
||||
t))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun verilog-align-ports-instantiation ()
|
||||
"Align SystemVerilog named port connections around point."
|
||||
(interactive)
|
||||
(let ((bounds (verilog-align-ports--inst-bounds)))
|
||||
(and bounds
|
||||
(let* ((start (car bounds))
|
||||
(end (cdr bounds))
|
||||
(entries (verilog-align-ports--collect start end)))
|
||||
(entries (verilog-align-ports--inst-collect start end)))
|
||||
(and entries
|
||||
(let ((lines (verilog-align-ports--format-lines entries)))
|
||||
(let ((lines (verilog-align-ports--inst-format-lines entries)))
|
||||
(verilog-align-ports--apply start lines)
|
||||
t))))))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user