Sublime Forum

Macros don't record Find/Replace?

#41

@deathaxe, That is a great script to automate find/replaces.

But what if you just need a Find? I need that awesome result window, with hotlinks to my code.

I have many ColdFusion markup documents that are basically function libraries. If I do a find on this regex, the results are a great table of contents for me to quickly go to the function I want.
RegEx: "<cffunction.*name\s?=\"([^\"]+)\""
And the search range is the current file.

Is it possible to make python create a Results page, or have ST3 do this automatically in some other way?

0 Likes

#42

If youā€™re using the excellent CFML package, those functions should be in the symbol list, so you can just hit ctrl-r.

2 Likes

#43

I wondered if the plugin I was already using had something like that! Awesome! Thank you!

0 Likes

#44

+1 not recording everything in a Sublime Text macro is a shocking omission. Even Microsoft product macros have been recording everything since the '90ā€™s

0 Likes

#46

Just stumbled on the same disappointment in ST3ā€¦ (even after all these years)

My use case is to perform ~15 steps to clean up and pre-process a data file,
which I need to do very oftenā€¦ many of the steps involve search and replace by regular expression
So unfortunately a macro canā€™t help me here.

My guess is that there is something fundamental to the API which limits scope and prevents recording of itā€¦
(does anyone have more details on why? are there any other actions that similarly arenā€™t recorded?)

0 Likes

#47

Just started using Sublime Text on a Mac having used TextPad on the PC for years
This macro search/replace issue came up pretty quick
All I want to do is remove all blank lines from a text file
e.g. something like: global search/replace on \n\n and replace with \n

0 Likes

#48

I am not certain if this will help, and I do not use it myself, but there is the package Delete Blank Lines.

1 Like

#49

There is also RegReplace. It allows you to define a find and replace (or multiple which you can chain together) and then create a command to execute it. Commands configured to display in the palette, bound to a key map, or even shown in the menu. I use it to set up replaces I commonly do.

1 Like

#50

No dependency workaround

I use find_replace by deathaxe above, because it has a human-readable syntax.

But here is a native-only workaround:

// clean-up-diacritics.sublime-macro
// Replace all incorrectly used Turkish diacritics with Romanian diacritics
[
  {"command": "select_all", "args": null},
  {"command": "insert_snippet", "args": {"contents": "${SELECTION/(?<1>Ş)|(?<2>ş)|(?<3>Å¢)|(?<4>Å£)/(?{1}Ș:(?{2}ș:(?{3}Ț:ț)))/gm}"}}
]

via this answer to [pcre] Multiple replacement with just one regex - Stack Overflow

1 Like

Variable substitution ignoring `g` flag?
#51

Been using sublime since I started programming and now Iā€™m starting to actually become a professional I was 100% sure I was going to purchase a license. Now that I found out that such basic feature is not implemented turns me down a bit, since this is essential for my work. Probably going to rely on emacs for doing things like this for now

2 Likes

#52

I just bought a license today. I was disappointed that I couldnā€™t properly use find in macro, as I have used this extensively (while on MS windows) with Notebook++.
I plan for Sublime text to be my go to data editor for Linux, but being able to create macho that can find starting point is crucial.

Please make this functionality high priority.

Larz60+ (python-forum.io)

1 Like

#53

Another vote for making this a priority, please! Iā€™m an outlier in that Iā€™m not a huge coder, but Sublime is my go-to for writing, and also converting texts in bulk from Word and other places to web-ready <p> wrapped copy, and for those purposes, being able to F&R things like \n\n with \n would be a huge help!

1 Like

#55

This was a horrible decision. Ideally, macros should be able to to record and replay any command available vie menues or hot-keys. Maybe this could be solved through scripting but I agree with others that this is overkill. Plus, I donā€™t want to learn a new scripting language, preferring to use SED from shell.

I switch to Notepad++ on windows when I need macros and have just downloaded Textmate II to my personal Mac book pro and use a third option on Linux. Iā€™d prefer to use the same editor across all my machines regardless of operating system.

Iā€™m uninstalling Sublime on all my plateforms. Sorry guys, you should really reconsider your choice.

Don Rau
Clearwateranalytics
Boise Idaho

0 Likes

#56

I still live in hope that a ā€˜record and playback anythingā€™ macro facility will find its way into Sublime. Itā€™d probably require some heavy lifting under the hood, because macros are presently implemented more or less for batching TextCommands together, an early part of Sublimeā€™s internal design. Those unfamiliar with STā€™s Python API wonā€™t be clear on what macros can and canā€™t do - and thereā€™s plenty they canā€™t.

