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.
When I want to see where my continue; jumps I have to delete ; and type it again (so something, let's call it Intellisense, will highlight continue and for or while line).
Same goes when I want to reformat something enclosed between { and } (in case formatting was not possible, because i wrote to example double a = inside and only after editing the rest could finish), I have to delete } (preferably the last one in the currently opened file) and type it again.
Question is:
are there keybindings to simplify this? Like pressing Ctrl+K and then something?
what are you guys doing, same as I deleting and retyping stuff to make things working?
P.S.: I know about Ctrl+Space (and one with the Shift) and I read this and also did some Googling, no luck.
A very simple example: I want to write a function, and there are already several levels of indentation (tabs before the word "function"). I first write:
1 function doCoolStuff() {
2
3 }
then go up one line from line 3 to line 2 and start typing the contents of the function. However, vim doesn't allow me to do so by removing the auto inserted tabs on line 2 after I type the bracket on line 3 and go up one line. So I have to insert tabs manually each time I write a new function. That's how it goes:
When I type the function's head and press enter, it looks like this:
1 function doCoolStuff() {
2 ▊
3
Vim correctly inserts auto tabs on line 2.
But!
Then I press Enter, type a closing bracket and go up one line. I expect it to be like this:
1 function doCoolStuff() {
2 ▊
3 }
but it turns out to be like this, without any tabs on line 2:
1 function doCoolStuff() {
2 ▊
3 }
Seems to be that vim sees that there is a line consisting entirely of tab characters and removes the tab characters. How do I disallow vim to remove trailing tabs?
The answer is to enter something on the line and delete it again, because ViM will not auto-remove the tab characters in that case:
:inoremap <CR> <CR>x<BS>
does the job. See this thread for more information.
What you are seeing is most likely the results of some kind of autoindent or cindent. There isn't really any tab or space there until you type something. So when you leave that line, it is not actually stripping a tab or space out, because it wasn't there in the first place.
What I usually do is move up to the line above where I want to start typing and then press o to start editing in the next line (and the autoindent handles the positioning correctly).
You could use DelimitMate or some other auto-pairing script or something like this answer of mine on a similar problem.
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.
Selecting a large amount of text that extends over many screens in an IDE like Eclipse is fairly easy since you can use the mouse, but what is the best way to e.g. select and delete multiscreen blocks of text or write e.g. three large methods out to another file and then delete them for testing purposes in Vim when using it via putty/ssh where you cannot use the mouse?
I can easily yank-to-the-end-of-line or yank-to-the-end-of-code-block but if the text extends over many screens, or has lots of blank lines in it, I feel like my hands are tied in Vim. Any solutions?
And a related question: is there a way to somehow select 40 lines, and then comment them all out (with "#" or "//"), as is common in most IDEs?
Well, first of all, you can set vim to work with the mouse, which would allow you to select text just like you would in Eclipse.
You can also use the Visual selection - v, by default. Once selected, you can yank, cut, etc.
As far as commenting out the block, I usually select it with VISUAL, then do
:'<,'>s/^/# /
Replacing the beginning of each line with a #. (The '< and '> markers are the beginning and and of the visual selection.
Use markers.
Go to the top of the text block you want to delete and enter
ma
anywhere on that line. No need for the colon.
Then go to the end of the block and enter the following:
:'a,.d
Entering ma has set marker a for the character under the cursor.
The command you have entered after moving to the bottom of the text block says "from the line containing the character described by marker a ('a) to the current line (.) delete."
This sort of thing can be used for other things as well.
:'a,.ya b - yank from 'a to current line and put in buffer 'b'
:'a,.ya B - yank from 'a to current line and append to buffer 'b'
:'a,.s/^/#/ - from 'a to current line, substitute '#' for line begin
(i.e. comment out in Perl)
:'s,.s#^#//# - from 'a to current line, substitute '//' for line begin
(i.e. comment out in C++)
N.B. 'a (apostrophe-a) refers to the line containing the character marked by a. ``a(backtick-a) refers to the character marked bya`.
To insert comments select the beginning characters of the lines using CTRL-v (blockwise-visual, not 'v' character wise-visual or 'V' linewise-visual). Then go to insert-mode using 'I', enter your comment-character(s) on the first line (for example '#') and finally escape to normal mode using 'Esc'. Voila!
To remove the comments use blockwise-visual to select the comments and just delete them using 'x'.
Use the visual block command v (or V for whole lines and C-V for rectangular blocks). While in visual block mode, you can use any motion commands including search; I use } frequently to skip to the next blank line. Once the block is marked, you can :w it to a file, delete, yank, or whatever. If you execute a command and the visual block goes away, re-select the same block with gv. See :help visual-change for more.
I think there are language-specific scripts that come with vim that do things like comment out blocks of code in a way that fits your language of choice.
Press V (uppercase V) and then press 40j to select 40 lines and then press d to delete them. Or as #zigdon replied, you can comment them out.
The visual mode is the solution for your main problem. As to commenting out sections of code, there are many plugins for that on vim.org, I am using tComment.vim at the moment.
There is also a neat way to comment out a block without a plugin. Lets say you work in python and # is the comment character. Make a visual block selection of the column you want the hash sign to be in, and type I#ESCAPE. To enter a visual block mode press C-q on windows or C-v on linux.
My block comment technique:
Ctrl+V to start blockwise visual mode.
Make your selection.
With the selection still active, Shift+I. This put you into column insert mode.
Type you comment characters '#' or '//' or whatever.
ESC.
Or you may want to give this script a try...
http://www.vim.org/scripts/script.php?script_id=23
For commenting out lines, I would suggest one of these plugins:
EnhancedCommentify
NERD Commenter
I find myself using NERD more these days, but I've used EnhancedCommentify for years.
If you want to perform an action on a range of lines, and you know the line numbers, you can put the range on the command line. For instance, to delete lines 20 through 200 you can do:
:20,200d
To move lines 20 through 200 to where line 300 is you can use:
:20,200m300
And so on.
Use Shift+V to go in visual mode, then you can select lines and delete / change them.
My usual method for commenting out 40 lines would be to put the cursor on the first line and enter the command:
:.,+40s/^/# /
(For here thru 40 lines forward, substitute start-of-line with hash, space)
Seems a bit longer than some other methods suggested, but I like to do things with the keyboard instead of the mouse.
First answer is currently not quite right?
To comment out selection press ':' and type command
:'<,'>s/^/# /g
('<, '> - will be there automatically)
You should be aware of the normal mode command [count]CTRL-D.
It optionally changes the 'scroll' option from 10 to [count], and then scrolls down that many lines. Pressing CTRL-D again will scroll down that same lines again.
So try entering
V "visual line selection mode
30 "optionally set scroll value to 30
CTRL-D "jump down a screen, repeated as necessary
y " yank your selection
CTRL-U works the same way but scrolls up.
v enters visual block mode, where you can select as if with shift in most common editors, later you can do anything you can normally do with normal commands (substitution :'<,'>s/^/#/ to prepend with a comment, for instance) where '<,'> means the selected visual block instead of all the text.
marks would be the simplest mb where u want to begin and me where u want to end once this is done you can do pretty much anything you want
:'b,'ed
deletes from marker b to marker e
commenting out 40 lines you can do in the visual mode
V40j:s/^/#/
will comment out 40 lines from where u start the sequence