Style token not saved
-
@Alan-Kilborn
There is an error when I choose YES or NO: -
Now it works fine!!!
Running Notepad as administrator the issue is fixed.Thank you very much @Alan-Kilborn
-
OK, with the more detailed error reporting I can see what failed with the script. While running as administrator solves the problem, it is rather like cutting off your arm because you have a hangnail – problem solved, but…
Note that I believe the intent of the script was just to demo the functionality, not really be useful in a general sense. Why do I say this? Because a single file is used for the data, it is only useful with a single source file. (There are some other logistical problems with saving and restoring styling, as well).
Let me rework the script a little, I’ll post a new one here; check back here in a few days…
-
It appears I didn’t give the original script a name in this thread, although I called it
StylingSaveOrLoad.py
on my setup. Thus, for a new script, I’ll call itStylingSaveOrLoad2.py
.The new script is similar to the old, but a major way it is different is that it saves a
.sty
file in the same folder as the original file, to hold the styling data. Thus, if you’re editingtest.txt
and then save the styling by running the script, you’ll seetest.sty
in the same folder.Basic instructions on PythonScripting may be found HERE.
Here’s the script listing:
# -*- coding: utf-8 -*- from __future__ import print_function # references: # https://community.notepad-plus-plus.org/topic/18134/style-token-not-saved/ from Npp import * import inspect import os #------------------------------------------------------------------------------- class SSOL2(object): def __init__(self): self.debug = True if 0 else False if self.debug: pass #console.show() #console.clear() self.this_script_name = inspect.getframeinfo(inspect.currentframe()).filename.split(os.sep)[-1].rsplit('.', 1)[0] # identifiers pulled from N++ source code: SCE_UNIVERSAL_FOUND_STYLE_EXT1 = 25 # N++ style 1 indicator number SCE_UNIVERSAL_FOUND_STYLE_EXT2 = 24 # N++ style 2 indicator number SCE_UNIVERSAL_FOUND_STYLE_EXT3 = 23 # N++ style 3 indicator number SCE_UNIVERSAL_FOUND_STYLE_EXT4 = 22 # N++ style 4 indicator number SCE_UNIVERSAL_FOUND_STYLE_EXT5 = 21 # N++ style 5 indicator number SCE_UNIVERSAL_FOUND_STYLE = 31 # N++ red-"mark" feature highlighting style indicator number self.indicator_number_list = [ SCE_UNIVERSAL_FOUND_STYLE_EXT1, SCE_UNIVERSAL_FOUND_STYLE_EXT2, SCE_UNIVERSAL_FOUND_STYLE_EXT3, SCE_UNIVERSAL_FOUND_STYLE_EXT4, SCE_UNIVERSAL_FOUND_STYLE_EXT5, SCE_UNIVERSAL_FOUND_STYLE, ] def get_data_file_path_for_active_tab(self): active_file_pathname = notepad.getCurrentFilename() if not os.path.isfile(active_file_pathname): return None if active_file_pathname.endswith('.sty'): return None data_file_for_active_tab = active_file_pathname.rsplit('.', 1)[0] + '.sty' return data_file_for_active_tab def save_data_file(self): data_file_for_active_tab = self.get_data_file_path_for_active_tab() if data_file_for_active_tab == None: self.mb('Problem saving styling data for active tab file') return with open(data_file_for_active_tab, 'w') as fo: for indic_number in self.indicator_number_list: for (styled_start_pos, styled_end_pos) in self.highlight_indicator_range_tups_generator(indic_number): fo.write('{i} {start} {stop}\n'.format(i=indic_number, start=styled_start_pos, stop=styled_end_pos)) def load_data_file(self): data_file_for_active_tab = self.get_data_file_path_for_active_tab() if data_file_for_active_tab == None or not os.path.isfile(data_file_for_active_tab): self.mb('Problem loading styling data for active tab file') return with open(data_file_for_active_tab) as fi: for line in fi: (indic, start, end) = line.rstrip().split() editor.setIndicatorCurrent(int(indic)) editor.indicatorFillRange(int(start), int(end) - int(start)) def run(self): saving_not_loading = self.yes_no_cancel('\r\n'.join([ "SAVE current doc's styling to disk file?\r\n", "YES = Yes, please SAVE it", "NO = LOAD styling info from file and apply to current doc", "CANCEL = I'm outta here"])) if saving_not_loading == None: return self.save_data_file() if saving_not_loading else self.load_data_file() def highlight_indicator_range_tups_generator(self, indicator_number): ''' the following logic depends upon behavior that isn't exactly documented; it was noticed that calling editor.indicatorEnd() will yield the "edge" (either leading or trailing) of the specified indicator greater than the position specified by the caller this is definitely different than the scintilla documentation: "Find the start or end of a range with one value from a position within the range" ''' if editor.indicatorEnd(indicator_number, 0) == 0: return indicator_end_pos = 0 # set special value to key a check the first time thru the while loop while True: if indicator_end_pos == 0 and editor.indicatorValueAt(indicator_number, 0) == 1: # we have an indicator starting at position 0! # when an indicator highlight starts at position 0, editor.indicatorEnd() # gives us the END of the marking rather than the beginning; # have to compensate for that: indicator_start_pos = 0 else: indicator_start_pos = editor.indicatorEnd(indicator_number, indicator_end_pos) indicator_end_pos = editor.indicatorEnd(indicator_number, indicator_start_pos) if indicator_start_pos == indicator_end_pos: break # no more matches yield (indicator_start_pos, indicator_end_pos) def print(self, *args): if self.debug: print(self.__class__.__name__ + ':', *args) def mb(self, msg, flags=0, title=''): # a message-box function return notepad.messageBox(msg, title if title else self.this_script_name, flags) def yes_no_cancel(self, question_text): retval = None answer = self.mb(question_text, MESSAGEBOXFLAGS.YESNOCANCEL, self.this_script_name) if answer == MESSAGEBOXFLAGS.RESULTYES: retval = True elif answer == MESSAGEBOXFLAGS.RESULTNO: retval = False return retval #------------------------------------------------------------------------------- if __name__ == '__main__': SSOL2().run()
You can directly invoke this script, to get a prompt box much like the original script:
Or, if you prefer, you can set two up new keycombo-invoked scripts, such that one directly saves the data file, and one applies the styling from the data file (i.e., loads it).
If you like the two-keycombo approach, here’s how to set up the additional scripts needed for that:
- Add these lines to (user)
startup.py
:
import StylingSaveOrLoad2 ssol2 = StylingSaveOrLoad2.SSOL2()
- Create a new script file called
StylingSaveForCurrentFile.py
with content:
# -*- coding: utf-8 -*- ssol2.save_data_file()
- Create a new script file called
StylingLoadForCurrentFile.py
with content:
# -*- coding: utf-8 -*- ssol2.load_data_file()
- Bind the running of these two scripts to keycombos of your choosing
- Add these lines to (user)
-
-
@Alan-Kilborn Works!!! I don’t use notepad++ to develop code, only to create content for my websites, and that helped me a lot, thank you very much.
-
-
@Alan-Kilborn thank you for this great script! I tried it and it works kind of.
Interestingly I have to run the script multiple times to let it apply (load) all word highlightings for a style token.
It seems to be arbitrary how much occurrences of the word that is to be styled are missing.Do you have an idea of the reason of this behaviour?
-
-
@nsk7even said in Style token not saved:
It seems to be arbitrary how much occurrences of the word that is to be styled are missing.
Do you have an idea of the reason of this behaviour?I can see the same thing; currently I don’t know why it is happening. :-(
-
@Alan-Kilborn said in Style token not saved:
Bind the running of these two scripts to keycombos of your choosing
hi I followed your guide it works perfect thank u.
but I dont know how can bind keys to those scripts.
can u help me with that?
sorry for necro if it is not allowed -
@Salep said in Style token not saved:
but I dont know how can bind keys to those scripts.
can u help me with that?The “Basic instructions on PythonScripting may be found HERE” link from Alan’s 2022-Nov-19 post contains the instructions on how to bind keys to those scripts, in installation step 4, in the point starting with “To give it a keyboard shortcut”
-
@PeterJones thank u sir I got it