これは、この特定の問題を自分で解決するために書いた関数です。
(defun delete-surrounding-whitespace ()
(interactive)
(let ((skip-chars "\t\n\r "))
(skip-chars-backward skip-chars)
(let* ((start (point))
(end (progn
(skip-chars-forward skip-chars)
(point))))
(delete-region start end))))
魚を提供することよりも釣りを教えるという精神で、Emacs の内部からこれを発見する方法を共有します。
詳細情報が必要な関数または変数の名前について何か知っている場合は、 apropos を使用してより深く掘り下げることができます。しかし、コマンドの名前がわからない場合はどうすればよいでしょうか。
たとえば、apropos を使用して del.*white、zap.*space、del.*space などを検索しても、just-one-space のような便利な空白関数に出くわすことはありません。
検索の範囲を広げるために、Ch i を押して Texinfo ドキュメントにアクセスすることにより、Emacs 内から Emacs のドキュメントを検索できます。mEmacs を押して、ドキュメントの Emacs 固有の部分に入ります (一部のパッケージのセクションもあります)。Emacs セクションで s を押して検索し、delete.*white などの検索を実行すると、ドキュメントの削除セクションに移動し、あらゆる種類の役立つ削除方法が表示されます。
12.1.1 Deletion
---------------
Deletion means erasing text and not saving it in the kill ring. For the
most part, the Emacs commands that delete text are those that erase just
one character or only whitespace.
‘<DEL>’
‘<BACKSPACE>’
Delete the previous character, or the text in the region if it is
active (‘delete-backward-char’).
‘<Delete>’
Delete the next character, or the text in the region if it is
active (‘delete-forward-char’).
‘C-d’
Delete the next character (‘delete-char’).
‘M-\’
Delete spaces and tabs around point (‘delete-horizontal-space’).
‘M-<SPC>’
Delete spaces and tabs around point, leaving one space
(‘just-one-space’).
‘C-x C-o’
Delete blank lines around the current line (‘delete-blank-lines’).
‘M-^’
Join two lines by deleting the intervening newline, along with any
indentation following it (‘delete-indentation’).
私が探していたものを正確に実行するものは何もありませんでした。しかし、apropos を使用して一部の関数のヘルプ バッファーを検索してプルアップすることで、それらがどのように実装されているかを確認し、同じ手法を使用して必要な関数を正確に記述することができました。
関数 just-one-space を simple.el.gz で調べると、近くにある cycle-spacing という関数が、必要な機能を備えているように見えました。
(defun cycle-spacing (&optional n preserve-nl-back mode)
"Manipulate whitespace around point in a smart way.
In interactive use, this function behaves differently in successive
consecutive calls.
The first call in a sequence acts like `just-one-space'.
It deletes all spaces and tabs around point, leaving one space
\(or N spaces). N is the prefix argument. If N is negative,
it deletes newlines as well, leaving -N spaces.
\(If PRESERVE-NL-BACK is non-nil, it does not delete newlines before point.)
The second call in a sequence deletes all spaces.
The third call in a sequence restores the original whitespace (and point).
If MODE is `single-shot', it only performs the first step in the sequence.
If MODE is `fast' and the first step would not result in any change
\(i.e., there are exactly (abs N) spaces around point),
the function goes straight to the second step.
Repeatedly calling the function with different values of N starts a
new sequence each time."
(interactive "*p")
(let ((orig-pos (point))
(skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
(num (abs (or n 1))))
(skip-chars-backward (if preserve-nl-back " \t" skip-characters))
(constrain-to-field nil orig-pos)
(cond
;; Command run for the first time, single-shot mode or different argument
((or (eq 'single-shot mode)
(not (equal last-command this-command))
(not cycle-spacing--context)
(not (eq (car cycle-spacing--context) n)))
(let* ((start (point))
(num (- num (skip-chars-forward " " (+ num (point)))))
(mid (point))
(end (progn
(skip-chars-forward skip-characters)
(constrain-to-field nil orig-pos t))))
(setq cycle-spacing--context ;; Save for later.
;; Special handling for case where there was no space at all.
(unless (= start end)
(cons n (cons orig-pos (buffer-substring start (point))))))
;; If this run causes no change in buffer content, delete all spaces,
;; otherwise delete all excess spaces.
(delete-region (if (and (eq mode 'fast) (zerop num) (= mid end))
start mid) end)
(insert (make-string num ?\s))))
;; Command run for the second time.
((not (equal orig-pos (point)))
(delete-region (point) orig-pos))
;; Command run for the third time.
(t
(insert (cddr cycle-spacing--context))
(goto-char (cadr cycle-spacing--context))
(setq cycle-spacing--context nil)))))
条件付きで改行を削除し、残りのスペースを n 個残す必要がなかったので、少し単純化できました。