如何在Emacs中实现类似Vim C-x C-l的整行补全?
实现Emacs整行补全(类似Vim的C-x C-l)
当然可以!在Emacs里实现整行补全其实不难,刚好能满足你想要的「整行版dabbrev-expand」需求,和Vim里C-x C-l的效果一致。下面给你两种实用的方案:
方案一:自定义专属整行补全函数
你可以自己写一段Elisp代码,基于dabbrev的匹配逻辑,但专门针对整行内容处理。把这段代码加到你的Emacs配置文件(比如~/.emacs或者~/.emacs.d/init.el)里:
(defun my-complete-line () "Complete the current line using matching lines from the buffer." (interactive) (let* ((current-line (buffer-substring-no-properties (line-beginning-position) (line-end-position))) (completion-ignore-case t) candidates) ;; 遍历缓冲区收集匹配的行 (save-excursion (goto-char (point-min)) (while (not (eobp)) (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) (when (and (not (equal line current-line)) (string-prefix-p current-line line)) (add-to-list 'candidates line t)))) (if candidates (progn (delete-region (line-beginning-position) (line-end-position)) (insert (completing-read "Complete line: " candidates nil t current-line))) (message "No matching lines found"))))) ;; 绑定快捷键,比如直接用和Vim一样的C-x C-l (global-set-key (kbd "C-x C-l") 'my-complete-line)
这个函数的逻辑很清晰:
- 先抓取当前行的内容作为匹配前缀
- 遍历整个缓冲区,收集所有以当前行为前缀且不重复的行
- 弹出补全菜单让你选择,选中后直接替换当前行
方案二:整合到hippie-expand的扩展补全
如果你平时习惯用Emacs内置的hippie-expand智能补全工具,可以给它添加一个整行补全的源。把这段代码加到配置里:
(defun try-complete-line (old) "Hippie expand function to complete the current line." (unless old (let ((current-line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) (setq hippie-expand-old-string current-line) (setq hippie-expand-point (point))) (goto-char (line-beginning-position))) (let ((candidates) (current-line hippie-expand-old-string)) (save-excursion (goto-char (point-min)) (while (not (eobp)) (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position)))) (when (and (not (equal line current-line)) (string-prefix-p current-line line)) (add-to-list 'candidates line t))))) (if candidates (progn (delete-region (line-beginning-position) (line-end-position)) (insert (completing-read "Complete line: " candidates nil t current-line)) t) nil))) ;; 把整行补全加入hippie-expand的候选列表 (add-to-list 'hippie-expand-try-functions-list 'try-complete-line t)
之后你用M-x hippie-expand(或者你绑定的快捷键,比如常见的M-/)时,工具会自动尝试整行补全,和其他补全逻辑无缝结合。
两种方案都能实现你要的效果,第一种更直接,一键触发;第二种适合已经习惯hippie-expand补全流程的用户,按需选择就好。
内容的提问来源于stack exchange,提问作者Lemurata
相关产品推荐
相关产品推荐

