6

When editing human language text and moving text fragments around, I frequently run into the problem that whitespace moved at the beginning or end of a fragment doesn't fit into the new position. For example, consider this paragraph:

This is the first sentence.  This is the second sentence.  These
three sentences are the whole paragraph.

If I move the last sentence before the first one by kill+yank, I have either leading or trailing whitespace. A similar problem occurs in enumerations.

Another use case is if I want to insert a single word or expression which is in the kill ring without any trailing or leading whitespace. For example, consider the word "very" in the kill ring, and the following sentence:

Such a minor mode would be useful.

After yanking, this may erroneously become:

Such a minor mode would bevery useful.

Is there a way to have white space in human texts adjusted automatically?

2 Answers 2

2

This seems to do what you have asked. By contrast if there is already extra white spaces, it keeps them as before.

  (defun yank-and-adjust-whitespace ()
  (interactive)
  (if (equal (char-after) ?\s)
      (progn
        (insert " ")
        (yank))
    (if (eolp) (if (bolp) (yank)
        (if (equal (char-before) ?\s)
            (yank)
          (insert " ")
          (yank)))
      (yank)
      (insert " "))))

Like the answer of Eric Bailey you can associate the below shortcut.

(global-set-key "\C-y" 'yank-and-adjust-whitespace)

Using eolp/bolp was borrowed from https://emacs.stackexchange.com/a/13741/.

2
  • @wasamasa thanks for editing, I saw that you have changed ? to?\s. It seems that both work. I am interested to know about their differences.
    – Name
    Jul 6, 2015 at 12:30
  • 1
    Correct, both are equivalent. The manual recommends ?\s though because it looks a lot less confusing than ? and ensures that you meant to match a space instead of mistyping.
    – wasamasa
    Jul 6, 2015 at 12:42
2

Here's a function, delete-leading-whitespace-on-line to do as the name suggests:

(defun delete-leading-whitespace-on-line ()
  "Delete whitespace at the beginning of the current line."
  (interactive)
  (let ((start (line-beginning-position))
        (end (line-end-position)))
    (save-excursion
      (delete-whitespace-rectangle start end nil))))

For trailing whitespace, I use M-x delete-trailing-whitespace.

To trigger these after yanks, you could do something like:

(defun yank-and-trim-whitespace ()
  "Yank and then trim whitespace on the line."
  (interactive)
  (yank)
  (delete-leading-whitespace-on-line)
  (delete-trailing-whitespace))

and bind it like:

(global-set-key "\C-y" 'yank-and-trim-whitespace)

You might also like to try Steve Purcell's whitespace-cleanup-mode, a minor mode that:

will intelligently call whitespace-cleanup before buffers are saved.

PS His GitHub account is a treasure trove of Emacs goodies.

4
  • I don't have the reputation yet, but here's a link to the pertinent documentation: gnu.org/software/emacs/manual/html_node/emacs/…
    – yurrriq
    Jul 3, 2015 at 15:38
  • Are the call-interactively's necessary here? Can you not just call the functions?
    – erikstokes
    Jul 3, 2015 at 16:27
  • @erikstokes, good catch. The call-interactively are redundant.
    – yurrriq
    Jul 3, 2015 at 17:31
  • I think using call-interactively here would make it work with yank-pop.
    – politza
    Jul 4, 2015 at 7:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.