尴尬了,发现一个同名的扩展 EmacsWiki: comment-edit.el
支持这种方框包围的注释:
;; Style n. 3: "narrow-box"
;;
;; ##################
;; # comment line 1 #
;; # comment line 2 #
;; # comment line 3 #
;; ##################
;;
;; Style n. 4: "wide-box"
;;
;; ########################################################################
;; # comment line 1 #
;; # comment line 2 #
;; # comment line 3 #
;; ########################################################################
不过它仅限于 shell-like 类的注释,不支持 /* */
以及其它形式的注释,也不支持 docstring 和注释里的 code block,我释然了。
2 个赞
还有 poporg
, org-commentary
outorg
等等的,只不过是用Org Mode编辑模式。我
自己就经常用 poporg
. 还是很好用的,尤其是对于我这样的Org Mode重度使用者。
1 个赞
Commentary 里写 README 是个好注意。
Commentary 里边的空行是否必须留白?如果不是必须,现在就可以用 comment-edit 来编辑,只需把 comment-edit-default-mode
设为 org-mode
:
(defun comment-edit-el-commentary ()
(interactive)
(let ((comment-edit-default-mode 'org-mode))
(comment-edit)))
如果希望保持空行留白,目前有两个问题需要解决:
-
comment-edit 以连续的 ;;
作为编辑块,遇到空行则认为块结束。
解决方案:设置一个 greedy
开关,为 t
时可以跨过空行搜索。
-
编辑完了之后,提交的时候会在每一行(包括空行)前面添加注释符 ;;
。
解决方案:允许提交函数忽略空行。
待我明天来看看怎么实现。
cireu
18
如果用el2org
生成README,是不需要对空白行额外加;;
的
pyim的源文件是一个例子,不过他那个太复杂了,类似文学编程。我用的是简化后的框架,只用来写README
我比较倾向于写完readme自动插入到el文件commentary里。不过comment-edit一包多用也不错
忽然想到,这个包应该改名为 escape-edit
。港台把 escape 翻译作「跳脱」,我认为更准确。
字符串引号加斜杠叫跳脱,那么加注释符和 code block 包裹符可视为另一种层次的跳脱。
干着 escape 字符串的活,名称却叫 comment-edit
,有一种词不达意、强行凑功能的感觉。
1 个赞
感觉这翻译一般。可惜我不是学中文的,想不出来更好的翻译。escape-edit可能更准确,但难理解其功能;comment-edit能一眼看出来能做什么,不失为一个好名字。
昨天思路不太对,反而把事情搞复杂了。现在给 comment-edit
加了一个参数,直接输入编辑区域(甚至可以考虑手动选择),
这样就可以应对 Commentary
以及类似场景了:
(defun comment-edit-el-commentary ()
"Edit elisp Commentary section."
(interactive)
(let* ((comment-edit-default-mode 'markdown-mode)
(comment-edit-leave-blank-line-in-comment t)
(beg (save-excursion
(goto-char (point-min))
(re-search-forward "^;;; Commentary:\n+" nil t)))
(end (save-excursion
(goto-char beg)
(re-search-forward "\n;;; .*$" nil t)
(goto-char (match-beginning 0)))))
(comment-edit (list :beginning beg :end end))))
EDIT: 1.调整匹配规则,忽略头部空行,2.无需将光标移动到 Commentary 区域内。
1 个赞
现在全面支持递归(之前只实现了字符串的递归 unscape)进入了:
+--------+ C-c ' +--------+ C-c ' +--------+ C-c '
| source | --------> | edit | --------> | edit | --------> ...
| buffer | <-------- | buffer | <-------- | buffer | <-------- ...
+--------+ C-c C-c +--------+ C-c C-c +--------+ C-c C-c
不过嵌套多了会晕,两次应该是日常比较用的到的:
source buffer -> edit buffer (markdown/orgmode) -> code block
1 个赞
乞丐版 el2readme:
(defun el-commentary-to-readme-md ()
"Write elisp Commentary section to README.md."
(interactive)
(let* ((beg (save-excursion
(goto-char (point-min))
(re-search-forward "^;;; Commentary:\n+" nil t)))
(end (save-excursion
(goto-char beg)
(re-search-forward "\n;;; .*$" nil t)
(goto-char (match-beginning 0))))
(str (buffer-substring-no-properties beg end)))
(with-temp-buffer
(insert str)
(comment-edit--remove-comment-delimiter
(comment-edit--comment-delimiter-regexp 'emacs-lisp-mode))
(write-file (expand-file-name "README.md")))))
cireu
26
可以直接用lm-commentary
(from builtin lisp-mnt
)获取Commentary
,不用自己手动搜索了。
2 个赞
刚刚想到 local variables 简单用 ```
包裹起来就可以在 emacs-lisp-mode
下编辑(冒号不影响缩进):
;; ```
;; Local Variables:
;; ...
;; End:
;; ```
或专门写个 comment-edit-el-local-variables
函数来处理 local variables 块 (加上之前的 commend-edit-el-commentary
和 el-commentary-to-readme-md
一并重新整理如下):
(defun comment-edit/region-between-regexps (begin-regexp end-regexp)
(save-excursion
(goto-char (point-min))
(when (re-search-forward begin-regexp)
(let ((begin (point)))
(when (re-search-forward end-regexp nil t)
(goto-char (match-beginning 0))
(cons begin (point)))))))
(defun comment-edit/edit-region (region edit-buffer-mode &optional leave-blank-p)
(let* ((comment-edit-default-mode edit-buffer-mode)
(comment-edit-leave-blank-line-in-comment leave-blank-p))
(comment-edit (list :beginning (car region)
:end (cdr region)))))
(defun comment-edit-el-commentary ()
(interactive)
(comment-edit/edit-region
(comment-edit/region-between-regexps "^;;; Commentary:\n+" "\n;;; .*$")
'markdown-mode
t))
(defun comment-edit-el-local-variables ()
(interactive)
(comment-edit/edit-region
(comment-edit/region-between-regexps "^;; Local Variables:\n+" "\n;; End:$")
'emacs-lisp-mode))
(defun el-commentary-to-readme-md ()
(interactive)
(let ((filename (expand-file-name "README.md")))
(when (yes-or-no-p (format "%s %S? "
(if (file-exists-p filename)
"Overwrite"
"Create")
filename))
(let* ((reg (or (comment-edit/region-between-regexps "^;;; Commentary:\n+" "\n;;; .*$")
(error "Commentary not found in current file!")))
(str (buffer-substring-no-properties (car reg) (cdr reg))))
(with-temp-buffer
(insert str)
(comment-edit--remove-comment-delimiter
(comment-edit--comment-delimiter-regexp 'emacs-lisp-mode))
(write-file filename))))))
Youmu
28
试用了一下,非常棒!
写 rust
时正好可以使用这个插件较美观的写 doc comment 了。
不过有一个问题,在 indirect-edit buffer 里的空白行也会在源文件里尾部添加一个空格,如图
我发了一个 pr 来可选去除尾部的空格了
EDIT: pr
2 个赞
cireu
29
写了个简单函数,从Elisp文件中直接提取Commentary
生成README。
(require 'subr-x)
(require 'org)
(require 'pcase)
(require 'lisp-mnt)
(defun limon-doc--sanitize-commentary (commentary)
"Clean up the COMMENTARY returned from `lm-commentary' for export."
(let ((bodies (cdr (split-string (string-trim commentary) "\n")))
(result nil))
(dolist (s bodies)
(pcase s
((or ";;" ";; ") nil)
((rx bol ";; " (let rest (1+ any))) (push rest result))
(some (push some result))))
(string-join (nreverse result) "\n")))
(defun limon-doc-export-commentary (dest)
"Export Org-formatted Commentary section in this buffer to DEST."
(interactive "F")
(pcase (lm-commentary)
(`nil (user-error "No valid commentary section in this buffer!"))
(some
(let ((body (limon-doc--sanitize-commentary some))
(summary (lm-summary)))
(with-temp-buffer
(insert body)
(org-export-to-file 'org dest nil nil nil nil `(:title ,summary)))))))
1 个赞
前面的自定义函数 comment-edit-el-local-variables
可以删除了,comment-edit:77bc3d1 现在已经可以识别 Local Variables 块,并且以 emacs-lisp-mode
作为编辑模式:
Youmu
31
可以加一个 feature 吗?
例如这样
class Foo {
/// 这是一个加一操作
/// 当前 buffer 的 fill-column 为 80, 如果在 comment-edit 编辑时,自动计算
/// 好 comment-edit 里的 fill-column 为 80 - (4空格 + 3个/ + 1个空格) = 72
/// 这样只需要在 comment-edit 的 buffer 里调用一下 fill-paragraph 就可以排版好而无需写完
/// documentation comment 之后再排版一下。
int add1(int x) {
return x + 1;
}
};
lentic后来我也放弃了,有一些特殊情况需要注意,每次都用的小心翼翼。。。
我是习惯直接在el文件中裸写 org 格式的 commentary 然后生成 readme.md
2 个赞