tags:

views:

601

answers:

4

I frequently find myself typing on a line, when I realize I need(ed) a variable definition (or something similar) on the line above. What I would like is to

  1. press C-return from anywhere on a line and have the cursor move to a newly inserted blank line above, with correct indentation (or at least the same as the original line).
  2. be able to yank any text...
  3. and C-u C-space to get back to the original position

I've managed to do #1, but my emacs-fu isn't strong enough to do the rest.

+3  A: 

Here's what you can do if you are not a Zen master emacs dude.

Emacs has a record-macro thing, kmacro-start-macro and kmacro-end-macro.

After recording your macro, do name-last-kbd-macro. then visit .emacs, and do insert-kbd-macro.

You then have an fset statement that defines your macro. It may look funny, and it is not as maintainable as elisp, but if you stuff it into your .emacs, that macro (by that name) will be available to any of your editing sessions. And you can bind it to a key sequence as well.

Cheeso
+2  A: 

Probably bad form to answer my own question, but Cheeso's answer motivated me to do some lisp programming for the second time in ten years (my original version was a named keyboard macro, but it stepped all over the kill/mark-rings). Here's what I came up with

(defun insert-and-indent-line-above ()
  (interactive)
  (push-mark)
  (let* 
    ((ipt (progn (back-to-indentation) (point)))
     (bol (progn (move-beginning-of-line 1) (point)))
     (indent (buffer-substring bol ipt)))
    (newline)
    (previous-line)
    (insert indent)))

(global-set-key [ (control return) ] 'insert-and-indent-line-above)

there are probably many better ways of doing this, but two hours of lisp-hacking can hardly be called wasted time :-)

thebjorn
+1  A: 

Just hold your thought on the variable declaration, finish typing your statement, then type RET (though C-j is usually more DWIM) and type your next line for the variable declaration, then hit C-x C-t to transpose the lines.

ashawley
If I could hold my thought until I reached the end of the line, this wouldn't be a problem -- you'll understand when you get "older" ;-)
thebjorn
A: 

Here's my humble solution:

(defun insert-before-line ()
  (interactive)
  (let ((pos (point))
        (cur-max (point-max)))
    (beginning-of-line)
    ; I've changed the order of (yank) and (indent-according-to-mode)
    ; in order to handle the case when yanked line comes with its own indent
    (yank)(indent-according-to-mode)
    ; could be as well changed to simple (newline) it's metter of taste
    ; and of usage
    (newline-and-indent) 
    (goto-char (+ pos (- (point-max) cur-max)))))

Hope it helps.

Serge
Interesting. IIUC, your solution keeps the cursor stationary and "auto-yanks" into a correctly indented line above. I think that might fit my usage pattern better than what I asked for. Thank you :-)
thebjorn
The code should use `save-excursion`, should avoid using `yank`, and should be general to handle when the text isn't at the end of the buffer (`point-max`).
ashawley
@aaronhawley - why 'save-excursion'? I don't change mark I handle properly point, and the above code will hardly provoke a crush of the buffer. Can you be more specific about "when the text isn't at the end of the buffer" case, it does the same thing whenever point is at the moment of invokation
Serge
I see, you're using `point-max` to do point arithmetic. Again, use `save-excursion` to let Emacs do that for you.
ashawley