Sublime Forum

Update script to ST3

#1

Hello,

I found a really useful and simple plugin for batch find and replace but it only seems to work in ST2, could anyone help me updating it to ST3? the code is simple but I donā€™t know much about codingā€¦
All credits go to the original coder: Phillips Koebbe (and here is the original code)

# This script allows you to do multiple find/replace operations in one pass. The find/replace
# pairs are defined in a file (defaults to ~/.st2_multiple_find_replace) using the format
#
# find <separator> replace

# By default, the separator is the hash-pointer (=>), but it can be changed if
# necessary (see below). To use multiple find and replace, save this code to a file in
# your Packages/User folder using whatever name you like. I use multiple_find_replace.py.
# Edit your user key bindings and pick whatever key combinations you want to trigger 
# these operations. On Mac OS X, I chose COMMAND+OPTION+M E to edit and COMMAND+OPTION+M R
# to replace. The actual key bindings are:
#
# { "keys": "super+alt+m", "f"], "command": "multiple_find_replace", "args": {"operation": "find"} },
# { "keys": "super+alt+m", "r"], "command": "multiple_find_replace", "args": {"operation": "replace"} }
#
# When you issue the multiple_find_replace command, if the file does not exist, it will
# be created and opened for editing. If the file does exist, it will be parsed for 
# find/replace pairs and the current file will be the operation's subject. In order to
# edit your find/replace pairs, issue the edit_multiple_find_replace command, which
# will either open or activate the search term file.
#
# To change the separator used in the search term file, include a comment at the top of
# the file like this:
#
# separator: ==
#
# changing the double equal to whatever ever separator you want to use. The script will
# then use that separator to split the line when parsing the find/replace pairs.
#
# All find/replace operations are done in a single edit, so a single undo returns the
# subject text to its original state. Also of importance is the pairs are processed
# in the order they appear in the file.
#
# At present, the find/replace operations work against the entire buffer. A future
# enhancement would be to operate against a selection only.

import sublime, sublime_plugin
import os

class MultipleFindReplaceCommand(sublime_plugin.WindowCommand):
    def run(self, operation):
        self.file_name = os.path.expanduser('~/.st2_multiple_find_replace')
        self.separator_key = 'separator:'
        self.separator = '=>'
        self.lines = None

        self.ensure_multiple_find_replace_file()

        if operation == 'find':
            self.find()
        else:
            self.replace()


    def ensure_multiple_find_replace_file(self):
        if not os.path.exists(self.file_name):
            contents = "# Put one find/replace pair on each line, separated by a separator. For example:\n"
            contents += "\n"
            contents += "ReplaceThis => WithThis\n"
            contents += "\n"
            contents += "# The default separator is =>. To change it, put the following line at the top\n"
            contents += "# of this file, replacing the double equal with whatever you want the separator\n"
            contents += "# to be:\n"
            contents += "\n"
            contents += "# separator: ==\n"

            with open(self.file_name, 'a') as the_file:
                the_file.write(contents)


    def find(self):
        self.window.open_file(self.file_name)


    def replace(self):
        self.load_file()

        view = self.window.active_view()
        edit = view.begin_edit()

        for line in self.lines:
            if line.startswith('#'):
                continue

            try:
                find, replace = line.split(self.separator)
            except:
                continue
            
            find = find.strip()
            replace = replace.strip()

            matches = view.find_all(find)
            matches.reverse()

            for region in matches:
                view.replace(edit, region, replace)

        view.end_edit(edit)


    def load_file(self):
        input_file = open(self.file_name, 'r')
        self.lines = input_file.readlines()
        input_file.close()

        for line in self.lines:
            if line.startswith('#'):
                pos = line.find(self.separator_key)
                if pos > 0:
                    junk, separator = line.split(self.separator_key)
                    self.separator = separator.strip()
                    break

As it is said in the code file comments:

  • I placed the .py in the Sublime Text 3/Packages/User folder

  • then created the shortcuts for ā€œfindā€ and ā€œreplaceā€

  • when pressing ā€œfindā€ shortcut it launch the template file where you should include your find=>replace list (you should delete everything in this file and only left your list)

  • save it, return to the file you want to batch find/replace and press ā€œreplaceā€ shortcutā€¦ and here happens nothing

If you do this in ST2 it works perfectly but in ST3 the ā€œreplaceā€ command doesnā€™t workā€¦

Can you guess where is the problem in ST3?
Thanks!!

0 Likes

#2

gist.github.com/titoBouzout/562 ā€¦ 6145e67a67

0 Likes

#3

Awesome!!
Thank you very much, I highly appreciate your help :smiley:

Cheers!

0 Likes