Syntax highlight entire line - or to end of line
-
Is there a way to have syntax highlighting color an entire line (i.e. the width of the notepad++ window). Scite and some other scintilla derived apps have the “eolfilled” option on syntax lexers but I can’t seem to find anything like it on notepad++
Please help - thank you
-
Notepad++ sets this option on a few of the lexers but doesn’t expose any type of option to the user. Is there a specific language/style you are wanting to set? With the right plugin you can most likely do it.
-
Thank you for the reply! Initially, I’d like to do it on the C++ lexer… but what I really want to do is make a custom lexer, not so much for coding-language syntax, but for note-taking. For example:
If I could define 8 or 10 different “line comment” character(s), I could use these to have a colored-line separating different topics / sub-topics.
I know this is a non-standard use, but if anyone has a way to do this it would really help me out a lot.
-
I’d like to do it on the C++ lexer
That is possible. There are plugins that can help out. PythonScript is one option if you are familiar with it. Another one is LuaScript that I created. Using LuaScript you could set all C++ line comments to extend the background color to the end of the line by doing
npp.AddEventHandler("OnSwitchFile", function(filename, bufferid) if npp.BufferLangType[bufferid] == L_CPP then editor.StyleEOLFilled[SCE_C_COMMENTLINE] = true end end)
Obviously that can be changed as needed, but that’s the gist of it.
what I really want to do is make a custom lexer
You have a few ways of doing it. One would be to create a custom User Defined Language in Notepad++. I’ve never done it myself so it may or may not be sufficient for what you need. Another way would be to write a custom lexer in C++ or C# as a plugin…certainly non-trivial to do. Another way would be to use the LuaScript plugin again. I’ve been working on some changes to the plugin that would allow writing a custom lexer in Lua. For example it would look something like this to highlight a CSV file with alternating line row colors.
npp.AddEventHandler("OnSwitchFile", function(filename, bufferid) if npp:GetExtPart() == ".csv" then npp.AddEventHandler("OnStyle", StyleCSV) editor.Lexer = SCLEX_CONTAINER editor.StyleBack[1] = 0xffffff editor.StyleBack[2] = 0xC0D9AF editor.StyleEOLFilled[1] = true editor.StyleEOLFilled[2] = true editor:ClearDocumentStyle() editor:Colourise(0, -1) editor.CaretLineVisible = false else npp.RemoveEventHandler("OnStyle", StyleCSV) editor.CaretLineVisible = true end end) -- A line oriented lexer - style the line according to the line number function StyleCSV(styler) local lineStart = editor:LineFromPosition(styler.startPos) local lineEnd = editor:LineFromPosition(styler.startPos + styler.lengthDoc) editor:StartStyling(styler.startPos, 31) for line=lineStart,lineEnd,1 do local lengthLine = editor:PositionFromLine(line+1) - editor:PositionFromLine(line) if line % 2 == 0 then editor:SetStyling(lengthLine, 1) else editor:SetStyling(lengthLine, 2) end end end
All this should be doable with the PythonScript plugin as well but I’m not as familiar with it. If you are interested in trying to right it in Lua I can get you a new build of the plugin to try it out.
-
I am not familiar with either python or lua but if I have a template to work with, I can probably work my way around.
Here’s an example of what I’m currently working with using programmers notepad - (hasn’t been developed in years)
http://i.imgur.com/fCq96tW.gif
but I’m limited to just a few line styles because I am using c++ syntax lexer.So, I would love to work on this - go ahead and let me know where to begin - or I can wait until you have the lua plugin ready.
Thanks again - it is appreciated.
p.s. how did you post the in-line images here? -
I didn’t have much to go on but this is what I put together real quick. Depending on what the line starts with, it will color the line. This expects exact indentation but if you provide a bit more info it wouldn’t be hard to change it.
It’s not perfect but with more time it can probably be tweaked. You can easily add new strings to style the line differently or change the colors. This is what it currently looks like
To use this…
- Download the latest LuaScript plugin
- Copy it to your plugins directory
- Start N++
- Select
Plugins > LuaScript > Edit Startup Script
- Paste the code (see below)
- You’ll probably have to change line #12. I have it based on file extension currently.
- You can change the colors too
- Save/Restart N++
- Open up one of your files
And the code…
styles = { -- string, foreground, background, bold -- colors are BGR hex {"///", 0x000000, 0xffffff, true}, {" //", 0xffffff, 0x00ff00, false}, {" '", 0xffffff, 0x0000ff, false}, -- add to this list as needed } default = {0xffffff, 0x000000, false} npp.AddEventHandler("OnSwitchFile", function(filename, bufferid) if npp:GetExtPart() == ".notes" then -- This is currently based on file extention npp.AddEventHandler("OnStyle", StyleNotes) editor.Lexer = SCLEX_CONTAINER editor.StyleFore[STYLE_DEFAULT] = default[1] editor.StyleBack[STYLE_DEFAULT] = default[2] editor.StyleBold[STYLE_DEFAULT] = default[3] for i,v in ipairs(styles) do editor.StyleFore[i] = v[2] editor.StyleBack[i] = v[3] editor.StyleBold[i] = v[4] editor.StyleEOLFilled[i] = true end editor:ClearDocumentStyle() editor:Colourise(0, -1) editor.CaretLineVisible = false -- Just remove it for now else npp.RemoveEventHandler("OnStyle", StyleNotes) editor.CaretLineVisible = true -- Restore it end end) -- Line oriented lexer function StyleNotes(styler) local function sstarts(String,Start)return string.sub(String,1,string.len(Start))==Start end local lineStart = editor:LineFromPosition(styler.startPos) local lineEnd = editor:LineFromPosition(styler.startPos + styler.lengthDoc) editor:StartStyling(styler.startPos, 31) for line=lineStart,lineEnd,1 do local lengthLine = editor:PositionFromLine(line+1) - editor:PositionFromLine(line) if lengthLine == 0 then break end local lineText = editor:GetLine(line) local styleToUse = STYLE_DEFAULT for i,v in ipairs(styles) do if sstarts(lineText, v[1]) then styleToUse = i break end end editor:SetStyling(lengthLine, styleToUse) end end
how did you post the in-line images here?
You’d type this…
![](http://i.imgur.com/fCq96tW.gif)
In your post and it shows up.
-
Thank you - this is great. Could you help me to change a couple of things?
- I would like the highlighting to start at the location of the syntax trigger - (i.e. // or ///, etc.) So any whitespace before the symbol would not be highlighted.
- I would like to be able to indent these as needed (related to request #1) so the syntax rule would be something like “Highlight if symbol begins a line or if there are only BRACES or whitespace preceding it (spaces, tabs)” - like this:
And then, am I able to add as many of these highlighting rules as I want and to define the characters / characterSets that trigger them? Currently, I am using these because they happen to be the comment symbols used by c++ but I would like to change/add a few.
And can this be used concurrently with another highlighting lexer? It doesn’t seem to work but I thought I’d ask. One of the reasons is that I’d like to be able to use BRACES { } or something in order to be able to collapse / fold the sections as needed.
Thank you again for the time you’ve spent on this.
-
So any whitespace before the symbol would not be highlighted.
Yep very doable.
I would like to be able to indent these as needed
Also doable.
am I able to add as many of these highlighting rules as I want
This should be able to handle about 30 of them. Any more than that then extra logic would have to be added to handle ~200.
and to define the characters / characterSets that trigger them?
Yep.
And can this be used concurrently with another highlighting lexer?
No that’s not possible.
in order to be able to collapse / fold the sections as needed.
I’ve never tried it but the folding can probably be done with Lua as well.
I’ll see what I can come up with.
-
You’ll have to re-download the DLL here since I tracked down a bug in the plugin. Follow the above steps again and replace the code with this…
styles = { -- pattern, foreground, background, bold -- colors are BGR hex {"^[%s{}]*()///", 0x000000, 0xffffff, true}, {"^[%s{}]*()//", 0xffffff, 0x00ff00, false}, {"^[%s{}]*()'", 0xffffff, 0x0000ff, false}, -- add to this list as needed } default = {0xffffff, 0x000000, false} npp.AddEventHandler("OnSwitchFile", function(filename, bufferid) -- Always try to remove it just to be safe npp.RemoveEventHandler("OnStyle", StyleNotes) if npp:GetExtPart() == ".notes" then npp.AddEventHandler("OnStyle", StyleNotes) editor.Lexer = SCLEX_CONTAINER editor.StyleFore[STYLE_DEFAULT] = default[1] editor.StyleBack[STYLE_DEFAULT] = default[2] editor.StyleBold[STYLE_DEFAULT] = default[3] for i,v in ipairs(styles) do editor.StyleFore[i] = v[2] editor.StyleBack[i] = v[3] editor.StyleBold[i] = v[4] editor.StyleEOLFilled[i] = true end editor:ClearDocumentStyle() editor:Colourise(0, -1) editor.CaretLineVisible = false -- Just remove it for now else editor.CaretLineVisible = true -- Restore it end end) -- Line oriented lexer function StyleNotes(styler) local lineStart = editor:LineFromPosition(styler.startPos) local lineEnd = editor:LineFromPosition(styler.startPos + styler.lengthDoc) editor:StartStyling(styler.startPos, 31) for line=lineStart,lineEnd,1 do local lengthLine = editor:PositionFromLine(line+1) - editor:PositionFromLine(line) if lengthLine == 0 then break end local lineText = editor:GetLine(line) local styleToUse = STYLE_DEFAULT for i,v in ipairs(styles) do local m = lineText:match(v[1]) if m ~= nil then if m > 1 then editor:SetStyling(m - 1, STYLE_DEFAULT) lengthLine = lengthLine - m + 1 end styleToUse = i break end end editor:SetStyling(lengthLine, styleToUse) end end
Again you’ll have to change the file extension you want to use, and you can easily change the colors. The styles toward the top can be added to as needed. Like I said you can add about 30 of them before you run into issues.
You can change what triggers the style. They use Lua patterns which are much like regular expressions. For example the first pattern is
^[%s{}]*()///
This means
^
- Start at the beginning of the line%s
- Any whitespace[]
- Creates a group of characters (in this case any whitespace and braces)*
- Allow 0 or more of the characters in the group///
- The actual text
From this you can probably piece together other stuff you want to match
-
I downloaded the latest plugin and used the new code and things are working great.
And thanks for the explanation on how to customize the syntax - 30 different types are plenty and I’ll be able to take it from here.
I do have a couple questions:
- After opening a document of the correct type ( i.e. “.notes” ) if I switch syntax highlighters to something else, how can I switch back to this custom highlighter - I couldn’t see a way?
quote:
I’ve never tried it but the folding can probably be done with Lua as well.I’ll see what I can come up with.
- Have you been able to brainstorm to figure out a way to do code-folding using BRACES or something? Currently the coloring works fine even if I use the braces (thanks to the update you sent) but it does not recognize it as a “code fold”.
Now I’m not is a great hurry and I certainly don’t want to pressure you because it turns out that you’ve ended up writing a partial custom lexer for me - which is more than I expected. I won’t be able to do much more with this until tomorrow evening or Wed. so I may not respond until then if there are any updates.
-
how can I switch back to this custom highlighter
The easiest way is probably just to switch to a file and switch back. The only other way I could think of is possibly tie it to a shortcut key.
to do code-folding using BRACES or something?
It technically should be possible since the plugin simply wraps all the API calls for Scintilla, however I’ve never actually messed with code folding at all so I’m not sure what all it would take to do it properly…so most likely I will pass on this.