Search code examples
pythonsublimetextsublime-text-pluginsublimerepl

Shortcut to launch REPL if no REPL running and send to REPL


I'd like to create a shortcut in sublime text that that does the following:

  • if a REPL for R is open, send the selected text to this REPL
  • else open a R REPL in a new window and send the text to this REPL.

I am using R-box. This package has a python class RboxSendTextCommand that uses the command repl_send

       external_id = self.view.scope_name(0).split(" ")[0].split(".", 1)[1] 
        self.view.window().run_command("repl_send", {"external_id": external_id, "text": cmd})
        return

This throws the error "Cannot find REPL for `r`" when no REPL is opened. I have tried to modify it in

        try:
            self.view.window().run_command("repl_send", {"external_id": external_id, "text": cmd})
        except:
            self.view.window().run_command("run_existing_window_command",{"id": "repl_r", "file": "config/R/Main.sublime-menu"})
            self.view.window().run_command("repl_send", {"external_id": external_id, "text": cmd})
            return
        else:
            self.view.window().run_command("repl_send", {"external_id": external_id, "text": cmd})
            return

However the same error happens when no REPL R window is open. Would you know how to do it? I don't particular need to do that through the R-box script.


Solution

  • First of all, from SublimeREPL source code, if there is no REPL R running, it just print an error message. It won't throw any error. So try...except... won't work here.

    class ReplSend(sublime_plugin.TextCommand):
        def run(self, edit, external_id, text, with_auto_postfix=True):
            for rv in manager.find_repl(external_id):
                ...
            else:
                sublime.error_message("Cannot find REPL for '{}'".format(external_id))
    

    I don't know if there is a better way to do this. However, you can detect REPL R via its view name.

        if App == "SublimeREPL":
            external_id = self.view.scope_name(0).split(" ")[0].split(".", 1)[1]
            current_window = self.view.window()
            found = False
            repl_name = "*REPL* [%s]" % external_id
            for w in sublime.windows():
                for v in w.views():
                    if v.name() == repl_name:
                        found = True
            if not found:
                current_window.run_command("run_existing_window_command",{"id": "repl_r", "file": "config/R/Main.sublime-menu"})
            current_window.run_command("repl_send", {"external_id": external_id, "text": cmd})
            return
    

    Open REPL in a new window:

        sublime.run_command("new_window")
        created_window = sublime.active_window()
        created_window.run_command("run_existing_window_command",{"id": "repl_r", "file": "config/R/Main.sublime-menu"})