Added bass and fish_ssh_agent to fish config
This commit is contained in:
parent
2570c19b2b
commit
7d3ba6c888
@ -7,6 +7,8 @@ and not set -q TMUX
|
|||||||
exec tmux
|
exec tmux
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fish_ssh_agent
|
||||||
|
|
||||||
function q
|
function q
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
139
fish/.config/fish/functions/__bass.py
Normal file
139
fish/.config/fish/functions/__bass.py
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
"""
|
||||||
|
To be used with a companion fish function like this:
|
||||||
|
|
||||||
|
function refish
|
||||||
|
set -l _x (python /tmp/bass.py source ~/.nvm/nvim.sh ';' nvm use iojs); source $_x; and rm -f $_x
|
||||||
|
end
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
BASH = 'bash'
|
||||||
|
|
||||||
|
FISH_READONLY = [
|
||||||
|
'PWD', 'SHLVL', 'history', 'pipestatus', 'status', 'version',
|
||||||
|
'FISH_VERSION', 'fish_pid', 'hostname', '_', 'fish_private_mode'
|
||||||
|
]
|
||||||
|
|
||||||
|
IGNORED = [
|
||||||
|
'PS1', 'XPC_SERVICE_NAME'
|
||||||
|
]
|
||||||
|
|
||||||
|
def ignored(name):
|
||||||
|
if name == 'PWD': # this is read only, but has special handling
|
||||||
|
return False
|
||||||
|
# ignore other read only variables
|
||||||
|
if name in FISH_READONLY:
|
||||||
|
return True
|
||||||
|
if name in IGNORED or name.startswith("BASH_FUNC"):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def escape(string):
|
||||||
|
# use json.dumps to reliably escape quotes and backslashes
|
||||||
|
return json.dumps(string).replace(r'$', r'\$')
|
||||||
|
|
||||||
|
def escape_identifier(word):
|
||||||
|
return escape(word.replace('?', '\\?'))
|
||||||
|
|
||||||
|
def comment(string):
|
||||||
|
return '\n'.join(['# ' + line for line in string.split('\n')])
|
||||||
|
|
||||||
|
def gen_script():
|
||||||
|
# Use the following instead of /usr/bin/env to read environment so we can
|
||||||
|
# deal with multi-line environment variables (and other odd cases).
|
||||||
|
env_reader = "%s -c 'import os,json; print(json.dumps({k:v for k,v in os.environ.items()}))'" % (sys.executable)
|
||||||
|
args = [BASH, '-c', env_reader]
|
||||||
|
output = subprocess.check_output(args, universal_newlines=True)
|
||||||
|
old_env = output.strip()
|
||||||
|
|
||||||
|
pipe_r, pipe_w = os.pipe()
|
||||||
|
if sys.version_info >= (3, 4):
|
||||||
|
os.set_inheritable(pipe_w, True)
|
||||||
|
command = 'eval $1 && ({}; alias) >&{}'.format(
|
||||||
|
env_reader,
|
||||||
|
pipe_w
|
||||||
|
)
|
||||||
|
args = [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])]
|
||||||
|
p = subprocess.Popen(args, universal_newlines=True, close_fds=False)
|
||||||
|
os.close(pipe_w)
|
||||||
|
with os.fdopen(pipe_r) as f:
|
||||||
|
new_env = f.readline()
|
||||||
|
alias_str = f.read()
|
||||||
|
if p.wait() != 0:
|
||||||
|
raise subprocess.CalledProcessError(
|
||||||
|
returncode=p.returncode,
|
||||||
|
cmd=' '.join(sys.argv[1:]),
|
||||||
|
output=new_env + alias_str
|
||||||
|
)
|
||||||
|
new_env = new_env.strip()
|
||||||
|
|
||||||
|
old_env = json.loads(old_env)
|
||||||
|
new_env = json.loads(new_env)
|
||||||
|
|
||||||
|
script_lines = []
|
||||||
|
|
||||||
|
for k, v in new_env.items():
|
||||||
|
if ignored(k):
|
||||||
|
continue
|
||||||
|
v1 = old_env.get(k)
|
||||||
|
if not v1:
|
||||||
|
script_lines.append(comment('adding %s=%s' % (k, v)))
|
||||||
|
elif v1 != v:
|
||||||
|
script_lines.append(comment('updating %s=%s -> %s' % (k, v1, v)))
|
||||||
|
# process special variables
|
||||||
|
if k == 'PWD':
|
||||||
|
script_lines.append('cd %s' % escape(v))
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
if k == 'PATH':
|
||||||
|
value = ' '.join([escape(directory)
|
||||||
|
for directory in v.split(':')])
|
||||||
|
else:
|
||||||
|
value = escape(v)
|
||||||
|
script_lines.append('set -g -x %s %s' % (k, value))
|
||||||
|
|
||||||
|
for var in set(old_env.keys()) - set(new_env.keys()):
|
||||||
|
script_lines.append(comment('removing %s' % var))
|
||||||
|
script_lines.append('set -e %s' % var)
|
||||||
|
|
||||||
|
script = '\n'.join(script_lines)
|
||||||
|
|
||||||
|
alias_lines = []
|
||||||
|
for line in alias_str.splitlines():
|
||||||
|
_, rest = line.split(None, 1)
|
||||||
|
k, v = rest.split("=", 1)
|
||||||
|
alias_lines.append("alias " + escape_identifier(k) + "=" + v)
|
||||||
|
alias = '\n'.join(alias_lines)
|
||||||
|
|
||||||
|
return script + '\n' + alias
|
||||||
|
|
||||||
|
script_file = os.fdopen(3, 'w')
|
||||||
|
|
||||||
|
if not sys.argv[1:]:
|
||||||
|
print('__bass_usage', file=script_file, end='')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
script = gen_script()
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
sys.exit(e.returncode)
|
||||||
|
except Exception:
|
||||||
|
print('Bass internal error!', file=sys.stderr)
|
||||||
|
raise # traceback will output to stderr
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||||
|
os.kill(os.getpid(), signal.SIGINT)
|
||||||
|
else:
|
||||||
|
script_file.write(script)
|
||||||
|
|
30
fish/.config/fish/functions/bass.fish
Normal file
30
fish/.config/fish/functions/bass.fish
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
function bass
|
||||||
|
set -l bash_args $argv
|
||||||
|
set -l bass_debug
|
||||||
|
if test "$bash_args[1]_" = '-d_'
|
||||||
|
set bass_debug true
|
||||||
|
set -e bash_args[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
set -l script_file (mktemp)
|
||||||
|
if command -v python3 >/dev/null 2>&1
|
||||||
|
command python3 -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file
|
||||||
|
else
|
||||||
|
command python -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file
|
||||||
|
end
|
||||||
|
set -l bass_status $status
|
||||||
|
if test $bass_status -ne 0
|
||||||
|
return $bass_status
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -n "$bass_debug"
|
||||||
|
cat $script_file
|
||||||
|
end
|
||||||
|
source $script_file
|
||||||
|
command rm $script_file
|
||||||
|
end
|
||||||
|
|
||||||
|
function __bass_usage
|
||||||
|
echo "Usage: bass [-d] <bash-command>"
|
||||||
|
end
|
||||||
|
|
32
fish/.config/fish/functions/fish_ssh_agent.fish
Normal file
32
fish/.config/fish/functions/fish_ssh_agent.fish
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
function __ssh_agent_is_started -d "check if ssh agent is already started"
|
||||||
|
if begin; test -f $SSH_ENV; and test -z "$SSH_AGENT_PID"; end
|
||||||
|
source $SSH_ENV > /dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -z "$SSH_AGENT_PID"
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep -q ssh-agent
|
||||||
|
#pgrep ssh-agent
|
||||||
|
return $status
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function __ssh_agent_start -d "start a new ssh agent"
|
||||||
|
ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
|
||||||
|
chmod 600 $SSH_ENV
|
||||||
|
source $SSH_ENV > /dev/null
|
||||||
|
true # suppress errors from setenv, i.e. set -gx
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function fish_ssh_agent --description "Start ssh-agent if not started yet, or uses already started ssh-agent."
|
||||||
|
if test -z "$SSH_ENV"
|
||||||
|
set -xg SSH_ENV $HOME/.ssh/environment
|
||||||
|
end
|
||||||
|
|
||||||
|
if not __ssh_agent_is_started
|
||||||
|
__ssh_agent_start
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user