如何让 abbrev mode table case-sensitive(区分大小写), 定义 sm, 不要展开 SM

我写了下面一段代码:

(defun current-buffer-abbrev-table-name()
  (let* ((bufname (buffer-file-name (buffer-base-buffer)))
         (prefix (substring (md5 bufname) 0 5))
         (tblsym (intern (concat prefix "-abbrev-table")))) tblsym)
  )
(defun set-local-abbrevs (abbrevs)
  "Add ABBREVS to `local-abbrev-table' and make it buffer local.
     ABBREVS should be a list of abbrevs as passed to `define-abbrev-table'.
     The `local-abbrev-table' will be replaced by a copy with the new
     abbrevs added, so that it is not the same as the abbrev table used
     in other buffers with the same `major-mode'."
  (let* ((tblsym (current-buffer-abbrev-table-name)))
    (unless (and (boundp tblsym) (eval tblsym)) (set tblsym (make-abbrev-table :case-fixed)) (abbrev-table-put (eval tblsym) :case-fold t))

    (dolist (abbrev abbrevs)
      (define-abbrev (eval tblsym)
        (car abbrev)
        (cadr abbrev)
        (caddr abbrev)))
    (setq-local local-abbrev-table (eval tblsym))))

(defun clear-local-abbrev()
  (let* ((tblsym (current-buffer-abbrev-table-name)))
  (if (boundp tblsym) (set tblsym nil))
  (setq-local local-abbrev-table nil))
  )

这段代码的目的是创建一个 buffer-local 的 abbrev table, 添加参数指定的 abbrev, 把 local-abbrev-table 设置为这个创建的 buffer-local 的 abbrev table. 为了防止大写展开, 我特意在能加的地方都加上了 :case-fixed.

(abbrev-mode);
(clear-local-abbrev);
(set-local-abbrevs '(("cc" "compute capability" nil) ("gm" "global memory" nil) ("sm" "shared memory" nil)));

然后 sm 空格, 展开了, 问题在于, SM 空格, 也会展开, 但我 不希望 SM 展开.

在 emacs -Q 也会有同样的问题. 我想是不是我对 :case-fixed 有误解. 我以为它能做到大写不展开.

目前我只好添加定义 ("SM" "SM" nil), 但是我不喜欢这样.

case-fold 是忽略大小写,改成 :case-fixed t 就好了

另外建议尝试下 GitHub - minad/tempel: 🏛 TempEl - Simple templates for Emacs

楼主最近的两个问题都能比较好的解决

1 个赞

呜呜呜, 非常感谢! 关于 tempel 我可不可以问个几个问题:

  1. 有没有现成的方案能让我做到随便搜任何 mode 下的 snippet, 我对 yasnippet 最难受的一点是我用 consult-yasnippet 只能搜到当前 mode 下的 snippet, 不过这个行为或许很容易改.
  2. 它对于长内容是不是不够友好? 它好像都是写在一个文件的, 我有大量多行的代码 snippet 需要保存.
  3. 相比 yasnippet 它能做到哪些 yasnippet 做不到的事?

关于第 1 个痛点, 我倒是解决了, 这个可以搜索所有的 yassnippets:

(defun my/yas--get-snippet-tables ()
  (hash-table-values yas--tables)
  )

(defun my/consult-yasnippet-all ()
  "Call consult-yasnippet with a custom yas--get-snippet-tables implementation."
  (interactive)
  (cl-letf (((symbol-function 'yas--get-snippet-tables) #'my/yas--get-snippet-tables))
    (consult-yasnippet nil)))

这个见仁见智了,反过来说对管理非长内容的 snippets 就很方便,我以前喜欢 yas 那种管理方式,现在更喜欢这种单文件的

yas 很成熟,功能也很强大,而且你也很难完全去掉它,因为很多插件都有 yas 依赖。

但是我对 yas 这个项目的健康状况不是很看好,它已经三年没有更新了。

1 个赞