vim how to cut text and insert into a new line - vim

I want to do this:
1 printf("hello world\n");
2 bool func() //I want to cut the comment and insert between line 1 and line 2
3 {
4 //to do
5 }
And, I want to cut the comment after // and to insert between line 1 and line 2. As I know, by using Ctrl+v, vim is transformed into VISUAL mode, and you can select the text, and by pressing d, you can cut the text, but How can I insert the text that be cutted and insert into a new line? Is there any command?
And I think after cutting the text, and you can press o and press esc and press p to paste, but it seems to tedious. Are there any better command?
Thank you in advance!

If you want to save keystrokes you can insert the " register in insert mode by using <c-r>".
Also you can delete from the cursor to the end of the line with D, which places the deleted section in the " register.
So if your cursor was on the first character of the comment you can use
DO<c-r>"
to transfrom
printf("hello world\n");
bool func() //I want to cut the comment and insert between line 1 and line 2
{
//to do
}
Into
printf("hello world\n");
//I want to cut the comment and insert between line 1 and line 2
bool func()
{
//to do
}
All you have to do is clean up the trailing white space after func().
Take a look at :help i_CTRL-R to learn more about <c-r> in insert mode.

Another solution beside the one suggested by FDinoff:
D at the first slash(cuts the comment until end of line)
And run:pu! (put the content above the current line.)

Related

How to insert original line number in g/pattern/move

vim: insert original line number in g/pattern/move $
I'm debugging some event order in a log and like to check two set of events sequence by the line number of the showing log. Usually, I used g/pattern/move $ for some interesting info. But I cannot find a way to insert the original line number of them. Please help.
I tried :
g/pattern/move $; printf("%d",line("."))
but it does not work.
Can't help thinking of something very straightforward, for example:
g/pattern/call append(line('$'), line('.') . ' ' . getline('.'))
A slightly different way but I have following mapping in my _vimrc
nnoremap <F3> :redir! #f<cr>:silent g//<cr>:redir! END<cr>:enew!<cr>:put! f<cr>:let #f=#/<cr>:g/^$/d<cr>:let #/=#f<cr>gg
It opens a new buffer with all your search matches, including the linenumbers where the match occured.
I have figured out a way to insert at first the line number on the lines that have the pattern and after that moving the same lines to the end of the file:
:%s,\v^\ze.*pattern,\=line('.') . ' ' ,g | g/pattern/m$
We have two commands:
:%s,\v^\ze.*pattern,\=line('.') . ' ' ,g
, ....................... we are using comma as delimiter
\v ...................... very magic substitution
^ ....................... Regular expression for beginning of line
\ze ..................... indicates that all after it will not be substituted
\=line('.') ............. gets the line number
. ' ' .................. concatenates one space after the number
The second command is separated with |
g/pattern/m$
m$ ....................... moves the pattern to the end of file

Katalon Studio to upload more than one file to same input field

There is file input field on page, where should be attached more than one file at the same time.
I try to use [WebUI] Upload File, but it is unable to handle two files simultaneously.
WebUI.uploadFile(findTestObject('Object Repository/validateFile/input_originalFile'), (d_directory.toString() + '\\') + file1, (d_directory.toString() + '\\') + file2)
file1 = "C:\\path\\file.extension";
file2 = "C:\\path\\file.extension";
multipleFiles = file1 + "\n" + file2;
WebUI.uploadFile(findTestObject('yourTestObject'), multipleFiles)
Hope this helps
also, this list might help you in the future
Escape Sequence Description
\t Insert a tab in the text at this point.
\b Insert a backspace in the text at this point.
\n Insert a newline in the text at this point.
\r Insert a carriage return in the text at this point.
\f Insert a formfeed in the text at this point.
check whether input file type is= "file".

Vim function to sort by lines by tags

