Answers:
这是一个将DOuble CApitals转换为Single Capitals的函数。我最初建议将其添加到中post-self-insert-hook
,但下面是美化的次要模式的一个选项,以便您仅在真正需要时添加到该钩子中:
(defun dcaps-to-scaps ()
"Convert word in DOuble CApitals to Single Capitals."
(interactive)
(and (= ?w (char-syntax (char-before)))
(save-excursion
(and (if (called-interactively-p)
(skip-syntax-backward "w")
(= -3 (skip-syntax-backward "w")))
(let (case-fold-search)
(looking-at "\\b[[:upper:]]\\{2\\}[[:lower:]]"))
(capitalize-word 1)))))
(add-hook 'post-self-insert-hook #'dcaps-to-scaps nil 'local)
和次要模式定义:
(define-minor-mode dubcaps-mode
"Toggle `dubcaps-mode'. Converts words in DOuble CApitals to
Single Capitals as you type."
:init-value nil
:lighter (" DC")
(if dubcaps-mode
(add-hook 'post-self-insert-hook #'dcaps-to-scaps nil 'local)
(remove-hook 'post-self-insert-hook #'dcaps-to-scaps 'local)))
值得一试的是,使用以下版本:
即使将其添加到中post-self-insert-hook
,至少根据一些简单的基准测试,开销几乎是不存在的。在我的机器上,这是我获得的10,000次重复的结果,每个重复都非常简单,而且dcaps-to-scaps
功能很简单:
(benchmark-run-compiled 10000 (+ 1 1)) ; => .001 to .003 -ish
(benchmark-run-compiled 10000 (dcaps-to-scaps)) ; => .003 to .006 -ish
因此,是的,它比加1 + 1慢,但是从绝对意义上讲您永远不会注意到。
forward-word
将不能很好地工作subword-mode
,通过(char-syntax (char-before))
将(我猜)忽略任何语法类集合与性质(其他的解决办法:(syntax-after (1- (point))
) ,以及(最后但并非最不重要的)正则表达式不会找到带重音的字母(例如法语中的“ÉMincer”)
forward-word
问题,并更改了正则表达式以处理重音符号。
and
了when
,特别是在第一个实例?
and
发生短路,因此逻辑类似于when
此处。我不确定是否有关于使用一种相对于另一种的最佳实践,但是似乎在此站点上会提出一个很好的问题(无论如何我都会赞成)。
我的喜好是简单地创建一个新功能,该功能可以执行通常的功能self-insert-command
以及更多功能。
原因如下:
org-mode
,text-mode
等。SPC
或RET
或.
后字键。因此,使用类似方法post-self-insert-hook
可能会过大,并且每次敲击任何键时,我们都会进行额外的处理。因此,下面提出的解决方案仅将此SPC
键与该功能绑定org-mode-map
(忽略转义情况,即单词可能是一行中的最后一个单词)。如果需要,用户可以将类似的包装器功能绑定到更多键。
(defun space-plus-more ()
(interactive)
(save-excursion
(backward-word 1)
(let ((case-fold-search))
(when (looking-at-p "[A-Z]\\{2\\}.*?[a-z]+.*?\\b")
(capitalize-word 1))))
(self-insert-command 1))
(define-key org-mode-map (kbd "<SPC>") #'space-plus-more)
这是一个有趣的elisp练习:)
我个人不想将此绑定到,RET
因为那样的话,我可能会丢失默认绑定,org-mode
并且可能还会丢失其他主要模式。但是了解elt
和有趣this-command-keys-vector
。
(defun my/fix-double-caps ()
(interactive)
(save-excursion
(backward-word 1)
(let ((case-fold-search))
(when (looking-at-p "[A-Z]\\{2\\}.*?[a-z]+.*?\\b")
(capitalize-word 1))))
(if (eq 13 (elt (this-command-keys-vector) 0)) ; detect RET
(newline)
(self-insert-command 1)))
(let ((maps-list (list org-mode-map
text-mode-map))
(keys-list (list "<SPC>" "<RET>" ".")))
(dolist (map maps-list)
(dolist (key keys-list)
(define-key map (kbd key) #'my/fix-double-caps))))
也许这个答案没有提供您所期望的解决方案(键入时对单词进行交互式更正),我想分享我解决此类问题的方法。
首先,我不喜欢无声地更改文本的内容(大写字母等,如果您想输入单词IBuffer
,我认为这样的“校正器”是错误的方法),所以我建议两件事:
首先,尝试启用功能“粘滞键”。乍一看似乎很奇怪,但我一直都在使用它。此功能在OS /桌面环境级别可用,不是Emacs的东西。启用此功能后,您先按 ⇧ Shift,然后再按另一个要大写的键。这样,您的问题甚至不会出现,在这种顺序方式中只有一个字母大写!它还可以减少您的手需要握住⇧ Shift钥匙的工作。我认为现在输入更加容易。
其次,现在您仍然可以⇧ Shift在认为有必要时正常使用(持有)密钥,但是我想向您提出一个名为Fix Word的Emacs软件包。即使您不喜欢“粘滞键”,也可以轻松地将单词更正为正确的形式,并且可以连续纠正多个单词而不会浪费光标。试试看,我一直都在用。(如果您输入了多个单词并且您需要大写的单词在中间,那么纠正问题仍然很困难。)
looking-at-p
,它根本不会设置匹配数据(没关系,因为您不需要或在此处使用它)。