roughed out the new render program in Python, closing #2 as we're not going to support fish
This commit is contained in:
parent
313a2dee99
commit
ca28ca1680
5 changed files with 230 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
__pycache__
|
||||
render
|
||||
colors.sh
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#! /bin/fish
|
||||
|
||||
function fish_prompt
|
||||
~/git/over-prompt/render .1 .35 $COLUMNS $status
|
||||
# ^ ^ ^ ^- last command's exit status
|
||||
# | \- terminal width
|
||||
# | \- yellow threshold
|
||||
# \- red threshold
|
||||
end
|
|
@ -6,7 +6,7 @@ EAPI=5
|
|||
|
||||
inherit git-2
|
||||
|
||||
DESCRIPTION="A nonintrusive shell prompt that provides: username, hostname, tty name, cwd, return value of the last command, current time, disk space, and system load. Fish or zsh is preferred, although bash is also somewhat supported."
|
||||
DESCRIPTION="A nonintrusive zsh prompt that provides useful data like pwd, git info and system stats to the user."
|
||||
|
||||
HOMEPAGE="https://git.covalent.cz/overwatch/over-prompt"
|
||||
SRC_URI=""
|
||||
|
|
213
render.py
Executable file
213
render.py
Executable file
|
@ -0,0 +1,213 @@
|
|||
#! /usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
|
||||
SYM_GIT = "\ue0a0"
|
||||
SYM_LOCK = "\ue0a2"
|
||||
|
||||
def style_color(fg, bg):
|
||||
return '\033[38;5;%dm\033[48;5;%dm' %(fg, bg)
|
||||
|
||||
def style_bold():
|
||||
return '\033[1m'
|
||||
|
||||
def style_reset():
|
||||
return '\033[0m'
|
||||
|
||||
class LoginPart:
|
||||
user_fg = 34
|
||||
root_fg = 196
|
||||
remote_fg = 202
|
||||
local_fg = 7
|
||||
screen_fg = 27
|
||||
bg = 0
|
||||
|
||||
def __init__(self):
|
||||
self.user = os.getlogin()
|
||||
self.remote = bool(os.getenv('SSH_CLIENT'))
|
||||
self.sign = ' ⇄ ' if self.remote else '@'
|
||||
self.host = socket.gethostname()
|
||||
self.screen = os.getenv('WINDOW')
|
||||
|
||||
@property
|
||||
def length(self):
|
||||
return len(self.user) + len(self.host) + len(self.screen) + len(self.sign) + 1
|
||||
|
||||
def __str__(self):
|
||||
output = ''
|
||||
|
||||
if os.geteuid() == 0:
|
||||
output += style_color(self.root_fg, self.bg)
|
||||
else:
|
||||
output += style_color(self.user_fg, self.bg)
|
||||
|
||||
output += self.user
|
||||
|
||||
if self.remote:
|
||||
output += style_color(self.remote_fg, self.bg)
|
||||
else:
|
||||
output += style_color(self.local_fg, self.bg)
|
||||
|
||||
output += self.sign
|
||||
output += self.host
|
||||
|
||||
if self.screen:
|
||||
output += style_reset()
|
||||
output += ':'
|
||||
output += style_color(self.screen_fg, self.bg)
|
||||
output += self.screen
|
||||
|
||||
output += style_reset()
|
||||
|
||||
return output
|
||||
|
||||
def list_homes():
|
||||
with open('/etc/passwd') as f:
|
||||
for line in f:
|
||||
tokens = line.split(':')
|
||||
|
||||
if tokens[5] != '/dev/null':
|
||||
yield (tokens[5], tokens[0])
|
||||
|
||||
class Dir:
|
||||
writable_fg = 34
|
||||
fg = 196
|
||||
bg = 0
|
||||
|
||||
def __init__(self, path, name=None, slash='/'):
|
||||
self.path = path
|
||||
self.slash = slash
|
||||
self.lock = not os.access(path, os.W_OK)
|
||||
self.truncated = False
|
||||
|
||||
if name is None:
|
||||
name = os.path.basename(path)
|
||||
|
||||
self.raw_str = name + ('' if self.lock else '')
|
||||
|
||||
@property
|
||||
def length(self):
|
||||
return len(self.raw_str) + len(self.slash)
|
||||
|
||||
def truncate(self):
|
||||
self.truncated = True
|
||||
|
||||
if self.raw_str:
|
||||
self.raw_str = self.raw_str[0]
|
||||
|
||||
def __str__(self):
|
||||
output = self.slash
|
||||
|
||||
if self.truncated:
|
||||
output += style_bold()
|
||||
|
||||
if self.raw_str:
|
||||
output += style_color(self.fg if self.lock else self.writable_fg, self.bg)
|
||||
output += self.raw_str
|
||||
|
||||
output += style_reset()
|
||||
|
||||
return output
|
||||
|
||||
class PathPart:
|
||||
def __init__(self, term_width):
|
||||
self.term_width = term_width
|
||||
self.segments = []
|
||||
|
||||
homes = dict(list_homes())
|
||||
dirs = os.getcwd().split('/')[1:]
|
||||
path = ''
|
||||
|
||||
for dir in dirs:
|
||||
path += '/' + dir
|
||||
|
||||
if path in homes:
|
||||
self.segments = []
|
||||
|
||||
if homes[path] == os.getlogin():
|
||||
self.segments.append(Dir(path, '', '~'))
|
||||
else:
|
||||
self.segments.append(Dir(path, homes[path], '~'))
|
||||
|
||||
else:
|
||||
self.segments.append(Dir(path))
|
||||
|
||||
@property
|
||||
def length(self):
|
||||
return sum(s.length for s in self.segments)
|
||||
|
||||
def truncate(self, length):
|
||||
for s in self.segments:
|
||||
if self.length > length:
|
||||
s.truncate()
|
||||
else:
|
||||
break
|
||||
|
||||
def truncate_fit(self, line):
|
||||
space = self.term_width - sum(part.length for part in line if part is not self)
|
||||
self.truncate(space)
|
||||
|
||||
def __str__(self):
|
||||
return ''.join(str(s) for s in self.segments)
|
||||
|
||||
class GitPart:
|
||||
def __init__(self):
|
||||
...
|
||||
|
||||
@property
|
||||
def length(self):
|
||||
return len(str(self))
|
||||
|
||||
def __str__(self):
|
||||
return 'GIT'
|
||||
|
||||
class Padding:
|
||||
def __init__(self, term_width):
|
||||
self.term_width = term_width
|
||||
self.length = 0
|
||||
|
||||
def expand_fit(self, line):
|
||||
self.length = self.term_width - sum(part.length for part in line if part is not self) - len(line) + 1
|
||||
|
||||
def __str__(self):
|
||||
return ' ' * self.length
|
||||
|
||||
class StatsPart:
|
||||
clock = 27
|
||||
space_good = 34
|
||||
space_warn = 208
|
||||
space_bad = 196
|
||||
|
||||
def __init__(self, red_thresh, yellow_thresh, warning_only=True):
|
||||
self.red = red_thresh
|
||||
self.yellow = yellow_thresh
|
||||
|
||||
@property
|
||||
def length(self):
|
||||
return len(str(self))
|
||||
|
||||
def __str__(self):
|
||||
return '[ 13:34 | 0.53 | r4.20M'
|
||||
|
||||
if __name__ == '__main__':
|
||||
red_thresh = float(sys.argv[1])
|
||||
yellow_thresh = float(sys.argv[2])
|
||||
term_width = int(sys.argv[3])
|
||||
exit_status = int(sys.argv[4])
|
||||
|
||||
lp = LoginPart()
|
||||
pp = PathPart(term_width)
|
||||
gp = GitPart()
|
||||
pad = Padding(term_width)
|
||||
sp = StatsPart(red_thresh, yellow_thresh)
|
||||
|
||||
line = [lp, pp, gp, pad, sp]
|
||||
pp.truncate_fit(line)
|
||||
pad.expand_fit(line)
|
||||
|
||||
line_str = ' '.join(str(part) for part in line)
|
||||
sys.stderr.write(line_str)
|
||||
sys.stderr.flush()
|
15
zsh-init
15
zsh-init
|
@ -15,6 +15,19 @@ function strlen {
|
|||
echo ${#PLAIN}
|
||||
}
|
||||
|
||||
function set_title {
|
||||
if [[ ${TERM} == "screen-bce" || ${TERM} == "screen" ]]; then
|
||||
print -Pn "\033k\033${@}\033\134"
|
||||
fi
|
||||
}
|
||||
|
||||
function preexec {
|
||||
local -a cmd
|
||||
cmd=(${(z)1})
|
||||
|
||||
set_title "${PWD}: ${cmd}"
|
||||
}
|
||||
|
||||
function precmd {
|
||||
local CUT OVER_OPTS RAW_DATA LOGIN_PART STATS_PART DATA TOP_LEFT TOP_RIGHT PADDING PADDING_SIZE GIT_BRANCH COLOR
|
||||
set -A OVER_OPTS ${(s. .)OVER_PROMPT_OPTS}
|
||||
|
@ -63,6 +76,8 @@ function precmd {
|
|||
else
|
||||
print -P "\e[5;31m!!! unable to run /usr/share/over-prompt/data\e[0m"
|
||||
fi
|
||||
|
||||
set_title "${PWD}"
|
||||
}
|
||||
|
||||
unset OVER_PROMPT_CFG
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue