views:

599

answers:

5

Hi there,

I am currently playing around with emacs and happy with most of the concepts. But I really adored the convenience of the three vim commands: dd,o,O Hopefully you can tell me how to mirror them in emacs :)

dd - deletes whole line, including newline, no matter where the cursor is.

I found something similar to do the trick:

C-a C-k C-k

While C-a moves the cursor to the beginning of the line, the first C-k kills the text, the second one kills the newline. The only problem is that this is not working on empty lines where I only need to type C-k which is quite inconvenient as I have to use different commands for the same task: killing a line.

o / O - creates a new empty line below / above cursor and moves cursor to the new line, indented correctly

Well, C-a C-o is nearly like O, just the idention is missing. C-e C-o creates an empty line below the current but does not move the cursor.

Are there any better solutions to my problems or do I have to learn Lisp and define new commands to fulfill my needs?

+1  A: 

You could create a macro and bind it to a key sequence. No need to learn any emacslisp yet.

Nifle
+9  A: 

For o and O, here are a few functions I wrote many years ago:

(defun vi-open-line-above ()
  "Insert a newline above the current line and put point at beginning."
  (interactive)
  (unless (bolp)
    (beginning-of-line))
  (newline)
  (forward-line -1)
  (indent-according-to-mode))

(defun vi-open-line-below ()
  "Insert a newline below the current line and put point at beginning."
  (interactive)
  (unless (eolp)
    (end-of-line))
  (newline-and-indent))

(defun vi-open-line (&optional abovep)
  "Insert a newline below the current line and put point at beginning.
With a prefix argument, insert a newline above the current line."
  (interactive "P")
  (if abovep
      (vi-open-line-above)
    (vi-open-line-below)))

You can bind vi-open-line to, say, M-insert as follows:

(define-key global-map [(meta insert)] 'vi-open-line)

For dd, if you want the killed line to make it onto the kill ring, you can use this function that wraps kill-line:

(defun kill-current-line (&optional n)
  (interactive "p")
  (save-excursion
    (beginning-of-line)
    (let ((kill-whole-line t))
      (kill-line n))))

For completeness, it accepts a prefix argument and applies it to kill-line, so that it can kill much more than the "current" line.

You might also look at the source for viper-mode to see how it implements the equivalent dd, o, and O commands.

seh
Wow great, thanks. Works like a charm :) Just the `vi-open-line-above` does not indent. Any ideas?
eteubert
I added `(indent-according-to-mode)` in `vi-open-line-above` below `(forward-line -1)`. This does the trick :)
eteubert
Funny, I was in the middle of editing it again when you noted that you found the solution. As you can tell, this is old code that I don't use often. I wrote it when I first learning Emacs Lisp. This question gave me an excuse to freshen it.
seh
Pedantic police:(if (not (foo)) (bar))is written better as(unless (foo) (bar))Then you don't have to wrap things in a progn if you add more forms.
scottfrazer
I thought `when` and `unless` were only available in Emacs if one loaded the `cl` library, but it turns out that's not the case. I took your suggestion into account above.
seh
+1  A: 

Here's how I addressed the issue of Emacs's lack of a vi-like "O" command:

(defadvice open-line (around vi-style-open-line activate)
  "Make open-line behave more like vi."
  (beginning-of-line)
  ad-do-it
  (indent-according-to-mode))

With this in place, I've never really felt the need for a corresponding version of vi's "o" command. C-n C-o does the trick.

As for the "dd" command, that grated a little at first, but I eventually came around to Emacs's way of doing things. Anyway, when I want to delete several lines at once, which is often the case, I just do it using the region (C-a C-SPC, go to the other end of the text I want to delete, C-w). Or if I can eyeball the number of lines I want to delete, I'll do eg. M-9 C-k to delete nine lines at once.

Sean
+1  A: 

Just use Viper-mode, Vimpulse or Vim Mode, Emacs keybindings are just not as ergonomic.

andreasw
This sounds awkward to me. If I want to use vim, then I use vim not emacs.
eteubert
Emacs' keybindings may(!) not be ergonomic, but for me at least, vi's modal **** grates on my brain.
jae
@eteubert not awkward at all. just think of emacs as the 3rd (or 4th) mode. it actually feels natural once you've picked up emacs and everything resides within emacs.
mt3
+6  A: 

For dd, use "kill-whole-line", which is bound to "C-S-backspace" by default in recent versions of Emacs.

sanityinc