separedit.el: 在单独的缓冲区编辑注释、docstring 或其中的代码块

你的意思是用 separedit 把代码中的 // 改成 ///

编辑之前      ->      编辑之后
// commen            /// commen

暂时不具备这项功能。不过你可以在编辑窗口中修改本地变量 separedit--line-delimiter ,把它从 // 改成 ///

github 支持全局范围按关键字搜代码吗?

是个可行的方法,多谢了。

这个过程可以写成函数,参考 #70 楼或 《 让 C-x C-e 支持被跨行注释的代码 - #3,来自 twlz0ne 》。

请问手动选择mode的变量可以提取出来吗?

如果可以我可以尝试着改一下,这块不太懂。

目前有类似这样的需求,@swagger里面是yaml格式,正则匹配想使用yaml-mode编辑。 image

目前临时改了源代码,然后通过选中区域在主动选择yaml-mode的方式可以实现。

可以把 @swagger 当作一个 code block 来处理:

(add-to-list 'separedit-block-regexp-plists
             '(:header "@swagger$"
               :body nil
               :footer ".*\\'"
               :mode yaml-mode))

这样就不用手动选区域和 mode 了,直接在 yaml 内容上按 C-c '

EDIT1:由于目前 separedit--code-block-end 在找到 block 末尾之后会自动退回一行,所以以上方法得到的可编辑内容会缺少一行,稍后我将提供一个更完善的解决方案。

EDIT2:已添加对 swagger-jsdoc 的支持,直接拉取最新的代码或等待 melpa 更新。

十分感谢,使用下来一切正常。 :smiley:

除了上述的 swagger-jsdoc 之外,自 v0.3.0 以来的新功能:

  • 支持无窗口模式(separedit-inhibit-edit-window-p)。
  • 允许用 heredoc 标记指定编辑模式(忽然觉得支持 heredoc 的语言都很可爱):
# example.rb            -- C-c ' ->  # edit buffer (sql-mode)
query = <<-SQL
SELECT * FROM #{table}               SELECT * FROM #{table} 
WHERE #{type} = true                 WHERE #{type} = true
SQL
1 个赞

如果 heredoc 也支持了,那是否意味着编辑 C 的宏也是原生就支持的?

例如这样的宏定义:

#define FOO(a, b)                               \
    do {                                        \
        auto _a = (a);                          \
        auto _b = (b);                          \
    } while (false)

在这个宏上调用 separedit-dwim 的话会变成

do {
    auto _a = (a);
    auto _b = (b);
} while (false)

现在我的作法是使用 edit-indirect-region,需要:

  1. edit-indirect-before-commit-hook 里给每一行末尾添加一个 \
  2. edit-indirect-after-creation-hook 里把 \ 给去掉

但是我感觉和 separedit 的功能有点像。另外还有个问题是 edit-indirect 默认用 normal-mode 来猜 mode,太卡了

@twlz0ne JS/TS 中常用的块注释不能正常解析,是 melpa 上的最新版本:

  /**
   * Renders instance on a given context
   * @param {CanvasRenderingContext2D} ctx context to render instance on
   */
  transform(ctx: CanvasRenderingContext2D) {
    // .....
  }

最好能提供截图、复现代码或条件,否则单凭“不能正常解析”我想象不出结果。

以下是我的测试代码 (emacsq.sh 来自 GitHub - twlz0ne/emacsq-sh: Helper script to run `emacs -Q`):

$ emacs --batch --eval "(with-temp-buffer (emacs-version 'here) (message (buffer-string)))"
GNU Emacs 28.0.50 (build 6, x86_64-apple-darwin17.7.0, NS appkit-1561.61 Version 10.13.6 (Build 17G14033))
 of 2021-09-13

