how to delete til a char in the next lines. - vim

I have the following text layout. and I want to delete from ON to the ";" I tried to use "dt;", but it said it can't find ";", looks like "t" only try to find the char in the same line, possible to find the next lines?
INNER JOIN () a *cursor* ON f.StoreID = a.StoreID
AND f.UPC = a.UPC
AND f.type = 'tom' ;
...other text...

You will have to search for it and delete up to it using d/;<CR>. (<CR> is carriage return: pressing the return/enter key) Using d with a search behaves like using t with d. It will delete up to that character (or word if using a search). This is the behavior you want. If you want to also delete the ; you should use v/;<CR>d to select all of it and then delete it.

You are correct that t, T, f and F all only look at the current line.
Zach's answer is the correct way to do this with vanilla vim however there are several plugins that you could use if you don't wish to use search.
I'd recommend you take a look at vim-sneak: Sneak is a minimalist, versatile Vim motion plugin that jumps to any location specified by two characters. Using sneak you would use dz;<cr> to delete to the next occurrence of ;. This has the advantage of not leaving all other ; characters highlighted.
The vim-sneak README also list a bunch of similar plugins.

"dt;" is only usefull in one line.I don't think there is a way to do this unless you define a macro, which makes no sense , because you can't decide delete to which ";", next line or next next line .I think you type D with your cursor on ON, then move to nextline and type dd.Use simple cmd to compose a strong cmd.Just like the unix, keep it simple。

I would add another option, using easyMotion plugin.
you can d<leader><leader>f; then choose which ; you want to delete to. pretty handy.

Related

Vim - Delete til last occurrence of character in line

I'm trying to figure out how to dt or df the last occurrence of a character in a string.
For example, let's say I have the following line:
foo not.relevant.text.bar
If I f df. I expectedly get foo relevant.text.bar but I would like to get foo bar. Using f 3df. is not an option as I don't know how many of that character will be in the string. Additionally, I may want to get foo .bar (f 3dt.), or if the line ends with a dot, I may want to get foo .. I want to always find the last one regardless of how many there are.
Is this possible without a regex? I suppose I could use a regex but I was hoping there was a simple vim command that I'm missing. I find myself trying to do something like this often.
one way without using regex, without counting "dot" (could be other letters)... see if others have better way..
foo[I]not.relevant.text.bar ([I] is cursor)
you could try:
lmm$T.d`m
or in this format, may look better?
lmm$T.d`m
this will do the job. you could create a mapping if you use that often.
EDIT
I add a GIF animation to show it works. :)
note
I typed #= in normal mode after moving my cursor to the right starting point (by f(space)), to display the keys I pressed in command line.
You can use my JumpToLastOccurrence plugin. It provides ,f / ,F / ,t / ,T commands that do just that.
I would use f df...
It is not necessarily shorter to type, but I find it easier to use "repeat last command" than counting in advance the number of word/sentence I want to delete.
Then you can adjust the number of . you type to adjust the length of the string you want to delete.
For your example: ET.dB
foo not.relevant.text.bar
And it works, as long as the cursor is anywhere within the text following "foo".
Strip Path from Path+Filename: ET/dB
I use it for stripping a pathname of all but the trailing filename.
Strip the path from /some/long/path/filename.ext leaving only the filename.
Just as long as:
The cursor is anywhere within the bold word
There are no spaces in that word
E Go to the end (since there are no spaces - also works if not the last thing on the line)
T/ Find the last / (stop just after it, so it will be deleted, as well)
dB Delete to the beginning of the word
In visual mode:
$F.d^
The $ goes to the end of the current line, F searches backward for a period and d^ deletes till the beginning of the line.

Vim global command to make each line containing a symbol, start with a word

