diff --git a/share/functions/__fish_complete_pids.fish b/share/functions/__fish_complete_pids.fish index 996f995fd..b670944cf 100644 --- a/share/functions/__fish_complete_pids.fish +++ b/share/functions/__fish_complete_pids.fish @@ -1,8 +1,15 @@ function __fish_complete_pids -d "Print a list of process identifiers along with brief descriptions" # This may be a bit slower, but it's nice - having the tty displayed is really handy - ps --no-heading -o pid,comm,tty --ppid %self -N | sed -r 's/ *([0-9]+) +([^ ].*[^ ]|[^ ]) +([^ ]+)$/\1'\t'\2 [\3]/' ^/dev/null - - # If the above is too slow, this is faster but a little less useful - # pgrep -l -v -P %self | sed 's/ /'\t'/' + # 'tail -n +2' deletes the first line, which contains the headers + # 'grep -v...' removes self from the output + set -l SELF %self + + # Display the tty if available + set -l sed_cmds 's/ *([0-9]+) +([^ ].*[^ ]|[^ ]) +([^ ]+) *$/\1'\t'\2 [\3]/' + + # But not if it's just question marks, meaning no tty + set -l sed_cmds $sed_cmds 's/ *\[\?*\] *$//' + + ps axc -o pid,ucomm,tty | grep -v '^\s*'$SELF'\s' | tail -n +2 | sed -E "-e "$sed_cmds ^/dev/null end diff --git a/share/functions/__fish_complete_proc.fish b/share/functions/__fish_complete_proc.fish index d1c2bcfff..d520a0302 100644 --- a/share/functions/__fish_complete_proc.fish +++ b/share/functions/__fish_complete_proc.fish @@ -1,4 +1,47 @@ function __fish_complete_proc --description 'Complete by list of running processes' - ps -A --no-headers --format comm | sort -u - + # Our function runs ps, followed by a massive list of commands passed to sed + set -l ps_cmd + set -l sed_cmds + if test (uname) = Linux + # comm and ucomm return a truncated name, so parse it from the command line field, + # which means we have to trim off the arguments. + # Unfortunately, it doesn't seem to escape spaces - so we can't distinguish + # between the command name, and the first argument. Still, processes with spaces + # in the name seem more common on OS X than on Linux, so prefer to parse out the + # command line rather than using the stat data. + # If the command line is unavailable, you get the stat data in brackets - so + # parse out brackets too. + set ps_cmd 'ps -A -o command' + + # Erase everything after the first space + set sed_cmds $sed_cmds 's/ .*//' + + # Erases weird stuff Linux gives like kworker/0:0 + set sed_cmds $sed_cmds 's|/[0-9]:[0-9]]$||g' + + # Retain the last path component only + set sed_cmds $sed_cmds 's|.*/||g' + + # Strip off square brackets. Cute, huh? + set sed_cmds $sed_cmds 's/[][]//g' + + # Erase things that are just numbers + set sed_cmds $sed_cmds 's/^[0-9]*$//' + else + # OS X, BSD. Preserve leading spaces. + set ps_cmd 'ps axc -o comm' + + # Delete parenthesized (zombie) processes + set sed_cmds $sed_cmds '/(.*)/d' + end + + # Append sed command to delete first line (the header) + set sed_cmds $sed_cmds '1d' + + # Append sed commands to delete leading dashes and trailing spaces + # In principle, commands may have trailing spaces, but ps emits space padding on OS X + set sed_cmds $sed_cmds 's/^-//' 's/ *$//' + + # Run ps, pipe it through our massive set of sed commands, then sort and unique + eval $ps_cmd | sed '-e '$sed_cmds | sort -u end