1

I often mistype a space-delimited string and when I do that, I just want to type the correct space-delimited string, without deleting the incorrect space-delimited string. After I have typed the correct space-delimited string, I do "C-c SPC" and I then want the incorrect space-delimited string to be removed.

(defun remove-penultimate-spadel () "Remove the penultimate space-delimited string from the current line." (interactive) (let ((line (thing-at-point 'line t)) (case-fold-search nil)) (if (string-match "\\(\\w+\\)\\s-+\\(\\w+\\)\\s-+\\(\\w+\\)\\s-*$" line) (let* ((start (match-beginning 2)) (end (match-end 2)) (new-line (concat (substring line 0 start) (match-string 3 line)))) (goto-char (line-beginning-position)) (delete-char (length line)) (insert new-line)) (message "No penultimate spadel found.")))) (global-set-key (kbd "C-c SPC") 'remove-penultimate-spadel) 

I have this test

foo bar hukarx hukarz bat 

If point is after "hukarz" and I eval the function, it correcly replaces "hukarx" with "hukarz", but it also moves "bat" up on the same line.

How can I prevent "bat" from moving up to the same line as "hukarz"?;)

EDIT: I also have to add that point should not move after this operation is done. It should remain after "hukarz".

EDIT: Be aware that this is a space delimited string and not a word.

2
  • 1
    line includes the \n, so you are getting rid of that when you delete the line. Commented Jan 15 at 0:49
  • Instrument your function with edebug and step through it to see what is happening. Commented Jan 15 at 0:50

2 Answers 2

3
  1. I'd say don't grab a string of text from a buffer and operate on it. In general, in Emacs you want instead to operate directly on text in a buffer. That's typically easier and more performant.

  2. In this case, if you just want to delete the (incorrect) word before the (correct) word that you just typed, then just do that. This is one way:

(defun my-kill-previous-word () "..." (interactive) (save-excursion (backward-word) (backward-kill-word 1))) 
5
  • Well, this is what happens when the question gets edited by someone else than the OP. My original title was "space delimited", not word, so 2, won't work;) Commented Jan 16 at 0:19
  • Your question described deleting text that matches a word immediately preceding whitespace that immediately precedes the word at point. If you want to distinguish space-delimited words from words delimited by other chars, then just say that in the text. The title shouldn't talk about "strings" etc. There are NO strings involved here at all. I've edited the title again and added tag [words] again. Commented Jan 16 at 4:12
  • 1
    If you no longer mean words then say so in the question, and don't use a regexp that matches only words. Commented Jan 16 at 4:21
  • Don't evolve a question. Instead, delete it and post a new one that expresses what you really want to know how to do. Commented Jan 16 at 4:23
  • 1
    Just use (search-backward-regexp "[[:space:]]") to move to the previous whitespace. You'll need to worry about remembering point before moving backward again, so you can delete the region. And you'll need to worry about multiple spaces separating the "bad" string and the "good" string: a loop using looking-at is a possible solution of this, Commented Jan 16 at 5:20
0

The easiest fix is probably to append a newline to the new-line string:

 .... (new-line (concat (substring line 0 start) (match-string 3 line) "\n"))) ... 

EDIT: although this explains where OP went wrong, it does not satisfy OP's (current) requirements, but more importantly it's not a good solution to the problem: using motion functions in the buffer, along the lines of @Drew's answer, is a better way to go.

2
  • I tried this, but point gets moved down to the line below. I've added a requirement that it should remain in place;) Commented Jan 16 at 0:15
  • 1
    @Drew's answer is the way to go. Commented Jan 16 at 1:14

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.