# -*- coding: UTF-8 -*- # based on: https://github.com/gnunn1/tilix/blob/master/data/nautilus/open-tilix.py from gettext import gettext, textdomain from subprocess import call try: from urllib import unquote from urlparse import urlparse except ImportError: from urllib.parse import unquote, urlparse from gi import require_version from gi.repository import Gio, GObject, Gtk, Nautilus require_version('Gtk', '3.0') require_version('Nautilus', '3.0') TERM_PARAMS = {"alacritty": "--working-directory ", "cool-retro-term": "--workdir ", "deepin-terminal": "--work-directory ", "gnome-terminal": "", "guake": "guake --show --new-tab=", "hyper": "", "kitty": "--directory ", "konsole": "--workdir ", "mate-terminal": "--working-directory=", "mlterm": "--working-directory=", "qterminal": "--workdir ", "st": "-d ", "terminator": "--working-directory=", "terminology": "--current-directory ", "termite": "-d ", "tilix": "-w ", "urxvt": "-cd ", "xfce4-terminal": "--working-directory="} NEW_TAB_PARAMS = {"alacritty": None, "cool-retro-term": None, "gnome-terminal": "--tab", "guake": None, "hyper": None, "deepin-terminal": None, "kitty": None, "konsole": "--new-tab", "mate-terminal": "--tab", "mlterm": None, "qterminal": None, "st": None, "terminator": "--new-tab", "terminology": None, "termite": None, "tilix": None, "urxvt": None, "xfce4-terminal": "--tab"} global terminal terminal = "gnome-terminal" new_tab = False GSETTINGS_PATH = "com.github.stunkymonkey.nautilus-open-any-terminal" GSETTINGS_KEYBINDINGS = "keybindings" GSETTINGS_TERMINAL = "terminal" GSETTINGS_NEW_TAB = "new-tab" REMOTE_URI_SCHEME = ["ftp", "sftp"] textdomain("nautilus-open-any-terminal") _ = gettext def _checkdecode(s): """Decode string assuming utf encoding if it's bytes, else return unmodified""" return s.decode('utf-8') if isinstance(s, bytes) else s def open_terminal_in_file(filename): if filename: # print('{0} {1} {2} "{3}" &'.format(terminal, NEW_TAB_PARAMS[terminal], TERM_PARAMS[terminal], filename)) # escape filename quotations filename = filename.replace('"', '\\"') if new_tab: call('{0} {1} {2}"{3}" &'.format(terminal, NEW_TAB_PARAMS[ terminal], TERM_PARAMS[terminal], filename), shell=True) else: call('{0} {1}"{2}" &'.format(terminal, TERM_PARAMS[terminal], filename), shell=True) else: call("{0} &".format(terminal), shell=True) def set_terminal_args(*args): global new_tab value = _gsettings.get_string(GSETTINGS_TERMINAL) newer_tab = _gsettings.get_boolean(GSETTINGS_NEW_TAB) if value in TERM_PARAMS: global terminal terminal = value if newer_tab and NEW_TAB_PARAMS[terminal] is not None: new_tab = newer_tab new_tab_text = "opening in a new tab" else: new_tab_text = "opening a new window" if newer_tab and NEW_TAB_PARAMS[terminal] is None: new_tab_text += " (terminal does not support tabs)" print('open-any-terminal: terminal is set to "{0}" {1}'.format(terminal, new_tab_text)) else: print('open-any-terminal: unknown terminal "{0}"'.format(value)) class OpenAnyTerminalShortcutProvider(GObject.GObject, Nautilus.LocationWidgetProvider): def __init__(self): source = Gio.SettingsSchemaSource.get_default() if source.lookup(GSETTINGS_PATH, True): self._gsettings = Gio.Settings.new(GSETTINGS_PATH) self._gsettings.connect("changed", self._bind_shortcut) self._create_accel_group() self._window = None self._uri = None def _create_accel_group(self): self._accel_group = Gtk.AccelGroup() shortcut = self._gsettings.get_string(GSETTINGS_KEYBINDINGS) key, mod = Gtk.accelerator_parse(shortcut) self._accel_group.connect(key, mod, Gtk.AccelFlags.VISIBLE, self._open_terminal) def _bind_shortcut(self, gsettings, key): if key == GSETTINGS_KEYBINDINGS: self._accel_group.disconnect(self._open_terminal) self._create_accel_group() def _open_terminal(self, *args): filename = unquote(self._uri[7:]) open_terminal_in_file(filename) def get_widget(self, uri, window): self._uri = uri if self._window: self._window.remove_accel_group(self._accel_group) if self._gsettings: window.add_accel_group(self._accel_group) self._window = window return None class OpenAnyTerminalExtension(GObject.GObject, Nautilus.MenuProvider): def _open_terminal(self, file_): if file_.get_uri_scheme() in REMOTE_URI_SCHEME: result = urlparse(file_.get_uri()) if result.username: value = "ssh -t {0}@{1}".format(result.username, result.hostname) else: value = "ssh -t {0}".format(result.hostname) if result.port: value = "{0} -p {1}".format(value, result.port) if file_.is_directory(): value = '{0} cd "{1}" ; $SHELL'.format(value, result.path) call('{0} -e "{1}" &'.format(terminal, value), shell=True) else: filename = Gio.File.new_for_uri(file_.get_uri()).get_path() open_terminal_in_file(filename) def _menu_activate_cb(self, menu, file_): self._open_terminal(file_) def _menu_background_activate_cb(self, menu, file_): self._open_terminal(file_) def get_file_items(self, window, files): if len(files) != 1: return items = [] file_ = files[0] if file_.is_directory(): if file_.get_uri_scheme() in REMOTE_URI_SCHEME: uri = _checkdecode(file_.get_uri()) item = Nautilus.MenuItem(name="NautilusPython::open_remote_item", label=_(u'Open Remote {}').format(terminal.title()), tip=_(u'Open Remote {} In {}').format(terminal.title(), uri)) item.connect("activate", self._menu_activate_cb, file_) items.append(item) filename = _checkdecode(file_.get_name()) item = Nautilus.MenuItem(name="NautilusPython::open_file_item", label=_(u'Open In {}').format(terminal.title()), tip=_(u'Open {} In {}').format(terminal.title(), filename)) item.connect("activate", self._menu_activate_cb, file_) items.append(item) return items def get_background_items(self, window, file_): items = [] if file_.get_uri_scheme() in REMOTE_URI_SCHEME: item = Nautilus.MenuItem(name="NautilusPython::open_bg_remote_item", label=_(u'Open Remote {} Here').format(terminal.title()), tip=_(u'Open Remote {} In This Directory').format(terminal.title())) item.connect("activate", self._menu_activate_cb, file_) items.append(item) item = Nautilus.MenuItem(name="NautilusPython::open_bg_file_item", label=_(u'In {} öffnen').format(terminal.title()), tip=_(u'Open {} In This Directory').format(terminal.title())) item.connect("activate", self._menu_background_activate_cb, file_) items.append(item) return items source = Gio.SettingsSchemaSource.get_default() if source.lookup(GSETTINGS_PATH, True): _gsettings = Gio.Settings.new(GSETTINGS_PATH) _gsettings.connect("changed", set_terminal_args) value = _gsettings.get_string(GSETTINGS_TERMINAL) if value in TERM_PARAMS: terminal = value if _gsettings.get_boolean(GSETTINGS_NEW_TAB): new_tab = bool(NEW_TAB_PARAMS[value] is not None)