<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages]]></title><description><![CDATA[<p dir="auto">Re: <a href="/topic/17134/enhance-udl-lexer">Enhance UDL lexer</a><br />
I’ve used the Enhance UDL Lexer (<code>EnhanceUDLLexer.py</code>) posted by <a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a> on February, 2019 to configure the syntax for Go (Golang) and Python. I know Notepad++ has a built-in Python syntax, but I wanted to change it. With that said, I got everything working the way I want: I have two scripts <code>GoUDLLexer.py</code> and <code>PythonUDLLexer.py</code> as well as one UDL <code>.xml</code> file for each language. The only problem is that, although both <code>.xml</code> UDL files take effect simultaneously just fine, only one script works when executing it from the PythonScript plugin. In other words, if I run <code>GoUDLLexer.py</code> first, <code>PythonUDLLexer.py</code> doesn’t work, and if I run <code>PythonUDLLexer.py</code> first, <code>GoUDLLexer.py</code> doesn’t work. If I want to switch languages I need to close and reopen Notepad++ to run the script I need.</p>
<p dir="auto"><strong>Questions:</strong><br />
[1] Am I doing something wrong? (I can post my scripts and <code>.xml</code> files if needed, but I haven’t altered them…just added some <code>regexes[(1, (139,233,253))] = (r'(\w+)\(', 1)</code> to both to change the highlight process.)<br />
[2] Is it possible to have only one script to do both Python and Go at the same time? Maybe even with a list <code>lexer_name = ['Go_Lang', 'Py_Lang']</code> in case I need to add more languages. <code>regexes</code> like the one mentioned above could only take effect on<br />
[3] I’ve read some discussions here about using Python 3 instead of Python 2 (which will be deprecated soon) (<a href="https://community.notepad-plus-plus.org/topic/13237/using-python-with-notepad/2">here</a>) and how to make the change when using it with the Python Script plugin. How does that affect the <code>EnhanceUDLLexer.py</code> script to control syntax on Notepad++?</p>
<p dir="auto">Any help is appreciated! Thank you!</p>
]]></description><link>https://community.notepad-plus-plus.org/topic/19822/using-enhance-udl-lexer-script-to-configure-the-syntax-for-multiple-languages</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Jul 2026 16:53:56 GMT</lastBuildDate><atom:link href="https://community.notepad-plus-plus.org/topic/19822.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 07 Aug 2020 20:46:10 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sun, 16 Aug 2020 00:16:00 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: Alan-Kilborn">@<bdi>Alan-Kilborn</bdi></a><br />
You’re absolutely right. I didn’t mean it like “you must notify me”, it was more like “hey looking forward to seeing any updates” that’s why I added the “lol” at the end. I apologize if I didn’t come across well. Also, thank you the suggestion, I’ll definitely keep an eye on his GitHub page! :D</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56851</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56851</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Sun, 16 Aug 2020 00:16:00 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 15 Aug 2020 23:53:07 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a> said in <a href="/post/56848">Using 'Enhance UDL Lexer' script to configure the syntax for multiple languages</a>:</p>
<blockquote>
<p dir="auto">If you do add more features, let me know!</p>
</blockquote>
<p dir="auto">I guess you could just check back occasionally at its github page for any updates.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56849</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56849</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Sat, 15 Aug 2020 23:53:07 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 15 Aug 2020 23:20:32 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a><br />
Thank you for clarifying this. I guess my understanding of the excluded styles functionality was a bit flawed, but everything makes more sense now.</p>
<blockquote>
<p dir="auto">Thanks for the discussion. Through this I realized that every regular expression should also have an “excluded styles” list to override the general one. That means, if you don’t specify a list in a regular expression, the “global” list will be used, otherwise the list defined by this regular expression will be used.</p>
</blockquote>
<p dir="auto">Glad I could help. If you do add more features, let me know! lol</p>
<p dir="auto">Thank you again for all the help!</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56848</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56848</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Sat, 15 Aug 2020 23:20:32 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Tue, 11 Aug 2020 11:04:35 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a></p>
<blockquote>
<p dir="auto">Which path should I choose for my user startup file to make it run on every startup?</p>
</blockquote>
<p dir="auto">Just create a new script and name it <a href="http://startup.py" rel="nofollow ugc">startup.py</a>.<br />
It will be automatically put into your user script directory.</p>
<blockquote>
<p dir="auto">Is it bad to alter the delivered <a href="http://startup.py" rel="nofollow ugc">startup.py</a> like I did with the extra import?</p>
</blockquote>
<p dir="auto">The included <a href="http://startup.py" rel="nofollow ugc">startup.py</a> will be replaced when there is a PythonScript update, otherwise, no.</p>
<blockquote>
<p dir="auto">I guess bulit-in lexers like HTML, CSS, JavaScript, etc. define their styles with large groups and a lot of keywords/operators etc.<br />
get grouped together in such a way that excluding one style may lead to losing the style on some other stuff that I didn’t want to lose style.</p>
</blockquote>
<p dir="auto">I have the feeling that we have different understandings on the “excluded styles” feature.<br />
This list is intended to be used only to avoid using your own regular expressions in certain situations.<br />
Everything the lexers have done before is not affected.<br />
For example, if we have the following Python code:</p>
<pre><code class="language-py">def my_function(p1, p2):
    ''' description was my_function(p1, p2) does '''
