I like to use vim's auto formatting command but it is causing a problem with me and my boss. At some point someone's editor added blank lines with spaces. When i run gg=G it removes that whitespace and is creating a bunch of noise in my git commits. I still want to be able to format the text but I don't want whitespace removed.
This seems like I need to change a setting somewhere. Any ideas?
There's no built-in option that you can simply set. The closest is autoformatting; with a and w in 'formatoptions', Vim will format as you type, and keep a single trailing space at the end of each line belonging to a paragraph. But that doesn't preserve existing trailing whitespace.
If you need to reindent and reformat with gg=G, that implies that the existing layout is pretty broken. Most people will argue that you shouldn't care about preserving trailing whitespace (itself a bad practice, and usually flagged by Git) in that case.
If you can, limit the scope of the = command, e.g. by applying it selectively only on few (bad) lines, or the visual selection. That will reduce the noise in commits.
If you really need to reformat while preserving trailing whitespace, I would open a diff inside Vim (using Git, the Fugitive plugin makes this very easy), and then manually edit the trailing spaces back in. The effort required in this should further convince you (and your team) that a bit more care about proper editing hygiene benefits everybody :-)
Related
In a given text file, I would like to work on a "filtered view" (hiding lines with a pattern), but still to be able to edit visible lines : the filtering would only affect the visibility of some lines, and as soon as I would reset the filter, the hidden lines would appear again.
The feature I describe could be compared to the & key in the less command (except, of course, that less can't edit the file's content) :
&some_pattern <RETURN> starts a new filter,
& <RETURN> reset the filter.
Does such a feature exist in vim, natively or as a plugin?
This usually is done with folding; you can easily define a 'foldexpr' that filters lines based on a regular expression match; see Folding with Regular Expression for implementations.
However, a single fold line will remain for each condensed block. To do away with those, I can only think of the NrrwRgn plugin, which transfers selected lines into a separate scratch buffer. It's usually only for a single block, but :help NR-multi-example suggests this works on ranges, too:
For example before editing your config file, you decide to strip all comments
for making big changes but when you write your changes back, these comments
will stay in your file. You would do it like this: >
:v/^#/NRP
:NRMulti
It can be done with plain Vim, and it's named folding. Drew Neil has two screencasts about it that you might find informative.
i. The Problem
My goal is something like the following:
I have a line of text like
Who left the dead mouse in the fridge?
and I want to highlight the first the in green, just this one occurrence. That is, I don't want to syn match ThisMagicWord "\<the\>" or anything that will overzealously highlight other thes.
There is one other requirement, which is that if the user edits the other text on the line, say to
Who on earth left the delicious dead mouse in the fridge?
the highlighting will track with the word the, so long as the user doesn't edit that one particular word.
ii. The Kludge
Now, I have a solution to this. In fact, I am proud of my solution, because it was tricky to think up. But it is not, by any stretch of the imagination, a good solution.
It turns out that the Unicode character Combining Grapheme Joiner is effectively a no-op in Vim. It produces no glyph, and takes up no width. It is the only such character that I have discovered. So what I do is, I surreptitiously edit the line in question to be
Who left the<CGJ> dead mouse in the fridge?
and then define a rule
syn match ThisMagicWord "the<CGJ>"
I will additionally trigger on BufWritePre and BufWritePost to strip the CGJs out of the file on disk.
iii. The Questions
Is there a no-op character in Vim (or a way to produce one) other than CGJ? Ideally a non-combining character, since the<CGJ> will not match a search for /the, due to the way Vim regexes handle combining characters.
Is there a better way to get at the behavior that I want?
You're right that there's currently no good way to mark static matches and keep them up-to-date when edits are done nearby. My approach would have been worse than your kludge: Include the line / column information in the match (via the \%l and \%v special atoms), and attempting to update those with a combination of marks (works for line changes) and intra-line custom diffing.
Though your use of special Unicode characters is clever, it's (as you admit) a hack. I've asked you for uses in the comments, and am still not completely satisfied / convinced. If you can come up with good, real use cases and current pain points, please direct them to the vim_dev mailing list (best with a functional draft patch attached). The functionality to keep track of such text is basically there (in the Vim internals), it's just not yet tracked and exposed to users / Vimscript. Though Vim development has been (often frustratingly) slow, with a compelling argument on your side, new functionality can and does happen.
How about using marks?
Move the cursor to the word you want, set a lowercase letter mark (e.g. mz), then add highlighting for the word like \%'zthe
Is there any way using either Vim scripting or search/replace to remove ghost newlines? I have come across times when I have to edit files that other developers using crappy software have left double newlines in like the attached picture.
I would love to find a way in Vim to remove all those stupid double spacing junk so it actually looks like it should.
Running the search-and-replace
%s/\n\n/\r/g
will replace every pair of two newlines with a single one. This will inevitably screw up files that aren't already double-spaced, though, so don't use it blindly.
Shorter solution:
:v:.:d
It those lines are really empty. If there might be white spaces:
:v:^\S*$:d
Yes, that title is the best I could come up with :-)
I have a text, and when activating spellchecking naturally a lot of words come out highlighted. Like emails, adresses, names and so on. How to tell Vim that some word is okey, without adding it to the wordlist.
Meaning, just, while editing this document I don't want to see my name highlighted.
Try: zG
:help internal-wordlist
From http://vimdoc.sourceforge.net/htmldoc/spell.html
zg Add word under the cursor as a good word to the first
name in 'spellfile'. A count may precede the command
to indicate the entry in 'spellfile' to be used. A
count of two uses the second entry.
In Visual mode the selected characters are added as a
word (including white space!).
When the cursor is on text that is marked as badly
spelled then the marked text is used.
Otherwise the word under the cursor, separated by
non-word characters, is used.
If the word is explicitly marked as bad word in
another spell file the result is unpredictable.
I have my Vim config in a git repository, which is useful for several things; For example, you could alias your vim to a small script that invokes Vim normally, but after Vim finishes checks if the ~/.vim/spell directory has any modifications and if so, asks you if you want to keep or discard them. If you want to keep them, it could automatically commit everything in spell and otherwise reset everything in there. So you usually wont be bothered by that script unless you actually do use the spellchecker.
The only drawback would be that you couldn't both make persistent and volatile additions to the dictionary in one session.
So oftentimes, while editing with Vim, I'll get into a variety of situations where whitespace gives me hassle. For example, say I have a comment like this:
#This program was featured on the Today show, it is an algorithm for promoting world peace in third-world countries
#given the name of that country and the name of a celebrity to endorse its cause
If I want to, for example, trim the lines so they go to X characters, I end up putting a newline somewhere in the middle of the top line to get this (after hitting the newline and auto-indenting):
#This program was featured on the Today show, it is an algorithm for promoting
world peace in third-world countries
#given the name of that country and the name of a celebrity to endorse its cause
I then add a # to the beginning of the line, and that's all well and good, but then I want that line to line up, too. To do so, I have to delete the newline, all the whitespace for the indent on the next line, and then the commenting # mark. It doesn't take an awfully long amount of time to do that, but this and similar situations all add up over a day's worth of coding.
Now the example above is pretty specific, but my question isn't. What's a good way in Vim to delete all whitespace INCLUDING NEWLINES up until the next non-whitespace character? If Vim already has movements that do that, that would be awesome, but if not, does anyone have a favorite Vim function they use to do the above that could be mapped to a key? At the very least, am I missing some Vim usage idiom that prevents me from even having to worry about this case?
EDIT: Formatting to width, while useful and applicable to the case above, isn't the focus of this question. I'm concerned more with whitespace removal that doesn't stop at the end of a line, but instead carries on to the first non-whitespace character of the next line.
You really just want to reformat that comment to fit the current 'textwidth'. If the comment is a paragraph (i.e., separated by a line of whitespace above and below), then you can just use gqip (gq is the reformat command, ip is the "inner-paragraph" text object) to reformat it. If it's not a standalone paragraph, you can visually select those lines and then use gq.
This likely also relies on having 'formatoptions' set correctly to make sure the comment characters are handled properly, but in many cases the ftplugin has already done that.
This is a while later, but I found that there is a command that does what I need to in 90% of circumstances:
J -- join line below to the current one
This command seems to work:
:.s/\W*$\n\W*//g
it uses a replace to remove whitespace up to end of line and the new line at the end.
In this example:
testting aad $
asdjkasdjsdaksddjk$
(to see meta characters in vim use the command :set list)
if you place the cursor on the first line and use the first command it will delete everything from aad to $ (not including aad but including $ and a newline.)
Also, note for what you are doing it is far more efficient to use an external program to format comments for you. In particular, par is a great small C program that edits text and wraps it to desired lengths.
If you have par in your path, to do what you are trying to do is as easy as selecting the block of comment with Shift+v and running the command
:!par 40pgr
where 40 is the desired width in columns.
If you are feeling hackish, write your own program in C/perl/C++/python that edits comments however you like, then put it in path and use the external filter command :! to process blocks of text through it.