Emacs builtin mode 功能介绍

不习惯use-package,我的配置如下,但是enter、escape并没有打到预期效果,是配置写错了吗?

(when (> emacs-major-version 26)
  (setq isearch-lazy-count t)
  (setq lazy-count-prefix-format "%s/%s ")
  (setq lazy-highlight-cleanup nil)
  )
(defvar my/isearch--direction nil)
(define-advice isearch-exit (:after nil)
  (setq-local my/isearch--direction nil))
(define-advice isearch-repeat-forward (:after (_))
  (setq-local my/isearch--direction 'forward))
(define-advice isearch-repeat-backward (:after (_))
  (setq-local my/isearch--direction 'backward))
(defun my/isearch-repeat (&optional arg)
  (interactive "P")
  (isearch-repeat my/isearch--direction arg))
(define-key isearch-mode-map (kbd "RET") 'my/isearch-repeat)
(define-key isearch-mode-map (kbd "ESC") #'isearch-exit)
(define-key isearch-mode-map [remap isearch-delete-char] 'isearch-del-char) ;

环境:Windows 10原生 GNU Emacs 28.2

试一下 global-goto-address-mode

1 个赞

真的是要global

请问你这个没有达到预期效果具体是什么?不清楚很难解答啊。

就是按enter并没有查找下一处,而是换行,同样esc也没有反应。

RET 改成 <return> ,试一下把 ESC 改成 <esc>

改成 <return><esc>确实有效了。还有两个小问题:

  1. 按esc退出查找后,查找词仍是高亮的,必须再按C-s进入查找模式才恢复;

  2. 进入正向查找后,按什么键可以反向查找?

因为你设置了 (setq lazy-highlight-cleanup nil)

根据代码的意思是你可以选择不断按 C-r 反查,或者按一次 C-r 后不断按 Enter 反查。

1 个赞

今天看视频的时候 https://youtu.be/TJrAkCyH6Dk?si=ar_OuixmgLieCTEL&t=379 学到几个命令 ,(indent-rigidly) 默认在C-x Tab 上,可以实现vim 的 <> 指令,用于 将选中的内容块 左右移动,操作步骤是 C-x Tab 之后 按左右键移动,或Shift+左右键根据缩进层级左右移动。

5 个赞

delim-col.el - helps to prettify columns in a text region or rectangle

Here is an example of columns:

horse	apple	bus
dog	pineapple	car	EXTRA
porcupine	strawberry	airplane

Doing the following settings:

(setq delimit-columns-str-before "[ ")
(setq delimit-columns-str-after " ]")
(setq delimit-columns-str-separator ", ")
(setq delimit-columns-separator "\t")

Selecting the lines above and typing:

M-x delimit-columns-region

It results:

[ horse    , apple     , bus     ,       ]
[ dog      , pineapple , car     , EXTRA ]
[ porcupine, strawberry, airplane,       ]

delim-col.el 的注释里包含更多可能的配置,可以作为 align-regexp 的补充。

4 个赞

看到一个接合 re-builderquery-replace-regexp 实现 在编辑regexp 时 可以在buffer 中可视化的看到哪部分能匹配上regexp (这是re-builder)的原生功能), 他通过将re-builder 与query-replace-regexp 接合后 达到 编辑完 regexp 并 按下return 后,输入 替换的结果,直接执行query-replace-regexp

原文在这: Bridging Islands in Emacs: re-builder and query-replace-regexp | Karthinks

https://www.reddit.com/r/emacs/comments/1dyn3zy/does_emacs_have_this_functionality/ 在他的基础上略作修改。1 是支持最新版的emacs ,2在minibuffer 中提醒用法:“Return:Query Replace,C-cC-c:quit”

(defvar my/re-builder-positions nil
  "Store point and region bounds before calling re-builder")
(defun reb-replace-regexp (&optional delimited)
  "Run `query-replace-regexp' with the contents of re-builder. With
non-nil optional argument DELIMITED, only replace matches
surrounded by word boundaries."
  (interactive "P")
  (reb-update-regexp)
  (let* ((re (reb-target-value 'reb-regexp))
         (replacement (query-replace-read-to
                       re
                       (concat "Query replace"
                               (if current-prefix-arg
                                   (if (eq current-prefix-arg '-) " backward" " word")
                                 "")
                               " regexp"
                               (if (with-selected-window reb-target-window
                                     (region-active-p)) " in region" ""))
                       t))
         (pnt (car my/re-builder-positions))
         (beg (cadr my/re-builder-positions))
         (end (caddr my/re-builder-positions)))
    (with-selected-window reb-target-window
      (goto-char pnt) ; replace with (goto-char (match-beginning 0)) if you want
                                        ; to control where in the buffer the replacement starts
                                        ; with re-builder
      (setq my/re-builder-positions nil)
      (reb-quit)
      (query-replace-regexp re replacement delimited beg end))))

(with-eval-after-load 're-builder
  (define-advice re-builder (:around (orig-fun &rest args) query-replace)
    (setq my/re-builder-positions
          (cons (point)
                (when (region-active-p)
                  (list (region-beginning)
                        (region-end)))))  
    (apply orig-fun args)
  (message "Return:Query Replace,C-cC-c:quit")
    )
  
  (define-key reb-mode-map (kbd "RET") #'reb-replace-regexp)
  (define-key reb-lisp-mode-map (kbd "RET") #'reb-replace-regexp)
  (define-key reb-mode-map (kbd "C-c C-c") #'reb-quit))

(global-set-key (kbd "C-M-%") #'re-builder)

最近移除了 corfu ,改用icomplete+global-completion-preview-mode 来作为completion

缺点和优点是 不会再自动弹出补全窗口(child frame),需要手动tab或C-i

优点 是 会用global-completion-preview-mode 进行补全, 有点类似于zsh-autosuggestions

使用 icomplete-in-buffer 与 icomplete-vertical-mode 的效果 似乎跟 corfu 差不太多了, 只是目前还没找到 与orderless 如何配合使用 几个核心配置如下

(setq icomplete-in-buffer t)
(setq tab-always-indent 'complete)
 (setq completion-auto-help t)
;https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS.30#L135
 (advice-add 'completion-at-point :after #'minibuffer-hide-completions)
; 如果想使用minibuffer 来补全 则使用下面这行注释掉的代码,否则就用上面这个advice-add
;(setq completion-in-region-function #'consult-completion-in-region)
(global-completion-preview-mode)
(setq completion-preview-ignore-case t)
(setq completion-ignore-case t)
;; 隐藏 preview 后再触发icomplete 的补全 ,否则 会出现下面动图的bug
(define-key completion-preview-active-mode-map (kbd "C-n") #'(lambda()(interactive)(completion-preview-hide) (indent-for-tab-command)))

;似乎有bug,当触发了icomplete的补全后,preview的内容没有隐藏,导致显示很诡异,见下面的动图
(define-key completion-preview-active-mode-map (kbd "C-e") #'completion-preview-complete)
(define-key completion-preview-active-mode-map (kbd "C-m") #'completion-preview-insert) 
(define-key completion-preview-active-mode-map (kbd "C-s") #'completion-preview-next-candidate)

(define-key completion-preview-active-mode-map (kbd "C-i") #'(lambda()(interactive)(completion-preview-hide) (indent-for-tab-command)))
(define-key completion-preview-active-mode-map (kbd "M-f") #'completion-preview-insert-word)

(setq completion-preview-completion-styles '(basic partial-completion initials orderless))
(setq completion-preview-minimum-symbol-length nil)

;cape 的包还是可以用的
(add-to-list 'completion-at-point-functions #'cape-file)
(add-to-list 'completion-at-point-functions #'cape-dabbrev)

global-completion-preview-mode 的效果如下:

latest

7 个赞

大佬,这个completion-preview-mode怎么和orderless的orderless-component-separator结合呢?corfu可以用corfu-insert-separetor,completion-preview-mode一旦输入空格就退出补全了


(defvar completion-preview-completion-styles '(basic)
  "List of completion styles that Completion Preview mode uses.

Since Completion Preview mode shows prefix completion candidates, this
list should normally only include completion styles that perform prefix
completion, but other candidates are filtered out and cause no harm.

See also `completion-styles'.")

看文档 preview 时似乎只能使用prefix 匹配, 没法用orderless

只能是preview 出现后 多按几个M-i(completion-preview-complete) 使用 completion-at-point 然后通过 icomplete 等minibuffer 里的completion .

(defun completion-preview-complete ()
  "Complete up to the longest common prefix of all completion candidates.

If you call this command twice in a row, or otherwise if there is no
common prefix to insert, it displays the list of matching completion
candidates unless `completion-auto-help' is nil.  If you repeat this
command again when the completions list is visible, it scrolls the
completions list."
  (interactive)
1 个赞

感觉这个更适合配合flx。。。

completion-preview-mode 还有待改善。

必须保持输入过程从头到尾无中断才会有补全:

image

一旦输入过程中断,比如往回删除字符,就没有补全了:

image

把你删除字符的命令加到 completion-preview-commands ,我用backspace 删 没你这个问题。

把删除命令假如到 completion-preview-commands 确实有补全了,但我觉得这里还有问题。

因为删除命令触发的补全,掩盖了继续输入字符没有触发补全的问题。

我这里可以通过以下方式得到验证:

  1. 输入 foobar| 然后 C-b 退一格(得到 fooba|r),再 C-d 删除字符(得到fooba|),然后再输入 r,在我这边没有补全。

  2. 输入 fooba| 然后 C-g 中断,光标移到别处再回来 fooba|,再输入 r,在我这边没有补全。

按理说有了 self-insert-command 任何时候继续输入都应该有补全。

我没复现,有可能是因为我用master 分支的代码编译的, 我看它最近确实对 preview 的代码有改动。

不知道大佬你有没有在用

补全?? 这个貌似不能使用 completion-preview