$ emacsq.sh -P separedit --eval \
          "(progn
             (define-key prog-mode-map (kbd \"C-c '\") #'separedit)
             (switch-to-buffer \"*.js\")
             (js-mode)
             (insert \"/**
            * Renders instance on a given context
            * @param {CanvasRenderingContext2D} ctx context to render instance on
            */
           transform(ctx: CanvasRenderingContext2D) {
             // .....
           }\"))" -nw

在我的电脑上并未发现问题:

你的 major mode 是什么?separedit 是根据 face 来提取编辑范围的,在 c-mode 下应该无法这样使用才对。

这我倒是没注意到,最然我用的是 2011 年的破电脑。

这里少了一个假设,假设这个结果是通过 edit-indirect 来实现的,或者是提供一种 C-u separedit-dwim 的方式来自定义是想要选择哪种样式:

  1. 在注释里写代码,从 uncomment-region 编辑 → comment-region 返回
  2. 编辑 C 的宏,从去掉尾部 \ 开始编辑 → 给每行加 \ 再返回
  3. heredoc 的形式,从 <<-IDID 的 region 开始编辑 → 再把前缀给加回去
  4. 其他的暂时没想到,不知这种通用性是否已经存在于 separedit 中了

个人感觉是存在这种相关性的

抱歉,昨天急着出去没描述清楚

出现问题的环境是 typescript-mode,但 js-mode 是没有问题的,下面是我真实操作的截图:

下面是关于这张图的说明:

  1. 图片的 1 是明确指示 typescript-mode
  2. 图片的 2 是指示错误的地方,多了注释的引导符号;
  3. 可以发现注释的部分少了一部分内容,也就是注释中以 @param 开头的那一行;
  4. 如果把注释引导符号更改为 /*,那注释编辑的部分就正常了,但是语法高亮就不对了,请参考下面截图;

解释一下第二张图:

  1. 图片中的 1 是更改了注释引导符号,更改后的引导符号是 /*:只有一个 * 了:但是不能这么改,会导致注释生成出现异常;
  2. 图片中的 2 是语法高亮异常了,但注释编辑好了:我怀疑是 typescript-mode 对注释有语法解析,导致不能正常解析注释中的全部文案了;

以上,就是我在这次 Bug 调试过程中得到的全部信息了。

想问下怎么给 separedit-comment-encloser-alist 这个变量添加新的配置呢?我需要添加一个 web-mode 的支持,因为目前写前端使用 web-mode 比较多。小白请求,如有不适请忽略 :joy:

  1. typescript 的问题比较简单,加几个 face 就改好了。
  2. web-mode 比较麻烦,目前有 40 种 engines,最少有 40 种以上的注释形式。如果全部揉成一个正则表达式,有可能会出问题。应该针对每一种 engine,给相对应的注释匹配正则。我可能要挑其中比较常用的几种,其余的等有人用到了再说吧。

EDIT: web-mode 的注释有点错乱:

$ emacsq.sh -P web-mode --eval \
  "(dolist (buf '(\"*.js\" \"*.jsx\" \"*.css\"))
   (switch-to-buffer buf)
   (web-mode)
   (print (list :content-type web-mode-content-type
                :comment-start comment-start)))" -nw --batch
;; => (:content-type "javascript" :comment-start "<!--")
;;    (:content-type "jsx"        :comment-start "<!--")
;;    (:content-type "css"        :comment-start "<!--")

不应该都是 /* 吗?

C-u separedit-dwim 目前用于选择 major mode,以编辑字符串/其它无法自动探明语言的代码。

主要问题在于,从一开始我的目标就只管北西南三面围栏的注释,不考虑四面包围和只有东面的情况。但是现在 separedit-dwim 已经很丑了,如果单独写一个东面围栏的还比较容易,让我想想怎么处理。

另外,这种用续行符 \ 连成块的宏是不是只存在于 c/c++?

了解了

应该是的

@Lenic @Youmu 获取最新代码试试。

  1. typescript 应该没问题。
  2. web-mode 是照着 web-mode.el - html template editing for emacs 的截图实现了常见 types 和 engines 下的注释编辑,不知道对不对。
  3. c/c++ 宏编辑的时候,因为需要在完成之后重新对齐 \,把 #define 也放入了编辑缓冲。主要功能已实现,还有些小问题:1. 不能在 #define 这行按 C-c '; 2. 进入编辑窗口后的光标位置飘了。
  1. typescript-mode 已经没问题了;
  2. web-mode 我试了下,还是不对,执行报错 Wrong type argument: listp, "/\\*+\\(?:!\\)?"

web-mode 报错的文件如下:

/**
 * abc<光标位置>
 */
const App = () => {
  // ..
};

文件扩展名是什么?web-mode-content-typeweb-mode-engine 是什么?

找到问题所在了。临 push 之前忽然想起要改一个地方,简单得不能再简单了,结果改漏了,没写测试就是不靠谱。

删除本地代码,重新获取,我刚刚强推了。