emacs 有没有这样的包: 保存常用 snippet 然后 consult 之类的搜索立即可以粘贴

如题. 我梦想中的效果就是, 有一个命令让我快速加入新的 snippet, 比如一键添加剪切板的内容. 然后 consult 搜索(其它的框架也可), 然后一敲回车就粘贴(相当于 insert 内容). 不需要像 yassnippet 那样自动展开. 如果没有, 我感觉可以保存一个 snippet 文件, 然后用 consult-line, 然后配合 embark 的 default action, 设置为 insert. 不知道是否可行.

  1. 善用 M-x,搜索 yas new snippet 能找到你要的函数
  2. 善用谷歌,搜索 emacs snippet consult 能找到你要的包

谢谢回复, 但 consult-yasnippet 并不能搜索 snippet 内容, 我不需要自动展开, 我只需要能快速添加和搜索内容.

看了这两楼我没有理解你的需求,单纯粘贴不是consult-yank-pop就可以了;而consult-snippet是可以搜索snippet的内容的呀

1 个赞
  1. yasnippet 不一定非得 【输入->TAB->展开】,通过 completion read 就是【搜索->回车->插入】。

  2. yas-new-snippet 就是快速创建 snippet 的方式。你完全可以创建一个原样输出的纯文本 snippet。

  3. consult-yasnippet 稍微改装一下就可以搜索内容(注意关键字前面要加一个空格):

$ emacsq.sh -P use-package,yasnippet,vertico,consult,consult-yasnippet --eval "\
 (progn
   (use-package vertico
     :init
     (vertico-mode))
 
   (use-package consult)
 
   (use-package yasnippet
     :config
     (yas-reload-all)
     (yas-global-mode))
 
   (use-package consult-yasnippet
     :after (consult yasnippet)
     :bind ((\"M-,\" . consult-yasnippet))
     :config
     (advice-add 'consult-yasnippet--candidates
                 :override
                 (defun consult-yasnippet--candidates@add-content (templates)
                   \"Convert TEMPLATES into candidates for `completing-read'.\"
                   (mapcar
                    (lambda (template)
                      (cons (concat
                             (propertize (concat (yas--table-name (yas--template-table template))
                                                 \" \")
                                         'invisible t)
                             (yas--template-name template)
                             \" [\"
                             (propertize (or (yas--template-key template)
                                             (and (functionp 'yas--template-regexp-key)
                                                  (yas--template-regexp-key template)))
                                         'face 'consult-key)
                             \"] \" (yas--template-content template)) ;; +++
                            template))
                    templates)))))" -nw

我猜你可能觉得 yasnippet 累赘,它的一个 snippet 最少包含 (name key content) 三个字段,你可能只想要 content 部分。但是如果有多个相似的 content,你很难在狭小的屏幕上快速区分。所以 name/key 字段就显得很有必要了。


3 个赞

谢谢你! 我一直就在想 emacs 上到底有没有剪切板管理工具, 结果真的就有. 我真的该把 consult 有哪些命令从头到尾看一遍的.

非常感谢~ 我还有个问题就是我的 snippet 动态性很强, 比如有些信息今天可能反复用到, 比如某些路径, 某些文件名, 但明天可能就不会再用了, yasnippet 删除好像要删除文件且执行 yas–remove-template-by-uuid, 感觉删除起来有点麻烦.

临时的 snippet 看看 GitHub - abo-abo/auto-yasnippet: quickly create disposable yasnippets ?键盘宏也是个方案

可以直接删除(在 Emacs 内部或外部都可以)snippet 文件,然后 yas-reload-all / yas-load-directory

也可以试试楼上说的 auto-yasnippet

试了下 auto-yasnippet, 感觉确实很符合需求, 但有个问题, snippet 是不是必须要有 marker 才能被 create? 就比如 a snippet~placeholder 调用 aya-create 就被创建了, 但是 a snippet 就不行. 我打算改一改代码.

那这感觉更像 Abbrevs (GNU Emacs Manual)

要说还有什么更轻/更无脑的话,就是 kill ring 了,helm 对应的实现 helm-show-kill-ring:

helm-show-kill-ring

ivy/consult 也许也有。

1 个赞

我理解的是 kill-ring 就是剪切板, 它有大小限制, 假设我不断复制粘贴, 没用的剪切板就可能把有用的给刷没了?

试了下,如果没理解错楼主的需求的话,用 abbrev 很方便,还可以设置变量 save-abbrevs 选择是否保存 abbrevs 文件,临时删除可以用 clear-abbrev-table

(defun elemacs-completing-read (prompt collection &optional predicate require-match initial-input hist def inherit-input-method)
  "Calls `completing-read' but returns the value from COLLECTION.

Simple wrapper around the `completing-read' function that assumes
the collection is either an alist, or a hash-table, and returns
the _value_ of the choice, not the selected choice. "
  (cl-flet ((assoc-list-p (obj) (and (listp obj) (consp (car obj)))))
    (let* ((choice
            (completing-read prompt collection predicate require-match initial-input hist def inherit-input-method))
           (results (cond
                     ((hash-table-p collection) (gethash choice collection))
                     ((assoc-list-p collection) (alist-get choice collection def nil 'equal))
                     (t                         choice))))
      (if results
		  (if (listp results) (car results) results)
		choice))))

(defun eli/global-abbrev-table--completions ()
  "Return an alist for global abbrev completion."
  (let ((symbols (abbrev--table-symbols 'global-abbrev-table))
		result)
	(dolist (symbol symbols)
	  (push (cons (concat (symbol-name symbol)
						  " "
						  (propertize (symbol-value symbol)
									  'face 'shadow))
				  (symbol-value symbol))
			result))
	result))

(defun eli/insert-global-abbrev ()
  "Select and insert global abbrevs."
  (interactive)
  (insert (elemacs-completing-read "Select: " (eli/global-abbrev-table--completions))))

Peek 2023-05-21 20-04

2 个赞

当然我为了省事用了 global-abbrev-table,可以自己定义一个专门的 table

非常感谢! exactly what I want.

深感 elemacs-completing-read 这个函数之有用, 之前我觉得自定义补全内容是很复杂的事, 但您的这段代码让我觉得对 alist 用补全框架是很轻松的事, 再次感谢!