I want to highlight lines that are longer than the set textwidth so that it is dynamic for different filetypes. I have the following:
autocmd BufEnter * highlight OverLength ctermbg=darkgrey guibg=#592929
autocmd FileType * execute 'match OverLength /%\{'.&textwidth.',}v.*/'
This code doesn't seem to activate the highlighting, however, the following does work:
autocmd BufEnter * highlight OverLength ctermbg=darkgrey guibg=#592929
autocmd BufEnter * match OverLength /\%>90v.\+*/
I have tried excluding the execute statement and adding the backslashes accordingly but I still cannot seem to get this to work. Also, I think using the execute statement makes this code cleaner. I would appreciate it if someone could explain to me what I am doing incorrectly.
I have referenced the following examples in pursuit of the answer:
highlight long lines
expand a variable in regular expression
If there is a more portable and cleaner way to go about this then please let me know. I am trying to learn as much as possible.
ANSWER:
What I ended up doing is utilizing vim's vim/after/ftplugin folder hierarchy and adding:
set textwidth=100
let &colorcolumn=join(range(&textwidth+1,999),",")
to each filetype.vim file e.g. markdown.vim, java.vim, vim.vim
And for help.vim and man.vim files I didn't want colorcolumn highlighting so I changed the textwidth in those files to 999. By doing this vim was able to distinguish between different file types when they were open in the same session.
What I ended up doing is utilizing vim's vim/after/ftplugin folder hierarchy and adding:
set textwidth=100
let &colorcolumn=join(range(&textwidth+1,999),",")
to each filetype.vim file e.g. markdown.vim, java.vim, vim.vim
And for help.vim and man.vim files I didn't want colorcolumn highlighting so I changed the textwidth in those files to 999. By doing this vim was able to distinguish between different file types when they were open in the same session.
– user2904000
Related
Why privateand publicinclass holdis not highlighted?
First finish the programme, then save the file as a .cpp file with the following vim command :
w your_programme_name.cpp
Vim might be applying the current color settings. Try to override the current
color settings with defaults using the below vim command :
syntax on
Occasionally though, I have seen vim getting confused on what to apply where.
Below is the help text from Vim Documentation. This might be the last resort.
The colors are wrong when scrolling bottom to top. Vim doesn't read
the whole file to parse the text. It starts parsing wherever you are
viewing the file. That saves a lot of time, but sometimes the colors
are wrong.
A simple fix is hitting CTRL-L.
Or scroll back a bit and then forward again.
For a real fix, see |:syn-sync|.
Some syntax files have a way to make it look further back, see the help for
the specific syntax file. For example, |tex.vim| for the TeX syntax.
I am having an annoying behavior in Sublime.
When I start typing out the line...
using namespace SomeNamespace;
The keywords 'using' and 'namespace' are properly colored the keyword coloring. Then when I add the semicolon to the end of the line, the namespace keyword goes white (default text color). I know this is not that significant, but it really annoys me.
Has anyone noticed this behavior before? The code compiles without errors or warnings, so I know sublime is not detecting some so of code problem.
Does anyone have any suggestions on how to fix this problem?
The problem is in this particular regex in the C++ syntax definition:
\b(namespace)\s+([A-Za-z_][_A-Za-z0-9:]*\b)?+(?!\s*?(;|=|,))
At the very end, in the negative lookahead - (?!...) - we see that semicolons are excluded from the match, meaning that if a semicolon is present at the very end of the line, there's no match.
To fix it, you'll need to install the very useful PackageResourceViewer plugin from Package Control. Then, open the Command Palette, type prv to bring up the PackageResourceViewer options, select the Extract Package one, then scroll down and select C++. There will now be a C++ directory in the directory opened by choosing Preferences -> Browse Packages.... Go into that directory and you'll see a bunch of files. Depending on what version of Sublime Text 3 you're using, you'll want to open either C++.tmLanguage or C++.sublime-syntax in Sublime. The .tmLanguage format is XML, so you can pick that for syntax highlighting if you wish, while the .sublime-syntax file is in YAML.
Once the appropriate file is open (you'll either have one or the other, not both), search for the regex above, or just search for namespace, you should find it pretty easily. Delete the ;| from near the end, making the whole thing:
\b(namespace)\s+([A-Za-z_][_A-Za-z0-9:]*\b)?+(?!\s*?(=|,))
Save the file, and that's it! Your C++ source files should update their behavior immediately - if not, just close and reopen them, and in the worst case you can just close them, restart Sublime, then reopen them.
To reproduce my issue:
$ vim -u NONE test.cpp
:set nocompatible
:set tw=20
:set fo=croql
Now type in the following text:
/*
test test test test test test test test test
*/
Notice that there is no leading asterisk on the line containing the tests. Vim will insert this by default, remove it.
Vim should be auto-wrapping this, but it doesn't.
How can I make Vim wrap automatically in comments, and only in comments? :set fo+=t works, but then everything gets wrapped and I do not want automatic hard wrapping for code.
With my OnSyntaxChange plugin, you can change the 'fo' option value depending on whether the cursor inside a comment or not:
call OnSyntaxChange#Install('Comment', '^Comment$', 0, 'a')
autocmd User SyntaxCommentEnterA setlocal fo+=t
autocmd User SyntaxCommentLeaveA setlocal fo-=t
It's also available on GitHub.
Sorry, but Vim by itself cannot be configured to automatically wrap text in multi-line comments, without some character at the beginning of the line. The 'comments' option controls how Vim recognizes comments for automatic wrapping. Multi-line comments must have a "s", "e", and "m" part in the 'comments' option to be recognized; :help format-comments says: "Three-piece comments must have a middle string because otherwise Vim can't recognize the middle lines."
Nevertheless, you can still manually reformat such lines with the gq operator (shorthand gqq for a single line) and Vim should mostly do what you want. If it is slightly off, you can mess with the 'formatexpr' option.
You're probably better off just using the leading * in multi-line comments, or using //-style comments.
There are plugins available that use syntax-defined regions in clever ways which may allow you to work around these limitations. See Ingo's answer.
I'm using VIM 8.2 and it CAN wrap comments out of the box.
Short answer how
set tw=80
set fo=croaq
Check your comments option with :set comments?. I must contains /*, * and */ sequences.
Long answer
You can read details in :help formatoptions, :help fo-table and :help comments.
The tw=80 option is for limiting line width.
The formatoptions uses next flags here:
The c flag is to apply wrapping only for comments
The r and o flag is for auto-inserting the comment-leader on new lines (* symbol for /* styled comment in C-like languages).
The a will auto-format your paragraphs while you are typing.
The q option will handle the comment leader the correct way.
For some types of buffers you can apply formatoptions for all text like next:
"Limit line width for git commit messages to 72 characters
autocmd FileType gitcommit setlocal tw=72
"Auto format all text for git commit messages and markdown files
autocmd FileType gitcommit,markdown setlocal formatoptions+=t
Here
The t flag is to apply wrapping for text (additionally to c)
The comments option will help vim to detect comments correctly.
I am attempting to map a hotkey to do the following in Vim:
Match the current c-word currently marked by the cursor
Generate a list of all found occurrences in current project
Open a new tab showing the results
So, one example I have that uses CTAGS opens the declaration of a variable/function in a new tab like so:
map <C-\> :split<CR>:exec("tag ".expand("<cword>"))<CR>
When it hit CTRL-\, a new tab is opened with the declaration of the variable/function the cursor is on.
The command I am trying to map is shown below:
:lvim /\<\(text_i_want_to_find\)\>/gj *.c
:lw
When I run this command, a new tab is opened showing a list of all .c files containing the text text_i_want_to_find. I need to modify this to do two things different from what it does now:
Search all files with extensions of .c, .h, .cpp, .mk, instead of just .c, and also search files named "Makefile"
Search for the c-word under the cursor like the CTRL-\ mapping I have shown above, as opposed to having to manually type in the text text_i_want_to_find
Here is the code in my .vimrc file for the mapping. I'm not entirely sure if CTRL-/ can be mapped at all, so there's one more problem for me to solve.
map <C-/> :split<CR>:lvim /\<\(.expand("<cword>")\)\>/gj *.c *.h *.cpp *.mk Makefile
Does anyone have any tips on fixing this Vim mapping?
EDIT:
After reviewing the answers provided to me, here's the final version of my code:
command! -nargs=1 SearchAll execute " grep -srnw --binary-files=without-match --exclude={*~,tags} --exclude-dir=.svn . -e " . expand("<args>") . " " <bar> cwindow
map <C-g> :SearchAll <cword><CR>
I mapped it to CTRL+g. I can also invoke it like so as a colon command:
:SearchAll my_text_to_search_for
Hope this helps others as well!
Of course, it does not work: you forgot :execute, :lvimgrep command on its own does not accept expressions, so you are searching for expand("<cword>") that is not followed by a keyword character (\>) and preceded by any character that does not follow keyword character (\<.). \( and \) are useless here. Other notes:
Don’t use map: you need neither this mapping working in visual and operator-pending modes nor ability to use other mappings.
Some patterns can be merged: *.[ch] *.cpp *.mk Makefile or even *.{[ch],cpp,mk} Makefile.
<C-\> can be mapped, but not <C-/> (I hope only currently, but no real work on fixing it is done): \ is 0x5C and <C-\> is 0x5C-0x40=0x1C. But / is 0x2F and 0x2F-0x40<0. On my system pressing <C-/> in terminal transforms into <C-_>, so does <C-->.
:split command does not open a new tab, it opens a new window. Prepend it with :tab to do this.
:lvimgrep is not going to show you the results. It is not either going to jump to the first result unless you remove the j flag.
You forgot final <CR> as well as :lw<CR>. I use :lopen below, in this context they produce just the same result.
You forgot <C-u> after first : or <C-\><C-n> before: it is needed to discard count.
You don’t really need :execute in either of your mappings because there is <C-r>=expand("cword")<CR>, or a default shortcut <C-r><C-w>.
Don’t write :exec(str): it is confusing because :execute is not a function and this syntax encourages others to think it is. Use :execute str.
Thus the final mapping is:
nnoremap <C-\> :<C-u>tab split \| lvimgrep /\V\<<C-r><C-w>\>/gj *.{[ch],cpp,mk} Makefile \| lopen<CR>
. Replace it with
nnoremap <C-\> :<C-u>lvimgrep /\V\<<C-r><C-w>\>/gj *.{[ch],cpp,mk} Makefile \| tab lopen<CR>
if you don’t want to see the current file in a newly opened tab.
Both mappings assume you have neither / nor \ in 'iskeyword' option, if you do replace <C-r><C-w> with <C-r>=escape(expand('<cword>'), '/\')<CR>.
I have ~30.000 lines of badly indented OCaml code (including mly and mll files) and would like to indent them. I tried googling for variations of 'ocaml indent' the closest I can get is to use Omlet.vim and indent the code one line at a time (via C-f in insert mode). Is there a way to do the indentation for all the 30000 lines?
I use Emacs as my editor with this package installed:
http://caml.inria.fr/pub/docs/u3-ocaml/emacs/index.html
To indent existing code you need to highlight it and then use the key combination C-M-\
You can script this per file pretty easily and I find the indentation to be pretty good.
When I want to re-indent a whole file in vim, I use the following key sequence:
g g V G =
Breaking this down for you, g g moves the cursor to the beginning of the file. V enters visual mode. G selects to the end of the file. = indents the selected lines.
This should be much faster than your method of applying indentation line by line, but yet will use the same rules (warning: using Omlet, indenting a whole file may take a while).
Now, one can use ocp-indent (opam install ocp-indent) and invoke it like this :
ocp-indent bad-indented-ocaml.ml > well-indented-file.ml
Use ocp-indent tool for this. Here is an example Makefile rule, that will automatically indent you ml files.
.PHONY: auto-ocp-indent
auto-ocp-indent: *.ml
for mlfile in $^; do ocp-indent -i $$mlfile; done