mirror of
https://github.com/XuehaiPan/nvitop.git
synced 2026-05-21 06:45:24 -06:00
feat(gui): full wide string support for username
Signed-off-by: Xuehai Pan <XuehaiPan@pku.edu.cn>
This commit is contained in:
parent
618a3faa1c
commit
3a80c60687
3 changed files with 81 additions and 51 deletions
|
|
@ -41,7 +41,7 @@ def wcslen(string):
|
|||
|
||||
|
||||
class WideString: # pylint: disable=too-few-public-methods
|
||||
def __init__(self, string, chars=None):
|
||||
def __init__(self, string='', chars=None):
|
||||
if isinstance(string, WideString):
|
||||
string = string.string
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ class WideString: # pylint: disable=too-few-public-methods
|
|||
else:
|
||||
self.chars = chars
|
||||
|
||||
def __add__(self, string):
|
||||
def __add__(self, other):
|
||||
"""
|
||||
>>> (WideString('a') + WideString('b')).string
|
||||
'ab'
|
||||
|
|
@ -64,29 +64,35 @@ class WideString: # pylint: disable=too-few-public-methods
|
|||
['a', 'f', 'd', 'b', 'c']
|
||||
"""
|
||||
|
||||
if isinstance(string, str):
|
||||
return WideString(self.string + string)
|
||||
if isinstance(string, WideString):
|
||||
return WideString(self.string + string.string, self.chars + string.chars)
|
||||
return None
|
||||
if isinstance(other, str):
|
||||
return WideString(self.string + other)
|
||||
if isinstance(other, WideString):
|
||||
return WideString(self.string + other.string, self.chars + other.chars)
|
||||
return NotImplemented
|
||||
|
||||
def __radd__(self, string):
|
||||
def __radd__(self, other):
|
||||
"""
|
||||
>>> ('bc' + WideString('afd')).chars
|
||||
['b', 'c', 'a', 'f', 'd']
|
||||
"""
|
||||
|
||||
if isinstance(string, str):
|
||||
return WideString(string + self.string)
|
||||
if isinstance(string, WideString):
|
||||
return WideString(string.string + self.string, string.chars + self.chars)
|
||||
return None
|
||||
if isinstance(other, str):
|
||||
return WideString(other + self.string)
|
||||
if isinstance(other, WideString):
|
||||
return WideString(other.string + self.string, other.chars + self.chars)
|
||||
return NotImplemented
|
||||
|
||||
def __iadd__(self, other):
|
||||
new = self + other
|
||||
self.string = new.string
|
||||
self.chars = new.chars
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
return self.string
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} '{}'>".format(self.__class__.__name__, self.string)
|
||||
return '<{} {!r}>'.format(self.__class__.__name__, self.string)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, (str, WideString)):
|
||||
|
|
|
|||
|
|
@ -454,11 +454,13 @@ class ProcessPanel(Displayable): # pylint: disable=too-many-instance-attributes
|
|||
self.addstr(
|
||||
y,
|
||||
self.x,
|
||||
'│{:>4} {:>7} {} {:>7} {:>8} {:>3} {} │'.format(
|
||||
'│{:>4} {:>7} {} {} {:>8} {:>3} {} │'.format(
|
||||
device_display_index,
|
||||
cut_string(process.pid, maxlen=7, padstr='.'),
|
||||
process.type,
|
||||
cut_string(process.username, maxlen=7, padstr='+'),
|
||||
str(
|
||||
WideString(cut_string(process.username, maxlen=7, padstr='+')).rjust(7)
|
||||
),
|
||||
process.gpu_memory_human,
|
||||
process.gpu_sm_utilization_string.replace('%', ''),
|
||||
WideString(host_info).ljust(self.width - 39)[: self.width - 39],
|
||||
|
|
@ -578,10 +580,10 @@ class ProcessPanel(Displayable): # pylint: disable=too-many-instance-attributes
|
|||
|
||||
host_info = cut_string(process.host_info, padstr='..', maxlen=self.width - 39)
|
||||
|
||||
info = '{:>7} {} {:>7} {:>8} {:>3} {}'.format(
|
||||
info = '{:>7} {} {} {:>8} {:>3} {}'.format(
|
||||
cut_string(process.pid, maxlen=7, padstr='.'),
|
||||
process.type,
|
||||
cut_string(process.username, maxlen=7, padstr='+'),
|
||||
str(WideString(cut_string(process.username, maxlen=7, padstr='+')).rjust(7)),
|
||||
process.gpu_memory_human,
|
||||
process.gpu_sm_utilization_string.replace('%', ''),
|
||||
WideString(host_info).ljust(self.width - 39)[: self.width - 39],
|
||||
|
|
|
|||
|
|
@ -394,8 +394,18 @@ class ProcessMetricsScreen(Displayable): # pylint: disable=too-many-instance-at
|
|||
process = self.process.snapshot
|
||||
columns = OrderedDict(
|
||||
[
|
||||
('PID', str(process.pid).rjust(3)),
|
||||
('USER', WideString('{} {}'.format(process.type, process.username).rjust(6))),
|
||||
(' GPU', self.process.device.display_index.rjust(4)),
|
||||
('PID ', '{} {}'.format(str(process.pid).rjust(3), process.type)),
|
||||
(
|
||||
'USER',
|
||||
WideString(
|
||||
cut_string(
|
||||
WideString(process.username).rjust(4),
|
||||
maxlen=32,
|
||||
padstr='+',
|
||||
)
|
||||
),
|
||||
),
|
||||
(' GPU-MEM', process.gpu_memory_human.rjust(8)),
|
||||
(' %SM', str(process.gpu_sm_utilization).rjust(4)),
|
||||
('%GMBW', str(process.gpu_memory_utilization).rjust(5)),
|
||||
|
|
@ -407,39 +417,53 @@ class ProcessMetricsScreen(Displayable): # pylint: disable=too-many-instance-at
|
|||
]
|
||||
)
|
||||
|
||||
self.addstr(self.y + 4, self.x + 1, '{:>4} '.format(self.process.device.display_index))
|
||||
x = self.x + 1
|
||||
header = ''
|
||||
fields = WideString()
|
||||
no_break = True
|
||||
for i, (col, value) in enumerate(columns.items()):
|
||||
width = len(value)
|
||||
if x + width < self.width - 2:
|
||||
if i == 0:
|
||||
header += col.rjust(width)
|
||||
fields += value
|
||||
else:
|
||||
header += ' ' + col.rjust(width)
|
||||
fields += ' ' + value
|
||||
x = self.x + 1 + len(fields)
|
||||
else:
|
||||
no_break = False
|
||||
break
|
||||
|
||||
self.addstr(self.y + 2, self.x + 1, header.ljust(self.width - 2))
|
||||
self.addstr(self.y + 4, self.x + 1, str(fields.ljust(self.width - 2)))
|
||||
self.color_at(
|
||||
self.y + 4, self.x + 1, width=4, fg=self.process.device.snapshot.display_color
|
||||
)
|
||||
x = self.x + 7
|
||||
for col, value in columns.items():
|
||||
width = len(value)
|
||||
self.addstr(self.y + 2, x, col.rjust(width) + ' ')
|
||||
self.addstr(self.y + 4, x, str(value + ' '))
|
||||
x += width + 1
|
||||
|
||||
x += 1
|
||||
if x + 4 < self.width - 2:
|
||||
self.addstr(
|
||||
self.y + 2,
|
||||
x,
|
||||
cut_string('COMMAND', self.width - x - 2, padstr='..').ljust(
|
||||
self.width - x - 2
|
||||
),
|
||||
)
|
||||
if process.is_zombie or process.no_permissions:
|
||||
self.color(fg='yellow')
|
||||
elif process.is_gone:
|
||||
self.color(fg='red')
|
||||
self.addstr(
|
||||
self.y + 4,
|
||||
x,
|
||||
cut_string(
|
||||
WideString(process.command).ljust(self.width - x - 2),
|
||||
self.width - x - 2,
|
||||
padstr='..',
|
||||
),
|
||||
)
|
||||
if no_break:
|
||||
x = self.x + 1 + len(fields) + 2
|
||||
if x + 4 < self.width - 2:
|
||||
self.addstr(
|
||||
self.y + 2,
|
||||
x,
|
||||
cut_string('COMMAND', self.width - x - 2, padstr='..').ljust(
|
||||
self.width - x - 2
|
||||
),
|
||||
)
|
||||
if process.is_zombie or process.no_permissions:
|
||||
self.color(fg='yellow')
|
||||
elif process.is_gone:
|
||||
self.color(fg='red')
|
||||
self.addstr(
|
||||
self.y + 4,
|
||||
x,
|
||||
cut_string(
|
||||
WideString(process.command).ljust(self.width - x - 2),
|
||||
self.width - x - 2,
|
||||
padstr='..',
|
||||
),
|
||||
)
|
||||
|
||||
self.color(fg='cyan')
|
||||
for y, line in enumerate(self.cpu_percent.graph, start=self.y + 6):
|
||||
|
|
@ -489,8 +513,6 @@ class ProcessMetricsScreen(Displayable): # pylint: disable=too-many-instance-at
|
|||
self.addstr(y, self.x + self.left_width + 2, line)
|
||||
|
||||
self.color_reset()
|
||||
self.addstr(self.y + 2, self.x + self.width - 2, ' │') # handle overflow
|
||||
self.addstr(self.y + 4, self.x + self.width - 2, ' │') # handle overflow
|
||||
self.addstr(self.y + 6, self.x + 1, ' {} '.format(self.cpu_percent.max_value_string()))
|
||||
self.addstr(self.y + 7, self.x + 5, ' {} '.format(self.cpu_percent))
|
||||
self.addstr(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue