matching regexp with contained keyword in vim - syntax-highlighting

I am using vim, and I want to highlight the following construct (which is accepted in ifort, but rejected by xlf)
write(5,*), foo
note the comma before the foo variable. I tried the following
syn match fortranWriteComma "write\s*\(.?*,.?*\),"
This works well as long as instead of "write" I use anything else. Example
syn match fortranWriteComma "whatever\s*\(.?*,.?*\),"
this matches and correctly highlights
whatever(5,*),
If I use write, the keyword recognition of write kicks in and does not perform any highlighting. How can I set vim to have the match prevail over the keyword recognition ?

I partially solved by redefining the keyword as a match
syn clear fortranReadWrite
syn keyword fortranReadWrite backspace close endfile inquire open print read rewind
syn match fortranWrite "write" contained
hi def link fortranWrite Keyword
syn match fortranWriteComma "write\s*(.*,.*)," contains=fortranWrite
hi def link fortranWriteComma Error
Unfortunately, this is still not perfect, as the "write" remains yellow, and only the parenthesized stuff becomes highlighted.
I could not fix this, but it's ok for my purposes. If anyone has a way of getting write in yellow in normal conditions, but everything red if the comma is added, please add it in comments so I can refine it.

Q. If I use write, the keyword recognition of write kicks in and does not perform any highlighting. How can I set vim to have the match prevail over the keyword recognition
A. I believe you should be able to have it both ways using a transparent syntax region:
TRANSPARENT
In a C language file you would like to highlight the () text after a "while"
differently from the () text after a "for". In both of these there can be
nested () items, which should be highlighted in the same way. You must make
sure the () highlighting stops at the matching ). This is one way to do this:
:syntax region cWhile matchgroup=cWhile start=/while\s*(/ end=/)/
\ contains=cCondNest
:syntax region cFor matchgroup=cFor start=/for\s*(/ end=/)/
\ contains=cCondNest
:syntax region cCondNest start=/(/ end=/)/ contained transparent
Now you can give cWhile and cFor different highlighting. The cCondNest item
can appear in either of them, but take over the highlighting of the item it is
contained in. The "transparent" argument causes this.
Notice that the "matchgroup" argument has the same group as the item
itself. Why define it then? Well, the side effect of using a matchgroup is
that contained items are not found in the match with the start item then.
This avoids that the cCondNest group matches the ( just after the "while" or
"for". If this would happen, it would span the whole text until the matching
) and the region would continue after it. Now cCondNest only matches after
the match with the start pattern, thus after the first (.

Related

Vim HereDoc Highlighting

I want to get syntax highlighting inside of a bash heredoc. In addition, I want bash variable dereference and command substitution highlighting in the heredoc.
Using these instructions as a starting point, I was able to add variable dereferencing by examining sh.vim. I imagine you could accomplish command substitution in a similar fashion.
let s:bcs = b:current_syntax
unlet b:current_syntax
syntax include #YAML syntax/yaml.vim
syntax region hereDocYAML matchgroup=Statement start=/<<-\?\s*\z(YML\)/ end=/^\s*\z1/ contains=#YAML,hereDocDeref,hereDocDerefSimple
syn match hereDocDerefSimple "\$\%(\h\w*\|\d\)"
syn region hereDocDeref matchgroup=PreProc start="\${" end="}" contains=#shDerefList,shDerefVarArray
hi def link hereDocDeref PreProc
hi def link hereDocDerefSimple PreProc
My problem is, this doesn't appear to work in any sort of block (if, function, for, etc.). For example:
The only thing I know is that this is not an indentation problem. Changing indentation has no effect, and using indentation outside of a block works properly.
The contains on the definition of shIf appears to limit the possible highlights to whatever items are in shIfList group.
Adding your item to the group as follows will give you highlighting withing that region:
syn cluster shIfList add=hereDocYAML
The same principle holds for all other blocks. For example:
syn cluster shFunctionList add=hereDocYAML
syn cluster shLoopList add=hereDocYAML
It should be noted that the approach you've outlined is not generally useful. First of all, it requires that the included syntax file use groups for their contains definitions.
In addition, it works for YAML because bash dereference syntax and YAML syntax do not conflict. For more complicated syntaxes like sed or awk, you will have conflicts, and the rules to resolve those conflicts will likely require a new syntax entirely.

vim own highlight with specific character

I want my vim to highlight in red some keywords from the Pouet group like 'if(' in my .c files.
I figured out how to highlight if with:
syn keyword Pouet if
(This is my ~/.vim/syntax/c.vim)
and with
highlight Pouet term=NONE cterm=NONE Ctermfg=160 ctermbg=NONE gui=NONE
(And this is a part of my .vimrc)
The problem is,this code doesn't work with special characters like '(' or maybe a space or many spaces.
My question is: how do I make sentences like 'if(' highlight in red ?
Thanks
:syn keyword only works for keyword characters (as defined by the 'iskeyword' setting), and ( usually is not contained.
You have to use :syn match instead, e.g.:
:syn match Pouet "\<if("
This is fine if you define your syntax all on your own. If you want this in addition to the existing C syntax highlighting, you need to analyze the original syntax groups and add stuff like containedin=cConditional, maybe you even have to modify the original syntax definition.
An alternative is matchadd(), which goes on top of the syntax highlighting:
:call matchadd('Pouet', '\<if(')
The problem here is that these matches are window-local, not bound to the filetype like syntax highlighting, so when you split windows or edit another filetype in the current window, the highlighting will be gone / will persist. These problems can be worked around with autocmds, but now it's getting really complex.

Is there a way to delete all comments in a file using Notepad++?

Notepad++ obviously recognizes all comments as such. Is there a way to simply delete all?
Edit: Stat-R's bookmark method has helped greatly, not only for removing comments but for conditionally removing lines in general.
For a general file, first of all you need to know the comment operator of the language you are writing the file in. For example, in java script the comment operator is //.
For the following code...
In NP++, you need to
Mark the lines that contains '//'. Make sure the bookmark option is enabled.
Then, choose from NP++ menu Search>Bookmark>Remove Bookmarked lines
EDIT:
Another solution after #Chris Mirno 's suggestion is as follows:
Use regular expression. See the image below. It is self explanatory
To understand it better, refer to these
In the Find & Replace Dialog, put the following regex and adjust the search options as depicted.
/\*.*?\*/
Replace with: (empty)
Select Mode: Regular Expression AND .(dot) matches newline
This should remove all your C style comments spanned across lines.
Star-R and Chris Mirno Answer are also Correct and Good.
But For Line Comment:
//.*?(?=\r?$)
Explanation:
// will be the Starting Position
.*? Will be any character
(?=\r?$) will search to the end of the line (as it is required in line comment)
Note:
But Still check each of the line because for example if your code contains soap format like
//www.w3.org/2001/XMLSchema-instance\x2......");
it will capture this line because the starting is // and it goes to end of the line so watch out for this :)
Warning to all using Stat-R's solution:
This method will remove lines of code if formatted like this:
echo "hello"; //This comment will be detected
Following his method, the entire line will be removed.
Therefore make sure to go through and make these comments, their own line before doing this method.
I have had some luck running a macro for the above. Basically:
search for // (F3)
select to end of line (shift+end)
delete (delete)
Put // into the search dialog by just searching for it once. Then record the three steps in a macro, then play it back until EOF.
The first time I did it I had a problem, but then it worked, not sure what I did differently.
Anton Largiader's answer was the most reliable one, including complex inline comments.
However, it will leave many empty lines, including ones with empty characters (space, tabs...) so I would just add another step to make it almost perfect:
After running the macro, just do:
Edit > Line Operations > Remove Empty Lines
OR
Edit > Line Operations > Remove Empty Lines (Containing Blank Characters)
1st option is good if you wish to remove only really empty lines
2nd options will remove every empty line even containing space etc. so there will be no more actual spacing left between code blocks. 1st option might be the safest with some manual cleanup afterwards.
As someone suggested in another post, the simplest and most reliable is maybe to export the all text in .RTF format using Menu Plugin-->NppExport-->Export to RTF and then:
-Open the newly created file in Word
-Select any part of any comment
-On the top-right side of Word clic Select--> Select all texts with similar formatting
-Remove the selected comments all at once (del or cut if doesn't work)
To remove Powershell comments if someone find it handy:
Removing Comment in a Powershell using Notepad ++
To find just lines beginning with # (and not with # elsewhere in the line).
Notepad++ SEARCH Menu > Find
‘Mark‘ Tab – fill in as below.
Select ‘Mark All’ (clear all marks if used previously).
Regex ^[#}
enter image description here
SEARCH Menu > bookmark > Remove (or do anything on the list with
them)
Clear all marks to reset
You can select no comments just code by doing the following:
Regex ^[^#}
enter image description here
Enter ctrl+shift+K to remove comment

Block Indent Regex

I'm having problems about a regexp.
I'm trying to implement a regex to select just the tab indent blocks, but i cant find a way of make it work:
Example:
INDENT(1)
INDENT(2)
CONTENT(a)
CONTENT(b)
INDENT(3)
CONTENT(c)
So I need blocks like:
INDENT(2)
CONTENT(a)
CONTENT(b)
AND
INDENT(3)
CONTENT(c)
How I can do this?
really tks, its almost that, here is my original need:
table
tr
td
"joao"
"joao"
td
"marcos"
I need separated "td" blocks, could i adapt your example to that?
It depends on exactly what you are trying to do, but maybe something like this:
^(\t+)(\S.*)\n(?:\1\t.*\n)*
Working example: http://www.rubular.com/r/qj3WSWK9JR
The pattern searches for:
^(\t+)(\S.*)\n - a line that begins with a tab (I've also captured the first line in a group, just to see the effect), followed by
(?:\1\t.*\n)* - lines with more tabs.
Similarly, you can use ^( +)(\S.*)\n(?:\1 .*\n)* for spaces (example). Mixing spaces and tabs may be a little problematic though.
For the updated question, consider using ^(\t{2,})(\S.*)\n(?:\1\t.*\n)*, for at least 2 tabs at the beginning of the line.
You could use the following regex to get the groups...
[^\s]*.*\r\n(?:\s+.*\r*\n*)*
this requires that your lines not begin with white space for the beginning of the blocks.

Visual Studio - How to replace text preserving case

Using the find and replace dialog in Visual Studio (2010) is it possible to replace some text but to preserve the case of the text being replaced.
ie. I want to change 'foo' to 'bar' but in my code I have Foo, foo and FOO. I want the replacement to be Bar, bar, BAR respectively.
Is it possible? I suspect I need to use the regular expression functionality but I need assistance in doing so.
EDIT: I know I can set the match case option, but all that option does is limit the replace to text matching the case of the search term. This is how I am doing it at the moment, but it is tiresome having to do three replacements - foo, Foo and FOO
It is - simply expand the Find Options area of the Find and Replace dialog and check the Match Case checkbox.
Full documentation on the dialog can be found here:
Match case - Only displays instances of the Find what string that are matched both by content and by case. For example, a search for "MyObject" with Match case selected will return "MyObject" but not "myobject" or "MYOBJECT."
Edit: (following clarification)
I don't know of an easy way to do what you want. A RegEx could possibly be constructed that does this, but I suspect that doing 3 search and replace would be faster, easier and less error prone than a RegEx, in this case.
I think if you use "match case" = true then you can replace "Foo" to "Bar" and "foo" to "bar"

Resources