• Login
Community
  • Login

Is there any alternative to Merge files in one plugin?

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
16 Posts 6 Posters 5.1k 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.
  • D
    Doğancan @Alan Kilborn
    last edited by Aug 31, 2023, 12:08 PM

    Txt (1)
    6c069b4e-32a0-4368-8391-a804418d1918-image.png
    Txt (2)
    2c53277e-7df8-42db-b1e8-f400101e2836-image.png

    Result : Txt (1,2)
    f224bed0-5d6f-47b6-823e-7375849da178-image.png

    M 1 Reply Last reply Aug 31, 2023, 10:19 PM Reply Quote 0
    • M
      Mark Olson @Doğancan
      last edited by Aug 31, 2023, 10:19 PM

      @Doğancan

      OK, so essentially your problem is something along the lines of:

      • Document A has text in lines ABEFJ
      • Document B has text in lines CD
      • Document C has text in lines GHI

      We want a document that contains lines ABCDEFGHIJ from Documents A, B, and C.

      This is very different from the problem we thought we were helping you with, and it would have been nice to know earlier.

      That said, here is a PythonScript solution (see that link for info on how to use) that can solve this problem:

      # -*- coding: utf-8 -*-
      # reference: https://community.notepad-plus-plus.org/topic/24872/is-there-any-alternative-to-merge-files-in-one-plugin/7?_=1693515221904
      from __future__ import print_function
      import re
      from Npp import *
      
      __version__ = '0.1.0'
      
      EOLS = ('\r\n', '\r', '\n')
      
      def getCurrentEol():
          return EOLS[editor.getEOLMode()]
      
      def main():
          fnames = [x[0] for x in notepad.getFiles()]
          setfnames = set(fnames)
          fnames_str = '\r\n'.join(fnames)
          while True:
              fnames_chosen_str = notepad.prompt("remove the names of any files in this list that you don't want to merge", 'merge files together', fnames_str)
              if fnames_chosen_str is None:
                  return
              fnames_chosen = [f for f in fnames_chosen_str.split('\r\n') if f]
              bad = False
              for fname in fnames_chosen:
                  if fname not in setfnames:
                      bad = True
                      notepad.messageBox('Filename %s was not a currently open file' % fname)
                      break
              if not bad:
                  break
          lines_fname_map = {}
          for fname in fnames_chosen:
              notepad.open(fname)
              text = editor.getText()
              eol = getCurrentEol()
              lines = text.split(eol)
              lines_fname_map[fname] = lines
          maxlen = max(len(x) for x in lines_fname_map.values())
          merged = []
          collisions = {}
          for ii in range(maxlen):
              line_filled_by = None
              for fname, lines in lines_fname_map.items():
                  len_ = len(lines)
                  if ii >= len_:
                      continue
                  line = lines[ii]
                  if line:
                      if line_filled_by:
                          if ii not in collisions:
                              collisions[ii] = {line_filled_by: merged[ii]}
                          collisions[ii][fname] = line
                      else:
                          line_filled_by = fname
                          merged.append(line)
          for ii, collision in collisions.items():
              collisions_text_list = []
              collision_lines = list(collision.values())
              for fname, line in collision.items():
                  existing_choice = merged[ii]
                  collisions_text_list.append('[ %s ] %s : %s' % (
                      'X' if line == existing_choice else '',
                      fname,
                      line
                  ))
              collisions_text = '\r\n'.join(collisions_text_list)
              result = notepad.prompt('Collision at line %d. Put an X in the box of the file whose line you want to keep, then hit OK or Cancel to skip this line' % ii, 'merge collisions', collisions_text)
              if not result:
                  continue
              for jj, result_line in enumerate(result.split('\r\n')):
                  if re.search(r'^\s*\\[\s*\S\s*\\]', result_line):
                      line_to_use = collision_lines[jj]
                      merged[ii] = line_to_use
                      break
          notepad.new()
          editor.setText('\r\n'.join(merged))
          notepad.messageBox('This file contains the merger of the selected files', 'merger complete')
          
      if __name__ == '__main__':
          main()
      

      Example usage:
      File new 1:

      a
      b
      bar
      
      e
      f
      
      
      
      j
      

      File new 2:

      
      
      c
      d
      

      File new 3:

      
      
      
      
      
      foo
      g
      h
      i
      

      5084a82f-dd28-4090-b74d-02b4fd677f01-image.png
      a583dc45-310b-43b8-8149-515f4e107c93-image.png
      659145be-ab3e-42c9-989f-a814767645af-image.png

      M 1 Reply Last reply Aug 31, 2023, 11:37 PM Reply Quote 1
      • M Mark Olson referenced this topic on Aug 31, 2023, 10:19 PM
      • M
        Mark Olson @Mark Olson
        last edited by Aug 31, 2023, 11:37 PM

        @Mark-Olson

        That said, here is a PythonScript solution (see that link for info on how to use) that can solve this problem:

        Improvement to the above script, with an “escape valve” added to stop processing collisions in case there are so many that going through all of them would take forever.

        # -*- coding: utf-8 -*-
        # reference: https://community.notepad-plus-plus.org/topic/24872/is-there-any-alternative-to-merge-files-in-one-plugin/7?_=1693515221904
        from __future__ import print_function
        import os
        import re
        from Npp import *
        
        __version__ = '0.2.0'
        
        EOLS = ('\r\n', '\r', '\n')
        
        def getCurrentEol():
            return EOLS[editor.getEOLMode()]
        
        def main():
            fnames = [x[0] for x in notepad.getFiles()]
            setfnames = set(fnames)
            fnames_str = '\r\n'.join(fnames)
            while True:
                fnames_chosen_str = notepad.prompt("remove the names of any files in this list that you don't want to merge", 'merge files together', fnames_str)
                if fnames_chosen_str is None:
                    return
                fnames_chosen = [f for f in fnames_chosen_str.split('\r\n') if f]
                bad = False
                for fname in fnames_chosen:
                    if fname not in setfnames:
                        bad = True
                        notepad.messageBox(
                            'Filename %s was not a currently open file' % fname,
                            'nonexistent filename',
                            MESSAGEBOXFLAGS.ICONEXCLAMATION
                        )
                        break
                if not bad:
                    break
            lines_fname_map = {}
            for fname in fnames_chosen:
                notepad.open(fname)
                text = editor.getText()
                eol = getCurrentEol()
                lines = text.split(eol)
                lines_fname_map[fname] = lines
            maxlen = max(len(x) for x in lines_fname_map.values())
            merged = []
            collisions = {}
            for ii in range(maxlen):
                line_filled_by = None
                for fname, lines in lines_fname_map.items():
                    len_ = len(lines)
                    if ii >= len_:
                        continue
                    line = lines[ii]
                    if line:
                        if line_filled_by:
                            if ii not in collisions:
                                collisions[ii] = {line_filled_by: merged[ii]}
                            collisions[ii][fname] = line
                        else:
                            line_filled_by = fname
                            merged.append(line)
            n_collisions = len(collisions)
            many_collisions = n_collisions > 10
            short_fnames = {}
            short_fname_values = set()
            for fname in fnames_chosen:
                fname_parts = fname.split(os.sep)
                first_part_idx = len(fname_parts) - 1
                short_fname = '\\'.join(fname_parts[first_part_idx:])
                while first_part_idx >= 0 and short_fname in short_fname_values:
                    first_part_idx -= 1
                    short_fname = '\\'.join(fname_parts[first_part_idx:])        
                short_fname_values.add(short_fname)
                short_fnames[fname] = short_fname
            for coll_ix, (ii, collision) in enumerate(collisions.items()):
                collisions_text_list = []
                collision_lines = list(collision.values())
                for fname, line in collision.items():
                    existing_choice = merged[ii]
                    collisions_text_list.append('[ %s ] %r : %r' % (
                        'X' if line == existing_choice else '',
                        short_fnames[fname],
                        line
                    ))
                collisions_text = '\r\n'.join(collisions_text_list)
                result = notepad.prompt('Collision at line %d. Put an X in the box of the file whose line you want to keep, then hit OK or Cancel to skip this line' % ii, 'merge collisions', collisions_text)
                stop_processing = False
                if result:        
                    for jj, result_line in enumerate(result.split('\r\n')):
                        if re.search(r'^\s*\\[\s*\S\s*\\]', result_line):
                            line_to_use = collision_lines[jj]
                            merged[ii] = line_to_use
                            break
                else:
                    stop_processing = True
                remaining_colisions = n_collisions - coll_ix - 1
                if coll_ix % 5 == 0 and remaining_colisions >= 5:
                    mb_result = notepad.messageBox(
                        'There are %d unresolved collisions left. Stop processing them now?' % remaining_colisions,
                        'Many collisions left',
                        MESSAGEBOXFLAGS.ICONQUESTION | MESSAGEBOXFLAGS.YESNO
                    )
                    if mb_result == MESSAGEBOXFLAGS.RESULTYES:
                        break
            notepad.new()
            editor.setText('\r\n'.join(merged))
            notepad.messageBox('This file contains the merger of the selected files', 'merger complete')
            
        if __name__ == '__main__':
            main()
        
        D 1 Reply Last reply Sep 1, 2023, 7:34 PM Reply Quote 3
        • M Mark Olson referenced this topic on Aug 31, 2023, 11:37 PM
        • D
          Doğancan @Mark Olson
          last edited by Doğancan Sep 1, 2023, 7:39 PM Sep 1, 2023, 7:34 PM

          @Mark-Olson It really worked. Endless thanks .Can you publish this as a plugin so that everyone can use it ?

          M 1 Reply Last reply Sep 1, 2023, 8:54 PM Reply Quote 0
          • M
            Mark Olson @Doğancan
            last edited by Sep 1, 2023, 8:54 PM

            @Doğancan said in Is there any alternative to Merge files in one plugin?:

            Can you publish this as a plugin so that everyone can use it ?

            Glad it worked! A plugin? No. PythonScript scripts have to be installed according to this link.

            The closest thing I can provide is a Github gist .

            D 1 Reply Last reply Sep 1, 2023, 9:07 PM Reply Quote 0
            • D
              Doğancan @Mark Olson
              last edited by Sep 1, 2023, 9:07 PM

              @Mark-Olson I thought that plugins work with python.What programming language are notepad++ plugins written in ?

              C E 2 Replies Last reply Sep 2, 2023, 5:41 AM Reply Quote 0
              • C
                Coises @Doğancan
                last edited by Sep 2, 2023, 5:41 AM

                @Doğancan said in Is there any alternative to Merge files in one plugin?:

                What programming language are notepad++ plugins written in ?

                Notepad++ plugins are DLLs using a C interface, so any language that can be compiled to that could be used to write a plugin. In addition to “native” C or C++, the documentation links to API files for Ada, C#, D and Delphi.

                M 1 Reply Last reply Sep 2, 2023, 5:13 PM Reply Quote 3
                • M
                  Mark Olson @Coises
                  last edited by Sep 2, 2023, 5:13 PM

                  @Coises
                  …and Pascal , V , as well as PythonScript-like plugins in Lua and JavaScript .

                  1 Reply Last reply Reply Quote 2
                  • E
                    Ekopalypse @Doğancan
                    last edited by Sep 4, 2023, 7:07 AM

                    @Doğancan said in Is there any alternative to Merge files in one plugin?:

                    @Mark-Olson I thought that plugins work with python.What programming language are notepad++ plugins written in ?

                    So far, besides what has already been mentioned, I have written plugins in Nim, Odin, Zig, Rust and Python (using cython and cffi). So basically it boils down to the language having to be able to create a native DLL that Npp can load.

                    1 Reply Last reply Reply Quote 4
                    • D Doğancan referenced this topic on Sep 12, 2023, 7:18 PM
                    • M Mark Olson referenced this topic on Sep 12, 2023, 8:52 PM
                    • C
                      César @Doğancan
                      last edited by César Feb 1, 2024, 2:53 AM Feb 1, 2024, 2:50 AM

                      @Doğancan This solution worked for me (I tried it on merging HTML files succesfully):

                      @Diego-Raguindin said in Combine Plugin Gone!?:

                      This worked perfectly for me:

                      Put all of the files you want to combine in the same folder. Easiest would be at root-level.
                      Run a command prompt
                      CD to the folder in Step 1
                      Enter command copy *.csv filename.csv where “filename” is the desired output filename
                      Hit enter
                      File ‘filename.csv’ is created in the same folder
                      

                      https://community.notepad-plus-plus.org/post/77090

                      1 Reply Last reply Reply Quote 0
                      16 out of 16
                      • First post
                        16/16
                        Last post
                      The Community of users of the Notepad++ text editor.
                      Powered by NodeBB | Contributors