</code></pre>
<p dir="auto">and we would have a regular expression to color p1 and p2, then it would be applied in the function definition line and in the comment line.<br />
If this is desired, then we would not enter the comment styleID in the “excluded styles” list.<br />
But if it is desired to color only the function definition line and not any mention in comments, then the comment styleIDs would be entered.</p>
<p dir="auto">The script doesn’t change what the lexers do, that’s all still there.<br />
The only thing it does is paint over the text of the regular expression matches.</p>
<p dir="auto">Thanks for the discussion. Through this I realized that every regular expression should also have an “excluded styles” list to override the general one.<br />
That means, if you don’t specify a list in a regular expression, the “global” list will be used, otherwise the list defined by this regular expression will be used.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56704</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56704</guid><dc:creator><![CDATA[Ekopalypse]]></dc:creator><pubDate>Tue, 11 Aug 2020 11:04:35 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Mon, 10 Aug 2020 22:29:14 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a><br />
First of all, thank you for the info about measuring execution time.</p>
<p dir="auto">My lexer script is saved here: <code>C:\Users\rtl\AppData\Roaming\Notepad++\plugins\config\PythonScript\scripts\EnhanceUDLLexer.py</code> and to automatically execute it on every startup I added the following line <code>import EnhanceUDLLexer</code>  at the <strong>end</strong> of the delivered <code>startup.py</code> from PythonScript (which is located here <code>C:\Program Files (x86)\Notepad++\plugins\PythonScript\scripts\startup.py</code>).</p>
<p dir="auto">I imported the lexer script (<a href="http://EnhanceUDLLexer.py" rel="nofollow ugc">EnhanceUDLLexer.py</a>) from the delivered <a href="http://startup.py" rel="nofollow ugc">startup.py</a> because I didn’t know you could have other <a href="http://startup.py" rel="nofollow ugc">startup.py</a> scripts. Which path should I choose for my user startup file to make it run on every startup? Is it bad to alter the delivered <a href="http://startup.py" rel="nofollow ugc">startup.py</a> like I did with the extra import?</p>
<p dir="auto">About my previous questions:<br />
[1] I think I understand the basics of this issues. That’s not a problem though…I asked just out of curiosity.</p>
<p dir="auto">[2] I guess bulit-in lexers like HTML, CSS, JavaScript, etc. define their styles with large groups and a lot of keywords/operators etc. get grouped together in such a way that excluding one style may lead to losing the style on some other stuff that I didn’t want to lose style.  But…now that I think about it, it might be easier to just copy the built-in stuff into an UDL and make all the changes I want. Never mind about this question.</p>
<p dir="auto">Thanks again!</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56699</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56699</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Mon, 10 Aug 2020 22:29:14 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Mon, 10 Aug 2020 19:59:59 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a></p>
<blockquote>
<p dir="auto">I know it’s a bit pointless to do this …</p>
</blockquote>
<p dir="auto">I even think this makes sense if you want to extend/modify existing code.<br />
Personally I learn fastest this way. Good job.</p>
<p dir="auto">Measuring execution time is one of those things.<br />
Actually you should make sure that only Npp and PythonScript(PS) are used<br />
to make sure that other plugins don’t interfere.<br />
Because of the accuracy I think that tests that take several milliseconds are relatively accurate,<br />
unless you are programming for a RealTime system, but then Python is probably the wrong language as well.<br />
Higher accuracy could be achieved with ctypes and highperformance counter,<br />
but do we shoot sparrows with cannons here?<br />
But if the question was about how to code timing functions, I prefer decorators.<br />
I have a <strong>user</strong> <a href="http://startup.py" rel="nofollow ugc">startup.py</a> file which is automatically executed on every startup, because it is called <a href="http://startup.py" rel="nofollow ugc">startup.py</a>.<br />
Please do not confuse it with the delivered <a href="http://startup.py" rel="nofollow ugc">startup.py</a> from PS. If you make changes there, they would be lost when you update.<br />
In this user <a href="http://startup.py" rel="nofollow ugc">startup.py</a> I have several functions like</p>
<pre><code class="language-py">from time import perf_counter
def timeit(func):
    def wrapped(*args, **kwargs):
        s = perf_counter()
        x = func(*args, **kwargs)
        e = perf_counter()
        print(f'Calling {func.__name__} took {e-s}')
        return x
    return wrapped
