How to attach character to the next N lines using Emacs? - emacs

Using emacs24 I'd like to attach for example # at the beginning of the next five lines.
So having this:
Line1
line2
line3
get this:
#Line1
#line2
#line3
for the number of lines that I specify. How can I do that? Thanks!

While there may be something built in to Emacs that does this, and you can certainly write a little Lisp to get it done, I would usually use "rectangular editing" features to get this done. Imagine that the buffer contains the following, with . representing the point (where your cursor is)
.Line1
line2
line3
Set the mark
Press C-n twice. This is the state of the buffer now:
Line1
line2
.line3
Press C-x r t.
Type #.
Press enter.
I would find this much more natural than entering a value for the number of times to repeat a command, because you can visually select the lines you want to edit. YMMV
Edit
Here's how to do this using a bit of Emacs Lisp. Note that although I've been using Emacs for a few years now, I only recently began learning how to actually use Emacs Lisp, so this code might not be that great! It does get the job done.
(defun insert-n-times (s n)
(interactive "Mstring:\nNtimes:")
(while (> n 0)
(insert s)
(goto-char (- (point) 1))
(next-line)
(setq n (- n 1))))
Use it by doing the following: M-x insert-n-times RET <type a string> RET <type a number>

Another method is using macro to get such repetitive work done. Here is a page that describes how to use macros in Emacs. You can have a look at it if you are not familiar with it.
In your case, the following keys would work:
Move the cursor to the beginning of Line1
C-x (
Type a '#'
C-n, then C-a
C-x )
Move the cursor to the line to the beginning of which you want to add '#'
C-u 10 C-x e
Basically, step 2-5 will record a macro which will add a # at the beginning, and then move to the beginning of the next line. Step 6-7 will execute the macro 10 times (of course, you can change it to arbitrary number). I guess this will be quite a lot of keystrokes and newbies may not like it. Maybe others have better solutions.

