关于Emacs中单词前后移动的行为

11

我不知道我的设置是否有问题,但是当我按下M-f(向前移动一个单词)时, 无论我在哪里,它都不会将光标放置在下一个单词中(只能在单词之间)。但是M-b可以将光标放置在前一个单词的开头。

这是正常行为吗?我该如何将光标放在下一个单词的开头处?


你可以使用 M-f C-f :) 来获得那个结果。 - Pascal Cuoq
3
已经有人提出并回答过这个问题了:https://dev59.com/8nI-5IYBdhLWcg3wm5lH#1772365 - scottfrazer
6个回答

12

虽然在会话中使用宏解决方案是实现此行为的好方法,但如果您想要这成为默认行为,则有点不太方便,因为每次启动emacs都需要重新定义。如果您希望M-f一直按此方式工作,可以定义一个elisp函数并将其绑定到该键。将以下内容放入您的.emacs文件中:

(defun next-word (p)
   "Move point to the beginning of the next word, past any spaces"
   (interactive "d")
   (forward-word)
   (forward-word)
   (backward-word))
(global-set-key "\M-f" 'next-word)

7
好的,让我们明确一下,我假设你在谈论默认绑定到Alt+fAlt+bforward-wordbackward-word命令。

例如字符串:"Hello dolly I am here"

如果您的光标位于“Hello”中的“H”上,并且执行forward-word,则光标将移动到“Hello”和“dolly”之间的空格处,但听起来您希望光标位于“dolly”的“d”字母上而不是其前面。

所以,先执行两次forward-word,然后再执行一次backward-word

这将把您的光标放在“dolly”的“d”字母上。

这可以使用宏自动完成。

;; = 注释,请勿输入

Ctrl+x ( ;;开始宏

Alt+f Alt+f Alt+b

Ctrl+x ) ;;结束宏

然后运行最后定义的宏:

Ctrl+x e

编辑:正如Pascal在评论中提到的,这也可以使用以下方法完成:

Alt+f Ctrl+f

您也可以将其放入宏中,无论哪种方式,结果都是相同的。


谢谢。我想我仍然受到后Vim创伤的影响(w和b键)。 - alexchenco
4
是的,我有这种感觉,你开始使用的文本编辑器会影响你对其他文本编辑器的看法。我从VIM开始,无法相信在emacs中你不能像在Vim中那样只需键入“w”和“b”来跳过单词。 - user798719
1
我也是ViM的忠实用户(虽然已经超过3年了),我真的很想念"w"命令。 "M-f C-f"不能总是奏效,特别是在单词之间有多个空格的情况下。 - GergelyPolonkai

4
向前移动两次,向后移动一次是可以的,除非你在一行开头有空格。那么向前移动两次,向后移动一次会将光标移到下一个单词而不是第一个单词。下面的代码将完美地模拟vi的“w”命令。我写得很快,所以这段代码还可以进一步优化。
(defun forward-word-to-beginning (&optional n)
  "Move point forward n words and place cursor at the beginning."
  (interactive "p")
  (let (myword)
    (setq myword
      (if (and transient-mark-mode mark-active)
        (buffer-substring-no-properties (region-beginning) (region-end))
        (thing-at-point 'symbol)))
    (if (not (eq myword nil))
      (forward-word n))
    (forward-word n)
    (backward-word n)))

(global-set-key (kbd "M-C-f") 'forward-word-to-beginning)

当单词之间有下划线时,这会出现错误。 - alecvn

4

这是正确的行为。根据 Emacs 手册,“向前移动在单词的最后一个字母后停止,而向后移动在单词的第一个字母前停止。”

为什么会这样呢?可能是为了与 kill-word (M-d) 保持一致。


0

尝试以下类似的内容:

;; replace common word-operations on same-syntax-operations

(require 'thingatpt)

(global-set-key "\M-f" 'forward-same-syntax)

(global-set-key "\M-b" (lambda() 
                         (interactive)
                         (forward-same-syntax -1)))

(defun kill-syntax (&optional arg)
  "Kill ARG sets of syntax characters after point."
  (interactive "p")
  (let ((opoint (point)))
    (forward-same-syntax arg)
    (kill-region opoint (point))))

(global-set-key "\M-d" 'kill-syntax)

(global-set-key [(meta backspace)] (lambda()
                                     (interactive) 
                                     (kill-syntax -1)))

0
您可以通过使用misc.el中的forward-to-wordbackward-to-word来实现这种行为。 我将它们绑定到Meta-F/Meta-B(即按下Shift键)。 这相当于forward-word/backward-wordMeta-f/Meta-b
我的.emacs文件具有以下绑定。
(global-set-key (kbd "M-F") #'forward-to-word)
(global-set-key (kbd "M-B") #'backward-to-word)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接