1

How can string-rectangle or C-xrt convert

aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1
aRandomText_-1

into this?

aRandomText_0
aRandomText_1
aRandomText_2
aRandomText_3
aRandomText_4
aRandomText_5
aRandomText_6
aRandomText_7
aRandomText_8
aRandomText_9
aRandomText_10
aRandomText_11
aRandomText_12
aRandomText_13
aRandomText_14
aRandomText_15

One can write the above from scratch with eval-expression (M-:) and then (dotimes (i 16) (insert (format "aRandomText_%d\n" i))), but how can you do it on an existing (rectangle of) text?

Also, how can you do this when using letters?

aRandomText_a
aRandomText_b
aRandomText_c
etc.
2
  • An alternative solution is using multiple-cursors. You mark each line and use the function mc/insert-numbers to insert incrementing numbers at every cursor. May 19, 2015 at 17:43
  • 1
    Have you tried this [solution][1]? [1]: stackoverflow.com/a/29845549/4780877
    – Emacs User
    May 19, 2015 at 17:45

3 Answers 3

1

You can do this with replace-regexp

In your replacement you have access to which Nth replacement is running.

This is from the docs:

In interactive calls, the replacement text can contain \, followed by a Lisp expression. Each replacement evaluates that expression to compute the replacement string. Inside of that expression, \& is a string denoting the whole match as a string, \N for a partial match, \#& and \#N for the whole or a partial match converted to a number with string-to-number, and \# itself for the number of replacements done so far (starting with zero).

So you could mark your text and run replace-regexp replacing _-1 with _\,\# and you would get _0, _1, ... _N.

In short, mark your text and then do this:

M-xreplace-regexpenter _-1 enter _\,\# enter

You can use the \, construct in the replacement to run any code you want which you could use to add increasing characters.

Here is a demo of doing characters for up to 26 entries.

enter image description here

This answer has an example of a more advanced usage of the function:

How can I modify a variable in a javascript file that meets specific conditions?

11
  • _\,\# is for numbers, what about letters (a,b,c,...)?
    – Blaz
    May 19, 2015 at 18:36
  • 1
    \# is just evaluated to a given number, so you can use it however you want in an expression: If your replacement regexp was _\,(string (+ \# ?a)) it would evaluate to a, b, c... z. May 19, 2015 at 18:48
  • I have added an example for reference. May 19, 2015 at 18:53
  • How do you get autosuggestions for M-x, as seen in your screencast as you type 'repregexp'?
    – Blaz
    May 20, 2015 at 5:59
  • 1
    I use the smex package. You can install it and rebind M-x to smex to get that kind of completion. May 20, 2015 at 12:15
1

Similar to this question: Add a constant decimal value to a column of numbers you could do this with Calc.

  1. Calculate the number of rows you need (just look at the modeline while the point is at the last row), let than number be N.
  2. C-x * c starts Calc.
  3. v xNRET creates a vector of length N and populates it with numbers 1..N.
  4. v u unpacks the vector.
  5. Select the entire stack and C-x r r1 - copies the selected rectangle to the register 1.
  6. Return to the buffer with your text, remove the -1 bit, by, for example, making a rectangular selection and C-x r k.
  7. Move the point to the end of the first line and press C-x r i1 - this will paste the rectangle stored in the register 1 in place of the (previously removed) column of -1.

There's also a way to do this with Org table (the data you are trying to arrange does look like a table, so why not use something more specialized for it?).

  1. M-xorg-mode.
  2. Place point in the beginning of the buffer, C-SPC, move it to the beginning of the last line, C-x r t|.
  3. In a similar way replace the column of -1 with a ||.
  4. TAB on the table to align.
  5. Add #+tblfm: $2=@#-1 after the table, the result will look like this:

    | aRandomText |  0 |
    | aRandomText |  1 |
    | aRandomText |  2 |
    | aRandomText |  3 |
    | aRandomText |  4 |
    | aRandomText |  5 |
    | aRandomText |  6 |
    | aRandomText |  7 |
    | aRandomText |  8 |
    | aRandomText |  9 |
    | aRandomText | 10 |
    | aRandomText | 11 |
    | aRandomText | 12 |
    | aRandomText | 13 |
    | aRandomText | 14 |
    | aRandomText | 15 |
    #+tblfm: $2=@#-1
    
1

It's not a rectangle-based answer, so if you're not tied to that, you could do this using an Emacs macro and the macro counter.

Inserting numbers

So record a macro:

C-x ( C-e <DEL> C-x C-k C-i C-n C-x e

And continue running it until you hit the end of the area you want to change by pressing e.

Let me break down the macro definition, because it's confusing:

C-x ( -- start the macro recording

C-e <DEL> -- go to the end of the line, and delete the 1 there.

C-x C-k C-i -- call #'kmacro-insert-counter, which will start the macro counter and insert its number. This gives you the state tracking of "which number gets inserted next?"

C-n -- go to the next line.

C-x e -- end recording the macro, and run it again. You can now repeat the macro just by pressing e.

Inserting characters

If you want to insert characters instead, we need to set the format string the macro uses to insert the counter. We can do that with kmacro-set-format, which is bound to C-x C-k C-f. So tell it to print the integer as a character:

C-x C-k C-f %c <RET>

Note that the macro counter format string is global; it's shared for other macros. So if you want to make another macro that inserts numbers, you have to reset it. You can do that again, with C-x C-k C-f <RET>. This resets the value to the default, which is %d. But if we instead set the format string inside the definition of the macro, it won't affect other macros. So we're left with this as the macro definition:

C-x (  C-x C-k C-f %c <RET>  C-e <DEL> C-x C-k C-i C-n C-x e
start | set the macro's     | the macro body
macro | format string       | as above     

So now we'll get something that inserts characters, but they're not the right ones; we'll get characters like ^@ ^A ^B and so forth, because those are the characters corresponding to the ASCII codes starting at 0. We need to start the macro's counter not at 0, but at the code for the character a.

Now, that character happens to be 97, so let's set that using kmacro-set-counter:

C-x C-k C-c 97 <RET>

And let's put the whole thing together. There's nothing new here, so instead of fully annotating it, I've just noted what the parts are doing. You can do them separately. Here it is:

C-x C-k C-c 97 <RET>  C-x (  C-x C-k C-f %c <RET>  C-e <DEL> C-x C-k C-i C-n C-x e
 set the macro's    | start | set the macro's     | the macro body
 counter value      | macro | format string       | as above

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.