Ctrlk would delete everything from the current position of the cursor to the end of line. Is there some equivalence to delete everything from the current position to the beginning of line?
For me Ctrl-0Ctrl-k does what you want. I think this is the default configuration, it's certainly not something I've modified.
If this doesn't work try Ctrl-u0Ctrl-k. Again, that seems to be Emacs' default behaviour on my installation (Emacs 24.x, Mac OS X).
If you prefer to have lesser keybinding (rather than having separate key to delete line, or having to invoke prefix-argument). You can use crux-smart-kill-line
which will "kill to the end of the line and kill whole line on the next
call". But if you prefer delete instead of kill, you can use the
code below.
For point-to-string operation (kill/delete) I recommend to use zop-to-char
(defun aza-delete-line ()
"Delete from current position to end of line without pushing to `kill-ring'."
(interactive)
(delete-region (point) (line-end-position)))
(defun aza-delete-whole-line ()
"Delete whole line without pushing to kill-ring."
(interactive)
(delete-region (line-beginning-position) (line-end-position)))
(defun crux-smart-delete-line ()
"Kill to the end of the line and kill whole line on the next call."
(interactive)
(let ((orig-point (point)))
(move-end-of-line 1)
(if (= orig-point (point))
(aza-delete-whole-line)
(goto-char orig-point)
(aza-delete-line))))
source
Emacs has steep learning curve. When a new user encounters this problem, she should record a macro of 2 keystrokes: Shift+Ctrl+a and Ctrl-w (cut), name it, save it, and set up a key binding so that the macro is available in the subsequent Emacs sessions.
Related
I have a bunch of links saved in an orgmode file, say...
http://www.stackoverflow.com
http://www.google.com
http://www.github.com
I can open each one by having the cursor on the link and doing C-c C-o, and it conveniently pops up my default browser and opens that link in a tab.
Now suppose I have like 20 of these links. Is there a convenient way to apply a function like this to each line within a selected region, without recording an explicit macro?
I'd imagine it looking something like...
Select region
M-x foreach-in-region
Keystrokes to apply to each line: C-c C-o
And this is just for functions already defined. I imagine the way without would be something like...
with cursor on first line of link
F3 # to start record macro
C-c C-o
down arrow
F4
Select region (omitting the first line, since that's now already opened in my browser)
C-x C-k r
Does this exist? If not, how would I lisp this?
You should record the macro for one line, then use apply-macro-to-region-lines to execute it for all lines in region. C-x C-k r
Alternatively, you can use multiple-cursors to create a cursor on each line and C-c C-o to open all. multiple-cursors will transform your usage patterns over time for the better if you give it a chance.
(defun do-lines (fun &optional start end)
"Invoke function FUN on the text of each line from START to END."
(interactive
(let ((fn (intern (completing-read "Function: " obarray 'functionp t))))
(if (use-region-p)
(list fn (region-beginning) (region-end))
(list fn (point-min) (point-max)))))
(save-excursion
(goto-char start)
(while (< (point) end)
(funcall fun (buffer-substring (line-beginning-position) (line-end-position)))
(forward-line 1))))
Update after your comment --
Now it sounds like you want to not enter a function name but hit a key, and have the command bound to that key be applied to each line in the region (or buffer).
Something like the following will do that. However, be aware that command often have particular behavior wrt lines. For example, if you were to hit key C-k (kill-lines) then it already moves forward after each line it kills. Because do-lines does not know what kind of function (command) you will invoke, it advances to the next line after each invocation. For a command such as kill-lines this will thus do the wrong thing: it will end up advancing two lines, not one, thus skipping lines. IOW, be aware that the code for do-lines cannot compensate for what a particular function it invokes might do that might not correspond to what you expect. Instead, it does what it says it does.
(defun do-lines (command &optional start end)
"Invoke COMMAND on the text of each line from START to END."
(interactive
(let* ((key (read-key-sequence-vector "Hit key sequence: "))
(cmd (lookup-key global-map key t)))
(when (numberp cmd) (error "Not a valid key sequence"))
(unless (commandp cmd) (error "Key `%s' is not defined" (key-description key)))
(if (use-region-p)
(list cmd (region-beginning) (region-end))
(list cmd (point-min) (point-max)))))
(setq start (copy-marker start)
end (copy-marker end))
(save-excursion
(goto-char start)
(while (< (point) end)
(funcall command (buffer-substring (line-beginning-position) (line-end-position)))
(forward-line 1))))
In some situations, you can use Emacs Repeating using C-x z following by more `z'. I was trying to comment all the lines in region and it worked nicely for my use case.
The command C-x z (repeat) provides another way to repeat an Emacs
command many times
To repeat the command more than once, type additional z’s: each z repeats the command one more time
In the spirit of TIMTOWTDI[1], I'll point out a technique that works well for some situations, including the one in the OP.
If you're looking to run an external command on a line of space-separated strings (like URLs):
Select the region
Invoke M-| (Alt+Shift+\, shell-command-on-region)
Use xargs as a prefix command to the desired command (e.g., xdg-open, or x-www-browser)
For example, the full command entered for step 3 might be:
xargs -n1 xdg-open
The -n1 switch causes xargs to open invoke the given program with one argument at a time; it will run the program once for each input. If the command can handle multiple arguments at once, you can omit -n1. For example, I have a web command that can open multiple URLs as arguments, so just xargs web works.
The major benefit of this approach is, it works on anything POSIX-compliant without doing anything in advance. Disadvantages include, it only works on external commands, and it requires xargs (not included with every OS by default).
[1] There's More Than One Way To Do It, originally from Perl, but useful elsewhere.
I'm new to elisp, so please forgive me if the following approach is totally clumsy.
In the team I'm currently working with, there is an usual convention of closing python blocks with a pass statement (if they aren't ended by closing keywords like else or except or such). While unusual, this has the advantage that one can always recover the original indentation of the program if it is unintentionally changed (using emacs indent-region).
To get existing code in line with this convention, I wrote a small elisp function:
(defun python-check-indent ()
"Check if automatic indentation changes current indent, insert pass keyword if it does."
(interactive)
(move-beginning-of-line 1)
(skip-chars-forward " ")
(if
(< 0
(let (original)
(setq original (point))
(indent-for-tab-command)
(- (point) original)
)
)
(progn
(insert "pass")
(newline)
(indent-for-tab-command)
)
)
(next-line)
)
(global-set-key (kbd "C-`") 'python-check-indent)
The idea is simply to test whether hitting TAB would change the indentation, and insert a pass statement in that case. To facilitate processing longer blocks of code, it then advances to the next line.
When I run it using M-x python-check-indent, it does what I want (except that it moves around empty lines slightly), also when running it repeatedly to process several lines. However, when I run it repeatedly using the C-` keybinding, it starts messing up the code from the second invocation on.
So here are my questions: What is the difference between invoking a command with M-x ... and using its keybinding? And how could I change the function to be not affected by this difference?
emacs-version: GNU Emacs 23.3.1 (x86_64-apple-darwin, NS apple-appkit-1038.35) of 2011-03-10 on black.porkrind.org
(edit) current workaround: I'm now wrapping it inside a keyboard-macro, so it's "bound" to C-x e, and behaves properly.
The general rule is that it is best to avoid complex interactive
commands in your functions because they could be affected by all sorts
of options.
(defun python-check-indent ()
"Check if automatic indentation changes current indent, insert pass keyword if it does."
(interactive)
(goto-char (line-beginning-position))
(skip-chars-forward " ")
(when (< 0
(let (original)
(setq original (point))
(python-indent-line)
(- (point) original)))
(insert "pass\n")
(python-indent-line))
(forward-line))
However, even this is probably not good because python-indent-line's behavior depends on last-command and python-indent-trigger-commands. I think it would be best if you replaced the first invocation of python-indent-line with the code which computes the target indentation instead of actually indenting, something like (nth python-indent-current-level python-indent-levels).
PS. If you still have problems, I suggest that you use edebug and step through the function.
What is the emacs equivalent of vi's dd? I want to delete the current line. Tried CTRL + k but it only deletes from current position.
C-a # Go to beginning of line
C-k # Kill line from current point
There is also
C-S-backspace # Ctrl-Shift-Backspace
which invokes M-x kill-whole-line.
If you'd like to set a different global key binding, you'd put this in ~/.emacs:
(global-set-key "\C-cd" 'kill-whole-line) # Sets `C-c d` to `M-x kill-whole-line`
If you want to delete a number of whole lines, you can prefix the command with a number:
C-u 5 C-S-backspace # deletes 5 whole lines
M-5 C-S-backspace # deletes 5 whole lines
C-u C-S-backspace # delete 4 whole lines. C-u without a number defaults to 4
C-u -5 C-S-backspace # deletes previous 5 whole lines
M--5 C-S-backspace # deletes previous 5 whole lines
Sometimes I also find C-x z helpful:
C-S-backspace # delete 1 whole line
C-x z # repeat last command
z # repeat last command again.
# Press z as many times as you wish.
# Any other key acts normally, and ends the repeat command.
In case you don't want to kill the line (which would put it into the OS clipboard and kill ring) but simply delete it:
(defun delete-current-line ()
"Delete (not kill) the current line."
(interactive)
(save-excursion
(delete-region
(progn (forward-visible-line 0) (point))
(progn (forward-visible-line 1) (point)))))
Another method to delete the line without placing it into the kill ring:
(defun delete-current-line ()
"Deletes the current line"
(interactive)
(delete-region
(line-beginning-position)
(line-end-position)))
This will leave the point at the beginning of a blank line. To get rid of this also, you may wish to add something like (delete-blank-lines) to the end of the function, as in this example, which is perhaps a little less intuitive:
(defun delete-current-line ()
"Deletes the current line"
(interactive)
(forward-line 0)
(delete-char (- (line-end-position) (point)))
(delete-blank-lines))
Rather than having separate key to delete line, or having to invoke
prefix-argument. You can use crux-smart-kill-line
which will "kill to the end of the line and kill whole line on the next
call". But if you prefer delete instead of kill, you can use the
code below.
For point-to-string operation (kill/delete) I recommend to use zop-to-char
(defun aza-delete-line ()
"Delete from current position to end of line without pushing to `kill-ring'."
(interactive)
(delete-region (point) (line-end-position)))
(defun aza-delete-whole-line ()
"Delete whole line without pushing to kill-ring."
(interactive)
(delete-region (line-beginning-position) (line-end-position)))
(defun crux-smart-delete-line ()
"Kill to the end of the line and kill whole line on the next call."
(interactive)
(let ((orig-point (point)))
(move-end-of-line 1)
(if (= orig-point (point))
(aza-delete-whole-line)
(goto-char orig-point)
(aza-delete-line))))
source
The fastest/simplest way to delete (kill) a full line, from any point
on the line, without selecting anything, is:
C-w ; kill-region
It is versatile in deleting whatever is selected, or a line by default
if nothing is selected.
Given the question, you're probably also interested in replicating
Vim's "yank", yy (though in Emacs parlance a "yank" is confusingly
Vim's "put", p). This is:
M-w ; kill-ring-save
Nice and congruent, and pretty easy to remember. Even slightly
similar to Vim's i_CTRL-W.
Once you've put something in the kill ring with either of the above,
you'll likely want to "yank" (paste) it:
M-y ; yank-pop
(Note that C-S-backspace may not work in terminal Emacs.)
Install package whole-line-or-region and then run (whole-line-or-region-global-mode). This will make C-w kill the whole line if no region (selection) is active.
See the Package's GitHub page https://github.com/purcell/whole-line-or-region
When I hit C-k, Emacs kills to end-of-line. When I hit C-k again, it "kills the newline" and brings the next line up. However, the next line's indentation remains intact, and you can end up with a line that has lots of spaces in the middle.
So, from this:
previous line material
next line material
to this:
previous line material next line material
I understand I can use M-^ to join lines properly, but that requires the cursor to be on the next line. How do I modify C-k so that when it kills the newline, also kills the next line's indentation?
For C-k I don't know, but you could use the just-one-space function to transform any number of space into juste one space (it's bound on M-space)
If you give M-^ an argument (for example C-u M-^), it will join the next line to the current line.
Here's a way to plug in the behavior (I think) you want into kill-line: when killing a newline, also kill the indentation that follows. Note that this may result in no space being present after the cursor, which is why I think I'd go with M-1 M-^ or C-k M-SPC instead.
(defadvice kill-line (around kill-indentation
activate compile)
"When killing a line break, also kill any subsequent indentation."
(let ((f-v-l (symbol-function 'forward-visible-line)))
(flet ((forward-visible-line (arg)
(funcall f-v-l arg)
(skip-chars-forward " \t")))
ad-do-it)))
I have this in my .emacs:
(defun pull-line ()
"Pull the next line that contains anything up to the end of this one"
(interactive)
(save-excursion
(end-of-line)
(while (looking-at "[ \n\r\t]")
(delete-char 1))
(if (looking-back "^[[:blank:]]*[[:punct:][:alnum:]].*")
(fixup-whitespace)
(indent-according-to-mode))))
(global-set-key "\C-cp" 'pull-line)
It pulls the next non-blank line up to the this one, and if there is anything on this line it makes calls (fixup-whitespace) which does the right thing about 95% of the time, otherwise it indents it to what emacs thinks is the right level. I think I copied the concept from vim?
I use it all the time, anyway.
I just realized I also have this in my .emacs, it is more exactly what you want, although I forget that I have it since I use pull-line much more often. I think I stole this from emacswiki:
(defun kill-and-join-forward (&optional arg)
"If at end of line, join with following; otherwise kill line.
Deletes whitespace at join."
(interactive "P")
(if (and (eolp) (not (bolp)))
(progn
(delete-indentation t)
(if (looking-at " $")
(delete-char 1)))
(kill-line arg)))
(global-set-key "\C-k" 'kill-and-join-forward)
This will do it:
(defun my-kill-line (&optional arg)
(interactive "P")
(if arg
(kill-line arg)
(when (prog1 (eolp) (kill-line))
(just-one-space 1))))
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
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).
be able to yank any text...
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.
Here's my humble solution:
(defun my-insert-before-line ()
(interactive)
(save-excursion
(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)))
Hope it helps.
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.
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 :-)