Search code examples
sublimetext3sublime-text-plugin

Hotkey to select text and console.log in new line


I stumbled across this snippet and it works great: https://gist.github.com/harthur/2951063

The problem is that it breaks syntax when I run the shortcut snippet. It inputs a console.log() inline and thus breaks syntax.

For example I want to console log the variable hello

var hello = 'World';

Well, the snippet linked above will turn it into:

var console.log(hello) = 'World';

That is not the behavior I would want. What I want is:

var hello = 'World';
console.log(hello);

Now, this looks like a multiple command, and out of the box I don't think ST3 supports multiple commands in keybindings. I've looked into the plugin Chain of Command but haven't had success in getting it to output how I want it to. Any one know of a solution?


Solution

  • If you stay with Chain of Command you can just define you keybinding as a sequence of commands. If you don't know which commands are executed open the console ctrl+` and write sublime.log_commands(True) to show all commands, which are executed.

    So how you could archive your behavior:

    1. copy the current selected variable
    2. goto the end of the line
    3. insert the console log snippet in the next line
    4. paste the copied variable
    {
        "keys": ["super+shift+l"],
        "command": "chain",
        "args": {
            "commands": [
                ["copy"],
                ["move_to", {"to": "eol"}],
                ["move_to", {"to": "eol"}],
                ["insert_snippet", {"contents": "\nconsole.log(\"$1 = \" + $1);$0"}],
                ["paste"]
            ]
        },
        "context":
        [
            { "key": "selector", "operator": "equal", "operand": "source.js" },
            { "key": "selection_empty", "operator": "equal", "operand": false }
        ]
    },
    

    An alternative would be to write a plugin to create a log command below the current line. A plugin has the advantage of multiple cursor support and not changing the clipboard. Press Tools >>> New Plugin... and write:

    import itertools
    import sublime_plugin
    
    class LogVariableCommand(sublime_plugin.TextCommand):
        def run(self, edit):
            view = self.view
            for sel in view.sel():
                if sel.empty():
                    continue
                content = view.substr(sel)
                line = view.line(sel)
    
                # retrieve the current indent
                indent = "".join(itertools.takewhile(lambda c: c.isspace(),
                                                     view.substr(line)))
    
                view.insert(edit, line.end(),
                            "\n{0}console.log(\"{1} = \" + {1})"
                            .format(indent, content))
    

    To assign a keybinding use:

    {
        "keys": ["super+shift+l"],
        "command": "log_variable"
    }