If I have a function declared as such:
public static void main(String[] args){
blahblahlbah;
}
Is there anyway to move from the "p" in public to the ending "}" of the function?
It can be assumed that the method body is of considerable length and does contain curly braces if that makes a difference.
Thanks!
Try this key sequence: f{% Should do it.
There is not a few ways to accomplish the movement.
The most appropriate motion command is
]M
which is short and to the point: It moves the cursor to the end of the next
method in a Java-like source code.
There are also three satellite motions that together with ]M give
possibility to jump to next or previous starts and ends of methods, see :help
]m and below. Therefore, in addition to ]M, in this situation one can
issue
]m%
The rest of the answer contains discussion of some tricks that should be used
only if the aforementioned motion commands for some reason have failed to
solve the problem in your case.
Another simple idea to take advantage of is to jump over the argument list,
find the next opening curly brace and move to its closing counterpart,
%l%
or
f{%
or even
/%Enter%
A similar idea to move the cursor to the very beginning of the method's body
and than jump to the next unmatched closing curly brace leads to the following
command,
j]}
Note, though, that three of the last four commands work only if the function
header is a single line. If that is not the case, they need modifications.
Under some assumptions on the code formatting, it is also possible to achieve
the same result using plain-text-oriented movements. If the opening curly
brace is the last character on the method header line, one can use
$%
or
g_%
if that brace is the last non-blank character.
In conclusion, stick to the ]M movement as far as it works for you (it
should, in the vast majority of cases), fall back upon tricks based on
combinations of other text motion commands, otherwise.
/{ will take you to the opening brace and % will jump to the matching closing one.
][ moves to the next } in the first column. So this will work for you as long as your function is properly indented.
See :help ][ and :help section
I use this while searching through a file and my cursor is positioned over a particular search result in the middle of some long function. Often, I'll want to know which function I'm in so ][% gets me to the function signature, and then n returns me to the search result where I started.
Related
I have a tedious task of converting chords from leadsheets into an inline format.
The format I have
G A
Never gonna give you up
F#m Bm
Never gonna let you down
G A F# Bm
Never gonna run around and desert you
And the format I need would b
Never gonna g[G]ive you [A]up
Never gonna l[F#m]et you do[Bm]wn
Never gonna r[G]un a[A]round and d[F#]esert [Bm]you
The problem with a script in Ruby or Python is, that the format isn't very consistent. So there could be newlines, weird characters, sometimes the chords are seperated with a dash... I haven't looked through all of the files, but I suspect more malformed stuff.
So I thought, if I have to go through of every leadsheet by hand, at least I can save some time using vim. This is the mapping I've come up with so far:
nmap <C-X> viWc[]<ESC>PviWx<down>p
Select the chord: viW
delete it and go into insert mode: c
add brackets
exit insert mode: <ESC>
paste the register to the left: P
select the chord again, including the brackets: viW
delete the selection: x
move cursor down, and paste it: p
But I few things I can't figure out is:
Sometimes the chords already have brackets, then I don't want to surround them with more brackets. Any idea how to only add brackets, if the chord isn't already surrounded with them?
It would be cool to do this with whole lines of chords. Sometimes there are multiple chords on the same line, and selecting them one by one is tedious. Any idea on how to operate the mapping above on a whole line?
well point 1 could be solved by adding the brackets around the chords on every second line:
:g/^/s/\[\=\zs[a-zA-Z#]\+\ze]\=/\[\0\]/g|+t+|-d
Credits: https://vi.stackexchange.com/questions/34785/search-and-replace-on-odd-even-numbered-lines-using-g
This however sucks, because it moves arround the chords, so we have to remove all brackets first and replace them with space
:%s/\[\([a-zA-Z#]\+\)\]/\1 /g
Then we can do the first line again, but remove some space too. Since there are no brackets left, it gets simpler (Note we use other brackets to get ride of some side effect the following code has):
:g/^/s/\([a-zA-Z#]\+\) \{0,3\}/\{\1\} /g|+t+|-d
Also we add a trailing whitespace at the end of the line so that the df} command will not move the cursor to a wrong place
Now that we have curly brackets everywhere, we can use reverse search with ?{ and then create a macro that jumps from results to result and moves it down, replaces the curly brackets with normal brackets and then calls itself (recursive macro):
gg0
qqq
?{<CR>
qq
df}jPr]F{r[n#qq
#q
And nearly all should be done.
The result:
Never gonna g[G]ive you [A]up
Never gonna l[F#m]et you dow[Bm]n
Never gonna r[G]un a[A]round and d[F#]esert [Bm]you
Note, we have to search backwards (? instead of /) so we can delete the chords directly.
If you have problems understanding what I did, feel free to ask.
Frequently when I am doing a find and replace in vi I will do it like this:
:%s/find/replace/gc
This gives you the option to skip by pressing n, or replace by pressing y. But, sometimes I will accidentally skip over one in a large file by pressing n when I meant to press y.
How do I go backwards to the previous one and give me a second change?
Essentially, how to I find (search) the other direction temporarily? thanks.
I'm not sure if you would like to interrupt current find-replace operation and resume it again. But if that is acceptable, here is my suggestion:
Start your find-replace the way you mentioned:
:%s/find/replace/gc
After you accidentally skip over a substitution by pressing n, interrupt the search by pressing <ctrl-C>
Press <shift-N> to go back to the previous occurrence of your find term
Run find-replace a little differently while you are at this word: :.,$s/find/replace/gc
Continue the operation
All this functionality works with vim native capabilities without having to install any addon.
Note: The .,$ range specifier indicates to perform :s (substitute) operation over a range of lines that start with current line (indicated by .) and until last line (indicated by $).
Note2: It might be known to you, but reiterating for anyone else who stumbles upon this post searching for something similar - The % range specifier indicates to perform :s (substitute) operation over all lines of currently active buffer.
This is not answer to the question, but a very good alternative. I recently discovered the CtrlSF plugin and it improves the search /replace process dramatically.
Basically, you have the search results in a buffer and you can do all the replacements in this single buffer.
In your scenario, you first do :CtrlSF find, get a buffer with all the matches in all files and then you do /find and move with n over your targets and change them (of course, you can actually change only the first one and then repeat the replacement with .).
If you miss some target, you just hit N to go back to the previous result and replace it.
Seems like you can't back to previous match using this pattern. Appeared bar propose following commands y/n/a/q/l/^E/^Y but no one of them will return backward to previous match.
But you can use little different pattern described bellow:
Type this /pattern replacing pattern with interested word;
Your cursor is navigated to first occurrence, if you don't need to change it press n it will navigates you to the next occurrence;
Since you understand you need to replace a word, do this by typing cw, this command cuts the forward word and turns you to insertion mode;
Type in desired text on the released place and press ESC to switch back to command mode;
Now again press n until desired occurrence;
Since you realize that you need to change an occurrence, just press on . it will repeat previously mentioned actions;
If you want to go back just use N.
In all honesty the title is bad. Consider the following 5 lines:
function Example()
let ## = "-_-"
execute "normal! ]P"
call cursor(line('.'), col('.')-1)
endfunction
When this function is called, I expect to get -_- as output and the cursor should be moved to the left, meaning that it is at the third character, so if I press a key, like I for example I will get -_i-
What happens in reality is quite different (and to some degree interesting)
The output the first time this is called is - _- and after that it's _--
I assume that "cursor" shifts the position of the word under the cursor.
Basically: Why is it happening? How can I get the desired effect ?
Very important edit:
Apperantly the problem isn't in the plugins. When I go for:
call Example()
It works flawlessly. Thing is it is supposed to be triggered by a key. I have currently bound it like so:
inoremap ' <C-O>: call Example()<CR>
So now I am thinking that something in the mapping is broken...
I cannot reproduce your strange behavior. I get ----_-_-_-_- on repeated invocations, as expected. I again suspect there are plugins at work. Try with vim -N -u NONE. As this is a paste, there's little that could influence this function, though. You could try to workaround via :noautocmd call Example(), but I'd rather try to find the root cause of this disconcerting strangeness.
The "-_-" is not a full line, so the ]P (paste with adapted indent) has no effect here. You could just as well have used P.
To move the cursor one left, rather use :normal! h. The subtraction from col('.') again only works for single-byte ASCII characters.
I want to delete the following codes in my config file:
server {
listen 80;
server_name xxx;
location / {
try_files xx;
}
}
I know I can use 7dd, but this is not handy enough- if the section is too long, counting the rows would be inconvenient.
Is there a better way to do this?
Sometimes, I have to delete a whole function, any ideas for that?
As in common in Vim, there are a bunch of ways!
Note that the first two solutions depend on an absence of blank lines within the block.
If your cursor is on the server line, try d}. It will delete everything to the next block.
Within the entry itself, dap will delete the 'paragraph'.
You can delete a curly brack block with da}. (If you like this syntax, I recommend Tim Pope's fantastic surround.vim, which adds more features with a similar feel).
You could also try using regular expressions to delete until the next far left-indented closing curly brace: d/^}Enter
]] and [[ move to the next/previous first-column curly brace (equivalent to using / and ? with that regex I mentioned above. Combine with the d motion, and you acheive the same effect.
If you're below a block, you can also make use of the handy 'offset' feature of a Vim search. d?^{?-1 will delete backwards to one line before the first occurrence of a first-column opening curly brace. This command's a bit tricky to type. Maybe you could make a <leader> shortcut out of it.
Note that much of this answer is taken from previous answer I gave on a similar topic.
If there is a blank line immediately after these lines, Vim will identify it as a paragraph, so you can simply use d} to delete it (assuming the cursor is on the first line).
Try using visual mode with %.
For example, say your cursor is at the beginning of the "server" line.
Press v to go into visual mode. Press % to highlight to the end of the block. Press d to delete it.
As David said their are many ways. Here are a few that I like:
Vf{%d This assumes you are on the line w/ server and you do a visual line selection, find the { and then find the matching } via the % command.
set relativenumber or set rnu for short. This turns on line numbering relative to your cursor. So you do not have to count the lines just look and 7dd away to deleting your block.
Use VaB to visually select a block i.e. { to }, line-wise. While still in visual mode continue doing aB until the proper block is selected then execute d. This means you can select a block from inside the block instead of at the start or end.
d} will delete a paragraph. This works in your current scenario because there is no blank line inside the block. If there is one then all bets are off. Although you can continue pressing . until the block is properly deleted.
If inside a block you can jump to the current block via [{ then continue executing [{ until you are at the correct block then V%d or d%dd to delete the block
Using the techniques above you can delete a function as well, but you can also use the [M and friends ([m, ]m, ]M) to jump to the start and endings of methods but they commonly work for functions as well.
For more information
:h %
:h 'rnu'
:h aB
:h }
:h .
:h [{
:h [m
Given matching parens, or braces, you can use % with d to delete, spanning lines.
So, assuming that you're on the server { line, you can do d%. This is generally useful for all code blocks, e.g. function blocks, loop blocks, try blocks.
Similarly, dip works, but d} is shorter. However, both will only delete to the next empty line.
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