</code></pre>
<p dir="auto">for Python2 it must be changed to</p>
<pre><code class="language-py">from time import time
def timeit(func):
    def wrapped(*args, **kwargs):
        s = time()
        x = func(*args, **kwargs)
        e = time()
        print('Calling {} took {}'.format(func.__name__, e-s))
        return x
    return wrapped
</code></pre>
<p dir="auto">Then all you need to do is</p>
<pre><code class="language-py">@timeit
def my_function_to_test(p1,p2):
    pass
</code></pre>
<blockquote>
<p dir="auto">I’m pretty happy with the result.</p>
</blockquote>
<p dir="auto">And that counts, script is readable, extendable … what would one else.</p>
<ol>
<li>
<p dir="auto">Yes and no. Scintilla knows two ways to colorize text, Styles and Indicators.<br />
Styles offer you the full range of possibilities scintilla offers to manipulate text attributes.<br />
Indicators can only change the font color. In general both can be manipulated from PS.<br />
The reason why indicators are used here is because Lexer uses styles.<br />
If we would also use styles we would always be in “clinch” with the lexers, whose definition is the final one.</p>
</li>
<li>
<p dir="auto">Currently the script doesn’t give that, maybe use a regular expression that takes that into account?<br />
Or am I in the middle of something and don’t understand what you mean?</p>
</li>
</ol>
]]></description><link>https://community.notepad-plus-plus.org/post/56684</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56684</guid><dc:creator><![CDATA[Ekopalypse]]></dc:creator><pubDate>Mon, 10 Aug 2020 19:59:59 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Mon, 10 Aug 2020 17:40:59 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a><br />
I followed your instructions regarding the use of <code>ctypes</code> and the execution of multiple callbacks. I’ve also read your <code>EnhanceAnyLexer.py</code> and “borrowed” a few things (<code>a_few_things == 99%</code> lol). I know it’s a bit pointless to do this since you’ve already wrote a great tool to control multiple lexers, but whatever…</p>
<p dir="auto">Differences include:</p>
<ul>
<li>I don’t check if the version is 1.5.4.0 since I know my version,</li>
<li>I don’t have a <code>rgb(r, g, b)</code> method – I do that outside the <code>EnhanceUDLLexer</code> class,</li>
<li>I don’t register lexers – your advice about “switching the <code>regexes</code> on a <code>bufferactivated</code> event” was very helpful and now I just switch dictionaries inside the style method (<code>self.all_regexes[self.current_language]</code>) based on <code>notepad.getLanguageName(notepad.getLangType())</code>,</li>
<li>I kept the configure method,</li>
<li>and some other minor changes.</li>
</ul>
<p dir="auto">I guess the real difference is the input method for each lexer style since the <code>set_up_list</code> at the beginning gets all rgb’s, regexes, etc… Here’s the final version:</p>
<pre><code># -*- coding: utf-8 -*-
# needs Python Script version 1.5.4.0
from Npp import (notepad,editor,editor1,editor2,NOTIFICATION,
				SCINTILLANOTIFICATION,INDICATORSTYLE,INDICFLAG,INDICVALUE)

set_up_list = [ \

# --------------------- CONFIGURATION AREA --------------------- #

#  "LANGUAGE"
#  R, G, B, "REGEX", MATCH_GROUP
#  ...
#  ...
#  R, G, B, "REGEX", MATCH_GROUP
#  [excluded_style_0, excluded_style_1, ..., excluded_style_23]

"Go_Lang", ## UDL
189, 147, 249, r"\d\.\d+", 0,
139, 233, 253, r"(\w+)\(", 1,
[1, 4, 6, 7, 16, 17, 18, 19],

"Py_Lang", ## UDL
189, 147, 249, r"\d\.\d+", 0,
120, 221, 84, r"(\w+)\(", 1,
240, 143, 47, r"\@\w+", 0,
198, 95, 107, r"\.(\w+)", 1,
86, 182, 194,r"(\w+)\.", 1,
195, 250, 195, r"^class(.\w*)", 1,
[1, 2, 3, 4, 6, 7, 12, 16, 17, 18, 19],

"C_Lang", ## UDL
183, 252, 55, r"(\w+)\(", 1,
255, 121, 198, r"\#\w+", 0,
90, 100, 250, r"\b(stack|node)\b",0,
[1, 3, 4, 6, 7, 12, 16, 17, 18, 19],

"JavaScript", ## not an UDL
120, 221, 84, r"\((.*?)\)", 0,
90, 100, 250, r"\b(var|require)\b",0,
[1, 2, 3, 4, 6, 7, 12, 16, 17, 18, 19],

"HTML", ## not an UDL
90, 100, 250, r"\b(href)\b",0,
189, 147, 249, r"\d\.\d+", 0,
120, 221, 84, r"(\w+)\(", 1,
[0],

"CSS", ## not an UDL
120, 221, 84, r"(.*?)\{", 1,
255, 166, 85, r"[{}]", 0,
255, 84, 18, r"[:;]", 0,
[0],

"R_Lang", ## UDL
120, 221, 84, r"(\w+)\(", 1,
[1, 3, 4, 6, 7, 12, 16, 17, 18, 19], ## add comma at the end

# --------------------- CONFIGURATION AREA --------------------- #

None
]#end of set_up_list's square brackets

