UDL: Suffix Mode
No, there is a misunderstanding, if I use
then a variable like UniqueKey$ will be colored but a variable like
Unique-Key$ won’t be.
If I know what the language allows, which chars can be used for a
variable name, then we can find the right regex to make this work.
String functions can also end with a $ but those I have listed as a keyword in my UDL with prefix mode enabled. Since every function begins with “fn”.
Good to know - do you have a reference to the language you are using?
http://brwiki2.brulescorp.com/index.php?title=Business_Rules! This is a link to the wiki.
Michael Miller31 last edited by Michael Miller31
I can also give you the section from my userDefineLang.xml if it’s helpful
So this is what we are looking for, right?
First the script
# -*- coding: utf-8 -*- from Npp import editor, editor1, editor2, notepad, NOTIFICATION, SCINTILLANOTIFICATION, INDICATORSTYLE import ctypes import ctypes.wintypes as wintypes from collections import OrderedDict try: EnhanceUDLLexer().main() except NameError: user32 = wintypes.WinDLL('user32') WM_USER = 1024 NPPMSG = WM_USER+1000 NPPM_GETLANGUAGEDESC = NPPMSG+84 class SingletonEnhanceUDLLexer(type): _instance = None def __call__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super(SingletonEnhanceUDLLexer, cls).__call__(*args, **kwargs) return cls._instance class EnhanceUDLLexer(object): __metaclass__ = SingletonEnhanceUDLLexer @staticmethod def rgb(r,g,b): return (b << 16) + (g << 8) + r @staticmethod def paint_it(color, pos, length): if pos >= 0: editor.setIndicatorCurrent(0) editor.setIndicatorValue(color) editor.indicatorFillRange(pos, length) def style(self): start_line = editor.getFirstVisibleLine() end_line = start_line + editor.linesOnScreen() start_position = editor.positionFromLine(start_line) end_position = editor.getLineEndPosition(end_line) editor.setIndicatorCurrent(0) editor.indicatorClearRange(0, editor.getTextLength()) for color, regex in self.regexes.items(): editor.research(regex, lambda m: self.paint_it(color, m.span(regex), m.span(regex) - m.span(regex)), 0, start_position, end_position) def configure(self): SC_INDICVALUEBIT = 0x1000000 SC_INDICFLAG_VALUEFORE = 1 # editor.indicSetFore(0, (181, 188, 201)) editor1.indicSetStyle(0, INDICATORSTYLE.TEXTFORE) editor1.indicSetFlags(0, SC_INDICFLAG_VALUEFORE) editor2.indicSetStyle(0, INDICATORSTYLE.TEXTFORE) editor2.indicSetFlags(0, SC_INDICFLAG_VALUEFORE) self.regexes = OrderedDict() # configuration area # self.regexes is a dictionary, basically a key=value list # the key is tuple starting with an increasing number and # the color which should be used, ored with SC_INDICVALUEBIT # the value is a raw bytestring which is the regex whose # matches get styled with the previously defined color # # using OrderedDict ensures that the regex will be # always executed in the same order. # This might matter if more than one regex is used. self.regexes[(0, self.rgb(79, 175, 239) | SC_INDICVALUEBIT)] = (r'fn[A-Za-z0-9_]+?\$|([A-Za-z0-9_]+?\$)', 1) # defining the lexer_name ensures that # only this type of document get styled # should be the same name as displayed in first field of statusbar self.lexer_name = 'User Defined language file - BR! Source' def get_lexer_name(self): ''' returns the text which is shown in the first field of the statusbar ''' language = notepad.getLangType() length = user32.SendMessageW(self.npp_hwnd, NPPM_GETLANGUAGEDESC, language, None) buffer = ctypes.create_unicode_buffer(u' '*length) user32.SendMessageW(self.npp_hwnd, NPPM_GETLANGUAGEDESC, language, ctypes.byref(buffer)) # print buffer.value # uncomment if unsure how the lexername in configure should look like - npp restart needed return buffer.value def __init__(self): editor.callbackSync(self.on_updateui, [SCINTILLANOTIFICATION.UPDATEUI]) notepad.callback(self.on_langchanged, [NOTIFICATION.LANGCHANGED]) notepad.callback(self.on_bufferactivated, [NOTIFICATION.BUFFERACTIVATED]) self.__is_lexer_doc = False self.lexer_name = None self.npp_hwnd = user32.FindWindowW(u'Notepad++', None) self.configure() def set_lexer_doc(self, bool_value): editor.setProperty(self.__class__.__name__, 1 if bool_value is True else -1) self.__is_lexer_doc = bool_value def on_bufferactivated(self, args): if (self.get_lexer_name() == self.lexer_name) and (editor.getPropertyInt(self.__class__.__name__) != -1): self.__is_lexer_doc = True else: self.__is_lexer_doc = False def on_updateui(self, args): if self.__is_lexer_doc: self.style() def on_langchanged(self, args): self.set_lexer_doc(True if self.get_lexer_name() == self.lexer_name else False) def main(self): self.set_lexer_doc(True) self.style() EnhanceUDLLexer().main()
Do the following
copy the script
goto Plugins->Python Script->New Script
give it a meaningful name and press save button
paste the script into the newly ceated document
open one of your BR! Source files
click on Plugins->Python Script->Scripts->NAME_OF_THE_NEWLY_CREATED_PYTHONSCRIPT
If you want to know the details, let me know.
btw, when it works like you want and want it to be available automatically
on every npp startup we need to create a USER startup.py but
I guess this can be discussed it the script is useful to you at all
Thanks for putting the time into this!
First, will this work on 64 bit N++?
I had some trouble finding a version of Python Script that was compatible but I managed to find a beta version.
also, I’m getting this error.
Traceback (most recent call last):
File “C:\Users\mmiller\AppData\Roaming\Notepad++\plugins\Config\PythonScript\scripts\create_strings.py”, line 4, in <module>
File “C:\Program Files\Notepad++\plugins\PythonScript\lib\ctypes_init_.py”, line 7, in <module>
from _ctypes import Union, Structure, Array
ImportError: No module named _ctypes
Yes, as I’m using x64 version as well.
Where did you download pythonscript plugin from?
Why didn’t you use Plugin Manager?
The official release channel for python script plugin is here.
I don’t have plugin manager so I went through http://docs.notepad-plus-plus.org/index.php?title=Plugin_Central .
Thanks for dealing with my idiocy. Going through plugin manager worked perfectly. Is there any way I can donate for your time?
Meta Chuh last edited by
Is there any way I can donate for your time?
yes, we urgently need 5 macbook pro’s. 👍
thanks in advance. 😂
Thank you very much for asking and yes there is one thing
you could do if you like :-)
It might sound strange but if you have or know a cooking recipe
which is worth testing - I would appreciate.
I know tastes are different so … :-)
REALLY - macbooks … NOWADAYS … :-D
I will get you a recipe when I get home from work. :-)
The macbooks will take some time. :-D
Thanks again for your help.
I also realized afterwards that there are a few internal functions that end with $ and don’t start with fn but I just modified the regex to take care of them.
thank you thank you very much - very much appreciated - I LOVE MUFFINS (who doesn’t ?)
And also nice to see that you already made the script do what you want.
Have a nice day.
Alan Kilborn last edited by
Much better to have an actual recipe than simply all the talk of “baking cookies” that goes on around here sometimes!