How to remove specific newlines - linux

So, below is a copypasta of my VIM file. Its 7000+ lines long so I'm trying to find the commands to clean it up. Basically, I need newlines to only start with P: or F:, but to do so, I have to move any lines that were mistakenly newlined back to the correct line: Below, the line starting with "Nobody can ... " needs to be moved back...
P: Well at this stage here, I can.t really say for anything really, cause I don.t know anything. $
F: Okay. And that.s my job Rob, my job is to come in here and explain $
some stuff to you and then once you.ve a better understanding you can choose whether or not you want to explain that stuff. Alright, because that.s gonna be your choice I.m not gonna force you to say anything. I.m not gonna make you do anything you don.t want to do. $
Nobody can ever make you do that, nobody can make Robert $

Use :v to find all lines that don't begin with either P or F, and join them with the previous one:
:v/^\(P\|F\)/ normal kJ

Related

vim: Run multiple commands based off of one :global command

Apologies if this has been posted already, for I cannot find an answer, even on the vim wiki.
Is there a way I can run multiple commands in vim command-line mode off of a single :g search?
For example,
:%g/foo/ s/bar/\=#a/g | exe "norm /cat\<enter>\"ayiw"
Which (for what I intend it to do) should, on every line matching foo, replace bar with the contents of register a, and then find the next iteration of cat (even if it is many lines ahead), and put the surrounding word into register a.
Instead, this specific syntax completes the subsitution command using the current contents of the initial a register, and then executes the normal mode command on a single line (after the substitution has been completed).
This example is not my specific use-case but shows one instance where this functionality is useful. I realize I could put it all into a single exe, i.e., %g/foo/exe "norm :s/bar/\\=#a/g\<enter>/cat\<enter>\"ayiw", but I would like to do it the first way, as I feel it is more flexible.
I would prefer to do this using vanilla vim, but if a plugin exists for this, that is an okay alternative. Does anybody know if there is syntax to do such a thing?
Okay a "little bit" dirty, but does this work for you?
:let list = split(execute('g/cat/p'), '\n') | g/foo/ s/bar/\=matchstr(remove(list, 0), '\s\d\+\s\zs.*')/g
It first reads all occurences of cat save them in a list.
Then replace the first bar with the first cat... and so on.
The dirty part ist the matchstr command. the g//p also returns a number for the result so the list looks like this:
1 cat
2 cat
3 cat
...
that's why we have to remove a bit from the front. I would love to hear if someone knows a clean solution for that (I am also interested in a clean vimscript solution, does not have to be a oneliner).
You can do this (at least for multiple :s commands applied to a single :g). Example:
" SHORT STORY TITLES to single word of CapitalizedWords within <h3>s
.,$g/^\L\+$/s/[^A-Z0-9 ]\+//ge|s/\u\+/\L&/ge|s/\<\l\+\>/\u&/ge|s/ \+//ge|s/.*/<h3>&<\/h3>/

Toward Vim moves from conventional moves (<left> <right> <up> <down> <backspace>)

I am not trying to play golf with my editor. I am just trying to improve my editing skills with vim.
Let's consider this piece of assembly that I would like to convert to C. In order to do it methodically, I want to make small changes iteratively line after line.
dm(__abcd_bar_id + axis) = f4;
f1 = dm(_abcd_foo_id + axis);
f5 = f4 - f1;
The job with this example is:
Simplify the first line with abcd_bar_id[axis] = f4
Simplify the second line with f1 = abcd_foo_id[axis]
Replace f1 in the third line with the second line
Remove the second line
These steps are not negotiable. I know I can easily get rid of all my dm(__variable + index) with a regex like the one below but this is off topic.
:%s/dm\s*(\s*_\+\(\w\+\)\s\++\s\+\(\w\+\)\s*)/\1[\2]/g
So, to achieve these changes I traditionally do this:
▶▶▶▶DelDelDelDelDel▶▶▶▶▶▶▶▶▶▶▶▶[DelDelDel▶▶▶▶Right]
▼DeleteDelDel[▶▶▶▶]Del
Home▶▶▶▶RightDelDelDelDel
Shift+End Shift+◀ Ctrl+c
▼End◀◀BackspaceBackspace Ctrl+v
And the result should be this:
abcd_bar_id[axis] = f4;
f5 = f4 - abcd_foo_id[axis];
What saves me is I am quite fast hitting the same key multiple times. However I am sure I can be more productive if I use vi features
vfahd
wh3lxi[wr]
j:%s/dm(_//Enter
f+hv2lxi[Escwr]
$hvF2ay
jf1hhplxxx
Well, this seems to me much more complicated for my brain because a pre-processing bain-time is needed before each keystrokes.
For instance if I want to move to f1 I need to parse with my eyes if there is no other 1 on the way to f1.
I really feel I need years of training to be 'fluent' with vim.
So the questions are:
How a vim guru will treat this example?
Does a vim guru exist?
I definitely don't consider myself vim guru, although I use it on the daily basis. Answering your second question first, probably there's somebody who can be treated as a guru, there are simply so many options and possibilities in vim, that everybody can have their own way of doing things. Moreover, because you can tailor vim to your needs, it's easy to simplify regular tasks, and those configurations may differ a lot. Also people who are considered gurus by me (like, for instance, Derek Wyatt) claim that have still much to learn about vim, so it can definitely take years to become one.
But don't be discouraged, it takes only some practise to start thinking vim-way, and your editing tasks will become much easier :)
Back to your example. First of all, I'd edit the first line with slightly less keystrokes:
dta
f)r]
bdTd
i[
The difference isn't huge in terms of number of keystrokes, but it illustrates different approach. It allows, in my opinion, much less pre-processing, which is the problem you highlighted. I divided those keystrokes into sections to show you my thought process:
delete till a
find ) and replace it with ]
back one word and delete Till (backwards) d
insert [
I don't have to think much, when I apply those changes. You might think that this is counter-intuitive, that I jumped to ) character first, but it was much easier for me to spot closing bracket than count words or
hit h or l multiple times. Of course you might know the keystrokes but when you edit something you don't always remember all of them. This comes with practise and forcing yourself to use some of them (like t/T)
to put them firmly under your fingers. Also, print a cheat-sheet trying to make use of every key, until you'll learn it by heart. It won't take long ;)
As William already suggested in the comment, I'd also think about macro here. It's a powerful and easy-to-use tool, which can really automate your changes.
I already know how to edit first line. In your example, I know that in the second step I'll be doing the same thing, but in slightly different location, so instead of editing first line, I instantly record a macro, but I have to make it universal
for easier application. So I think about putting my cursor in proper location first, before making any changes. My macro would look like this:
qq
0fd dta f)r] bdTd i[
q
Notice, that I added 3 keystrokes at the beginning (not counting qq, which starts recording macro to q register). That might look redundant in the first line, but it ensures proper location of the cursor before making any changes.
That way I can easily apply this macro in the second line with #q
Now, you have to replace this f1 in the third line. You're still in the second line with your cursor, so you just yank with:
0fay$
and then paste it to the third line:
j$bPlD
Using macros mith look like a redundant thing when you edit just 3 lines, but when you get used to making changes in a vim way, you'll really feel you're taking advantage of it's power.
When it comes to remembering recorded macros it's not that hard, you have to have the proper attitude. First of all, you record your macros to registers, so typing :registers will show you also your macros. Secondly, you can edit them,
by pasting specific register, altering it and then saving to the same register. And then you can play it with #[register_letter]. And finally, don't get attached to specific macros. Save one or two, use them to make multiple changes at
once and forget about them. And then record another one under the same letter. For example, if you realize that you have to make some repetitive change across the file, use qq, because it's fast and intuitive. After making changes you rarely
need to play the same macro over again, because whole buffer is already in the right state. But if you know, that you'll need it, record next macro under another letter. If you'll get comfortable making changes intuitively vim way, so that
they can easily be repeted, you'll find that's much easier to record another macro than trying to remember under which letter you recorded previous one.
I hope that this answer will convince you, that you don't need years of training to get fluent, but of course it won't happen overnight ;)