Line1
line2
line3
I wrote the following code:
You first give a digit argument (the amount of times you want to do this), e.g. M-3 (hold alt, hit 3), to do the following 3 times
Either use a key for it, like a suggestion below (f8), or use M-x prompt-for-insert
It will ask you for a string to enter. e.g. "foo" and hit return button.
It will then do as you ask.
(defun prompt-for-insert (val)
(interactive "P")
(let ((astring (read-string "What do you want to insert?"))
(value val))
(while (> value 0)
(insert astring)
(move-beginning-of-line 2)
(decf value)))
)
(global-set-key [f8] 'prompt-for-insert)
The whole sequence will then be:
M-3 [f8] foo RET
Resulting in:
fooLine1
fooline2
fooline3

Why not just query-replace-regexp or replace-regexp? E.g. select the region and do C-M-%^RET#RET!

Try M-x string-insert-rectangle. This command inserts a string on every line of the rectangle.

While comment-region is good in this specific example, check out the multiple-cursors package for a very powerful way to do this kind of thing in general.
You can just hit C-> repeatedly until you have a cursor at the beginning of each line, then hit # and you're done (C-g to get rid of the extra cursors.)
It's a much more interactive form of C-x r t and works with non-rectangular regions too (after a C-s for example.)

Related

repeat macro after error stops execution

My objective is to remove duplicated stanzas in xml files. I am sure I have a duplicated stanza if the first line of the stanza is found multiple times in the file.
I have created a macro that finds the first line of my stanzas through interactive search, then Ctrl-S again to go to the next occurrence. If found, I then mark the section I want to delete and delete it. My macro terminates here.
If my Ctrl-s does not find the next occurrence, my macro stops, which is exacly what I want it to do. However, when I Esc 1000 Ctrl-x e to execute my macro multiple times, when the error is found also the 1000 cycle stops. I am happy for the macro to stop, but I want to execute it again after the error. Is this possible? Or is there already a macro somewhere to remove duplicates stanzas or groups of lines from a file?
My macro:
C-s ;; isearch-forward
<Conduit ;; self-insert-command * 8
SPC ;; self-insert-command
6*C-w ;; kill-region
C-s ;; isearch-forward
C-a ;; beginning-of-line
C-SPC ;; set-mark-command
C-s ;; isearch-forward
< ;; self-insert-command
/ ;; nxml-electric-slash
Conduit> ;; self-insert-command * 8
<right> ;; forward-char
C-w ;; kill-region
Thanks
Joe
Hmm. It would be nice if Emacs provided a convenient interactive way to handle error conditions inside keyboard macros, but I suspect juanleon's answer might be your best bet at present.
A workaround in general is to not use C-s, but instead use something like M-: (search-forward "foo" nil t) RET to search for "foo" without triggering an error if it's not there. In this example there would be more to it, though.
For one-off processing, what I tend to do in these kinds of situation is generate a buffer of the results I'm interested in, and then process that with the keyboard macro.
This example is actually a bit tricky, but you could occur all the lines matching the pattern, pipe through sort | uniq --all-repeated=separate, and then eliminate the first line of each group. That leaves you with a the exact number of instances you wish to remove for each duplicate, so your keyboard macro could grab a line from that list, find the last instance of it in the original buffer, delete it, and move to the next line in the list.
If this is a common activity, a custom elisp function would seem like the way to go.
If what you want to achieve is to run a macro repeatedly regardless of errors, this would be a way to do it:
(defun repeat-macro-until-abort ()
(interactive)
(while t
(ignore-errors
(kmacro-call-macro 0))))
It will run your last macro until you hit C-g. Please notice that it won't be stopped even by reaching end-of-buffer.
There is a easy way to remove lines that match a regexp: M-x flush-lines
If you know the regexp for the stanza you want to remove, you can type C-M-% <your-regexp> RET RET and you witll iterate over the occurences chosing what to remove (type ! for removing every of them). C-M-% is the default keybinding for query-replace-regexp.

A quick way to repeatedly enter a variable name in Emacs?

I was just typing in this sort of code for Nth time:
menu.add_item(spamspamspam, "spamspamspam");
And I'm wondering if there's a faster way to do it.
I'd like a behavior similar to yasnippet's mirrors, except
I don't want to create a snippet: the argument order varies from
project to project and from language to language.
The only thing that's constant is the variable name that needs to be
repeated several times on the same line.
I'd like to type in
menu.add_item($,"")
and with the point between the quotes, call the shortcut and start typing,
and finally exit with C-e.
This seems advantageous to me, since there's zero extra cursor movement.
I have an idea of how to do this, but I'm wondering if it's already done,
or if something better/faster can be done.
UPD The yasnippet way after all.
Thanks to thisirs for the answer. This is indeed the yasnippet code I had initially in mind:
(defun yas-one-line ()
(interactive)
(insert "$")
(let ((snippet
(replace-regexp-in-string
"\\$" "$1"
(substring-no-properties
(delete-and-extract-region
(line-beginning-position)
(line-end-position))))))
(yas/expand-snippet snippet)))
But I'm still hoping to see something better/faster.
yasnippet can actually be used to create a snippet on-the-fly:
(defun yas-one-line ()
(interactive)
(let ((snippet (delete-and-extract-region
(line-beginning-position)
(line-end-position))))
(yas-expand-snippet snippet)))
Now just type:
menu.add_item($1,"$1")
and call yas-one-line. The above snippet is expanded by yasnippet!
You could try
(defvar sm-push-id-last nil)
(defun sm-push-id ()
(interactive)
(if (not sm-push-id-last)
(setq sm-push-id-last (point))
(text-clone-create sm-push-id-last sm-push-id-last
t "\\(?:\\sw\\|\\s_\\)*")
(setq sm-push-id-last nil)))
after which you can do M-x sm-push-id RET , SPC M-x sm-push-id RET toto and that will insert toto, toto. Obviously, this would make more sense if you bind sm-push-id to a convenient key-combo. Also this only works to insert a duplicate pair of identifiers. If you need to insert something else, you'll have to adjust the regexp. Using too lax a regexp means that the clones will tend to overgrow their intended use, so they may become annoying (e.g. you type foo") and not only foo but also ") gets mirrored on the previous copy).
Record a macro. Hit F3 (or possibly C-x (, it depends) to begin recording. Type whatever you want and run whatever commands you need, then hit F4 (or C-x )) to finish. Then hit F4 again the next time you want to run the macro. See chapter 17 of the Emacs manual for more information (C-h i opens the info browser, the Emacs manual is right at the top of the list).
So, for example, you could type the beginning of the line:
menu.add_item(spamspamspam
Then, with point at the end of that line, record this macro:
F3 C-SPC C-left M-w C-e , SPC " C-y " ) ; RET F4
This copies the last word on the line and pastes it back in, but inside of the quotes.

emacs equivalent of ct

looking for an equivalent cut and paste strategy that would replicate vim's 'cut til'. I'm sure this is googleable if I actually knew what it was called in vim, but heres what i'm looking for:
if i have a block of text like so:
foo bar (baz)
and I was at the beginning of the line and i wanted to cut until the first paren, in visual mode, I'd do:
ct (
I think there is probably a way to look back and i think you can pass more specific regular expressions. But anyway, looking for some emacs equivalents to doing this kind of text replacement. Thanks.
Here are three ways:
Just type M-dM-d to delete two words. This will leave the final space, so you'll have to delete it yourself and then add it back if you paste the two words back elsewhere.
M-z is zap-to-char, which deletes text from the cursor up to and including a character you specify. In this case you'd have to do something like M-2M-zSPC to zap up to and including the second space character.
Type C-SPC to set the mark, then go into incremental search with C-s, type a space to jump to the first space, then C-s to search forward for the next space, RET to terminate the search, and finally C-w to kill the text you selected.
Personally I'd generally go with #1.
as ataylor said zap-to-char is the way to go, The following modification to the zap-to-char is what exactly you want
(defun zap-up-to-char (arg char)
"Like standard zap-to-char, but stops just before the given character."
(interactive "p\ncZap up to char: ")
(kill-region (point)
(progn
(search-forward (char-to-string char) nil nil arg)
(forward-char (if (>= arg 0) -1 1))
(point))))
(define-key global-map [(meta ?z)] 'zap-up-to-char) ; Rebind M-z to our version
BTW don't forget that it has the ability to go backward with a negative prefix
That sounds like zap-to-char in emacs, bound to M-z by default. Note that zap-to-char will cut all the characters up to and including the one you've selected.

Emacs: adding 1 to every number made of 2 digits inside a marked region

Imagine I've got the following in a text file opened under Emacs:
some 34
word 30
another 38
thing 59
to 39
say 10
here 47
and I want to turn into this, adding 1 to every number made of 2 digits:
some 35
word 31
another 39
thing 60
to 40
say 11
here 48
(this is a short example, my actual need is on a much bigger list, not my call)
How can I do this from Emacs?
I don't mind calling some external Perl/sed/whatever magic as long as the call is made directly from Emacs and operates only on the marked region I want.
How would you automate this from Emacs?
I think the answer I'm thinking of consist in calling shell-command-on-region and replace the region by the output... But I'm not sure as to how to concretely do this.
This can be solved by using the command query-replace-regexp (bound to C-M-%):
C-M-%
\b[0-9][0-9]\b
return
\,(1+ \#&)
The expression that follows \, would be evaluated as a Lisp expression, the result of which used as the replacement string. In the Lisp expression, \#& would be replaced by the matched string, interpreted as a number.
By default, this works on the whole document, starting from the cursor. To have this work on the region, there are several posibilities:
If transient-mark-mode is turned on, you just need to select the region normally (using point and mark);
If for some reason you don't like transient-mark-mode, you may use narrow-to-region to restrict the changes to a specific region: select a region using point and mark, C-x n n to narrow, perform query-replace-regexp as described above, and finally C-x n w to widen. (Thanks to Justin Smith for this hint.)
Use the mouse to select the region.
See section Regexp Replacement of the Emacs Manual for more details.
Emacs' column editing mode is what you need.
Activate it typing M-x cua-mode.
Go to the beginning of the rectangle (leave cursor on character 3) and press C-RET.
Go to the end of the rectangle (leave cursor on character 7). You will be operating on the highlighted region.
Now press M-i which increments all values in the region.
You're done.! remove dead ImageShack links
It doesn't protect against 99->100.
(defun add-1-to-2-digits (b e)
"add 1 to every 2 digit number in the region"
(interactive "r")
(goto-char b)
(while (re-search-forward "\\b[0-9][0-9]\\b" e t)
(replace-match (number-to-string (+ 1 (string-to-int (match-string 0)))))))
Oh, and it operates on the region. If you want the entire file, then you replace b and e with (point-min) and nil.
Moderately tested; use M-: and issue the following command:
(while (re-search-forward "\\<[0-9][0-9]\\>" nil t) (let ((x (match-string 0))) (delete-backward-char 2) (insert (format "%d" (1+ (string-to-int x))))))
I managed to get it working in a different way using the following (my awk-fu ain't strong so it probably can be done in a simpler way):
C-u M-x shell-command-on-region RET awk '$2>=0&&$2<=99 {$2++} {print}' RET
but I lost my indentation in the process : )
Seeing all these answers, I can't help but have a lot of respect for Emacs...

How to get Emacs to unwrap a block of code?

Say I have a line in an emacs buffer that looks like this:
foo -option1 value1 -option2 value2 -option3 value3 \
-option4 value4 ...
I want it to look like this:
foo -option1 value1 \
-option2 value2 \
-option3 value3 \
-option4 value4 \
...
I want each option/value pair on a separate line. I also want those subsequent lines indented appropriately according to mode rather than to add a fixed amount of whitespace. I would prefer that the code work on the current block, stopping at the first non-blank line or line that does not contain an option/value pair though I could settle for it working on a selected region.
Anybody know of an elisp function to do this?
Nobody had what I was looking for so I decided to dust off my elisp manual and do it myself. This seems to work well enough, though the output isn't precisely what I asked for. In this version the first option goes on a line by itself instead of staying on the first line like in my original question.
(defun tcl-multiline-options ()
"spread option/value pairs across multiple lines with continuation characters"
(interactive)
(save-excursion
(tcl-join-continuations)
(beginning-of-line)
(while (re-search-forward " -[^ ]+ +" (line-end-position) t)
(goto-char (match-beginning 0))
(insert " \\\n")
(goto-char (+(match-end 0) 3))
(indent-according-to-mode)
(forward-sexp))))
(defun tcl-join-continuations ()
"join multiple continuation lines into a single physical line"
(interactive)
(while (progn (end-of-line) (char-equal (char-before) ?\\))
(forward-line 1))
(while (save-excursion (end-of-line 0) (char-equal (char-before) ?\\))
(end-of-line 0)
(delete-char -1)
(delete-char 1)
(fixup-whitespace)))
In this case I would use a macro. You can start recording a macro with C-x (, and stop recording it with C-x ). When you want to replay the macro type C-x e.
In this case, I would type, C-a C-x ( C-s v a l u e C-f C-f \ RET SPC SPC SPC SPC C-x )
That would record a macro that searches for "value", moves forward 2, inserts a slash and newline, and finally spaces the new line over to line up. Then you could repeat this macro a few times.
EDIT: I just realized, your literal text may not be as easy to search as "value1". You could also search for spaces and cycle through the hits. For example, hitting, C-s a few times after the first match to skip over some of the matches.
Note: Since your example is "ad-hoc" this solution will be too. Often you use macros when you need an ad-hoc solution. One way to make the macro apply more consistently is to put the original statement all on one line (can also be done by a macro or manually).
EDIT: Thanks for the comment about ( versus C-(, you were right my mistake!
Personally, I do stuff like this all the time.
But I don't write a function to do it unless I'll be doing it
every day for a year.
You can easily do it with query-replace, like this:
m-x (query-replace " -option" "^Q^J -option")
I say ^Q^J as that is what you'll type to quote a newline and put it in
the string.
Then just press 'y' for the strings to replace, and 'n' to skip the wierd
corner cases you'd find.
Another workhorse function is query-replace-regexp that can do
replacements of regular expressions.
and also grep-query-replace, which will perform query-replace by parsing
the output of a grep command. This is useful because you can search
for "foo" in 100 files, then do the query-replace on each occurrence
skipping from file to file.
Your mode may support this already. In C mode and Makefile mode, at least, M-q (fill-paragraph) will insert line continuations in the fill-column and wrap your lines.
What mode are you editing this in?