我每天都在使用verilg-mode用于emacs,但代码对齐对我来说并不好。所以想要添加像垂直对齐这样的东西。
首先,我希望将这些声明行对齐:
bit [1:0] a;
bit [3254:0] b;
bit unsigned [P_DWIDTH-1:0] c;
bit unsigned [P_DWIDTH-1:P_DWIDTH-4] d;
int e;
为:
bit [ 1:0 ] a;
bit [ 3254:0 ] b;
bit unsigned [P_DWIDTH-1:0 ] c;
bit unsigned [P_DWIDTH-1:P_DWIDTH-4] d;
int e;
我没有太多的Elisp经验。我不确定像align-regexp
这样的东西是正确的看法吗?或者任何人请指出一个正确的方向开始。
答案 0 :(得分:3)
根据@homeless的回复,我做了修改:使用narrow-to-region
来避免区域边界变化。
(defun align-decl-vertically ()
"Align verilog declarations."
(interactive)
(save-excursion
(save-restriction
(narrow-to-region (region-beginning) (region-end))
;; remove spaces around ":"
(goto-char (point-min))
(while (re-search-forward "\\s-*:\\s-*" (point-max) t)
(replace-match ":"))
;; align "["
(align-regexp (point-min) (point-max) "\\(\\s-*\\)\\[" -1 1 0)
;; align ":"
(align-regexp (point-min) (point-max) "\\[\\(.+:\\)" -1 0 0)
;; align "]"
(align-regexp (point-min) (point-max) "\\s-*\\(\\]\\)" -1 0 0)
;; align variable name
(align-regexp (point-min) (point-max) "\\(\\s-+\\)\\S-+;" -1 1 0)
(widen))))
还找到另一种更新align
规则的方法来实现这个目标(这不符合我的预期,但只是在这里列出可能有些可以帮我解决):
(add-to-list 'align-mode-rules-list
'(declaration-range-field-alignment
(regexp . "\\(\\s-*\\[\\)\\(.*:\\).*\\S-+\\(\\s-*\\]\\)\\(.*\\)")
(group . (1 2 3 4))
(modes . '(verilog-mode))
(tab-stop . nil)
(spacing . (1 0 0 1))
(repeat . nil)
(justify . t)))
(add-to-list 'align-mode-rules-list
'(declaration-variable-name-alignment
(regexp . "\\(\\s-*\\S-*\\s-*;\\)")
(group . 1)
(modes . '(verilog-mode))
(repeat . nil)
(tab-stop . nil)
(spacing . 1)
(justify . t)))
但有时可能需要多次运行align
才能获得最终结果。我还没弄明白为什么。
答案 1 :(得分:2)
您可以尝试使用align-regexp
。以下是否有助于您:
(defun align-decl-vertically ()
"Align verilog declarations."
(interactive)
(let ((BEG (region-beginning))
(END (region-end)))
(align-regexp BEG END "\\(\\s-*\\)\\[" 1 1 0)
(align-regexp BEG END "\\(\\s-*\\)\\]" 1 1 0)
(align-regexp BEG END "\\(\\s-*\\)\\s-[^ ]*;" 1 0 0)))
;; declare a key binding
(add-hook 'verilg-mode-hook (lambda() (local-set-key (kbd "C-c =") 'align-decl-vertically)))
您必须将其粘贴到Emacs init文件中(例如.emacs或init.el)。进入verilog-mode
后,您可以突出显示该区域,然后按C-c =
以对齐声明。我用你的例子对它进行了测试,结果很好。我不知道它是否会在一般情况下起作用,因为我不知道verilog编程语法。
<强>更新强>
第一个版本无法正常工作,原因很简单,因为我们不应该在每个align-regexp
调用后更改变量中的区域的开头和结尾。这是一个应该有效的版本:
(defun align-decl-vertically ()
"Align verilog declarations."
(interactive)
(align-regexp (region-beginning) (region-end) "\\(\\s-*\\)\\[" 1 1 0)
(align-regexp (region-beginning) (region-end) "\\(\\s-*\\)\\]" 1 1 0)
(align-regexp (region-beginning) (region-end) "\\(\\s-*\\)\\s-[^ ]*;" 1 0 0))