def language_set_up(set_up_list):
	all_regexes = {}
	excluded_styles = {}
	regexes = {}
	pattern = lambda x,k: 5*x + k
	change_rgb = lambda r,g,b: (b &lt;&lt; 16) + (g &lt;&lt; 8) + r

	row_count = 0

	while True:
		if isinstance(set_up_list[pattern(row_count,1)], list):
			LANGUAGE = set_up_list[0]
			all_regexes[LANGUAGE] = regexes
			excluded_styles[LANGUAGE] = set_up_list[pattern(row_count,1)]
			if set_up_list[pattern(row_count,2)] != None:
				del set_up_list[0:pattern(row_count,2)]
				regexes = {}
				row_count = 0
			else:
				break

		ID = row_count
		R = set_up_list[pattern(row_count,1)]
		G = set_up_list[pattern(row_count,2)]
		B = set_up_list[pattern(row_count,3)]
		REGEX = set_up_list[pattern(row_count,4)]
		MATCH_GROUP = set_up_list[pattern(row_count,5)]
		
		regexes[(ID, change_rgb(R,G,B) | INDICVALUE.BIT)] = (REGEX,MATCH_GROUP)
		
		row_count += 1

	all_regexes[LANGUAGE] = regexes	
	return all_regexes, excluded_styles

regexes, excluded_styles = language_set_up(set_up_list)

class EnhanceUDLLexer:
	
	def __init__(self, all_regexes, excluded_styles):
		self.INDICATOR_ID = 0
		self.doc_is_of_interest = False
		self.all_regexes = all_regexes
		self.excluded_styles = excluded_styles
		self.current_language = ""
		self.configure()

	def configure(self):
		editor1.indicSetStyle(self.INDICATOR_ID, INDICATORSTYLE.TEXTFORE)
		editor1.indicSetFlags(self.INDICATOR_ID, INDICFLAG.VALUEFORE)
		editor2.indicSetStyle(self.INDICATOR_ID, INDICATORSTYLE.TEXTFORE)
		editor2.indicSetFlags(self.INDICATOR_ID, INDICFLAG.VALUEFORE)
		editor.callbackSync(self.on_updateui, [SCINTILLANOTIFICATION.UPDATEUI])
		editor.callbackSync(self.on_marginclick, [SCINTILLANOTIFICATION.MARGINCLICK])
		notepad.callback(self.on_langchanged, [NOTIFICATION.LANGCHANGED])
		notepad.callback(self.on_bufferactivated, [NOTIFICATION.BUFFERACTIVATED])

	def paint_it(self, color, match_position, length, start_position, end_position):
		if (match_position + length &lt; start_position or
			match_position &gt; end_position or
			editor.getStyleAt(match_position) in self.excluded_styles[self.current_language]):
			return

		editor.setIndicatorCurrent(0)
		editor.setIndicatorValue(color)
		editor.indicatorFillRange(match_position, length)


	def style(self):
		start_line = editor.docLineFromVisible(editor.getFirstVisibleLine())
		end_line = editor.docLineFromVisible(start_line + editor.linesOnScreen())
		if editor.getWrapMode():
			end_line = sum([editor.wrapCount(x) for x in range(end_line)])

		onscreen_start_position = editor.positionFromLine(start_line)
		onscreen_end_pos = editor.getLineEndPosition(end_line)

		editor.setIndicatorCurrent(0)
		editor.indicatorClearRange(0, editor.getTextLength())
		for color, regex in self.all_regexes[self.current_language].items():
			editor.research(regex[0],
							lambda m: self.paint_it(color[1],
													m.span(regex[1])[0],
													m.span(regex[1])[1] - m.span(regex[1])[0],
													onscreen_start_position,
													onscreen_end_pos),
							0,
							onscreen_start_position,
							onscreen_end_pos)

	def check_lexer(self):
		current_language = notepad.getLanguageName(notepad.getLangType()).replace('udf - ','')
		if current_language in self.all_regexes:
			self.doc_is_of_interest = True
			self.current_language = current_language

	def on_marginclick(self, args):
		if args['margin'] == 2 and self.doc_is_of_interest:
			self.style()

	def on_bufferactivated(self, args):
		self.check_lexer()

	def on_updateui(self, args):
		if self.doc_is_of_interest:
			self.style()

	def on_langchanged(self, args):
		self.check_lexer()


	def main(self):
		self.on_bufferactivated(None)
		self.on_updateui(None)


