I am trying to highlight multiple lines that match between two words which are present on two different lines.
1.Todo: used for the todo comments (ones that have "TODO: something" in them)
2.Comment: indicates a code comment.
3.Statement: a code statement like a for loop
4.Type: a user defined type generally
5.PreProc: a pre-processor statement like #include <stdio.h>
To highlight between todo and something on single line we use
/todo.*something
but to highlight between todo and stdio(which is present on 5th line) is there any command.
Thanks.
you can make use \_. to include linebreaks. For the example todo ... stdio, you can try:
/todo\_.\{-}stdio
Related
I have a folder with a few header .h files and the .c application file. Many of the #define's in the header file contain lower case names that I would like to replace with capitalized names. I would like it to search through all the files in the directory for an instance of that defined constant and replace it as well.
I could write a macro to do it in the header file alone by selecting all instances of the word, setting to uppercase and going through the file and forcing the rest to be uppercase (also not great because I'm assuming a maximum number of versions of the word in a file with however many n.n.n.n.'s I have)
*NveUn.n.n.n.n.
Desired output is....
Example BEFORE,
//test.h
#define test 0
//test.c
int main(void) {
printf("%d\n\r",test)
}
Example AFTER,
//test.h
#define TEST 0
//test.c
int main(void) {
printf("%d\n\r",TEST)
}
I think this is the case for a refactoring plugin capability, otherwise will be very difficult to tell if a word found in other file places is actually the word we used in #define. This is just an assumption, but there are many videos on youtube about refactoring. Neovim now has treesitter support, which is a different way to parse code, instead of using regex for it.
I am just giving you these links related to the subject:
Refactoring in Vim
https://github.com/autozimu/LanguageClient-neovim
https://www.youtube.com/watch?v=Qb7v1MZSrFc
You can grep all files creating a quickfix list and run something like:
:vimgrep '\v(.define |,)\zstest' **/*.c
:cfdo %s/\v( |,)\zstest/\U&
:cfdo update
Explaining the above commands:
:vimgrep ........ grep a pattern
**/*.c ......... recursive search
\v .............. very magic (avoid many backslashes)
(.define |,) .... search for define + space or comma
\zs ............. start actual matching from this point
test ............ literal test
cfdo ............ Execute {cmd} in each file in the quickfix list.
cfdo update ..... write changes to all files
I hope this information could be any useful.
What I am trying to do is add #ifdef and #endif before and after of puts.
There are hundreds of puts in the code. The string inside of puts is different in each case. I'm working on this problem with text editors like vim and sublime text 2.
Is there a smarter way of doing such task?
#ifdef SOMETHING
puts("blah blah blah"); ========> puts("blah blah blah");
#endif
Sublime Text:
AFAIR you could use multiple cursors functionality in ST like:
">find_all<, puts, then ctrl+shift+l (or something like that which will give you individual cursor for each highlighted line), then go type required modifications (which will do exact same movement/typing for each line)"
Of course it wouldn't work that well with different indentation and stuff, im afraid...
VIM:
In substitute it should look more or less like this:
:%s/puts(.\{-});/#ifdef SOMETHING\n &\n#endif/g
(though im not sure if something wouldn't need escaping here)
basically it means:
% - for whole file
s - substitute
/first_part/second_part/ - substitute occurence of first_part with second_part
g - globally - meaning for each line found among % (whole file)
and first part is:
normal: 'puts(', then non-greedy (if you don't know what that mean - google for it, really worth to know) regex for any character, then normal: ');' which should match your puts'
and second:
normal: '#ifdef SOMETHING', then newline, then four spaces, then & which means 'found pattern' (basically this puts of yours), then newline, then normal: '#endif'
I wrote it of top of my head so please take into account that some things may need correction (shortcuts in ST or escaping some characters in substitute formula).
Thanks for understanding
I would like to know how am I gonna be able to check if in my 1000 lines txt-file, no two lines have the same pattern. in the third section, namely, "CF.Name" i.e. I have something like :
APPNAME NO CF.Name
automotive_bitcount 1 -funsafe-math-optimizations -fno-guess-branch-probability
automotive_bitcount 1 -fno-guess-branch-probability -fno-inline-functions -funroll-all-loops -O2
security_blowfish_e 2 -funsafe-math-optimizations -fno-ivopts -O2
security_blowfish_e 2 -funsafe-math-optimizations -fno-ivopts -fno-tree-loop-optimize -funroll-all-loops -O2
and so on. Just wanna make sure all the generated CF.Name are different from each other.
My PatternsOnText plugin has a :PrintDuplicateLinesIgnoring command that searches for duplicate content in lines while skipping over certain parts. In your example, you want to ignore the first two sections, which can be matched by start of line, some non-whitespace, some whitespace, some non-whitespace, some whitespace. Ergo:
:PrintDuplicateLinesIgnoring /^\S\+\s\+\S\+\s\+/
Note: This still won't find lines where the same arguments are given in a different order; hopefully, your creation process ensures that, or you'll have to sort the arguments first.
Delete all columns except the one you want to check, then :sort u. If the result is 1000 lines, then you know that no two lines have the same pattern in that section.
I would take parts of the other answers: use :sort as in #Jeff's answer, but use a pattern as in #Ingo Karkat's answer instead of deleting the other columns:
:sort /^\S\+\s\+\S\+\s\+/
Now for something new: a multi-line pattern. If you want to find two consecutive lines that are identical, use /^\(.*\)\n\1$. If you care about the third column (delimited by whitespace) then search for
/\v^\S+\s+\S+\s+(\S+).*\n\S+\s+\S+\s+\zs\1\S#!
For variety, I have used the \v ("very magic") variant. (This way the + and #! do not need to be preceded by \.) Also, I slipped in \zs ("start here") so that you highlight only the interesting part.
I am currently writing a plugin in Vim that needs to highlight arbitrary lines in a file
at the same time.
My approach so far has been implementing match with the line number to highlight it, but the problem is that I would need to add | for every other line in a file and append that information and then call it every time the window gets redrawn.
There is another problem with match in my case, and that is that a line that may not have any whitespace would not look highlighted (match only highlights existing text/whitespace).
So even if I had match rewrite the window and highlighting all the lines I need, from a user's perspective this wouldn't be to useful if the highlighting doesn't show anything if there is no whitespace/text.
Can I get any suggestions in how to effectively show/display/highlight (I'm open to different implementations to solve my problem) arbitrary lines in a file at the same time regardless of amount of text or whitespace?
Edit: My main request is to be able to highlight lines by line number not by regex
matching. So any solution should need to be flexible enough to accept a Line number to match.
Edit: signs is the answer to my problem, and I found this tutorial the best way to grasp and implement what I needed: http://htmlpreview.github.io/?https://github.com/runpaint/vim-recipes/blob/master/text/07_navigation/12_bookmarking_lines_with_visible_markers.html
I would use region rather than match. Here is part of my manuscript syntax file that highlights speech:
:syntax region msSpeech start=/"/ end=/"\|\n\n/
:highlight msSpeech guifg=#000088
It starts with a double quote and ends with another double quote or the end of the paragraph. It will highlight multiple lines if need be.
I need a script code to highlight "[Capítulo" and "]" and everything between them. Thank you.
I want it to work everytime I open , for example, a .txt file. Just like code highlighting.
Here's an easy way to do it:
in vim, make sure syntax highlighting is on with :syn on
run the command :highlight to get a listing of all the highlight group names, and samples of what they look like. The Error group looks like it stands out well in my colorscheme, so I'll use that in my example (but you can use any of the other names, like Todo or Search)
:syntax match Error /\[Capítulo[^\]]*\]/
This pattern will keep you from greedily matching the largest chunk. Even though other people are suggesting you use the regular expression /\[Capítulo.*\]/ - it's probably not what you want, because it will match everything in between if there are two or more such patterns on a line.
For example /\[Capítulo.*\]/ will match this entire line:
[Capítulo foo] these words should not be highlighted [Capítulo bar]
The same example but with /\[Capítulo[^\]]*\]/ will only match stuff inside []:
[Capítulo foo] these words should not be highlighted [Capítulo bar]
With regular expressions, it's a common trick to make a group that matches everything but the character that you want to end your match, instead of using the .* which will match as many characters as it can. In this case, we make the group [^\]]* - which says "match everything except ]."
If this works the way you want it to, add the syntax match line without the ":" to your .vimrc
A regular expression is what you're looking for:
Type / to enter in "search mode" and type:
\[Capítulo.*\]/