Vim Repeat dot (".") command buffer?

I really like the behavior of YankRing, which lets me access the last several things I've yanked or deleted or changed without thinking.
However a complementary feature like this is completely missing for the . repeat command, most often when I type something I really want to repeat, then accidentally overwriting that edit by pressing x to clean something up.
Often it's possible to get back some time still by visual-mode yanking what I just typed, but this is not ideal.
It should be really easy to remember the past few commands.
The question is how possible is it to extract from Vim the representation of the last command contained in whatever stores what . will do before it gets blown away?
If it is as I fear, the only way is to get a plugin to bind to every single command that could edit something, and instrument it in such a way as to store our own repeat-buffer. This is really not practical because I can already imagine how many other plugins that will break. But, I would still really really want this feature if it is possible in any way.
Unfortunately, there's no way to get and replay the command behind the . command. The only workaround is to be perpetually in macro recording mode, and use the macro register as a replacement for the . command.
This tactic is employed by the RepeatLast plugin, which might offer what you want.
Keyword completion and/or ctrl-a in insert mode should cover your needs.
A more yankring-like solution should be possible but, as you say, probably a little too intrusive. Did you look on vim.org by yourself before asking others to do it for you?

Jumping [f]orward to a letter into the next line

Say that in the following paragraph my cursor lies on the first are in the first sentence (wish I could highlight it, but I can't so ...). Upon pressing ff twice that will get me to fools in the first sentence, and then to of. Further pressing it will get me nowhere.
Some people are confident because they are fools. Leonard had the look of
someone who was confident because, so far, he'd never found reason not to be. He
would step off a high building in the happy state of mind of someone who
intended to deal with the problem of the ground when it presented itself.
What would I need to modify so I can "move" across lines, so that further pressing ff will make Vim jump into the next lines?
Nothing to modify except Vim's source code. fFtT are linewise and there's nothing you can do about it. See :h left-right-motions
You could use /f, which is not limited to the current line, instead but it's not as fast as it requires another keypress.
Or a plugin like easymotion.
Did you know that you can hit ; to redo the previous fFtT?
There are a couple of solutions, but none do exactly what you want. Usually in this situation I would do ff followed by a series of ; characters to repeat f. When I reach the end of the line I hit + and then continue with ;. Similarly, you can use , to go backwards and 0<BS> to go back a line.
Another option is to write lines with set wrap and no hard breaks, but for various reasons users may not find that ideal.
Despite this seeming like nonsense it can actually be useful in some situations. For example, the :norm command will skip a line if ff doesn't find anything. You can use this for complex :norm commands over multiple lines to check for a particular character before you proceed with the command.
Edit:
There's a plugin that accomplishes this: https://github.com/dahu/vim-fanfingtastic

Vim - How to move the result of a search to the beginning of the file?

I want to search some text and move the entire line where the text belongs to the beginning of the file. Just that.
How about the simple move command?
:g/^C/m0
:g/^B/m0
:g/^A/m0
:g/regex/norm dd1Gp
Well, what I'm gonna suggest is a primitive answer as primitive it can get. But nothing else springs to mind currently.
:g/A ... some text not including A, B or C.../d
(will tell you how many lines it has yanked)
and then you go to the beginning of the file and, for example
5P
Although, if cases are as simple as this, maybe sorting lines by first letter .... I've never done anything similar but look for older questions.

Resources