Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feature/save user session venv (solves #879) #880

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions terminatorlib/cwd.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,15 @@ def get_pid_cwd(pid = None):
# return func
return psinfo['cwd']

def get_pid_venv(pid = None):
"""Determine the virtual environment of the current process"""
psinfo = psutil.Process(pid).as_dict()
dbg('psinfo: %s' % (psinfo))
#dbg('psinfo: %s %s' % (psinfo['venv'],psinfo['pid']))
# prefix = getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
# if prefix != sys.prefix: # session is in a virtual environment
# return sys.prefix
# return func
return "my-venv" #psinfo['venv']

# vim: set expandtab ts=4 sw=4:
69 changes: 69 additions & 0 deletions terminatorlib/plugins/save_user_session_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import os
import sys

# Fix imports when testing this file directly
if __name__ == '__main__':
sys.path.append( os.path.join(os.path.dirname(__file__), "../.."))

from gi.repository import Gtk,Vte

from terminatorlib.config import Config
import terminatorlib.plugin as plugin
from terminatorlib.translation import _
from terminatorlib.util import get_config_dir, err, dbg, gerr
from terminatorlib.terminator import Terminator
from terminatorlib import util


# AVAILABLE must contain a list of all the classes that you want exposed
AVAILABLE = ['SaveUserSessionLayout']

class SaveUserSessionLayout(plugin.MenuItem):
capabilities = ['terminal_menu', 'session']

config = None
conf_file = os.path.join(get_config_dir(),"save_last_session_cwd")
conf_sessions = []
emit_close_count = 0

vte_version = Vte.get_minor_version()

def __init__(self):
dbg("SaveUserSessionLayout Init")
plugin.MenuItem.__init__(self)

def callback(self, menuitems, menu, terminal):
""" Add save menu item to the menu"""
vte_terminal = terminal.get_vte()
item = Gtk.MenuItem.new_with_mnemonic(_('Save _UserSessionLayout'))
item.connect("activate", self.save_all_session_layouts, terminal)
menuitems.append(item)

def save_all_session_layouts(self, menuitem, terminal):
for term in Terminator().terminals:
self.save_session_layout("", "")

#not used, but capability can be used to load automatically
def load_session_layout(self, debugtab=False, widget=None, cwd=None, metadata=None, profile=None):
dbg("SaveUserSessionLayout load layout")
terminator = Terminator()
util.spawn_new_terminator(terminator.origcwd, ['-u', '-l', 'SaveUserSessionLayout'])

def save_session_layout(self, debugtab=False, widget=None, cwd=None, metadata=None, profile=None):

config = Config()
terminator = Terminator()
current_layout = terminator.describe_layout(save_cwd = True)
dbg("SaveUserSessionLayout: save layout(%s)" % current_layout)
res = config.replace_layout("SaveUserSessionLayout", current_layout)
if (not res):
r = config.add_layout("SaveUserSessionLayout", current_layout)
config.save()
return True


def close(self, term, event, arg1 = None):
if (self.emit_close_count == 0):
self.emit_close_count = self.emit_close_count + 1
self.save_session_layout("", "")

37 changes: 36 additions & 1 deletion terminatorlib/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


import os
import sys
import signal
import gi
from gi.repository import GLib, GObject, Pango, Gtk, Gdk, GdkPixbuf, cairo
Expand All @@ -19,6 +20,7 @@
from . import util
from .config import Config
from .cwd import get_pid_cwd
from .venv import get_pid_venv
from .factory import Factory
from .terminator import Terminator
from .titlebar import Titlebar
Expand Down Expand Up @@ -94,6 +96,7 @@ class Terminal(Gtk.VBox):

group = None
cwd = None
venv = None
origcwd = None
command = None
clipboard = None
Expand All @@ -106,6 +109,7 @@ class Terminal(Gtk.VBox):
layout_command = None
relaunch_command = None
directory = None
virtual_env = None

is_held_open = False

Expand Down Expand Up @@ -140,6 +144,7 @@ def __init__(self):
self.config = Config()

self.cwd = get_pid_cwd()
self.venv = get_pid_venv() # TODO: vritual env still needs to be activated in the current terminal
self.origcwd = self.terminator.origcwd
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)

Expand Down Expand Up @@ -262,6 +267,21 @@ def get_cwd(self):
# Fall back to old gtk2 method
dbg('calling get_pid_cwd')
return(get_pid_cwd(self.pid))

def get_venv(self):
"""Return our virtual environment"""

vte_venv = False #= self.vte.get_current_virtual_environment_uri()
if vte_venv:
# OSC7 pwd gives an answer
# return remote venv - if possible
return(GLib.filename_from_uri(vte_venv)[0])
else:
# Fall back to old gtk2 method
dbg('calling get_pid_venv')
return(get_pid_venv(self.pid))



def close(self):
"""Close ourselves"""
Expand Down Expand Up @@ -1509,6 +1529,11 @@ def set_cwd(self, cwd=None):
if cwd is not None:
self.cwd = cwd

def set_venv(self, venv=None):
"""Set our virtual environment"""
if venv is not None:
self.venv = venv

def held_open(self, widget=None, respawn=False, debugserver=False):
self.is_held_open = True
self.titlebar.update()
Expand Down Expand Up @@ -1558,6 +1583,10 @@ def spawn_child(self, widget=None, respawn=False, debugserver=False, init_comman
self.set_cwd(options.working_directory)
options.working_directory = ''

# virtualenv set in layout config
if self.virtual_env:
self.set_venv(self.virtual_env)

if type(command) is list:
shell = util.path_lookup(command[0])
args = command
Expand Down Expand Up @@ -1816,10 +1845,14 @@ def describe_layout(self, count, parent, global_layout, child_order, save_cwd =
layout['uuid'] = self.uuid
if save_cwd:
layout['directory'] = self.get_cwd()

if self.get_venv() is not None:
layout['venv'] = self.get_venv()

name = 'terminal%d' % count
count = count + 1
global_layout[name] = layout
return count
return count

def create_layout(self, layout):
"""Apply our layout"""
Expand All @@ -1837,6 +1870,8 @@ def create_layout(self, layout):
self.titlebar.set_custom_string(layout['title'])
if 'directory' in layout and layout['directory'] != '':
self.directory = layout['directory']
if 'venv' in layout and layout['venv'] != '':
self.virtual_env = layout['venv']
if 'uuid' in layout and layout['uuid'] != '':
self.uuid = make_uuid(layout['uuid'])

Expand Down
30 changes: 30 additions & 0 deletions terminatorlib/venv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Terminator by Chris Jones <[email protected]>
# GPL v2 only
"""venv.py - function necessary to get the current virtual environment for a given pid on various OSes


>>> venv = get_pid_venv(None)
>>> venv.__class__.__name__
'str'

"""

import psutil
from .util import dbg

def get_pid_venv(pid = None):
"""Determine the virtual environment of the current process"""
psinfo = psutil.Process(pid).as_dict()
#dbg('\npsinfo: env : \n%s' % psinfo) # psinfo['environ'])
#dbg('psinfo: %s %s' % (psinfo['VIRTUAL_ENV'],psinfo['pid']))

# prefix = getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
# if prefix != sys.prefix: # session is in a virtual environment
# return sys.prefix

try:
return psinfo['environ']['VIRTUAL_ENV']
except KeyError:
return ""

# vim: set expandtab ts=4 sw=4:
2 changes: 1 addition & 1 deletion terminatorlib/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
"""

APP_NAME = 'terminator'
APP_VERSION = '2.1.3'
APP_VERSION = '2.1.8'
Loading