Enhance = EnhanceUDLLexer(regexes,excluded_styles)
Enhance.main()
</code></pre>
<p dir="auto">I timed this script, my old script (with multiple callbacks) and your <code>EnhanceAnyLexer.py</code> script. All of them were timed using the same method and with the same number of lexers (7 = 4 UDLs and 3 built-in lexers). I did not change the registration process when timing <code>EnhanceAnyLexer.py</code>. In other words, I added styles as expected, for example: <code>r_regexes = _dict()</code> =&gt; <code>r_regexes[(0, (120, 221, 84))] = (r"(\w+)\(", 1)</code> =&gt; <code>r_excluded_styles = [1, 3, 4, 6, 7, 12, 16, 17, 18, 19]</code>.</p>
<p dir="auto">I timed all scripts by adding a the following to them:</p>
<pre><code>import time
start = time.time()
#
# actual lexer script
#
end = time.time()
print "Lexer Time: %.2f ms" % (1000*(end-start))
</code></pre>
<p dir="auto">I don’t know if this method is accurate or appropriate for this particular situation (if you know of a better way, please let me know), but both <code>EnhanceAnyLexer.py</code> and my new script got an average of 30 ms, which seems to indicate that I don’t have any performance issues like multiple callbacks, etc. However, my old script, just as you said, got an average of 3250 ms lol … 7 lexers with multiple callbacks do add up quickly.</p>
<p dir="auto">So, that’s it. I’m pretty happy with the result. Two things I’d like to ask are: [1] is it possible to control bold/italic/underline/other rich text stuff via Python? [2] instead of excluding entire styles, is it possible to excluded specific keywords/operators/delimiters/etc. like excluding only the word <code>def</code> for example.?</p>
<p dir="auto">Thank you!!</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56671</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56671</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Mon, 10 Aug 2020 17:40:59 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 22:17:22 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a> <a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: Alan-Kilborn">@<bdi>Alan-Kilborn</bdi></a></p>
<p dir="auto">I did the test with PythonScript3 and a compiled (pyc) and a non-compiled version.</p>
<p dir="auto">The result is that both are more or less equally fast.<br />
I used the script itself to measure how long it takes to format the code in an update ui event.<br />
Result: 0.8 - 2.0 milliseconds on my machine.<br />
Sometimes the non-compiled version was faster, next time the pyc version was faster.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56622</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56622</guid><dc:creator><![CDATA[Ekopalypse]]></dc:creator><pubDate>Sat, 08 Aug 2020 22:17:22 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 20:59:26 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a> <a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: Alan-Kilborn">@<bdi>Alan-Kilborn</bdi></a></p>
<p dir="auto">I never timed a compiled version with a non-compiled version but I<br />
assume that the difference isn’t that big if there is a difference at all.<br />
I’ll try to measure this.</p>
<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a></p>
<p dir="auto">With the newest PythonScript version 1.5.4 there is no need to use<br />
ctypes in order to get the language name anymore. You can use<br />
<code>notepad.getLanguageName(notepad.getLangType())</code></p>
<p dir="auto">A performance issue might arise for this part of the code</p>
<pre><code class="language-py">for key in list(regexes.keys()):
	EnhanceUDLLexer(regexes[key],key).main()
