Merge pull request #1016 from ZyX-I/tmux-attached_clients

Add segment with count of clients attached to tmux
This commit is contained in:
Nikolai Aleksandrovich Pavlov 2014-08-24 21:19:04 +04:00
commit 2954a5c404
11 changed files with 125 additions and 56 deletions

View File

@ -0,0 +1,6 @@
*************
Tmux segments
*************
.. automodule:: powerline.segments.tmux
:members:

View File

@ -2,58 +2,15 @@
from __future__ import absolute_import, unicode_literals, print_function
from collections import namedtuple
import os
import subprocess
import re
import sys
from powerline.config import POWERLINE_ROOT, TMUX_CONFIG_DIRECTORY
from powerline.lib.config import ConfigLoader
from powerline import generate_config_finder, load_config, create_logger, PowerlineLogger, finish_common_config
from powerline.lib.shell import run_cmd, which
TmuxVersionInfo = namedtuple('TmuxVersionInfo', ('major', 'minor', 'suffix'))
def get_tmux_executable_name():
'''Returns tmux executable name
It should be defined in POWERLINE_TMUX_EXE environment variable, otherwise
it is simply tmux.
'''
return os.environ.get('POWERLINE_TMUX_EXE', 'tmux')
def _run_tmux(runner, args):
return runner([get_tmux_executable_name()] + list(args))
def run_tmux_command(*args):
'''Run tmux command, ignoring the output'''
_run_tmux(subprocess.check_call, args)
def get_tmux_output(pl, *args):
'''Run tmux command and return its output'''
return _run_tmux(lambda cmd: run_cmd(pl, cmd), args)
NON_DIGITS = re.compile('[^0-9]+')
DIGITS = re.compile('[0-9]+')
NON_LETTERS = re.compile('[^a-z]+')
def get_tmux_version(pl):
version_string = get_tmux_output(pl, '-V')
_, version_string = version_string.split(' ')
version_string = version_string.strip()
major, minor = version_string.split('.')
suffix = DIGITS.subn('', minor)[0] or None
minor = NON_DIGITS.subn('', minor)[0]
return TmuxVersionInfo(int(major), int(minor), suffix)
from powerline.lib.shell import which
from powerline.bindings.tmux import TmuxVersionInfo, run_tmux_command, get_tmux_version
CONFIG_FILE_NAME = re.compile(r'powerline_tmux_(?P<major>\d+)\.(?P<minor>\d+)(?P<suffix>[a-z]+)?(?:_(?P<mod>plus|minus))?\.conf')

View File

@ -0,0 +1,53 @@
# vim:fileencoding=utf-8:noet
from __future__ import absolute_import, unicode_literals, division, print_function
import re
import os
import subprocess
from collections import namedtuple
from powerline.lib.shell import run_cmd
TmuxVersionInfo = namedtuple('TmuxVersionInfo', ('major', 'minor', 'suffix'))
def get_tmux_executable_name():
'''Returns tmux executable name
It should be defined in POWERLINE_TMUX_EXE environment variable, otherwise
it is simply tmux.
'''
return os.environ.get('POWERLINE_TMUX_EXE', 'tmux')
def _run_tmux(runner, args):
return runner([get_tmux_executable_name()] + list(args))
def run_tmux_command(*args):
'''Run tmux command, ignoring the output'''
_run_tmux(subprocess.check_call, args)
def get_tmux_output(pl, *args):
'''Run tmux command and return its output'''
return _run_tmux(lambda cmd: run_cmd(pl, cmd), args)
NON_DIGITS = re.compile('[^0-9]+')
DIGITS = re.compile('[0-9]+')
NON_LETTERS = re.compile('[^a-z]+')
def get_tmux_version(pl):
version_string = get_tmux_output(pl, '-V')
_, version_string = version_string.split(' ')
version_string = version_string.strip()
major, minor = version_string.split('.')
suffix = DIGITS.subn('', minor)[0] or None
minor = NON_DIGITS.subn('', minor)[0]
return TmuxVersionInfo(int(major), int(minor), suffix)

View File

@ -38,6 +38,7 @@
"cwd": { "fg": "gray9", "bg": "gray4", "attr": [] },
"cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] },
"cwd:divider": { "fg": "gray7", "bg": "gray4", "attr": [] },
"virtualenv": { "fg": "white", "bg": "darkcyan", "attr": [] }
"virtualenv": { "fg": "white", "bg": "darkcyan", "attr": [] },
"attached_clients": { "fg": "gray8", "bg": "gray0", "attr": [] }
}
}

