Forcing vimdiff to wrap lines? - vim

When diffing 2 files in VIM, I prefer the lines to be wrapped. However, vimdiff sets wrap to off by default.
Is there a way to set line wrap automatically for every diff?

I use the following:
autocmd FilterWritePre * if &diff | setlocal wrap< | endif
FilterWritePre is triggered immediately before a generated diff is written to the buffer, and setlocal wrap< copies the global value of wrap. Of course it's also possible to simply force setlocal wrap.

You can put the following in your vimrc.
au VimEnter * if &diff | execute 'windo set wrap' | endif

When vim is already started, the commands to start a diff and a wrap are, on each of the split window files:
:diffthis
:set wrap
However, the diff+wrap is improperly displayed:
If you have a long line on one file, and a short or missing line on the other, then the long line will occupy, say, 2 lines on the first side, by the short or missing line will only occupy 1 line on the second side.
This results in a vertical shift of the 2 files. Sure, the colors help to visually compensate this shift. But over several lines of diff, the shift may be higher than the height of the window, making diff unreadable.
So the question is not fully solved...
Please advise.

You can run this
vimdiff -c 'set wrap' -c 'wincmd w' -c 'set wrap' file1 file2

I had to solve this question for a demo where I wanted vimdiff to wrap only when launched from a certain terminal.
I finally resorted on the crude:
alias vimdiff='vimdiff +"windo set wrap"'
vimdiff file.orig file

If you have more files, and you don't want to make this permanent in your vimrc
vimdiff -c 'windo set wrap' file1 file2 file3 [file4]
or just windo set wrap once vim is open

Starting from VIM 8.2.2490 there is a followwrap option for diffopt. You can set it with :set diffopt+=followwrap.

I find that the :set diffopt+=followwrap setting only affects the second pane, for reasons unknown to me. I have to :setlocal wrap separately to get the first pane to also wrap, and that setting only operates if the diffopt setting is also in play. Bizarre, but at least it works. The trick now will be to put that inside some conditional that checks the vim version, so I can have one .vimrc that works across platforms.

Related

set complete+=k[file] not working for whole line completion?

