Hide/shade code not #defined
-
Hi,
I would like to know if is there any plugins which is able to do hide/shade code not defined by macros?
In the style of C language, I could not find any option to hide/shaded code not #defined.
If not already implemented, is there any plans to develop such plugin?
Thank you in advance.
-
How would you expect a text editor to know the difference between.
#define SOMETHING real_name int SOMETHING = 5; return SOMETHING;
and
int SOMETHING = 5; return SOMETHING;
Or any number of combinations where SOMETHING is #defined in a different .h file which is included in the file actively being edited.
How could Notepad++ (or any other text editor) be able to tell you that
SOMETHING is undefined
in any reliable manner, without being a compiler/linker. (And yes, when Visual Studio tells you there’s something undefined, it’s performing behind-the-scenes compilation/linking or similar… since it’s an IDE bundled with its own compiler/linker, it can do that; Notepad++ is more generic than that, and doesn’t have an associated linker/compiler… especially one that could handle any of the >5 dozen languages that Notepad++ will syntax highlight natively.)Some of us have ways that we’ve hooked external tools to lint or compiler/error-check code. For example, using the PythonScript plugin, I have defined a callback/notification-handler which will run python2 code through the plugin’s internal python interpreter, or run perl code through my external perl.exe, and report back compiler errors which I display as annotations in Notepad++. This allows me to see errors and know where to fix them.
So that is one possible way of handling it.
Someone could, of course, write a custom plugin to do the same thing – but there aren’t anybody just hanging out in this forum looking for ideas for new plugins, AFAICT, so I’ve never seen a random “can someone write this plugin” request be fulfilled. And if they saw that there was a script in one of the scripting language plugins, unless they were disappointed in the speed/performance/features or they were really interested in the concepts behind it, they wouldn’t likely re-implement in a true plugin.
-
How could Notepad++ (or any other text editor) be able to tell you that
SOMETHING is undefined
in any reliable manner, without being a compiler/linker.In fact, Lexilla’s C/C++ lexer already has a basic implementation of this capability:
lexer.cpp.track.preprocessor Set to 1 to interpret #if
/#else
/#endif
to grey out code that is not active.Here’s a quick demo in SciTE (where it’s enabled by default; style enhanced for improved visibility):
@Gustavo-Supplier, I think a language server plugin is what you’re looking for.
-
In fact, Lexilla’s C/C++ lexer already has a basic implementation of this capability:
Cool. I guess it makes sense – I am now thinking it must be only looking at preprocessor directives for the checks, so it’s got an easier job than the example I came up with. When I have some time, I will have to make up a script in PythonScript to enable that attribute, and then play around to confirm where it does and doesn’t come into play.
-
@PeterJones thank you for the answer. You sure have broadened my horizons with your explanation. Indeed, I was aiming at a simpler solution as answered by @rdipardo.
-
@Gustavo-Supplier said in Hide/shade code not #defined:
I was aiming at a simpler solution as answered by @rdipardo.
Since Notepad++ uses Scintilla, then that feature technically exists in Notepad++, but is hidden.
Using the PythonScript plugin and registering a callback, you can make it so that Notepad++ will enable that feature whenever you go into a C/C++ file:
# encoding=utf-8 """in response to https://community.notepad-plus-plus.org/topic/24173/ Enables the lexer.cpp.track.preprocessor property when it's a C/CPP file; also needs to set a style for the appropriate StyleID (though I don't know what it is yet) ### === INSTRUCTIONS === 1. Follow the [FAQ](https://community.notepad-plus-plus.org/topic/23039/faq-desk-how-to-install-and-run-a-script-in-pythonscript) to install PythonScript plugin and this script 2. Run it once normally (per the Usage section of the FAQ) 3. Go to a C/C++ file, and see that code like the following will have different colors for ELSEWHAT and THEREFORE ~~~ #define XYZ #ifdef XYZ #define ELSEWHAT #else #define THEREFORE #endif ~~~ 4. If you want this to run every time you run Notepad++, 1. I assume you named the script PreProcessor24173.py 2. Put the following lines in your "user startup" script (the FAQ explains how to find that) from PreProcessor24173 import PreProcessor24173 lexer_interface_24173 = PreProcessor24173() """ from Npp import editor, notepad, console, NOTIFICATION class PreProcessor24173(object): SCE_C_DEFAULT = 0 SCE_C_PREPROCESSOR = 9 SCE_C_PREPROC_HIDDEN = 64 | SCE_C_PREPROCESSOR def __init__(self): notepad.callback(self.on_bufferactivated, [NOTIFICATION.BUFFERACTIVATED, NOTIFICATION.LANGCHANGED]) self.on_bufferactivated(None) console.write("Registered PreProcessor24173 for C/C++ PREPROCESSOR #define tracking\n") def on_bufferactivated(self,args): lexer = editor.getLexerLanguage() langtype = "{}".format(notepad.getCurrentLang()) if lexer == 'cpp': self.update_cpp() def update_cpp(self): editor.setProperty("lexer.cpp.track.preprocessor", 1) bg = editor.styleGetBack(self.SCE_C_PREPROCESSOR) fg = editor.styleGetFore(self.SCE_C_PREPROCESSOR) clr = ( (bg[0]+fg[0])//2, (bg[1]+fg[1])//2, (bg[2]+fg[2])//2 ) # halfway between FG and BG editor.styleSetFore(self.SCE_C_PREPROC_HIDDEN, clr) if __name__ == '__main__': # notepad.clearCallbacks() # uncomment when debugging lexer_interface_24173 = PreProcessor24173()
=== INSTRUCTIONS ===
- Follow the FAQ to install PythonScript plugin and this script
- Run it once normally (per the Usage section of the FAQ)
- Go to a C/C++ file, and see that code like the following will have different colors for
ELSEWHAT
andTHEREFORE
#define XYZ #ifdef XYZ #define ELSEWHAT #else #define THEREFORE #endif
- If you want this to run every time you run Notepad++,
-
I assume you named the script PreProcessor24173.py
-
Put the following lines in your “user startup” script (the FAQ explains how to find that)
from PreProcessor24173 import PreProcessor24173 lexer_interface_24173 = PreProcessor24173()
-
The script chooses the color as halfway between the foreground and background color of the normal #define preprocessor lines – so in light mode (as shown), it will be lighter/faded; in dark mode, it should get darker (so less contrast with the background)
-
-
@PeterJones Thanks for the solution. It helped me a lot.
-
@PeterJones , Thank you for the post, I tried it and it works!
I wonder if there is a way to set a background to grey for a disabled block of C code, e.g. between
#if 0
…
#endifAlso, where can I find a description of editor.styleSetFore() function, namely the second argument (clr). What are the three integers there?
Thank you,
Vitaly -
I wonder if there is a way to set a background to grey for a disabled block of C code
Use
editor.styleSetBack(...)
instead ofeditor.styleSetFore(...)
Also, where can I find a description of editor.styleSetFore() function
If you click on
editor.styleSetFore()
in your script inside Notepad++, and use Plugins > PythonScript > Context-Help, it will take you to the PythonScript documentation forstyleSetFore
, which tells you that the second argument is the colornamely the second argument (clr). What are the three integers there?
The “color” to use. Specifically, the three integers in the tuple are the red, green, and blue values. In my calculation, I had it set the “disabled/hidden preprocessor section” (aka “SCE_C_PREPROC_HIDDEN”) to the foreground color that’s halfway between the foreground and background of a normal preprocessor (which is a reasonable hidden value, whether in Light Mode or Dark Mode).
So if you want to set the background, you would have to pick red/green/blue values that make sense given your theme, and use
editor.styleSetBack(self.SCE_C_PREPROC_HIDDEN, ...)
where...
is either a tuple variable (likeclr
) or a literal tuple (like(63,63,63)
).(Please note that Scintilla, and thus Notepad++, treat the
#if 0
exactly the same as the#ifdef NOTDEFINED
, so there is no way to distinguish between a hardcoded#if 0
and the define-based#ifdef NOTDEFINED
– so I hope you weren’t asking to be able to distinguish between the two, as you would be disappointed if you were.)—
PS: the
styleSetFore()
didn’t specifically describe that a “color” was in a tuple, because near the top of the Editor Object page, there is a paragraph which says,Colours are a tuple of
(red, green, blue)
where each ofred
,green
, andblue
is between0
and255
.… and that paragraph applies to all “color/colour” arguments throughout the documentation.