Emacs命令删除至非空白字符

46

我经常希望将多行函数调用转化为一行。例如,将...

function_call(
     'first_arg',
     'second')
function_call('first_arg', 'second')

Emacs是否有一些命令来帮助完成这个任务?具体而言,是否有一个命令可以从光标位置到第一个非空白字符删除所有空白字符?

10个回答

66

你可以尝试使用我的最爱命令delete-indentation来将多行合并成一行。在你的例子中,将光标放在"second"所在的那一行,然后按两次M-^键。以下是文档:

M-^键执行delete-indentation命令,它是一个交互式的编译过的Lisp函数,位于simple.el文件中。

它绑定到M-^键上。

(delete-indentation &optional arg)

将当前行与上一行连接,并在连接处修复空格。如果存在填充前缀,则从该行开头删除它。使用参数时,将当前行与下一行连接。


2
不错。我一直在想这样的功能在哪里可以找到。这对我帮助很大。 - user673046

33
请看一下fixup-whitespace函数。它是Emacs中的一个函数,在simple.el文件中。这里是它的文档:

整理点附近对象之间的空白,根据上下文留下一个空格或者不留。

类似的函数还有just-one-space,它会删除光标周围所有的空格和制表符,只留下一个空格。通常将其绑定到M-SPC

3
M-SPACE指的是“只有一个空格”,而不是“修复空白”。尽管它们看起来做了类似的事情。 - Chris Conway

23
具体来说,是否有一种命令可以从光标位置删除所有空格直到第一个非空白字符?
有一种几乎可以实现此功能的命令:
M-\ 这个命令运行 delete-horizontal-space 函数,它是一个交互式的编译Lisp函数,在simple.el文件中。
用快捷键 M-\ 绑定了该函数。
(delete-horizontal-space &optional backward-only)
删除点周围的所有空格和制表符。如果backward-only是非nil,则只在点之前删除它们。

7

您可以始终使用M-z删除一个字符。

例如,在您的情况下:

M-z '可以删除单引号(不幸的是,这也会删除单引号,但这只是一个小问题)。


1
一种非常有用的技巧。我正在养成双击字符键以快速跳转以克服这个小缺点的习惯。 - Ébe Isaac

6
我使用以下宏来“拉”下一行到当前行的末尾,压缩空白。
(defun pull-next-line() 
  (interactive) 
  (move-end-of-line 1) 
  (kill-line)
  (just-one-space))

这恰好与@jrockway的 move-line-up delete-indentation 相反,我发现后者更自然。宏中的just-one-space 命令恰好是@Mike的 M-SPACE 。 我将pull-next-line 绑定到M-J (类似于Vim的 J 命令)在我的.emacs 中使用以下命令。
(global-set-key (kbd "M-J") 'pull-next-line)

例子。 在第一行上调用pull-next-line

function_call(
     'first_arg',
     'second')

收益率
function_call( 'first_arg',
     'second')

第二次调用会产生以下结果:
function_call( 'first_arg', 'second')

5

按下Alt+空格将把一串空格缩减为一个单个空格字符,但不会删除换行符。这应该有所帮助。

要删除从光标到第一个非空格字符(或换行符)的所有内容,请键入一个非空格字符,然后依次按下Alt+空格、退格键(删除最后一个空格字符),再次按下退格键(删除您添加的字符)。

要将多行函数声明转换为单行声明,请使用组合的Alt+空格、退格和Alt+E(转到行尾)命令。


谢谢Alt+Space的提示,我刚刚搜索了一下,我知道肯定有这样的功能存在,只是不知道它的名称或快捷键。 - ahilsend
这太棒了,我创建了一个宏并将其绑定到了一个快捷键。谢谢! - aeu

4

一种比较激进的做法是使用Hungry-Delete模式:

Hungry-Delete是一个小型模式,它会使得删除操作连同方向上的所有空格一并删除。


3

一个稍微不同的方法是创建一个键盘宏来为您完成这项工作。因此,要创建宏阶段,可以像下面这样进行一般情况的设想:

foo


               bar

[一行文字中包含 "foo",然后几行后有一些空格,再写 "bar"]

然后在 foo 和 bar 之间的任何位置,执行以下操作:

C-x (                    ; 开始录制宏
M-b                      ; 向后移动到 foo 的开头
END                      ; 移动到 foo 的结尾
C-space                  ; 标记
C-M-f                    ; 移动到 bar 的结尾
HOME                     ; 移动到行的开头
C-w                      ; 删除所有空格
M-SPACE                  ; 只留一个空格
C-x )                    ; 结束录制宏
M-x name-last-kbd-macro  ; 命名它,称其为 jline 或其他名称 

现在您可以使用 M-x one-line 始终删除两个单词之间的所有空格。

请确保在您的 .emacs 文件中发出 M-x insert-kbd-macro 命令以保存您的键盘宏 - 它应如下所示:

(fset 'jline
   [?\M-b end ?\C-  ?\C-\M-f home ?\C-w escape ? ])

1
如果你想让所有的删除操作都按照这种方式进行,你可以尝试使用贪婪删除。

1
我这样做:
(defun move-line-up ()
  "Removes leading spaces from the current line, and then moves
the current line to the end of the previous line."
  (interactive)
  (let (start end)
    (save-excursion
      (beginning-of-line)
      ; get first non-space character, only look on this line
      (let ((search-end (save-excursion (end-of-line) (point))))
        (re-search-forward "[^[:space:]]" search-end))
      (setq end (1- (point)))
      (previous-line)
      (end-of-line)
      (setq start (point))
      (delete-region start end))
    (goto-char start)))

(defun move-next-line-up ()
  "Moves the next line to the end of the current line"
  (interactive)
  (next-line)
  (move-line-up))

将它们绑定为:

(global-set-key (kbd "C-x ,") 'move-line-up)
(global-set-key (kbd "C-x .") 'move-next-line-up)

所以为了解决你的问题,在代码中写有"second)"的那一行,只需要运行C-x , C-x ,即可。


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