[分享] comment-edit.el: 在单独的缓冲区编辑注释、docstring 或其中的代码块


#1

这个扩展其实在几个月前讨论《 如何善用注释/文档中的代码? 》的时候就差不多了(当时没实现的功能现在也没😅)。

一直捂着,不如放出来,集思广益,慢慢改进。

现在整理了一下,并把包名由 commentdown 改为 comment-edit,一是因为并没有以 markdown-mode 作为编辑主模式,二是保留将来支持 orgmode 的可能(不被名称限定)。

用这个包的好处是:

  • 可以方便的编辑注释、docstring 或其中的代码块,如果编辑的其中的代码块,则会自动去除代码块的包裹符号,例如:

      在注释或 docstring 中              在编辑模式中
    
      ```
      code block1                      code block1
      code block1                      code block1
      ```
    
       ,---
       | code block2                   code block2
       | code block2                   code block2
       `---
    

    编辑完,返回,恢复包裹字符。

    代码块如果没有指定语言,则跟随当前文件。

  • 编辑 docstring 时免受双引号转义之累。例如:

      在 docstring 中                   在编辑模式中
      
    
      (foo \"bar\")                    (foo "bar")
    

不足/未实现的功能:

  • 编辑主模式为 fundamental-mode (表示目前没有任何作为,放任由 Emacs 自行决定),而非 markdown-mdoe / org-mode

  • 不能嵌套进入。也就是说,编辑 docstring 和编辑 docstring 中的 code block 必须分开进入。不能:

                   C-'                  C-'
      source file ====> edit docstring ====> edit code block in docstring
    

    必须:

                   C-'
      source file ====> edit docstring
    
                   C-'
      source file ====> edit code block in docstring
    
  • 不支持单引号转义


#2

老铁真是高产啊


#3

都是些无关紧要的 idea


#4

以前看tumashu推荐过lentic,和本贴所要达到的目标类似,不过太高端了,至今我不会用。。


#5

有装类似的 string-edit,一直想不起来用。


#6

这个厉害了,只是我感觉平时都不这么用呢


#7

我只是想要在Commentary里用org-mode写个README而已 :joy: 因为Melpa的default recipe居然只能抓取Texinfo格式的文档

tumashu还写了专门提取Commentary的插件


#8

这个很强大。不知道它在进入编辑状态( org-mode ) 之后,能否再次进入 code block 的编辑?

没看到有 docstring 的例子?


#9

例子太少了,所以根本不知道怎么用

@tumashu 能不能指教一下?

另外有点讨厌的是他不能直接复用Elisp文件原有的outline而是要自己再弄一层outline


#10

总觉得把简单的事给复杂化了,可能是不会用吧 :joy::joy::joy:


#11

刚刚试了一下 string-edit,发现它对 js 字符串单/双引号嵌套使用和 python docstring 支持不好。

我参考 string-edit 修复了 comment-edit--string-region 函数结果不准确的问题,并把上述需求也一并解决了。


#12

多层嵌套的转义符号竟然是指数增长(原以为是x2):

(cl-labels ((escape
             (sl)
             (cond ((not sl) "")
                   ((stringp sl) (format "%S" sl))
                   (t (format "%S" (concat (car sl) (escape (cadr sl))))))))
  (insert
   (escape '("a" ("b" ("c" ("d" ("e" ("f" ("g" ("h" "i")))))))))))

;; => "a\"b\\\"c\\\\\\\"d\\\\\\\\\\\\\\\"e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"f\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"g\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"h\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\"i\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\
;;    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\
;;    \\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\"\\\"\""

试了一下 4 层转义(再多层就晕了),层层进入编辑(代码还没提交到 github)时的缓冲区内容是这样的:

| n | *edit buffer*                                                       |
|---|---------------------------------------------------------------------|
| 0 | "a\"b\\\"c\\\\\\\"d\\\\\\\\\\\\\\\"e\\\\\\\\\\\\\\\"\\\\\\\"\\\"\"" |
| 1 | "b\"c\\\"d\\\\\\\"e\\\\\\\"\\\"\""                                  |
| 2 | "c\"d\\\"e\\\"\""                                                   |
| 3 | "d\"e\""                                                            |
| 4 | "e"                                                                 |

编辑完了再一层一层提交回去。