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

我自己挖一下坟。

正在实现 multible string 功能(issue#38),不是 multi-line string 一个字符串包含多行,而是把个多个连续(无论直排/横排)的单行字符串聚集起来编辑:

Screenshot_2023-07-01_at_9.13.01_PM Screenshot_2023-07-01_at_9.12.17_PM

对于某些语言或场景需要经常拼接字符串有帮助。

现在比较纠结的是,如何触发这个动作。

  1. 光标位于在字符串之外时触发。
["foo"      C-c '   foo
 |"bar"     ---->   b|ar
  "quxx"]           quux
  1. 光标位于在字符串之中时触发。但有时我有可能又只想编辑单个字符串,这就有冲突了。
["foo"      C-c '   foo
  "b|ar"    ---->   b|ar
  "quxx"]           quux

代码暂时放在分支 feat-multi-string-block

3 个赞

很棒的包 :star_struck:,之前一直想找 emacs 中实现类似 jetbrian idea Language injections 的方案。

我配合 GitHub - andreasjansson/language-detection.el: Automatic programming language detection of code snippets, in Emacs Lisp, 可以大概自动识别字符串中的语言

(use-package separedit
  :ensure t
  :demand t

  :config
  (add-to-list 'separedit-string-quotes-alist
	       '(ruby-mode "\"\"\"" "'''" "\"" "'" "`"))

  :init
  (defun bind-separedit-key()
    (local-set-key (kbd "C-c '") #'separedit))
  (add-hook 'prog-mode-hook 'bind-separedit-key))

(use-package language-detection
  :ensure t
  :demand t

  :init
  (defun my-separedit-guass-mode()
    "Guass buffer's code language using `language-detection-buffer'.
And then switch to prefer mode."
    (when (derived-mode-p 'separedit-single-quote-string-mode
                          'separedit-double-quote-string-mode)
      (let* ((language (language-detection-buffer))
	     (mode (intern (concat (symbol-name language) "-mode")))
	     (header-line-format-back header-line-format))
	(if (fboundp mode)
	    (progn
	      (funcall mode)
	      (setq-local header-line-format header-line-format-back))))))
  
    (add-hook 'separedit-buffer-creation-hook 'my-separedit-guass-mode))```

美中不足的是目前还没有支持 “" 的识别,例如 ruby 中 "” 是直接调用 shell 的,可以考虑加一个 'separedit-back-quote-string-mode,在这个 mode 中默认打开 shell-script-mode.

等有空看看能不能搞个 pr 出来支持 :stuck_out_tongue:

2 个赞

好用!推荐!

感谢,很好用的包。请教下有没有办法保留 python 的缩进?

在 Info-mode 中查看python的文档,会遇到一些代码样例,想用 separedit 去掉前面的缩进,但保留代码部分的缩进。如图:

python_indent

拉取最新代码试试。

1 个赞

可以了,感谢。

看不太懂,只在 Info-mode中可用吗?昨天重新定义 separedit--remove-comment-delimiter 为正向搜索,也实现了目的。但未全部弄懂该函数。

(defun separedit--remove-comment-delimiter (regexp &optional max-width)
    "Remove comment delimiter of each line when entering comment edit buffer.

REGEXP          regexp expression that matches the delimiter
MAX-WIDTH       maximum width that can be removed"
    (let ((line-delimiter)
          (inhibit-read-only t)
          match-len
          replace-str
          indent-len)
      (save-excursion
        (goto-char (point-min))
        (catch 'break
          (while (and (not (eobp)) (re-search-forward regexp nil t))
            (setq match-len (length (match-string 0)))
            (when (and (> match-len 0)
                       (not indent-len))
              (setq indent-len match-len))
            (setq replace-str
                  (if (and max-width (> match-len max-width))
                      (setq replace-str (substring (match-string 0) max-width))
                    (if (and indent-len
                             (length> (match-string 0) 0))
                        (setq replace-str (substring (match-string 0) indent-len))
                      "")))
            (unless line-delimiter
              (setq line-delimiter
                    (if max-width
                        (if (zerop max-width)
                            ""
                          (substring (match-string 0) 0 (- (length (match-string 0))
                                                           (length replace-str))))
                      (match-string 0))))
            (replace-match replace-str)
            (when (eq (point) (point-max))
              (throw 'break nil))
            (goto-char (1+ (line-end-position))))))
      line-delimiter))