移动到代码行开头: Emacs

42

我使用emacs进行开发,很常需要将光标移动到行首 (C-a)。但是如果该行有缩进,我希望光标能够移到代码开始的位置。

例如在浏览代码: ( ) for x in xy|z:。 在按下 C-a 后,会得到这样的结果:|( ) for x in xyz:。但是,我想要的是这样:( ) |for x in xyz:

这里的 | 表示光标位置,() 表示空格或制表符。

如何实现?


https://emacs.stackexchange.com/questions/48121/is-there-an-emacs-command-to-go-to-end-of-code-line-before-line-comment-and-whi/48160#48160 - rofrol
5个回答

85

Meta-m


8
默认情况下,Meta-m 运行 back-to-indentation - aculich
我见过的最短(也是最正确)的答案!幸运的是你写了“Meta”,而不是“M-m”。 - SureshS

32

我处理这个问题的最喜欢方法之一是使用C-a在行首和代码开头之间切换。您可以使用以下函数实现:

(defun beginning-of-line-or-indentation ()
  "move to beginning of line, or indentation"
  (interactive)
  (if (bolp)
      (back-to-indentation)
    (beginning-of-line)))

在你喜欢的模式映射中添加适当的绑定:

(eval-after-load "cc-mode" 
     '(define-key c-mode-base-map (kbd "C-a") 'beginning-of-line-or-indentation))

22

我执行了与Trey相同的切换技巧,但默认为缩进而不是行首。这需要稍微更多的代码,因为我不知道是否存在“在缩进开始处”的函数。

(defun smart-line-beginning ()
  "Move point to the beginning of text on the current line; if that is already
the current position of point, then move it to the beginning of the line."
  (interactive)
  (let ((pt (point)))
    (beginning-of-line-text)
    (when (eq pt (point))
      (beginning-of-line))))

这样做可能会让你继续使用Ctrl-a并且大多数情况下达到你想要的效果,同时仍然可以轻松地获得内置行为。


在您的解决方案中,我遇到了问题,当某一行被注释时,它会跳过注释符号内的2个字符。请参见:https://emacs.stackexchange.com/q/66590/18414 - alper
1
@alper 我喜欢这种行为。我在注释行的开头可能会做两件事:使用C-k删除整行;编辑注释文本。我想不出任何理由,为什么我希望光标定位在缩进后的注释字符之前。此外,如果您想回到那个位置,已经有M-m了。 - amalloy

8

默认情况下,Meta-m 运行 back-to-indentation 命令,根据文档的说明,该命令将“将光标移动到此行中第一个非空白字符处。”


3

现代IDE中常见的惯用语是在第二次按键时移动到第一个/最后一个非空白字符:

(defun my--smart-beginning-of-line ()
  "Move point to `beginning-of-line'. If repeat command it cycle
position between `back-to-indentation' and `beginning-of-line'."
  (interactive "^")
  (if (and (eq last-command 'my--smart-beginning-of-line)
           (= (line-beginning-position) (point)))
      (back-to-indentation)
    (beginning-of-line)))

(defun my--smart-end-of-line ()
  "Move point to `end-of-line'. If repeat command it cycle
position between last non-whitespace and `end-of-line'."
  (interactive "^")
  (if (and (eq last-command 'my--smart-end-of-line)
           (= (line-end-position) (point)))
      (skip-syntax-backward " " (line-beginning-position))
    (end-of-line)))

(global-set-key [home]     'my--smart-beginning-of-line)
(global-set-key [end]      'my--smart-end-of-line)

这段代码首先移动到实际的开始/结束位置,新的行为将出现在后续的按键操作中。因此,任何旧的键盘宏都将按预期工作!


2
太棒了。这段代码将反转顺序:首先到代码开头,然后到行的开头。 "将光标移动到“行首”。如果重复命令,则在“回到缩进”和“行首”之间循环位置。" (interactive "^") (if (eq last-command 'my--smart-beginning-of-line) (if (= (line-beginning-position) (point)) (back-to-indentation) (beginning-of-line)) (back-to-indentation)))``` - tanenbring

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