View File

@ -6,7 +6,8 @@
"exit_fail": { "fg": "white", "bg": "darkestred", "attr": [] },
"exit_success": { "fg": "white", "bg": "darkestgreen", "attr": [] },
"environment": { "fg": "white", "bg": "darkestgreen", "attr": [] },
"mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }
"mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] },
"attached_clients": { "fg": "white", "bg": "darkestgreen", "attr": [] }
},
"mode_translations": {
"vicmd": {

View File

@ -12,6 +12,7 @@
"cwd:current_folder": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
"cwd:divider": { "fg": "gray61", "bg": "darkgreencopper", "attr": [] },
"hostname": { "fg": "oldlace", "bg": "darkgreencopper", "attr": [] },
"environment": { "fg": "oldlace", "bg": "green", "attr": [] }
"environment": { "fg": "oldlace", "bg": "green", "attr": [] },
"attached_clients": { "fg": "oldlace", "bg": "green", "attr": [] }
}
}

View File

@ -27,6 +27,7 @@
"virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10", "attr": [] },
"col_current": { "fg": "gray6", "bg": "gray10", "attr": [] },
"modified_buffers": { "fg": "brightyellow", "bg": "gray2", "attr": [] },
"attached_clients": { "fg": "gray8", "bg": "gray2", "attr": [] },
"error": { "fg": "brightestred", "bg": "darkred", "attr": ["bold"] },
"warning": { "fg": "brightyellow", "bg": "darkorange", "attr": ["bold"] },
"current_tag": { "fg": "gray9", "bg": "gray2", "attr": [] }

View File

@ -28,6 +28,7 @@
"virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "lightyellow", "attr": [] },
"col_current": { "fg": "azure4", "bg": "lightyellow", "attr": [] },
"environment": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
"attached_clients": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
"error": { "fg": "oldlace", "bg": "red", "attr": ["bold"] },
"warning": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
"current_tag": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] }

View File

@ -0,0 +1,22 @@
# vim:fileencoding=utf-8:noet
from __future__ import absolute_import, unicode_literals, division, print_function
from powerline.bindings.tmux import get_tmux_output
def attached_clients(pl, minimum=1):
'''Return the number of tmux clients attached to the currently active session
:param int minimum:
The minimum number of attached clients that must be present for this
segment to be visible.
'''
session_output = get_tmux_output('list-panes', '-F', '#{session_name}')
if not session_output:
return None
session_name = session_output.rstrip().split('\n')[0]
attached_clients_output = get_tmux_output('list-clients', '-t', session_name)
attached_count = len(attached_clients_output.rstrip().split('\n'))
return None if attached_count < minimum else str(attached_count)

View File

@ -44,6 +44,14 @@ def urllib_read(query_url):
else:
raise NotImplementedError
class Process(object):
def __init__(self, output, err):
self.output = output
self.err = err
def communicate(self):
return self.output, self.err
class ModuleReplace(object):
def __init__(self, name, new):

View File

@ -2,12 +2,16 @@
from __future__ import unicode_literals
from powerline.segments import shell, common
from powerline.lib.vcs import get_fallback_create_watcher
import tests.vim as vim_module
import sys
import os
from functools import partial
from powerline.segments import shell, tmux, common
from powerline.lib.vcs import get_fallback_create_watcher
import tests.vim as vim_module
from tests.lib import Args, urllib_read, replace_attr, new_module, replace_module_module, replace_env, Pl
from tests import TestCase, SkipTest
@ -279,6 +283,20 @@ class TestShell(TestCase):
self.assertEqual(common.date(pl=pl, format='%H:%M', istime=True), [{'contents': '%H:%M', 'highlight_group': ['time', 'date'], 'divider_highlight_group': 'time:divider'}])
class TestTmux(TestCase):
def test_attached_clients(self):
def get_tmux_output(cmd, *args):
if cmd == 'list-panes':
return 'session_name\n'
elif cmd == 'list-clients':
return '/dev/pts/2: 0 [191x51 xterm-256color] (utf8)\n/dev/pts/3: 0 [191x51 xterm-256color] (utf8)'
pl = Pl()
with replace_attr(tmux, 'get_tmux_output', get_tmux_output):
self.assertEqual(tmux.attached_clients(pl=pl), '2')
self.assertEqual(tmux.attached_clients(pl=pl, minimum=3), None)
class TestCommon(TestCase):
def test_hostname(self):
pl = Pl()