Ideally, at least anything that affects the state of a buffer should be recordable into a macro. That includes cursor movements, S&R, indentations, selections etcā€¦ There might be a few exceptions, one example being code folding.

Before Sublime, I used Brief and then Crisp, both of which had ā€˜record everything, no-brainerā€™ macro facilities which could be either learnt or hand-coded. For a number of editing situations I still need to fall back to other editors because I canā€™t mirror a repeat a sequence of actions in a macro, and going the route of building a Python extension is the proverbial sledgehammer.

With full featured macros, effortless huge file support, proper column selection and syntax aware folding added to the core, I could quite see Sublime being the first and last editor I would ever need, except maybe vim for ssh sessions. Further, I think that would expand its reach and sales beyond coders and towards anyone who needs a robust, swiss army knife editor with native performance in their technology workflow. Just my 2p.

0 Likes

#57

I would also like to see find (and replace) in Macros, but a workaround is to copy/paste to a different text editor (notepad++ or emacs), use their well developed macros, then copy/paste the result back to the sublime text editor. clunky but it works for me, and I can use the powerful emacs macros

0 Likes

#58

Deathaxe python script above totaly resolves this, and in addition gives a great way forward for more ST automation.
So if, like me, you came here looking for a solution - scroll up and use it. no need for a new ST feature.

For the record - here is how you use it from within a macro:
{
ā€œargsā€: {
ā€œpatternā€: ā€œ^whatever you want(ed)?ā€,
ā€œreplace_byā€: ā€œWhat you need\1ā€
},
ā€œcommandā€:ā€œfind_replaceā€
}

0 Likes

#59

Hey @deathaxe,
your script runs fine at first look.
When using a ā€œ.ā€ as the search/find pattern I discovered strange beaviour, killing parts of the text expected to be the remains.

Adding the flag ā€œLITERALā€, limit the code now to replace almost all occurences of ā€œ.ā€ but still killing some text at the start of the orginal.

Finally I discovered that you swapped two arguments in the line with the ā€œfind()ā€ function.

in your code change the line after the ā€œwhile True:ā€ statement

from

        found = self.view.find(pattern, self._flags(flags), start_pt)

to

       found = self.view.find(pattern, start_pt, self._flags(flags))

and you are fine.

@deathaxe please edit your example above if possible!

Thanks for you work!

0 Likes

#60

Good catch. Unfortunatelly I looks like I canā€™t edit the post anymore.

So hereā€™s the fixed version:

import sublime
import sublime_plugin


class FindReplaceCommand(sublime_plugin.TextCommand):
    """The implementation of 'find_replace' text command.

    Example:

        view.run_command(
            "find_replace", {
                "pattern": "the",
                "replace_by": "THE",
                "start_pt": 100,
                "flags": ["LITERAL"]
            }
        )
    """

    FLAGS = {
        "LITERAL": sublime.LITERAL,
        "IGNORECASE": sublime.IGNORECASE
    }

    def run(self, edit, pattern, replace_by, start_pt=0, flags=[]):
        """Find and replace all patterns.

        Arguments:
            edit (sublime.Edit):
                The edit token used to undo this command.
            pattern (string):
                The regex pattern to use for finding.
            replace_by (string):
                The text to replace all found words by.
            start_pt (int):
                The text position where to start.
            flags (list):
                The flags to pass to view.find()
                ["LITERAL", "IGNORECASE"]
        """
        while True:
            found = self.view.find(pattern, start_pt, self._flags(flags))
            if not found:
                return
            self.view.replace(edit, found, replace_by)
            start_pt = found.begin()

    def _flags(self, flags):
        """Translate list of flags."""
        result = 0
        for flag in flags:
            result |= self.FLAGS.get(flag, 0)
        return result
0 Likes

Variable substitution ignoring `g` flag?
#61

hi @deathaxe
when I try to replace \n with ',\n', then this code will run forever, because from start point begin() it will find the same \n . How about start_pt = found.begin() + len(replace_by) ? what do u think ?

1 Like

#62

For the deathaxe script, is there a way to use backreferences in replacements? The self.view.replace method takes the replacement as a string and and says nothing more about it as far as I can tell.

Taking the example from omriā€™s post, "replace_by": "What you need\1" for me just causes an error for bad escaping. Escaping the backslash makes the .sublime-macro valid, but the replace then uses literal backslashes.

Not doable? Am I missing something? Working example?

0 Likes