</code></pre>
<p dir="auto">This will lead to multiple callbacks calls. Every new language will<br />
create another set of callbacks and all do get called even only one language is used at a time.<br />
Switch the regexes on a bufferactivated event.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56619</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56619</guid><dc:creator><![CDATA[Ekopalypse]]></dc:creator><pubDate>Sat, 08 Aug 2020 20:59:26 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 20:28:14 GMT]]></title><description><![CDATA[<p dir="auto">Ohhh - this changed more than I thought it might do but good to see<br />
that you already started to improve it - well done.</p>
<p dir="auto">I just was about to post the <a href="https://github.com/Ekopalypse/NppPythonScripts/tree/master/npp" rel="nofollow ugc">link to the repo</a> with the modified version</p>
<p dir="auto">Regarding the question about Npp object, this is the object<br />
PythonScript itself defines within its cpp code. It uses boost::python to<br />
create the python objects.</p>
<p dir="auto">I will have a look at your version and see if I can “borrow” some code :-)</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56617</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56617</guid><dc:creator><![CDATA[Ekopalypse]]></dc:creator><pubDate>Sat, 08 Aug 2020 20:28:14 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 20:20:30 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a></p>
<p dir="auto">So a bit of background.  <code>NppExec</code> can certainly run Python, but the environment you’d get isn’t the one you need for the task at hand.  You need something that is aware of the Notepad++ objects, specifically the <code>editor</code> object.  This relates to the <code>import</code> stuff you were asking about before.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56616</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56616</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Sat, 08 Aug 2020 20:20:30 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 19:39:16 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/alan-kilborn" aria-label="Profile: Alan-Kilborn">@<bdi>Alan-Kilborn</bdi></a> yeah…I thought that this might be a bit weird. I’ve used the <code>NppExec</code> plugin in the past to do some simple stuff, so I was curious to know if that sort of stuff would be possible with or without the <code>NppExec</code> plugin.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56615</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56615</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Sat, 08 Aug 2020 19:39:16 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 19:24:08 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a> said in <a href="/post/56613">Using 'Enhance UDL Lexer' script to configure the syntax for multiple languages</a>:</p>
<blockquote>
<p dir="auto">compiling the script to .pyc or .exe to optimize</p>
</blockquote>
<p dir="auto">That one doesn’t make any sense in the context, but I’ll let <a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a> comment on the other stuff as he is the author of the original.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56614</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56614</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Sat, 08 Aug 2020 19:24:08 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Sat, 08 Aug 2020 18:59:06 GMT]]></title><description><![CDATA[<p dir="auto"><strong>After a lot of trial and error, I’ve found a solution!! :D</strong></p>
<p dir="auto">I do <strong>not</strong> know if it’s the best method or the most efficient, but it’s certainly getting the job done. Now, I can call a single script to make all the changes I want (in all the User Defined Languages).</p>
<p dir="auto">It’d be awesome to get a second opinion. Please let me know what mistakes I made (situations where this script might fail, inefficiency, etc…).</p>
<p dir="auto">Here it is:</p>
<p dir="auto">This first snippet really made my day. I used <code>lambda</code> functions to match the pattern <strong>inside</strong> the configuration area. So, if you follow the pattern below, you can use its predictability to compute everything. I only tested this with two languages (Go and Python), but I added different styles to both to make sure everything works. This should work on more UDLs and/or more styles, but I’m not 100% sure.</p>
<pre><code># --------------------- CONFIGURATION AREA --------------------- #

# LANGUAGE,
# R, G, B, REGEX, MATCH_GROUP

"Go_Lang",
189, 147, 249, "\d\.\d+", 0,
139, 233, 253, "(\w+)\(", 1,

"Py_Lang",
189, 147, 249, "\d\.\d+", 0,
120, 221, 84, "(\w+)\(", 1,
240, 143, 47, "\@\w+", 0,
252,196,153,"\.(\w+)",1,
195,250,195,"^class(.\w*)",1

# --------------------- CONFIGURATION AREA --------------------- #
</code></pre>
<p dir="auto"><strong>Note:</strong></p>
<ul>
<li><code>"Go_Lang"</code> and <code>"Py_Lang"</code> are the exact names (matching upper/lowercase) of my UDLs in the <code>Languages</code> tab.</li>
<li>UDL names must be defined once – no more, no less. After that, you can just describe the style for each respective language.</li>
<li>The style configuration should follow the <a href="https://community.notepad-plus-plus.org/topic/17134/enhance-udl-lexer">original script</a> by <a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a>  with a few minor changes: [1] do not add the <code>r</code> that precedes the regex byte string; [2] do not add a unique number for each style configuration, this is done automatically; [3] remember to add a comma <code>,</code> after each and every item, <strong>except</strong> for the last one.</li>
</ul>
<p dir="auto">Here’s the full script:</p>
<pre><code># -*- coding: utf-8 -*-

from Npp import editor, editor1, editor2, notepad, NOTIFICATION, SCINTILLANOTIFICATION, INDICATORSTYLE
import ctypes
import ctypes.wintypes as wintypes
from collections import OrderedDict


set_up_list = [ \

# --------------------- CONFIGURATION AREA --------------------- #

# LANGUAGE,
# R, G, B, REGEX, MATCH_GROUP

"Go_Lang",
189, 147, 249, "\d\.\d+", 0,
139, 233, 253, "(\w+)\(", 1,

"Py_Lang",
189, 147, 249, "\d\.\d+", 0,
120, 221, 84, "(\w+)\(", 1,
240, 143, 47, "\@\w+", 0,
252,196,153,"\.(\w+)",1,
195,250,195,"^class(.\w*)",1

# --------------------- CONFIGURATION AREA --------------------- #

]#end of set_up_list's square brackets

def language_set_up(set_up_list):
	all_regexes = {}
	regexes = {}
	pattern = lambda x,k: 5*x + k
	
	row_count = 0
	keep_going = True

	while keep_going == True:
		try:
			LANGUAGE = set_up_list[0]
			ID = row_count
			R = set_up_list[pattern(row_count,1)]
			G = set_up_list[pattern(row_count,2)]
			B = set_up_list[pattern(row_count,3)]
			REGEX = r"%s" % set_up_list[pattern(row_count,4)]
			MATCH_GROUP = set_up_list[pattern(row_count,5)]
			regexes[(ID, (R,G,B))] = (REGEX,MATCH_GROUP)
			
			row_count += 1

			if type(set_up_list[pattern(row_count,1)]) == str:
				all_regexes[LANGUAGE] = regexes
				del set_up_list[0:pattern(row_count,1)]
				regexes = {}
				row_count = 0
		except IndexError:
			keep_going = False
	all_regexes[LANGUAGE] = regexes	
	return all_regexes

regexes = language_set_up(set_up_list)

excluded_styles = [1, 2, 16, 17, 18, 19, 20, 21, 22, 23]

user32 = wintypes.WinDLL("user32")
WM_USER = 1024
NPPMSG = WM_USER+1000
NPPM_GETLANGUAGEDESC = NPPMSG+84
SC_INDICVALUEBIT = 0x1000000
SC_INDICFLAG_VALUEFORE = 1

class EnhanceUDLLexer:
	
	def __init__(self, current_regex, current_language):
		self.current_regex = current_regex
		self.current_language = current_language
		editor.callbackSync(self.on_updateui, [SCINTILLANOTIFICATION.UPDATEUI])
		notepad.callback(self.on_langchanged, [NOTIFICATION.LANGCHANGED])
		notepad.callback(self.on_bufferactivated, [NOTIFICATION.BUFFERACTIVATED])
		self.doc_is_of_interest = False
		self.lexer_name = None
		self.npp_hwnd = user32.FindWindowW(u"Notepad++", None)
		self.configure()

	@staticmethod
	def rgb(r, g, b):
		return (b &lt;&lt; 16) + (g &lt;&lt; 8) + r


	@staticmethod
	def paint_it(color, pos, length):
		if pos &lt; 0 or editor.getStyleAt(pos) in excluded_styles:
			return
		editor.setIndicatorCurrent(0)
		editor.setIndicatorValue(color)
		editor.indicatorFillRange(pos, length)

	def style(self):
		start_line = editor.docLineFromVisible(editor.getFirstVisibleLine())
		end_line = editor.docLineFromVisible(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[0],
							lambda m: self.paint_it(color[1],
													m.span(regex[1])[0],
													m.span(regex[1])[1] - m.span(regex[1])[0]),
							0,
							start_position,
							end_position)
	def configure(self):
		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([ ((k[0], self.rgb(*k[1]) | SC_INDICVALUEBIT), v) for k, v in self.current_regex.items() ])
		self.lexer_name = u"User Defined language file - %s" % self.current_language

	def check_lexer(self):
		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))
		self.doc_is_of_interest = True if buffer.value == self.lexer_name else False

	def on_bufferactivated(self, args):
		self.check_lexer()


	def on_updateui(self, args):
		if self.doc_is_of_interest:
			self.style()

	def on_langchanged(self, args):
		self.check_lexer()


	def main(self):
		self.on_bufferactivated(None)
		self.on_updateui(None)


