views:

278

answers:

5

Hi,

I have a small problem with the way the commands "backward-word" and "backward-kill-word" work. When I hit "backward-kill-word" on a line that is only white-spaces (for example, the first char of an indented line), the command will kill all the white-space, as well as the last word of the previous line.

This behavior is completely unintuitive for me. I much prefer the way it works in Eclipse, for example, which will kill the white-space characters up to the beginning of the line on the first press of "backward-kill-word", will move to the end of the previous line on the next hit, and only then will start killing words off the end of the line.

I'm pretty sure this behavior is the default in most applications (since it does seem to be more intuitive, which is probably because I'm used to it, but I'm not sure), so I'm wondering if there is a way to configure Emacs to have this behavior also. A few searches on Google unfortunately turned up nothing.

Thanks

EDIT:

Thanks all for the answers (including the elisp code which does what I asked for).

The same problem comes up, obviously, with forward-kill-word and the movement commands, and I was hoping that there was just some configurable flag in emacs to change the behavior, but it looks I'm just going to take these elisp functions and rebind the default movement and killing commands for these ones.

+1  A: 

In this case, you might want to try M-\ (delete-horizontal-space), which does what you want for the first keypress. And if you really need a function that combines the two, it shouldn't be too hard to write one which checks if there are any non-space characters in the current line before the cursor, and call one or the other based on that.

David Hanak
+1  A: 

this is quite a big question. you'll have to look into emacs lisp programming and learn some stuff about it. i'd suggest starting here: rattlesnake emacs tutorial, and work your way through that.

just for your information, looking at my TAGS file tells me that backward-word is defined in simple.el and has the following form:

(defun backward-word (&optional arg)

"Move backward until encountering the beginning of a word. With argument, do this that many times."

(interactive "p")

(forward-word (- (or arg 1))))

so the next step would be to add an if to this call.

howlingmadhowie
+4  A: 

How about this:

(defun my-backward-kill-word ()
  "Kill words backward my way."
  (interactive)
  (if (bolp)
      (backward-delete-char 1)
    (if (string-match "^\\s-+$" (buffer-substring (point-at-bol) (point)))
        (kill-region (point-at-bol) (point))
      (backward-kill-word 1))))
scottfrazer
+1  A: 

This should do it:

(defun eclipse-kill-word (repeat)
  "Redefine `backward-kill-word' to work as Eclipse does.

Now stops at the beginning of the line, deleting only whitespace."
  (interactive "p")
  (let (cnt)
    (dotimes (cnt repeat)
      (if (= (point) (save-excursion (beginning-of-line) (point)))
       (kill-region (point) (save-excursion (backward-word) (point)))
     (kill-region (point)
         (max (save-excursion (beginning-of-line) (point))
           (save-excursion (backward-word) (point))))))))

Has the added benefit of being repeatable using the prefix key (Ctrl-U).

Joe Casadonte
A: 

Note, in cc-mode, there's an option for hungry deletion, and you can enable it like so:

(add-hook 'c-mode-common-hook (lambda () (c-toggle-auto-hungry-state 1)))

Obviously this only applies to the C,C++,Java,... files, and applies to the backspace key (not deletion of words).

Trey Jackson