I have ~/.bash_history that contains lines such as sudo apt-get install, aplay foo.wav, etc. I thought it would be convenient if I could use these lines for completing whole lines while writing shell scripts.
:h compl-whole-line says:
CTRL-X CTRL-L
Search backwards for a line that starts with the
same characters as those in the current line before
the cursor. Indent is ignored. The matching line is
inserted in front of the cursor.
** The 'complete' option is used to decide which buffers
are searched for a match. Both loaded and unloaded
buffers are used.**
Note the asterisks I inserted. :h 'complete' says:
k k{dict} scan the file {dict}. Several "k" flags can be given,
patterns are valid too. For example: >
:set cpt=k/usr/dict/*,k~/spanish
So I thought :set complete+=k~/.bash_history would do the job. It didn't.
Start vim with
$ vim -u NONE -N
then
:set complete+=k~/.bash_history
:set complete?
" complete=.,w,b,u,t,i,k~/.bash_history
, I enter to the insert mode (i), and when I type
su<C-x><C-l>
, vim says Whole line completion (^L^N^P) Pattern not found. The completion is working for words, so when I type
su<C-p>
sudo is suggested.
What am I missing? How can I use my history for whole line completion without :sp ~/.bash_history?
set complete+=k[file] has nothing to do with line completion: whatever file you give to it will only be used as a source by dictionary completion (<C-x><C-k>) and keyword completion (<C-n>/<C-p>).
:help i_ctrl-x_ctrl-l is clear: line completion only works with lines found in loaded and unloaded buffers. Since ~/.bash_history is not loaded as a buffer, line completion will obviously never use it as a source.
So yes, the only practical solution is to load that file.
:sp ~/.bash_history is not really optimal, though, because a) it takes too much room, both physically and in your buffer list, and b) it requires way too many keystrokes.
The "too much room" part of the problem is easily solved with a more suited command:
:badd ~/.bash_history
The "too many keystrokes" part of the problem could be solved with an autocommand that runs the command above each time you edit a shell script:
augroup shell
autocmd!
autocmd BufNewFile,BufRead *.sh badd ~/.bash_history
augroup END

How to use tidy with vim without unix linebreak in quickfix window and how to correct only the errors?

After a lot of searching and trying I found this to make my tidy work with vim:
:set makeprg=tidy\ -e\ --gnu-emacs\ yes
:set shellpipe=2>
:set errorformat=%f:%l:%c:\ %m
:make %
:copen
But why does the output in the quickfix window has an ^M unix line-break at the end of every line?
I tried to remove it but the content in quickfix window is not modifiable.
I tried also to make tidy correct the errors, but only the errors.
I created this:
let errorf = "d:\\error.txt"
let currentf = expand("%:p")
let writef = "d:\\".expand("%:t:r")."_tidy.".expand("%:e")
exe a:type."!tidy -w 0 -f ".errorf." -o ".writef." ".currentf
exe ":bot split ".writef
exe ":bot split ".errorf
But this changes the complete output of my file.
I want to correct only the errors.
I have read the manual of tidy but can't find a simple option to correct only the errors without changing the rest of the file.
p.e.
<h1>test</h2> --> <h1>test</h1>
Are there tidy users who know how to change only the errors in tidy?
You can pipe the output of tidy to sed to create a filter to remove carriage returns before vim puts it in the quickfix window.
set makeprg=tidy\ -e\ --gnu-emacs\ yes\ $*\ \\\|\ sed\ 's/\\r$//'
The pipe needs to be escaped twice one by set and once for the interpretation of the command.
The sed command I used was
sed 's/\r$//
Which removes carriage returns that appear at the end of the line.
Have a look at the syntastic plugin. It supports tidy as one of the syntax checkers for HTML.

Vim: For Multiple Files: Copy all Text, Replace and Paste

I want to do the following for multiple files using Vim:
Copy all text in each file
Replace some text
Paste the copied text at the end of the each file
Replace some other text
Here are my commands for one file:
:%y
:%s/old1/new1/g
:G
:P
:%s/old2/new2/g
Can anybody tell me the syntax to do so? Especially that I'm new to Vim!
I found out that argdo can execute commands on multiple files. I found many examples to use argdo in replacing text, but I couldn't find the syntax to use argdo with :%y, :G, or :P
Thanks.
Like #ib mentioned, I'd do this with ex commands1
:argdo %y | %s/old1/new1/g | $pu | %s/old2/new2/g
There's also a good chance that you might want to operate on exclusive ranges (do the first substitution only on the first part, and the second only on the second):
:argdo $mark a | %co$ | 1,'a s/old1/new1/g | 'a,$s/old2/new2/g
To allow non-matching substitutions, add s///e and add silent! to make operation much faster in the case of many files.
:silent! argdo $mark a | %co$ | 1,'a s/old1/new1/ge | 'a,$s/old2/new2/ge
1 (note that argdo expects an Ex command list by default. You'd use e.g. argdo norm! ggyG to use normal mode commands)
UPD: my Vim-fu is not as strong as #ib's or #sehe's ones, so you might want to use the solutions they suggested instead of mine one.
But, my solution is easier to edit and to debug personally for me (as a Vim apprentice), so, let it be here anyway.
You can add the following temporary function in your vimrc:
function! MyTmpFunc()
:%y
:%s/old1/new1/g
normal! G
normal! P
:%s/old2/new2/g
endfunction
Then restart Vim with the files you need to affect (something like vim myfile1.txt myfile2.txt myfile3.txt), and execute the following command:
:argdo call MyTmpFunc()
That's what you described in your question: function MyTmpFunc() will be called for each argument given to Vim.
Now you can delete MyTmpFunc() from vimrc.
Be also aware with :bufdo - it calls some command for each opened buffer. There is also :windo, which executes command for each window, but personally I found :bufdo the most useful.
Also please note that you don't have to create temporary function if you need to execute just a single command in the each buffer. Say, if you need just to replace "old1" to "new1" in the each buffer, then you can execute the following command:
:bufdo %s/old1/new1/g
and that's it.

vim autocommand doesn't run when opening file

I'm using QuickCursor for entering text to forms.
My problem with that is I always have MacVim open, and with hidden enabled, so when I :wq from the temp file QuickCursor make, the buffer stays in MacVim, so I have to delete it to get QuickCursor paste back to the window.
I wanted to solve this with an autocommand in my vimrc:
autocmd BufRead "/private/var/folders/fg/gv_*/T/*" set bufhidden="delete" | startinsert!
but this never run. What could be the problem ? What is the right event to use ? I tried BufWinEnter, BufNewFile, neither of them works, or maybe something else is the problem.
Ok, after several hours of try, I finally found out.
I had added quotes to the bufhidden setting and the filename. It should be:
autocmd BufRead /private/var/folders/fg/gv_*/T/* set bufhidden=delete | startinsert!
With the extra quotes it doesn't work:
"delete" is an invalid option value (see :he bufhidden)
quotes around a filename prevent the wildcards (glob characters) from matching (see doc)
If anybody else using QuickCursor, you can fine-tune it:
autocmd BufWinEnter /private/var/folders/fg/gv_*/T/* set bufhidden=delete |
exe "normal G$" | startinsert!
So it changes to insert mode at the end of the text

How to avoid syntax-highlighting for large files in vim?

Huge files take forever to load and work with in vim, due to syntax-highlighting.
I'm looking for a way to limit size of highlighted files, such that files larger than (say) 10MB will be colorless.
Adding the following line to _vimrc does the trick, with a bonus: it handles gzipped files, too (which is a common case with huge files):
autocmd BufWinEnter * if line2byte(line("$") + 1) > 1000000 | syntax clear | endif
Add to your .vimrc:
autocmd BufReadPre * if getfsize(expand("%")) > 10000000 | syntax off | endif
Note that this disables syntax highlighting in ALL buffers; syntax is a global vim thing and cannot be restricted to a single buffer.
I haven't tried it myself, but the LargeFile plugin seems to be exactly to address the kind of stuff you're looking for.
vim -u NONE <filename>
This will skip all initializations from configuration files.
Use uppercase U when running gvim.
"-i NONE" does only exclude viminfo from being loaded. If you defined syntax hilighting in there, that would help too.
vim -c 'syntax off' filename.ext

Resources