1"""Utility and helper methods for tmuxp.
2
3tmuxp.util
4~~~~~~~~~~
5
6"""
7import logging
8import os
9import shlex
10import subprocess
11import sys
12
13from libtmux.exc import LibTmuxException
14
15from . import exc
16from ._compat import console_to_str
17
18logger = logging.getLogger(__name__)
19
20PY2 = sys.version_info[0] == 2
21
22
23def run_before_script(script_file, cwd=None):
24    """Function to wrap try/except for subprocess.check_call()."""
25    try:
26        proc = subprocess.Popen(
27            shlex.split(str(script_file)),
28            stderr=subprocess.PIPE,
29            stdout=subprocess.PIPE,
30            cwd=cwd,
31        )
32        for line in iter(proc.stdout.readline, b''):
33            sys.stdout.write(console_to_str(line))
34        proc.wait()
35
36        if proc.returncode:
37            stderr = proc.stderr.read()
38            proc.stderr.close()
39            stderr = console_to_str(stderr).split('\n')
40            stderr = '\n'.join(list(filter(None, stderr)))  # filter empty
41
42            raise exc.BeforeLoadScriptError(
43                proc.returncode, os.path.abspath(script_file), stderr
44            )
45
46        return proc.returncode
47    except OSError as e:
48        if e.errno == 2:
49            raise exc.BeforeLoadScriptNotExists(e, os.path.abspath(script_file))
50        else:
51            raise e
52
53
54def oh_my_zsh_auto_title():
55    """Give warning and offer to fix ``DISABLE_AUTO_TITLE``.
56
57    see: https://github.com/robbyrussell/oh-my-zsh/pull/257
58
59    """
60
61    if 'SHELL' in os.environ and 'zsh' in os.environ.get('SHELL'):
62        if os.path.exists(os.path.expanduser('~/.oh-my-zsh')):
63            # oh-my-zsh exists
64            if (
65                'DISABLE_AUTO_TITLE' not in os.environ
66                or os.environ.get('DISABLE_AUTO_TITLE') == "false"
67            ):
68                print(
69                    'Please set:\n\n'
70                    '\texport DISABLE_AUTO_TITLE=\'true\'\n\n'
71                    'in ~/.zshrc or where your zsh profile is stored.\n'
72                    'Remember the "export" at the beginning!\n\n'
73                    'Then create a new shell or type:\n\n'
74                    '\t$ source ~/.zshrc'
75                )
76
77
78def raise_if_tmux_not_running(server):
79    """Raise exception if not running. More descriptive error if no server found."""
80    try:
81        server.sessions
82    except LibTmuxException as e:
83        if any(
84            needle in str(e)
85            for needle in ['No such file or directory', 'no server running on']
86        ):
87            raise LibTmuxException(
88                'no tmux session found. Start a tmux session and try again. \n'
89                'Original error: ' + str(e)
90            )
91        else:
92            raise e
93
94
95def get_current_pane(server):
96    """Return Pane if one found in env"""
97    if os.getenv('TMUX_PANE') is not None:
98        try:
99            return [
100                p
101                for p in server._list_panes()
102                if p.get('pane_id') == os.getenv('TMUX_PANE')
103            ][0]
104        except IndexError:
105            pass
106
107
108def get_session(server, session_name=None, current_pane=None):
109    if session_name:
110        session = server.find_where({'session_name': session_name})
111    elif current_pane is not None:
112        session = server.find_where({'session_id': current_pane['session_id']})
113    else:
114        session = server.list_sessions()[0]
115
116    if not session:
117        raise exc.TmuxpException('Session not found: %s' % session_name)
118
119    return session
120
121
122def get_window(session, window_name=None, current_pane=None):
123    if window_name:
124        window = session.find_where({'window_name': window_name})
125        if not window:
126            raise exc.TmuxpException('Window not found: %s' % window_name)
127    elif current_pane is not None:
128        window = session.find_where({'window_id': current_pane['window_id']})
129    else:
130        window = session.list_windows()[0]
131
132    return window
133
134
135def get_pane(window, current_pane=None):
136    try:
137        if current_pane is not None:
138            pane = window.find_where({'pane_id': current_pane['pane_id']})  # NOQA: F841
139        else:
140            pane = window.attached_pane  # NOQA: F841
141    except exc.TmuxpException as e:
142        print(e)
143        return
144
145    return pane
146