for key in list(regexes.keys()):
	EnhanceUDLLexer(regexes[key],key).main()

</code></pre>
<p dir="auto">I’ll try to make improvements to this script. I thought about other things like adding bold/ underline/italic, changing background color, compiling the script to <code>.pyc</code> or <code>.exe</code> to optimize, getting rid of the <code>.xml</code> style file and do everything via script to literally control every bit of the text editor, prevent tab lag (it happens sometimes). However, I don’t know if these things are possible or if I’m able to do it. If anyone has insight on these topics or the script itself, it’d be great to hear about it.</p>
<p dir="auto">Thank you!</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56613</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56613</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Sat, 08 Aug 2020 18:59:06 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Fri, 07 Aug 2020 22:37:17 GMT]]></title><description><![CDATA[<p dir="auto">Just an update: I fixed the indentation error, but now I’m getting this message</p>
<pre><code>Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:19:08) [MSC v.1500 32 bit (Intel)]
Initialisation took 140ms
Ready.
Traceback (most recent call last):
  File "C:\Users\riccl\AppData\Roaming\Notepad++\plugins\Config\PythonScript\scripts\EnhanceUDLLexer.py", line 91, in &lt;module&gt;
    class EnhanceUDLLexer(object):
  File "C:\Users\riccl\AppData\Roaming\Notepad++\plugins\Config\PythonScript\scripts\EnhanceUDLLexer.py", line 276, in EnhanceUDLLexer
    EnhanceUDLLexer().main()
NameError: name 'EnhanceUDLLexer' is not defined
</code></pre>
]]></description><link>https://community.notepad-plus-plus.org/post/56597</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56597</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Fri, 07 Aug 2020 22:37:17 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Fri, 07 Aug 2020 21:52:59 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/ekopalypse" aria-label="Profile: Ekopalypse">@<bdi>Ekopalypse</bdi></a> Thank you for your reply. I’m currently trying to make the original script work for multiple languages, if I do find a solution I’ll make sure to post it here.</p>
<p dir="auto">I’ll also keep an eye on your NppPythonScripts repository, but please, if you can, do post the solution here (or a message saying that the solution has been added to your repository).</p>
<p dir="auto">Lastly, I’m new to Notepad++, so I’m having a bit of trouble. It would help me a lot if you could clarify something really quick for me:</p>
<p dir="auto">I’m getting an indentation error here, but there is no indentation error…everything is identical (I only added a second <code>lexer_name</code>, I’ll try using a <code>lexer_name = ['Go', 'Py']</code> list next), which means there’s some other mistake that I’m not seeing. Does the original script accept only one lexer_name?</p>
<pre><code>...
lexer_name_Go = 'Go_Lang'
lexer_name_Py = 'Py_Lang'