I'm trying to create a custom function in gVim to sort lines based on a tag and I'm a bit out of my depth. The goal is for me to create a custom function in my _gvimrc so I can resort like this quickly and as necessary. I need some pointers as to where to study.
My goal is to group lines by a tag at the start of the line
file contents 1
:a some text
:b some other text
:a more text
:b more other text
:c final text
file contents 2
will become
:a
some text
more text
:b
some other text
more other text
:c
final text
file contents 1
file contents 2
The challenge is largely that I don't want to mess with the other lines in the file - those which have no tags. the :sort function will reorder all of those.
I have a feeling I will need to:
1. yank all the lines with tags into a register, and delete them (some kind of :g/pattern/yank register ?)
2. put them all at the beginning of the file (some kind of :g/pattern/put register ?)
3. sort the block by the tags (some kind of :sort r /pattern/ ?)
4. iterate over each tag to reformat from
:a text
:a text
:a text
to
:a
text
text
text
I'm not proficient enough in gVim to know where to really start - if anyone here is expert enough to assist with one of these sub-problems, so to speak, or has a better idea for the methodology, I'd really appreciate it. I'm particularly stymied on number 4.
If this isn't the kind of thing gVim is capable of, please let me know, but I have a feeling this is quite possible and just out of my pay grade.
I think awk or some higher language would fit this better. Example using awk and Vim's filter, %!:
:%!awk '$1 ~ /^:/ { a[$1] = a[$1] substr($0, 3) "\n"; next} {r = r $0 "\n"} END { asorti(a, keys); for (k in keys) { print keys[k]; print a[keys[k]] } print ""; print r}'
Prettier version:
$1 ~ /^:/ {
a[$1] = a[$1] substr($0, 3) "\n";
next
}
{
r = r $0 "\n"
}
END {
asorti(a, keys);
for (k in keys) {
print keys[k];
print a[keys[k]]
}
print "";
print r
}
Note: I use gawk

Replace end of line for lines that start with a particular pattern

I have a file in the following format
--Some-XYZ-code ;
--Somemore--xyz--code;
COMMENT = " THIS IS A DEMO"
--somemore--code;
--somemore--code;
I want to put an semicolon at the end of line COMMENT, keeping the rest of the line intact.
Try this:
:g/^COMMENT/ normal A;
For every line that matches COMMENT at the beginning enter in Insert Mode at the end of the line and append a semicolon.
Explanation: :g selects every line that matches following pattern ^COMMENT and does the action after last slash, normal A;
This should do it:
:g/COMMENT/norm A;
g: globally on all lines matching /COMMENT/,
norm: execute normal command
A;: of appending a semicolon to the end of the line.
This should work
:%s/^COMMENT.*/&;/

How to insert spaces up to column X to line up things in columns?

