fastest way to insert lines repeatedly? - text-editor

What I am trying to do is add #ifdef and #endif before and after of puts.
There are hundreds of puts in the code. The string inside of puts is different in each case. I'm working on this problem with text editors like vim and sublime text 2.
Is there a smarter way of doing such task?
#ifdef SOMETHING
puts("blah blah blah"); ========> puts("blah blah blah");
#endif

Sublime Text:
AFAIR you could use multiple cursors functionality in ST like:
">find_all<, puts, then ctrl+shift+l (or something like that which will give you individual cursor for each highlighted line), then go type required modifications (which will do exact same movement/typing for each line)"
Of course it wouldn't work that well with different indentation and stuff, im afraid...
VIM:
In substitute it should look more or less like this:
:%s/puts(.\{-});/#ifdef SOMETHING\n &\n#endif/g
(though im not sure if something wouldn't need escaping here)
basically it means:
% - for whole file
s - substitute
/first_part/second_part/ - substitute occurence of first_part with second_part
g - globally - meaning for each line found among % (whole file)
and first part is:
normal: 'puts(', then non-greedy (if you don't know what that mean - google for it, really worth to know) regex for any character, then normal: ');' which should match your puts'
and second:
normal: '#ifdef SOMETHING', then newline, then four spaces, then & which means 'found pattern' (basically this puts of yours), then newline, then normal: '#endif'
I wrote it of top of my head so please take into account that some things may need correction (shortcuts in ST or escaping some characters in substitute formula).
Thanks for understanding

Related

Editing multiple lines of same parameter

I'm working with a large dataset and multiple lines need change on a certain parameter. Something like this for example:
funct(35, circle, square, triangle);
funct(42, sphere, cube, prism);
funct(74, disc, rhombus, rectangle);
needs to become:
funct(35, circle, my_square, other_triangle);
funct(42, sphere, my_cube, other_prism);
funct(74, disc, my_rhombus, other_rectangle);
How could I go about doing this?
An additional vim approach. Visually select all of the lines you would like to change, and then type this:
:norm 2Wimy_<C-v><esc>Wiother_
Note that <C-v> and <esc> are ctrl-v and esc, not text. Or, if you want to do this on every line, do this:
:%norm 2Wimy_<C-v><esc>Wiother_
You could also do this on lines in a certain range. For example, lines 3-100:
:3,100norm 2Wimy_<C-v><esc>Wiother_
I'll speak about emacs because I just love emacs !
to enter commands in the prompt : Alt + x
For small datasets
You can install the multiple-cursors package. It's like the Ctrl+D in SublimeText. Here is the doc.
For big datasets with some controls
You can use built-in package query-replace. It will replace the string/regex you want with another. Documentation.
The advantage of this one is that you can choose if you want to replace or not each occurence.
For big datasets without control
The built-in packages replace-string and replace-regexp will replace the pattern of your choice with a string or another pattern.
replace-regexp
replace-string
If you just want to rename some variables, multiples-cursors, replace-string and query-replace are fine.
If you want to replace patterns in huge datasets, replace-regexp is fun, but nothing's better than a script (bash, js, python ...).
There are amazing books about sed and awk bash commands (sed & awk, 2nd Edition)
With Vim:
:%s/\vfunct\(([^,]+,\s*){2}\zs/my_/
The 2 above is the number of arguments you want to skip.
The catch: this breaks if some parameters are themselves function calls. There are plugins that allows you to cope with that situation.
Using vim's regex engine:
:%s/\v(%(\s*\w+,){PARAMETER_NUMBER})(\s+)(\w+)/\1\2NEW_PREFIX\3
Substitute PARAMETER_NUMBER with the index (starting from 0) of the parameter you'd like to change and NEW_PREFIX with the prefix you'd like to add to it.
For instance, running:
:%s/\v(%(\s*\w+,){2})(\s+)(\w+)/\1\2my_\3
Changes your example code into:
funct(35, circle, my_square, triangle);
funct(42, sphere, my_cube, prism);
funct(74, disc, my_rhombus, rectangle);
You can modify this to customize it in other ways by changing the order of the backreferences (the \1, \2 and \3) at the end of the command. \1 refers to the parameters before the one you're changing, \2 refers to the whitespace just before the parameter you're changing and \3 to the parameter itself.
I'm aware of multiple-cursors, and they look really cool, but I've been to lazy to learn them. Here's a solution using only Emacs built ins.
(defun align-regexp-comma (beginning end)
"Align columns using comma as a delimiter."
(interactive "*r")
(align-regexp beginning end
",\\(\\s-*\\)" 1 1 t))
(global-set-key (kbd "C-<return>") 'cua-rectangle-mark-mode)
Then select the region you of interest, do M-x align-regexp-comma, which should align the arguments, then you can use C-<return> to start the rectangle mark, which lets you edit several lines at once. If you then want to remove the aligning spaces, use query-regexp-replace (M-%) with ", +" -> ", ".

Yank column number in Vim

I'd like to be able to easily make pretty code titles in vim, by making a macro. I'd like them to like something like this:
################################################################################
### Preamble ###
################################################################################
To make these I'd like to start with a line with just:
Preamble
Then the macro will make the surrounding hashes and spaces. To do this, I need to somehow yank the number for characters in the title. So in the case of preamble; I'd like to copy 8, its length, to some register.
Any ideas how to do this?
Instead of counting the length, I would paste using Replace mode, as #FDinoff said. First, yank the following line into a register, for example the t register: "tyy
### ###
Next, grab the Preamble line without the endline: 0vg_d
Then, paste our line from t and move to the appropriate spot: "tP4l
Finally, paste Preamble using Replace mode: RCtrl+r"
I would not recommend this style, as it's maintenance requires high(er) effort (and not everybody is using a powerful editor like Vim, or has your macros), but you can do this with the strdisplaywidth() function:
:echo strdisplaywidth(getline('.'))
Older Vim versions don't have this; strlen() is a replacement that will only handle normal ASCII letters.
Oh, and before you ask, you can create the header lines with repeat('#', num)

Delete all lines until line that starts with dashes

I use Vim to edit my e-mails and what I do like hundred times a day is to delete all the quoted lines until my signature starts:
Some my text and the caret _
> Some other quoted text I want to get rid of
> Blah blah
--
My signature
What I always do is jVjjjjjjd or something similar.
I would like to be more efficient in this and delete everything until the double dashes. Unfortunately df- works only on the current line and I would like to specify regexp like "^--".
How to do that? Thanks!
How about d/^--? (That is, delete everything from the caret position until the first hit of a search for "--" at the start of a line.)
My mail_movement plugin defines motions to go to quoted blocks and corresponding text objects. With it, deleting a quoted block is as simple as daq (delete a quote).

What is the use case of marks?

Both Sublime Text 2 and VIM have a feature called marks. However, I've not been able to find a use case for it. It feels like everything you can do with it can also be done with other things, often even better.
So the question is: what is the use case of marks?
If you mean marking text lines as in vim, I use it quite a bit.
For example, if you want to quickly go look at something else, you can use ma to mark the current line as a, then go check out something else in the file, then return to where you were with a simple 'a.
Similarly, if you want to delete an unknown number of lines between your current position and somewhere else, use ma, go to that "somewhere else, and just use d'a.
There are many more things you can do with them (such as changing text between your current position and a mark), those two are just the most common ones I use (and I use them a lot).

Remove command with matching braces

I'm using (mac)vim with tex-suite and would like to have a single regex command (or any other way) to do the following thing:
Change
\textcolor{green}{some random text}
into
some random text
This should be done for all occurrences of \textcolor{green}{} in my tex file...
Any idea?
EDIT: I need it to recognize matching braces. Here an example :
\textcolor{green}{
with $v_\text{F}\sim10^6$m.s$^{-1}$ the massless Dirac fermions
velocity in pristine graphene}.
In my experience, things like this most often crop up during editing, and you might have the search for \textcolor{green}{ already highlighted.
In such a scenario, :global is usually my weapon of choice:
:g//norm d%diBvaBp
diBvaBp: diB (delete inner block), vaB (select block), p (put)
If you have surround.vim installed (recommend it!) you could remove the pair of braces simply doing dsB (delete surrounding {})
:g//norm d%dsB
Of course, you can combine it like
:g/\\textcolor{green}{/norm d%dsB
I just noted a potential issue when the target patterns don't start at the beginning of a line. The simplest way to get around that is
:g//norm nNd%diBvaBp
A more involved way (possibly less efficient) would be using a macro:
/\\textcolor{green}{
gg
qqd%diBvaBpnq
Followed by something like 100#q to repeat the macro
:%s,\\textcolor{green}{\([^}]\+\)},\1,g
Updated as per your updated question:
:%s,\\textcolor{green},\r-HUUHAA-&,g
:g/\\textcolor{green}/normal 0f\df}lvi{xhP$xx
:%s/\n-HUUHAA-//
Quick explanation of how it works:
Put all \textcolor{green} lines onto a line of their own, with 'special' marker -HUUHAA-
Use visual selection vi{ to select everything in between the {}, paste it outside and delete the now empty {}.
Delete leftover stuff including the marker.

Resources