mirror of
https://github.com/powerline/powerline.git
synced 2025-07-31 01:35:40 +02:00
Merge pull request #1016 from ZyX-I/tmux-attached_clients
Add segment with count of clients attached to tmux
This commit is contained in:
commit
2954a5c404
6
docs/source/configuration/segments/tmux.rst
Normal file
6
docs/source/configuration/segments/tmux.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
*************
|
||||||
|
Tmux segments
|
||||||
|
*************
|
||||||
|
|
||||||
|
.. automodule:: powerline.segments.tmux
|
||||||
|
:members:
|
@ -2,58 +2,15 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import, unicode_literals, print_function
|
from __future__ import absolute_import, unicode_literals, print_function
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from powerline.config import POWERLINE_ROOT, TMUX_CONFIG_DIRECTORY
|
from powerline.config import POWERLINE_ROOT, TMUX_CONFIG_DIRECTORY
|
||||||
from powerline.lib.config import ConfigLoader
|
from powerline.lib.config import ConfigLoader
|
||||||
from powerline import generate_config_finder, load_config, create_logger, PowerlineLogger, finish_common_config
|
from powerline import generate_config_finder, load_config, create_logger, PowerlineLogger, finish_common_config
|
||||||
from powerline.lib.shell import run_cmd, which
|
from powerline.lib.shell import which
|
||||||
|
from powerline.bindings.tmux import TmuxVersionInfo, run_tmux_command, get_tmux_version
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_FILE_NAME = re.compile(r'powerline_tmux_(?P<major>\d+)\.(?P<minor>\d+)(?P<suffix>[a-z]+)?(?:_(?P<mod>plus|minus))?\.conf')
|
CONFIG_FILE_NAME = re.compile(r'powerline_tmux_(?P<major>\d+)\.(?P<minor>\d+)(?P<suffix>[a-z]+)?(?:_(?P<mod>plus|minus))?\.conf')
|
||||||
|
53
powerline/bindings/tmux/__init__.py
Normal file
53
powerline/bindings/tmux/__init__.py
Normal 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)
|
@ -38,6 +38,7 @@
|
|||||||
"cwd": { "fg": "gray9", "bg": "gray4", "attr": [] },
|
"cwd": { "fg": "gray9", "bg": "gray4", "attr": [] },
|
||||||
"cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] },
|
"cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] },
|
||||||
"cwd:divider": { "fg": "gray7", "bg": "gray4", "attr": [] },
|
"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": [] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"exit_fail": { "fg": "white", "bg": "darkestred", "attr": [] },
|
"exit_fail": { "fg": "white", "bg": "darkestred", "attr": [] },
|
||||||
"exit_success": { "fg": "white", "bg": "darkestgreen", "attr": [] },
|
"exit_success": { "fg": "white", "bg": "darkestgreen", "attr": [] },
|
||||||
"environment": { "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": {
|
"mode_translations": {
|
||||||
"vicmd": {
|
"vicmd": {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"cwd:current_folder": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
|
"cwd:current_folder": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
|
||||||
"cwd:divider": { "fg": "gray61", "bg": "darkgreencopper", "attr": [] },
|
"cwd:divider": { "fg": "gray61", "bg": "darkgreencopper", "attr": [] },
|
||||||
"hostname": { "fg": "oldlace", "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": [] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
"virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10", "attr": [] },
|
"virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10", "attr": [] },
|
||||||
"col_current": { "fg": "gray6", "bg": "gray10", "attr": [] },
|
"col_current": { "fg": "gray6", "bg": "gray10", "attr": [] },
|
||||||
"modified_buffers": { "fg": "brightyellow", "bg": "gray2", "attr": [] },
|
"modified_buffers": { "fg": "brightyellow", "bg": "gray2", "attr": [] },
|
||||||
|
"attached_clients": { "fg": "gray8", "bg": "gray2", "attr": [] },
|
||||||
"error": { "fg": "brightestred", "bg": "darkred", "attr": ["bold"] },
|
"error": { "fg": "brightestred", "bg": "darkred", "attr": ["bold"] },
|
||||||
"warning": { "fg": "brightyellow", "bg": "darkorange", "attr": ["bold"] },
|
"warning": { "fg": "brightyellow", "bg": "darkorange", "attr": ["bold"] },
|
||||||
"current_tag": { "fg": "gray9", "bg": "gray2", "attr": [] }
|
"current_tag": { "fg": "gray9", "bg": "gray2", "attr": [] }
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "lightyellow", "attr": [] },
|
"virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "lightyellow", "attr": [] },
|
||||||
"col_current": { "fg": "azure4", "bg": "lightyellow", "attr": [] },
|
"col_current": { "fg": "azure4", "bg": "lightyellow", "attr": [] },
|
||||||
"environment": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
|
"environment": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
|
||||||
|
"attached_clients": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
|
||||||
"error": { "fg": "oldlace", "bg": "red", "attr": ["bold"] },
|
"error": { "fg": "oldlace", "bg": "red", "attr": ["bold"] },
|
||||||
"warning": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
|
"warning": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
|
||||||
"current_tag": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] }
|
"current_tag": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] }
|
||||||
|
22
powerline/segments/tmux.py
Normal file
22
powerline/segments/tmux.py
Normal 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)
|
@ -44,6 +44,14 @@ def urllib_read(query_url):
|
|||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
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):
|
class ModuleReplace(object):
|
||||||
def __init__(self, name, new):
|
def __init__(self, name, new):
|
||||||
|
@ -2,12 +2,16 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
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 sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from functools import partial
|
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.lib import Args, urllib_read, replace_attr, new_module, replace_module_module, replace_env, Pl
|
||||||
from tests import TestCase, SkipTest
|
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'}])
|
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):
|
class TestCommon(TestCase):
|
||||||
def test_hostname(self):
|
def test_hostname(self):
|
||||||
pl = Pl()
|
pl = Pl()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user