I have my source code for copy operators written as follows.
foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;
I'd like to line things up as follows (more human readable, isn't it?).
foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;
Is there a VIM magic insert-up-to-column-N, or something like that that would allow me to line things up using a couple of keystrokes per line?
The other answers here are great, especially #nelstrom's comment for Tabular.vim and his excellent screencast.
But if I were feeling too lazy to install any Vim plugins, yet somehow willing to use Vim macros, I'd use macros.
The algorithm:
For each line,
Add tons of spaces before the symbol =
Go to the column you want to align to
Delete all text up to =, thereby shifting the = into the spot you want.
For your example,
foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;
Position the cursor anywhere on the first line and record the macro for that line by typing, in normal mode:
qa0f=100i <Esc>8|dwjq
Which translates to:
qa -- Record a macro in hotkey a
0 -- Go to the beginning of the line
f= -- Go to the first equals sign
100i <Esc> -- (There's a single space after the i, and the <Esc> means press escape, don't type "<Esc>".) Insert 100 spaces
8| -- Go to the 8th column (sorry, you'll have to manually figure out which column to align to)
dw -- Delete until the next non-space character
j -- Go to the next line
q -- Stop recording.
Then run the macro stored at hotkey a, 3 times (for the 3 remaining lines), by putting the cursor on the second line and pressing:
3#a
If you are using a unix-like environment, you can use the command line tool column. Mark your lines using visual mode, then:
:'<,'>!column -t
This pastes the selected text into the stdin of the command after '<,'>!. Note that '<,'>! is inserted automatically when you hit : in visual mode.
There is a nice plugin which does exactly that and more, called Align.vim
For you case, you would need to select your expression and then type :Align =. It will align everything, using = as a separator and reference.
(There is a lots of options to align, left, right, cyclically, etc)
You can also check Tabular.vim which provides similar features. See the screencast there for a demo.
A quick, simple way to proceed is to add X spaces and then delete back to column X. For example, if X=40, type
40a<Space><Esc>d40|
An alternative solution is to perform two consecutive substitutions:
%s/=/ =/
%s/\%>7c *//
The trick is the column pattern \%>7c that matches white spaces * only after the 7th column. Here foobar is the longest variable name with 6 characters so we need 7 in the regex.
We can use these two functions that I described in the below path for the same scenario : https://stackoverflow.com/a/32478708/3146151
simply put those two functions in your .vimrc or .gvimrc and call the functions as normal function call in your editor whenever you want.
The functions I have posted it here : https://github.com/imbichie/vim-vimrc-/blob/master/MCCB_MCCE.vim
We need to call this function in vim editor and give the Number of Occurrence of the Character or Space that you wants to move and the character inside the '' and the column number.
The number of occurrence can be from the starting of each line (MCCB function) or can be at the end of each line (MCCE function).
for the above example mentioned in the question we can use the MCCB function and the character we can use '=', so the usage will be like this in the vim editor.
:1,4call MCCB(1,'=',8)
So this will move the first = sign to the 8th column from line number 1 to 4.
These are the functions :
" MCCB - Move the Character to the Column from the Begin of line
" This is a function for Moving the specified Character
" in a given range of lines to a the specified Column from the Begin of the line
" NOTE 1 :- If the specified character and the first character of the line are same
" then the number of Occurance (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range
" of lines should be less than or equal to 80, if we need more than 80
" then we need to insert more spaces by increasing the value 80 in the
" "nmap s 80i <ESC>" line inside the function
" Usage :- in command mode do it like below
" Eg 1:- :5,11call MCCB(1, '=', 8)
" The above command will move the 1st Occurance from the begin of Character =
" to the 8th Column of the lines from 5 to 11
" Eg 2 :- :7,10call MCCB(2, '+', 12)
" The above command will move the 2nd Occurance of Character = to the 12th
" Column of the lines from 7 to 10
function! MCCB (num_occr, mv_char, col_num) range
if (a:firstline <= a:lastline)
nmap s 80i <ESC>
let line_num = a:firstline
while line_num <= a:lastline
execute "normal " . line_num . "G0" . a:num_occr . "f" . a:mv_char . "s" . a:col_num . "|dw"
let line_num = line_num + 1
endwhile
nunmap s
else
execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
endif
endfunction
" MCCE - Move the Character to the Column from the End of line
" This is a function for Moving the specified Character
" in a given range of lines to a the specified Column from the End of the line
" NOTE 1 :- If the specified character and the last character of the line are same
" then the number of Occurance (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range
" of lines should be less than or equal to 80, if we need more than 80
" then we need to insert more spaces by increasing the value 80 in the
" "nmap s 80i <ESC>" line inside the function
" Usage :- in command mode do it like below
" Eg 1:- :5,11call MCCE(1, ';', 20)
" The above command will move the 1st Occurance from the End of Character ;
" to the 20th Column of the lines from 5 to 11
" Eg 2 :- :7,10call MCCE(5, 'i', 26)
" The above command will move the 5th Occurance from the End of Character i
" to the 26th Column of the lines from 7 to 10
function! MCCE (num_occr, mv_char, col_num) range
if (a:firstline <= a:lastline)
nmap s 80i <ESC>
let line_num = a:firstline
while line_num <= a:lastline
execute "normal " . line_num . "G$" . a:num_occr . "F" . a:mv_char . "s" . a:col_num . "|dw"
let line_num = line_num + 1
endwhile
nunmap s
else
execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
endif
endfunction
I know this is old but I thought #talklittle had the right idea, the answer just got verbose. A quicker way is to insert spaces after the = and then remove all spaces after the 10th column like this:
:1,4 s/^\(.*=\) *\(.*\)$/\1 \2/
:1,4 s/^\(.\{10\}\) *\(.*\)$/\1\2/

Resources