Consider following text file:
something
something
something = someother thing
other thing = third thing
another thing = forth thing
I want to make it look like this:
something
something
keyword something = someother thing
keyword other thing = third thing
keyword another thing = forth thing
so that, I add keyword to each line, what is contains a equals symbol in it.
Can I do this with global command, or how do you recommend I should do this?
:g/=/s/^/keyword /
or
:g/=/normal ikeyword
Note the space after "keyword"
For this type of problem, it's also quite common to use a solution like:
:%!sed '/=/s/^/keyword /'
I'm not quite sure what you're attempting to accomplish. Your title suggests a common pattern, but I don't see one in your example. So I'll show you both.
Making Changes Among Things With A Common Pattern
You can do search and replace with the following:
:s/<regex you are searching for>/<string to replace with>/g
s/pattern/replacement/ does search & replace, and the extra g will propogate the changes
Multi-Line Edit
Vim also lets you edit multiple lines at once. Say you want to edit the following three lines:
something = someother thing
other thing = third thing
another thing = fourth thing
Put your cursor on the s at the first something line.
Press <ctrl>-v outside of insert mode to go into Visual mode.`
Scroll down to the a on the bottom line. All three starting characters of all 3 lines should be highlighted.
Press A to append or I to enter directly into insert mode and start typing. When you hit escape your changes should reflect! You can also do other commands like y and d, etc.

Vim - Search and replace the results

I'm getting more and more comfortable with Vim after a few months.
BUT, there is only one simple feature I can't get any answer from the web. That is "Search and replace the results". The problem is that I know:
:/keyword to search, and hit enter "keyword" will be highlighted (of course with set hlsearch)
n, or N to navigate
:% s/keyword/new_keyword/g to replace all occurences of keyword with new_keyword.
BUT, I would think that there must be a way to search, and replace the matched keyword (highlighted) with any new_keyword WITHOUT doing ":% s/keyword/new_keyword/g", which is a lot of typing considering search & replace is such a day-to-day feature.
Any answers/comments will be greatly appreciated!
If you've already done a search you can do a substitution for the same pattern by simply leaving out the pattern in the substitute command. eg:
/keyword
searchs for "keyword", and then:
:%s//new_keyword/g
will replace all occurrences of "keyword" with "new_keyword".
Searching and using the dot command (you didn't meantion you are using the dot command, that's why I highlight it) to repeat the last input action is my best bet here.
I use s///g for search and replace.
Well, since #keyword# and #new_keyword# account for most of the characters, and you need some way to differentiate between them (i.e., a character in vim, or tab between entry fields in dialog in a different editor), you're left with maybe four or five keystrokes beyond that.
So I think you're probably overestimating number of keystrokes and also forgetting that (1) it becomes very natural, and (2) working this way allows you also to naturally modify the action performed by specifying a different range or option flag.
But you can cut down on keystrokes. If you want you can map a key to automatically bring up the command line with '%s/' already in place. e.g.:
nmap s :%s/
The command above would remap 's' (I'm not recommending remapping to that key, but it gives the idea) and set you up to insert the keyword.
Also, you can set the 'gdefault' option to default to substituting multiple times per line. This lets you skip the ending '/g' in your keystrokes:
set gdefault
See ':h gdefault' for help section on that option.
In the end I would say just get used to the default way it works, because using it that way allows you to keep same basic operation when you want to specify different ranges or option flags, and creating a new special map is just another thing to remember. gdefault may be worth setting if you think you're going to want it majority of time, adding /g flag at end when gdefault is set has effect of turning /g off. . .
Move to the first highlighted word then record a macro for replacing the word and moving to the next one, e.g:
gg
n
qq
caw new_word^[
n
q
#q
##
##
...

Is there a good Vi(m) command for transposing arguments in a function call? Bonus points for Emacs

For example if I have some code like:
foo = bar("abc", "def", true, callback);
Is there a nice command to move true to the 1st or 2nd position leaving the commas intact?
P.S as a bonus my friend want to know if this works in Emacs too.
In Vim if you place the cursor at the start of the first word and do dWWP then it will have the desired effect. Here is a breakdown:
dW delete the current word, including the comma and the following whitespace
W move to the start of the next word
P insert the deleted text before the cursor
This will work if there are further parameters after the pair to be swapped - it will need to be modified if there are only two parameters or you want to swap the last two parameters, since it will paste the text after the closing bracket.
Alternatively you could use a regex substitution:
:%s/(\([^,]\+\),\s*\([^,)]\+\)/(\2, \1/
This will find the first two arguments after the open bracket and swap them.
update:
A search of vim.org found the swap parameters plugin, which should do exactly what you want and can handle situations that either of the above methods cannot.
I don't know the answer for vi, but in Emacs, transpose-sexps (C-M-t) will swap two arguments either side of the cursor. Actually transpose-words (M-t) was my first guess, but that leaves the quotes behind.
You need a transpose emacs command. But its limited to not guessing that its transposing in lists, it only considers text (it can't guess the 1st, 2nd word of list). Try this.
Keep your cursor at after comma of true. Use M-x transpose-words. By default it will transpose with next word from the point. Shortcut is M-t.
You can use C-u 2 M-t for transpose with next second word.
Now coming to your question. If you want to move true, to backward 1 word, use C-u -1 M-t, and for backward 2 words C-u -2 M-t.
Am not a VIM guy. So sorry bout that.
If you want to do this as a refactoring, not just as text manipulation, I'd suggest looking into Xrefactory, a refactoring tool for Emacsen (free for C/Java, commercial for C++).
Transposing previous (Ctrl-t p) and next (Ctrl-t n) argument ... add the
following into your .vimrc file:
map <C-t>p ?,\\|(<CR>wd/,\\|)<CR>?,\\|(<CR>"_dw?,\\|(<CR>a, <C-c>?,<CR>P/,<CR>w
map <C-t>n ?,\\|(<CR>wv/,<CR>d"_dw/\\,\\|)<CR>i, <C-r>"<C-c>?,<CR>?,\\|(<CR>w

Vim copy and paste

My previous question seems to be a bit ambiguous, I will rephrase it:
I have a file like this:
copythis abc
replacethis1 xyz
qwerty replacethis2
hasfshd replacethis3 fslfs
And so on...
NOTE: replacethis1, replacethis2, replacethis3, ... could be any words
How do I replace "replacethis1","replacethis2","replacethis3",.. word by "copythis" word by using minimum vim commands.
One way I can do is by these steps:
delete "replacethis1","replacethis2","replacethis3",.. by using 'dw'
copy "copythis" using 'yw'
move cursor to where "replacethis1" was and do 'p'; move cursor to where "replacethis2" was and do 'p' and so on...
Is there a better way to do this in VIM (using less number of vim commands)?
Since you changed your question, I'd do it this way:
Move to the first "replacethis1" and type cw (change word), then type "copythis" manually.
Move to the next "replacethis", hit . (repeat last operation)
Move to the next "replacethis", hit .,
and so on, and so on.
If "copythis" is a small word, I think this is the best solution.
The digit needs to be included, and there could be more than one instance per line:
:%s/replacethis\d/copythis/g
Given that "replacethis[1-3]" can be arbitrary unrelated words, the quickest/simplest way to do this globally would be:
:%s/replacethis1\|replacethis2\|replacethis3/copythis/g
(Note that you need to use \| to get the pipes to function as "or". Otherwise, vim will look for the literal | character.)
I've been struggling with this for a long time too, I think I just worked out the cleanest way:
Use whichever command is cleanest to put copythis into register r:
/copythis
"rye
Then go to the replacement and replace it with the contents of r:
/replacethis
cw<CTRL-R>r<ESC>
Then you can just n.n.n.n.n.n.n. for the rest of them, or if they're wildly different just go to the beginning of each and hit .
The key is replacing and pasting in one step so you can use . later.
:%s/copythis/replacethis/g
To replace all occurrences of copythis with replacethis. Or you can specify a range of line numbers like:
:8,10 s/copythis/replacethis/g
Note, the /g on the end will tell it to replace all occurrences. If you leave that off it will just do the first one.
create this mapping:
:map z cwcopythis^[
( ^[ is the escape character, you can type it in vim using Ctrl+V Ctrl+[ )
go to each word you want to replace and press z
if u need to do essentially the same action multiple times - swap 1st word of one line with second word of the next line, I say you could record a macro and call it whenever you need to
Have you tried string replacement?
%s/replacethis/copythis
A host of other parameters are possible to fine-tune the replacement. Dive into the Vim help for more details. Some more examples here.
You can remap e.g. the m key in normal mode to delete the word under the cursor and paste the buffer: :nnoremap m "_diwP.
Then you can just copy the desired word, move the cursor anywhere onto the to-be-replaced word and type m.
EDIT: Mapping to m is a bad idea since it is used to mark locations. But you can use e.g. ; anyway.

Resources