Community
    • Login

    renumbering/incremental

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    45 Posts 7 Posters 6.8k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Scott RaskinS
      Scott Raskin @Alan Kilborn
      last edited by

      @Alan-Kilborn thank you. I cant say I am not a little dummy-esque when it comes to this. I can build computers, have written macros, do most things within most software programs (or at least figure it out on my own), but I think with 3 boys, my 4 year old being sick, my 2 year old super enjoying waking us up at night, me waking up at 330-4 every morning and therefore averaging less than 5 hours of sleep a night, Im just not seeing it in that script why it isnt working ( i changed it a little as I realized some things when looking at the programs on a different machine that have 4 digits after the N)

      in the script

      def add_10(m):
      return ‘N’ + str(int(m.group(1)) + 10)

      editor.rereplace(‘N([0000-0400]+)’, add_10);

      I just dont know what is doing what and why it isnt working (as I thought I made the appropriate changes from that link you sent me) and then even THEN, once I get it working, and run the script (I already installed python and tried to run this), hw I get it to run on all open files in the workspace

      so, not a “dummy” per se, but something. The thing that frustrates me the most is, its not like I have no computer knowledge, in which case I would find someone to write it for me. The frustrating part is knowing how to do things similar to this. Knowing that Im on the right path, but I lost my GPS signal a few stops short of my goal

      Lycan ThropeL Alan KilbornA 2 Replies Last reply Reply Quote 0
      • Lycan ThropeL
        Lycan Thrope @Scott Raskin
        last edited by

        @Scott-Raskin ,

        That’s because there is a difference between following a recipe, and knowing how to cook. :) It’s not a slight to you, or a description of the difficulty of the task…it’s simply the difference between something you do all the time, and something you’re trying to pick up that doesn’t work like what you’re used to, even though it can get it done if you knew it better. :)
        Even cooking requires going through the awkward stage of mistakes and experimentation before the knowledge is learned, beyond the concepts. :)

        1 Reply Last reply Reply Quote 1
        • Alan KilbornA
          Alan Kilborn @Scott Raskin
          last edited by Alan Kilborn

          @Scott-Raskin said in renumbering/incremental:

          [0000-0400]

          This is a nonsensical regular expression, as I tried to point out before. And if you are talking about running the script at this stage (i.e., with that expression), I can tell you didn’t heed the earlier advice about getting the replacement working without the script first. :-(

          Is there any reason you didn’t try searching for ^N\d{4}?
          BTW, it looks like you might be trying to limit the number that follows the N to the range 0 <= x <= 400 – is that right? Or are you just looking for “any 4 digits”?

          Things are filling with so much uncertainty it is getting hard to help.

          averaging less than 5 hours of sleep a night

          I feel for you, for those other problems, but I have no other such problems and I still average less than 5 hours myself. :-(

          Scott RaskinS 1 Reply Last reply Reply Quote 2
          • Scott RaskinS
            Scott Raskin @Alan Kilborn
            last edited by

            @Alan-Kilborn So, when I do that search string (I was at at a computer whereit only had 2 digits so I changed it to ^N\d{2} it finds the first line N00, then when I do next it finds the N01 and so on, and I can replace it with any text (I just told it to replace it with “please please please work”

            As for limiting the #s, no I dont need to limit it to anything, some programs have up to N300 some have up to N150.

            Alan KilbornA 1 Reply Last reply Reply Quote 0
            • Alan KilbornA
              Alan Kilborn @Scott Raskin
              last edited by Alan Kilborn

              @Scott-Raskin said:

              I changed it to ^N\d{2} it finds the first line N00, then when I do next it finds the N01 and so on, and I can replace it with any text

              Smells like progress.

              I just told it to replace it with “please please please work”

              Praying can sometimes help. :-)

              As for limiting the #s, no I dont need to limit it to anything, some programs have up to N300 some have up to N150.

              OK, so maybe ^N\d+ is what you want.
              ^ : make sure we are at start of line
              N : literal N
              \d+ : one or more digits

              But hold on…need to know where the digits are so we can replace them.

              Go with ^N(\d+).
              The parens “capture” what we call “group 1” data.

              In the script code, you can see how it uses m.group(1)?
              That refers to whatever was found, for digits after N.
              and you can see how the script code adds 10 to it…

              I think we’re ready to be scriptable; mostly based on your previous attempt, but changed slightly:

              def add_10(m):
                  return 'N' + str(int(m.group(1)) + 10)
              editor.rereplace(r'^N(\d+)', add_10)
              
              Alan KilbornA 1 Reply Last reply Reply Quote 2
              • Alan KilbornA
                Alan Kilborn @Alan Kilborn
                last edited by

                @Scott-Raskin

                I think I see a wrinkle in your original idea of creating some numerical spacing between entries, with your “add 10” idea.

                If you had the sequence 1,2,3,… and you did a simple “add 10” replacement, you’d get 11,12,13,… But you don’t get the desired spacing between the resultant numbers. You’d want to do more of a “multiply by 10” to obtain that spacing: 10,20,30…

                But maybe another problem unforeseen (or really, unthought of, in detail) to this point, is that you want to renumber, not merely increment (by ten, or whatever) an existing number.

                Never fear, let’s just keep going, and we can make the adjustments for the above at the appropriate time!

                swegmikeS Scott RaskinS 3 Replies Last reply Reply Quote 0
                • swegmikeS
                  swegmike @Alan Kilborn
                  last edited by

                  @Alan-Kilborn
                  Probably a lot faster to do this in excel by dragging down column to renumber and if needed use excels macros.

                  Alan KilbornA 1 Reply Last reply Reply Quote 0
                  • Alan KilbornA
                    Alan Kilborn @swegmike
                    last edited by

                    @swegmike said in renumbering/incremental:

                    Probably a lot faster to do this in excel by dragging down column to renumber and if needed use excels macros.

                    One sentence, so many things wrong with it…

                    1 Reply Last reply Reply Quote 0
                    • Phil ColbertP
                      Phil Colbert
                      last edited by

                      Writing here as a former N/C Systems programmer.

                      1. Renumbering is usually easiest if you simply remove all the line numbers, completely, and generate a new set from scratch.

                      Fortunately, this is not like BASIC programs, where the numbers were referenced (GOTO, GOSUB) from other lines. (Some CNC controllers did allow that, but I never saw it used very much in actual CNC programs.)

                      If such references do exist, then you’d need to track down the references, and update them, too, to match. This requires good recordkeeping, and is definitely a candidate for automation.

                      If I recall correctly, some users would number only a selected few lines, e.g., those where a tool change occurred, or those beginning a subroutine or loop. The rest would remain unnumbered. On the other hand, if the machine found a syntax or other error, then tracking it down, without line numbers, became a major pain. There were, then, sometimes, two versions of a program: one with line numbers, used for early runs, and one without, used after the fully-numbered version had been proven reliable.

                      BASIC programs were often numbered in increments of 10, to allow for easy insertion of lines, without having to renumber the whole darn program. If you want to number every line, then I suggest doing the same thing here.

                      1. Doing it for thousands of distinct program files will require two distinct automations: one to locate and enumerate all the CNC files to be changed, wherever they are in the file system, and another to renumber each one.

                      I recommend putting the new, renumbered versions in a new location entirely, to avoid accidentally overwriting the original files. After all, programs rarely work right the first time!

                      Under Windows 10, CMD.EXE’s batch language can probably handle this kind of work. The advantage being that you don’t need to install it; it’s already there. The disadvantage being that it is a horrible programming language for newbies. (And just about everyone else.)

                      Having several years of experience, now, with Python, I can confidently say that Python is a much better bet for writing programs that novices can actually read, understand, and update. No add-on modules are required. Moreover, for tasks like this, very little of the Python language needs to be understood, to do an adequate job.

                      Python is available, free, in the Windows Store, so it is virtually painless to install. And Notepad++ is an excellent editor for writing your Python programs.

                      The sheer volume of work to be done makes it hard for me to recommend Notepad++ – or any manually-operated editor – in any other capacity, for this particular task.

                      1 Reply Last reply Reply Quote 1
                      • Scott RaskinS
                        Scott Raskin @Alan Kilborn
                        last edited by

                        @Alan-Kilborn Yes, that is what I was saying could be a wrinkle. However having been up since 2am, I am realizing that having to insert lines in between is an exception to the rule, rather than the rule.

                        That being said, I ran that script and it worked perfectly. I am going to study (I mean its only 3 lines, but still) that script and try to understand what each part means so maybe I can go forward and make changes on my own. Really my end goal with everything is to be able to learn, so I really appreciate all of the help youve given me to get here.

                        The only thing I dont see, is how to run that script on ALL of the files in the workspace. When I do a find/replace, you can run it on all files open in the workspace (which I will do when I get to the point that you previously helped me with (replacing by line # within program), but I am sure that is somewhere in the python help guides!

                        Thank you again and I will let you know my progress and what I have learned (I know, you are waiting with bated breath)

                        1 Reply Last reply Reply Quote 0
                        • Scott RaskinS
                          Scott Raskin @Alan Kilborn
                          last edited by

                          @Alan-Kilborn and then I am going to do some more research on seeing if I can combine the two things you helped me with into one script (the replacing specific line thing: \A(?-s).\R.\R.*\R)
                          Every time I start looking for the ability to use the script to replace EVERY file in a folders info, someone comes and interrupts me (and with my ADD I have to start all over again) How do you guys do this as I am assuming you are helping dozens of people on top of your regular life?

                          Alan KilbornA 1 Reply Last reply Reply Quote 1
                          • Alan KilbornA
                            Alan Kilborn @Scott Raskin
                            last edited by

                            @Scott-Raskin said in renumbering/incremental:

                            Every time I start …“task x”…, someone comes and interrupts me (and with my ADD I have to start all over again) How do you guys do this as I am assuming you are helping dozens of people on top of your regular life?

                            Hah, well, occupational hazard I guess.
                            Work-from-home helps. :-)
                            But yea, sometimes I wish the “real world” would go away, so I could sit around and play with Notepad++ all day. :-)

                            Scott Raskin 0S 1 Reply Last reply Reply Quote 1
                            • Scott Raskin 0S
                              Scott Raskin 0 @Alan Kilborn
                              last edited by

                              @Alan-Kilborn yeah, can’t work from home unfortunately as production of a physical product is a bit difficult remotely (until we have fully automated robots to do it all)
                              So, before I exhaust myself looking for naught, are either of those things possible (running the script on all of the files loaded in the workspace) and/or adding that line renumbered thing to the python code? If so. I will spend my weekend on the hunt

                              Alan KilbornA 1 Reply Last reply Reply Quote 0
                              • Alan KilbornA
                                Alan Kilborn @Scott Raskin 0
                                last edited by

                                @Scott-Raskin-0 said in renumbering/incremental:

                                are either of those things possible (running the script on all of the files loaded in the workspace) and/or adding that line renumbered thing to the python code?

                                Yes and yes, both are possible.
                                But…I think you started out talking about 1000 files…surely you aren’t going to have that many “loaded in the workspace” of Notepad++??

                                I think you’ve put in some hard work on this solution; how about if I finish up the script for you and post it? We sort of need such a model for the next time someone asks for this frequent need. We already have a template for a similar task that I can modify…

                                Scott Raskin 0S 1 Reply Last reply Reply Quote 0
                                • Scott Raskin 0S
                                  Scott Raskin 0 @Alan Kilborn
                                  last edited by

                                  @Alan-Kilborn so what I did was click load folder into workspace and loaded that folder. I think there were close to 1000 files on the tree on the left. So, if I right click on the folder and do a find/replace and then click replace in all, it will replace in all 1000 files there. As for posting the code that would be amazing (as I’ve already seen a few people with my specific problem, and I imagine others with something similar)

                                  Alan KilbornA 1 Reply Last reply Reply Quote 0
                                  • Alan KilbornA
                                    Alan Kilborn @Scott Raskin 0
                                    last edited by

                                    @Scott-Raskin-0 said in renumbering/incremental:

                                    so what I did was click load folder into workspace and loaded that folder. I think there were close to 1000 files on the tree on the left. So, if I right click on the folder and do a find/replace and then click replace in all, it will replace in all 1000 files there.

                                    OK, I understand your thinking on this now. Unfortunately, there’s no easy way to hook a script with custom-replace functionality into that action. But never fear, what I have in mind will work, albeit a bit differently.

                                    As for posting the code that would be amazing (as I’ve already seen a few people with my specific problem, and I imagine others with something similar)

                                    Yes, give me a bit of time to do it and post it. Although it is 4am where I am (and I’ve just arisen after my 5 hours of sleep), I have a few other tasks to get to as well. Check back here periodically…

                                    Scott Raskin 0S 1 Reply Last reply Reply Quote 3
                                    • Scott Raskin 0S
                                      Scott Raskin 0 @Alan Kilborn
                                      last edited by

                                      @Alan-Kilborn not a problem. You’re doing us all a favor, and thr time it will save me will be way more than the time between now and you posting it so we are all very appreciative. Also I’m in NY so I think we are on the same time zone, and as you can see by when I posted that. We both need to sleep more

                                      1 Reply Last reply Reply Quote 2
                                      • Alan KilbornA
                                        Alan Kilborn
                                        last edited by Alan Kilborn

                                        Under construction, please come back soon. :-(

                                        Edit:

                                        I posted the script, then I wanted to add some comments about it, so I edited it, but the site told me my post was “too long”, so I chopped off the first part (containing the script), thinking that when I submitted, what I submitted would be an additional posting. Doh! It just replaced the original (of course, like it is supposed to do).

                                        So please wait while I reconstruct the two postings. I saved the second one, so no loss there; the first one I have the script listing , of course, but I lost the surrounding data there. :-(

                                        Scott RaskinS 1 Reply Last reply Reply Quote 1
                                        • Alan KilbornA Alan Kilborn referenced this topic on
                                        • Scott RaskinS
                                          Scott Raskin @Alan Kilborn
                                          last edited by

                                          @Alan-Kilborn nothing to be frowny-faced about. Will appreciate it as much next Monday as I would have today

                                          Alan KilbornA 1 Reply Last reply Reply Quote 2
                                          • Alan KilbornA
                                            Alan Kilborn @Scott Raskin
                                            last edited by PeterJones

                                            @Scott-Raskin

                                            So the script listing follows. Before you think, from the length of it, that it was (a) a lot of work for me, or (b) that it is very complicated, well, it really was/is neither. The base algorithm is minimal, and I basically recycled ANOTHER SCRIPT for most of the logic.

                                            Here’s the script listing for what I call ReplaceInFilesUsingCustomReplacementFunction.py (wow, sorry for long name!); after the listing are some details about running it:

                                            # -*- coding: utf-8 -*-
                                            from __future__ import print_function
                                            
                                            # references:
                                            #  https://community.notepad-plus-plus.org/topic/23750/renumbering-incremental
                                            #  also https://community.notepad-plus-plus.org/topic/23638/massive-list-and-massive-search-and-replace
                                            
                                            from Npp import *
                                            import inspect
                                            import os
                                            import fnmatch
                                            
                                            #-------------------------------------------------------------------------------
                                            
                                            class RIFUCRF(object):
                                            
                                                def __init__(self):
                                            
                                                    self.this_script_name = inspect.getframeinfo(inspect.currentframe()).filename.split(os.sep)[-1].rsplit('.', 1)[0]
                                            
                                                    self.debug = True if 0 else False
                                                    if self.debug:
                                                        pass
                                                        #console.show()
                                                        #console.clear()
                                            
                                                    self.run_example_from_pythonscript_docs = True if 0 else False
                                            
                                                    if not self.debug:
                                                        prompt = '\r\n\r\n\r\n'.join([
                                                            'Prompt 1 (of 6):',
                                                            'IT IS STRONGLY SUGGESTED TO MAKE A BACKUP OF ALL ORIGINAL FILES BEFORE CONTINUING !!',
                                                            'Press Cancel to exit script and do that. After that, re-run the script.',
                                                        ])
                                                        if not self.mb_ok_cancel(prompt): return
                                            
                                                    active_tab_filepath = notepad.getCurrentFilename()
                                                    active_tab_filename = active_tab_filepath.rsplit(os.sep, 1)[-1]
                                                    active_tab_extension = active_tab_filename.rsplit('.', 1)
                                            
                                                    if not os.path.isfile(active_tab_filepath):
                                                        self.mb('You must have a tab that has been saved into the file system active when running this script; exiting.')
                                                        return
                                            
                                                    if self.run_example_from_pythonscript_docs:
                                                        # base example from PythonScript docs:
                                                        self.search_regex = r'X([0-9]+)'  # search for X followed by some number of digits; remember what the digits are for use at replace time
                                                    else:
                                                        # vvvvvvvvvv---------- USER MODS REQUIRED BELOW ----------vvvvvvvvvv
                                                        self.search_regex = r'^N\d+'  # search for N followed by some number of digits (but must be at start-of-line)
                                                        # ^^^^^^^^^^---------- USER MODS REQUIRED ABOVE ----------^^^^^^^^^^
                                            
                                                    prompt = '\r\n\r\n'.join([
                                                        'Prompt 2 (of 6):\r\n',
                                                        'Is this the correct search expression to use for the custom replacement?:',
                                                        self.search_regex + '\r\n',
                                                        'Answering No will give you a path to stopping script execution; Yes will continue.',
                                                    ])
                                                    yes = self.yes_no(prompt)
                                                    if not yes:
                                                        msg = '\r\n\r\n'.join([
                                                            'Edit the script code and set this variable to the indended value:',
                                                            'self.search_regex',
                                                            '\r\n',
                                                            'Also verify replacement functionality in this function:',
                                                            'perform_custom_replace_in_one_file',
                                                            '\r\n',
                                                            'After you close this box, the script will exit so you can go off and do that stuff. After that, re-run the script.',
                                                        ])
                                                        self.mb(msg)
                                                        return
                                            
                                                    suggested_search_folder_top_level_path = active_tab_filepath.rsplit(os.sep, 1)[0] + os.sep
                                                    self.print('(default) suggested_search_folder_top_level_path:', suggested_search_folder_top_level_path)
                                            
                                                    user_input = suggested_search_folder_top_level_path
                                                    while True:  # loop until valid folder input is obtained
                                                        search_folder_top_level_paths_list = []
                                                        prompt = '\r\n'.join([
                                                            'Prompt 3 (of 6):',
                                                            'Perform custom replacements in the files in this folder?',
                                                        ])
                                                        user_input = self.prompt(prompt, user_input)
                                                        if user_input == None: return  # user cancel
                                                        input_list = user_input.rstrip().split('\r\n')
                                                        self.print('input_list:', input_list)
                                                        all_input_is_valid = True
                                                        for folder in input_list:
                                                            folder = folder.strip()
                                                            self.print('folder:|{}|'.format(folder))
                                                            if len(folder) == 0: continue
                                                            if folder[-1] != os.sep: folder += os.sep
                                                            if not os.path.isdir(folder):
                                                                self.mb('Invalid folder name specified!:\r\n\r\n{}\r\n\r\nYou will be given a chance to correct this.'.format(folder))
                                                                all_input_is_valid = False
                                                            else:
                                                                search_folder_top_level_paths_list.append(folder)
                                                        if all_input_is_valid and len(search_folder_top_level_paths_list) > 0:
                                                            break  # exit the while loop
                                                    self.print('search_folder_top_level_paths_list:', search_folder_top_level_paths_list)
                                                    only_1_top_level_folder = True if len(search_folder_top_level_paths_list) == 1 else False
                                            
                                                    process_subfolders = self.yes_no_cancel('\r\n\r\n'.join([
                                                        'Prompt 4 (of 6):\r\n',
                                                        'Do custom replacements in files in SUBFOLDERS (if any) {}also?'.format('of this folder ' if only_1_top_level_folder else ''),
                                                        (search_folder_top_level_paths_list[0] if only_1_top_level_folder else '') + '\r\n',
                                                        '(Cancel will exit the script.)',
                                                        ]))
                                                    if process_subfolders == None: return  # user cancel
                                                    self.print('process_subfolders:', process_subfolders)
                                            
                                                    suggested_filespec = '*.*'
                                                    if len(active_tab_extension) == 2: suggested_filespec = '*.' + active_tab_extension[-1]
                                                    prompt = '\r\n'.join([
                                                        'Prompt 5 (of 6):',
                                                        'Supply filespec filter list (ex1.:    *.html *.txt *.log            ex2.:    *.*    )',
                                                    ])
                                                    filter_input = self.prompt(prompt, suggested_filespec)
                                                    if filter_input == None: return  # user cancel
                                                    filters_list = filter_input.split(' ')
                                                    filters_list = [ f for f in filters_list if len(f) > 0 ]  # remove any empty entries in filters_list
                                                    self.print('filters_list:', filters_list)
                                            
                                                    pathnames_matching_filters_list = []
                                                    total_folders_encountered = total_files_encountered = 0
                                            
                                                    for top_level_path in search_folder_top_level_paths_list:
                                                        for (root, __, filenames) in os.walk(top_level_path):
                                                            total_folders_encountered += 1
                                                            total_files_encountered += len(filenames)
                                                            for filter_filespec in filters_list:
                                                                for filename in fnmatch.filter(filenames, filter_filespec):
                                                                    pathnames_matching_filters_list.append(os.path.join(root, filename))
                                                            if not process_subfolders: break
                                                        self.print('pathnames_matching_filters_list:', pathnames_matching_filters_list)
                                            
                                                    num_files_matching_filters = len(pathnames_matching_filters_list)
                                                    if num_files_matching_filters == 0:
                                                        self.mb('Of {tf} files examined in {td} folders, no files matched specified filter(s). Script will exit.'.format(
                                                            tf=total_files_encountered, td=total_folders_encountered))
                                                        return
                                            
                                                    pathname_currently_open_in_a_tab_list = []
                                                    for (pathname, __, __, __) in notepad.getFiles():
                                                        if pathname not in pathname_currently_open_in_a_tab_list:
                                                            pathname_currently_open_in_a_tab_list.append(pathname)
                                                    self.print('pathname_currently_open_in_a_tab_list:', pathname_currently_open_in_a_tab_list)
                                            
                                                    num_folders_below_top_levels = total_folders_encountered - len(search_folder_top_level_paths_list)
                                            
                                                    prompt = '\r\n\r\n'.join([
                                                        'Prompt 6 (of 6):\r\n',
                                                        '---- FINAL CONFIRMATION !!! ----\r\n',
                                                        'Make custom replacements in {nf} candidate files in this folder{b} ?:'.format(
                                                            nf=num_files_matching_filters,
                                                            b=' AND {} folders below'.format(num_folders_below_top_levels) if process_subfolders else '\r\n(but not its subfolders)'),
                                                        (search_folder_top_level_paths_list[0] if only_1_top_level_folder else '(multiple top-level folders specified)') + '\r\n',
                                                        'Answering Yes will make the replacements.\r\n(No will exit the script, changing nothing.)',
                                                    ])
                                                    confirmed = self.yes_no(prompt)
                                                    if not confirmed: return
                                            
                                                    total_replacements_made_in_all_files = 0
                                                    pathnames_with_replacements_made_dict = {}
                                                    folders_with_replacements_made_dict = {}
                                                    first_time_thru = True
                                            
                                                    for pathname in pathnames_matching_filters_list:
                                            
                                                        foldername_of_pathname = pathname.rsplit(os.sep, 1)[0]
                                            
                                                        # the 'pathname' var here could be in "poor case" if user has entered the directory in a different
                                                        #  case than what the file system has, so compensate for that possibility:
                                                        open_in_a_npp_tab = pathname.lower() in map(str.lower, pathname_currently_open_in_a_tab_list)
                                            
                                                        if open_in_a_npp_tab:
                                                            self.print('switching active tab to', pathname)
                                                            notepad.activateFile(pathname)
                                                            editor.beginUndoAction()
                                                        else:
                                                            self.print('opening', pathname)
                                                            notepad.open(pathname)
                                                        assert notepad.getCurrentFilename().lower() == pathname.lower()
                                            
                                                        if editor.getReadOnly():
                                                            self.print('file is readonly so cannot change:', pathname)
                                                            if not open_in_a_npp_tab: notepad.close()
                                                            continue
                                            
                                                        self.print('making replacements in', pathname)
                                                        replacements_made_in_this_file = self.perform_custom_replace_in_one_file(first_time_thru)
                                                        self.print('{} replacements made in current file'.format(replacements_made_in_this_file))
                                            
                                                        if replacements_made_in_this_file > 0:
                                                            total_replacements_made_in_all_files += replacements_made_in_this_file
                                                            pathnames_with_replacements_made_dict[pathname] = replacements_made_in_this_file
                                                            folders_with_replacements_made_dict[foldername_of_pathname] = 1
                                            
                                                        if open_in_a_npp_tab:
                                                            editor.endUndoAction()
                                                        else:
                                                            if editor.getModify():
                                                                self.print('saving', pathname)
                                                                notepad.save()
                                                            self.print('closing', pathname)
                                                            notepad.close()
                                            
                                                        first_time_thru = False
                                            
                                                    # restore tab that was active before we started:
                                                    notepad.activateFile(active_tab_filepath)
                                            
                                                    info = '\r\n\r\n'.join([
                                                        '---- DONE !!! ----',
                                                        '{} total replacements made'.format(total_replacements_made_in_all_files),
                                                        'Do you want to see details of the replacements made?' if total_replacements_made_in_all_files > 0 else '',
                                                        '(Script will end after your response.)',
                                                        ])
                                                    if total_replacements_made_in_all_files == 0:
                                                        self.mb(info)
                                                    elif self.yes_no(info):
                                                        eol = ['\r\n', '\r', '\n'][editor.getEOLMode()]
                                                        d = pathnames_with_replacements_made_dict
                                                        digits = len(str(max(d.values())))
                                                        summary_line_list = []
                                                        summary_line_list.append('{tr} replacements made in {rp} files in {md} folders'.format(
                                                            tr=total_replacements_made_in_all_files,
                                                            rp=len(pathnames_with_replacements_made_dict),
                                                            md=len(folders_with_replacements_made_dict),
                                                            ))
                                                        summary_line_list.append('{} folders examined'.format(total_folders_encountered))
                                                        summary_line_list.append('{mf}/{tf} files matched the filter(s) provided:  {filts}'.format(
                                                            mf=num_files_matching_filters,
                                                            tf=total_files_encountered,
                                                            filts=' '.join(filters_list),
                                                            ))
                                                        summary_line_list.append('-' * 40)
                                                        summary_line_list.append(eol.join([ '{v:{d}} replacements - "{k}"'.format(v=v, k=k, d=digits) for (k, v) in sorted(d.items()) ]))
                                                        notepad.new()
                                                        editor.setText(eol.join(summary_line_list) + eol)
                                                        editor.scrollRange(0, 0)  # ensure line 1 is shown
                                                        editor.setSavePoint()  # make the temporary file seem saved
                                            
                                                def perform_custom_replace_in_one_file(self, first_time):
                                            
                                                    # since the editor.replace() function won't tell us how many replacements it made,
                                                    #  count them by searching for the matches BEFORE doing the replacement:
                                                    match_list = []
                                                    editor.research(self.search_regex, lambda m: match_list.append(1))
                                            
                                                    if len(match_list) > 0:
                                            
                                                        if self.run_example_from_pythonscript_docs:
                                            
                                                            # base example from PythonScript docs:
                                                            def return_replacement_text_func(m):
                                                                # replace X followed by numbers by an incremented number, e.g.  X56 X39 X999  becomes  Y57 Y40 Y1000
                                                                return 'Y' + str(int(m.group(1)) + 1)
                                            
                                                        else:
                                            
                                                            # vvvvvvvvvv---------- USER MODS REQUIRED BELOW ----------vvvvvvvvvv
                                            
                                                            renumbering = [ 1, 1 ]  # default to re-numbering starting with 1 and incrementing by 1; this would be the general case
                                                            CURRENT = 0; INCREMENT = 1  # indexes into the re-numbering list
                                                            renumbering[INCREMENT] = 10  # override our default increment-by and change it to 10, for our specific need
                                            
                                                            def return_replacement_text_func(m):
                                                                repl_text = 'N{0:02}'.format(renumbering[CURRENT])  # replace with N and a minimum of 2 digits, e.g. N01, N90, N300
                                                                renumbering[CURRENT] += renumbering[INCREMENT]
                                                                return repl_text
                                            
                                                            # ^^^^^^^^^^---------- USER MODS REQUIRED ABOVE ----------^^^^^^^^^^
                                            
                                                        editor.rereplace(self.search_regex, return_replacement_text_func)
                                            
                                                    return len(match_list)
                                            
                                                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 mb_ok_cancel(self, msg, title=''):  # returns True(OK) or False(Cancel)
                                                    okay = notepad.messageBox(msg, title if title else self.this_script_name, MESSAGEBOXFLAGS.OKCANCEL) == MESSAGEBOXFLAGS.RESULTOK
                                                    return okay
                                            
                                                def yes_no(self, question_text):  # returns True(Yes), False(No)
                                                    answer = self.mb(question_text, MESSAGEBOXFLAGS.YESNO, self.this_script_name)
                                                    return True if answer == MESSAGEBOXFLAGS.RESULTYES else False
                                            
                                                def yes_no_cancel(self, question_text):  # returns True(Yes), False(No), or None(Cancel)
                                                    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
                                            
                                                def prompt(self, prompt_text, default_text=''):
                                                    if '\n' not in prompt_text: prompt_text = '\r\n' + prompt_text
                                                    prompt_text += ':'
                                                    return notepad.prompt(prompt_text, self.this_script_name, default_text)
                                            
                                                def print(self, *args):
                                                    if self.debug:
                                                        print(self.__class__.__name__ + ':', *args)
                                            
                                            #-------------------------------------------------------------------------------
                                            
                                            if __name__ == '__main__': RIFUCRF()
                                            

                                            To reiterate from an earlier post in this thread, information about setting up and running a PythonScript is in the FAQ, HERE.

                                            So how do you run it, specifically for this application?

                                            Open into Notepad++ a data file in the top-level folder where you want to do the replacements. Execute the script from the PythonScript menu in Notepad++. You’ll be asked some questions, and then the core replacement logic will run to make your changes.

                                            –
                                            Moderator EDIT (2024-Jan-14): fixed EOL order

                                            1 Reply Last reply Reply Quote 3
                                            • Alan KilbornA Alan Kilborn referenced this topic on
                                            • First post
                                              Last post
                                            The Community of users of the Notepad++ text editor.
                                            Powered by NodeBB | Contributors