diff --git a/README.md b/README.md index 13c6de6..81aad95 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,29 @@ Project-wise settings could also be specified in `sublime-project` as } ``` +#### Enabling selection by window name/title (WM_NAME) for linux-terminal + +If you have multiple instances of the same terminal emulator running (e.g. one `alacritty` window for R, one for IPython, etc.), you may want to want to send code to a terminal with a specific name/title (e.g. so `python` code is sent to the window named `My Special IPython` but `julia` code is sent to `My Julia`). If you force a permanent window name when running your terminal emulator (e.g. `$ alacritty -t "My Special IPython"`), you can place this name in a `linux_window_name` SendCode setting. SendCode will then first try to find a window with the corresponding `WM_NAME` *before* using the `WM_CLASS` specified by the `linux_terminal` global setting. A minimal example is: + +```js +{ + "linux_terminal": "alacritty", + "prog": "linux-terminal", + + // First try to send Python & Julia code to the named windows, respectively + "python" : { + "linux_window_name": "My Special IPython", + "bracketed_paste_mode": true, + }, + "julia" : { + "linux_window_name": "My Julia", + "bracketed_paste_mode": true, + } + // Other code behaves as usual (e.g. R gets sent to the last alacritty window) +} +``` + +It is not recommended to use the `linux_window_name` setting unless you specify a permanent window name when running your terminal emulator; by default, window names may change frequently, which makes this setting unreliable (although you can use a regular expression in `linux_window_name` to try to catch these windows). Note that `linux_window_name` is only meaningful when in a settings block where `prog` is set to `linux-terminal`. ### Block expansion diff --git a/code_sender/linux/__init__.py b/code_sender/linux/__init__.py index 55194cd..19c5a24 100644 --- a/code_sender/linux/__init__.py +++ b/code_sender/linux/__init__.py @@ -2,18 +2,17 @@ import time import os from ..clipboard import clipboard +from subprocess import CalledProcessError plat = sublime.platform() if plat == "linux": from ..xdotool import xdotool - def send_to_linux_terminal(linux_terminal, cmd_list): - wid = xdotool("search", "--onlyvisible", "--class", linux_terminal) - if not wid: - raise Exception("{} not found.".format(linux_terminal)) + def send_to_linux_terminal(linux_window_name, linux_terminal, cmd_list): + wids = get_linux_wids(linux_window_name, linux_terminal) - wid = wid.decode("utf-8").strip().split("\n")[-1] + wid = wids.decode("utf-8").strip().split("\n")[-1] if isinstance(cmd_list, str): cmd_list = [cmd_list] @@ -42,7 +41,25 @@ def send_to_linux_terminal(linux_terminal, cmd_list): else: xdotool("windowfocus", sublime_id) + def get_linux_wids(linux_window_name, linux_terminal): + if linux_window_name: + try: + wids = xdotool("search", "--onlyvisible", "--name", linux_window_name) + except CalledProcessError: + sublime.status_message("{} (WM_NAME) not found; trying {} (WM_CLASS)" + .format(linux_window_name, linux_terminal)) + wids = xdotool("search", "--onlyvisible", "--class", linux_terminal) + else: + wids = xdotool("search", "--onlyvisible", "--class", linux_terminal) + + if not wids: + raise Exception("{} not found.".format(linux_terminal)) + + return wids else: def send_to_linux_terminal(cmd): pass + + def get_linux_wids(cmd): + pass diff --git a/code_sender/sender.py b/code_sender/sender.py index 102d344..36aedf8 100644 --- a/code_sender/sender.py +++ b/code_sender/sender.py @@ -57,8 +57,9 @@ def send_to_cmder(self, cmd): send_to_cmder(cmd, conemuc, bracketed=self.bracketed_paste_mode) def send_to_linux_terminal(self, cmd): + linux_window_name = self.settings.get("linux_window_name") linux_terminal = self.settings.get("linux_terminal") - send_to_linux_terminal(linux_terminal, cmd) + send_to_linux_terminal(linux_window_name, linux_terminal, cmd) def send_to_tmux(self, cmd): tmux = self.settings.get("tmux", "tmux") @@ -225,15 +226,17 @@ def send_to_cmder(self, cmd): send_to_cmder(cmd, conemuc) def send_to_linux_terminal(self, cmd): + linux_window_name = self.settings.get("linux_window_name") linux_terminal = self.settings.get("linux_terminal") if len(re.findall("\n", cmd)) > 0: if self.bracketed_paste_mode: - send_to_linux_terminal(linux_terminal, [cmd, ""]) + send_to_linux_terminal(linux_window_name, linux_terminal, [cmd, ""]) else: - send_to_linux_terminal(linux_terminal, [r"%cpaste -q", cmd, "--"]) + send_to_linux_terminal(linux_window_name, linux_terminal, + [r"%cpaste -q", cmd, "--"]) else: - send_to_linux_terminal(linux_terminal, cmd) + send_to_linux_terminal(linux_window_name, linux_terminal, cmd) def send_to_tmux(self, cmd): tmux = self.settings.get("tmux", "tmux")