### Go_Lang ###
regexes[(0, (189,147,249))] = (r'\d\.\d+', 0)
regexes[(1, (139,233,253))] = (r'(\w+)\(', 1)

## Py_Lang ###
regexes[(2, (189,147,249))] = (r'\d\.\d+', 0)
regexes[(3, (129,234,132))] = (r'(\w+)\(', 1) 

...

class EnhanceUDLLexer(object):
    ...
    self.doc_is_of_interest = False
    self.lexer_name_Go = None
    self.lexer_name_Py = None
    self.npp_hwnd = user32.FindWindowW(u'Notepad++', None) # indentation error here
    self.configure()
</code></pre>
<p dir="auto">Where are these modules?</p>
<pre><code>from Npp import editor, editor1, editor2, notepad, NOTIFICATION, SCINTILLANOTIFICATION, INDICATORSTYLE
import ctypes
import ctypes.wintypes as wintypes
from collections import OrderedDict
</code></pre>
<p dir="auto">I’ve found:<br />
C:\Program Files (x86)\Notepad++\plugins\PythonScript\lib\ctypes\wintypes.py<br />
C:\Program Files (x86)\Notepad++\plugins\PythonScript\lib\collections.py<br />
But couldn’t figure out where <code>Npp</code> was.</p>
<p dir="auto">Thank you again!</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56596</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56596</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Fri, 07 Aug 2020 21:52:59 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Fri, 07 Aug 2020 21:02:57 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/tyler-durden" aria-label="Profile: tyler-durden">@<bdi>tyler-durden</bdi></a></p>
<ol>
<li>
<p dir="auto">probably not - I’ve never tested it with multiple languages before but I will start doing it. And if there is an issue it should be easy to fix.</p>
</li>
<li>
<p dir="auto">I would say yes, this should be the goal having one script<br />
but different configuration for each used language.</p>
</li>
<li>
<p dir="auto">Also PythonScript plugin is moving towards <a href="https://github.com/bruderstein/PythonScript/releases" rel="nofollow ugc">Python3</a> but the impact on this script are minimal.</p>
</li>
</ol>
<p dir="auto">In general, I’m working on an updated version which will be released soon <a href="https://github.com/Ekopalypse/NppPythonScripts" rel="nofollow ugc">here</a>.<br />
I’m planning to do this on monday/tuesday next week.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56589</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56589</guid><dc:creator><![CDATA[Ekopalypse]]></dc:creator><pubDate>Fri, 07 Aug 2020 21:02:57 GMT</pubDate></item><item><title><![CDATA[Reply to Using &#x27;Enhance UDL Lexer&#x27; script to configure the syntax for multiple languages on Fri, 07 Aug 2020 20:55:04 GMT]]></title><description><![CDATA[<p dir="auto">Missing phrase on second question: <code>regexes</code> like the one mentioned above could only take effect on the the language intended to. I tried changing the original script, but haven’t found a way to make it work. I ended up going back to the original script.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/56588</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/56588</guid><dc:creator><![CDATA[tyler durden]]></dc:creator><pubDate>Fri, 07 Aug 2020 20:55:04 GMT</pubDate></item></channel></rss>