如何为Emacs的主模式添加垂直对齐功能

如何为Emacs的主模式添加垂直对齐功能,emacs,elisp,vertical-alignment,system-verilog,Emacs,Elisp,Vertical Alignment,System Verilog,我每天都在使用verilg模式进行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; 致: 我没有太多的经验。我不确定像align regexp这样的东西是不是合适的?或者任何人请给我指出一个正确的开始方向。您确实可以尝试使用

我每天都在使用verilg模式进行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;
致:


我没有太多的经验。我不确定像
align regexp
这样的东西是不是合适的?或者任何人请给我指出一个正确的开始方向。

您确实可以尝试使用
align regexp
。以下内容是否有助于您:

(将decl垂直对齐()
“对齐verilog声明。”
(互动)
(let((BEG(区域开始))
(完(地区完))
(对齐regexp BEG END“\\(\\s-*\\)\\\[“1 1 0)
(对齐regexp BEG END“\\(\\s-*\\)\\]”1 1 0)
(对齐regexp BEG END“\\(\\s-*\\)\\s-[^]*;“1 0”))
;; 声明密钥绑定
(添加钩子“verilg”模式钩子(lambda()(本地设置键(kbd“C-C=)”垂直对齐decl)))
您必须将其粘贴到Emacs init文件(例如.Emacs或init.el)中。一旦进入
verilog模式
,就可以突出显示该区域并按
C-C=
对齐声明。我用你的例子进行了测试,结果很好。我不知道它是否能在一般情况下工作,因为我不知道verilog编程语法

更新

第一个版本不能正常工作,原因很简单,我们不应该在变量中保存区域的开头和结尾,因为它们在每次
align regexp
调用后都会发生变化。下面是一个应该可以工作的版本:

(将decl垂直对齐()
“对齐verilog声明。”
(互动)
(对齐regexp(区域开始)(区域结束)“\\(\\s-*\\)\\[“1 1 0)
(对齐regexp(区域开始)(区域结束)“\\(\\s-*\\)\\]”1 10)
(对齐regexp(区域开始)(区域结束)“\\(\\s-*\\)\\s-[^]*;“1 0”)

根据@无家可归者回复,我做了修改:使用
缩小到区域
以避免区域边界更改

(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
的规则,以实现这一点(这与我预期的效果不完全一样,但请在此处列出一些可能有助于我解决的问题):


但有时可能需要多次运行
align
以获得最终结果。我还不知道为什么。

你也可以在Emacs StackExchange上询问。谢谢@无家可归者。但是您的代码不适用于最后一行对齐。我做了一点修改,并将它放在另一个答案中。我刚刚找到了它不起作用的原因。实际上我在这里发布了一个修改版本。我会更新我的答案,现在只要打一个电话就可以了。
(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))))
(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)))