33set -Eeuo pipefail # -x
44SCRIPTNAME=` basename $0 ` && function die { [ -n " $* " ] && echo " $SCRIPTNAME : **ERROR**: ${*:- aborting} " >&2 ; exit 127 ; }
55SELF=" $0 "
6- # for function exports to work sub-shell must be bash too
7- export SHELL=bash
86
97# == PREVIEW fast path ==
108export REVPAT=' ^[^a-z()0-9]*([k-xyz]{7,})([?]*)\ ' # line start, ignore --graph, parse revision letters, catch '??'-postfix
5250
5351# == Check Deps ==
5452VERSION=0.23.0
55- jj --version --ignore-working-copy | grep -Eq ' jj 0\.2[3-9]\.' || die ' jj-0.23 is required'
56- fzf --help | grep -Fq ' --header-first' || die ' fzf-0.29 is required'
57- sed --version | grep -Fq ' GNU sed' || die ' GNU sed is required'
58- awk --version | grep -Fq ' GNU Awk' || die ' GNU Awk is required'
53+ jj --version --ignore-working-copy | grep -Eq ' jj 0\.2[3-9]\.' || die " failed to find 'jj' version 0.23 in \$ PATH"
54+ fzf --help | grep -Fq ' --header-first' || die " failed to find 'fzf' version 0.29 in \$ PATH"
55+ sed --version | grep -Fq ' GNU sed' &&
56+ gsed () { sed " $@ " ; } && export -f gsed ||
57+ gsed --version | grep -Fq ' GNU sed' || die " failed to find 'gsed' in \$ PATH (GNU sed)"
58+ gawk --version | grep -Fq ' GNU Awk' || die " failed to find 'gawk' in \$ PATH (GNU Awk)"
5959TRACK=--track && FZFHELP=" $( fzf --help 2>&1 ) " && [[ " $FZFHELP " =~ " --track" ]] || TRACK=
6060
6161# == Early Options ==
@@ -77,8 +77,7 @@ JJROOT=$(jj --ignore-working-copy root) || die "$PWD: not a JJ repository"
7777JJFZFSHOW=" jj --no-pager --ignore-working-copy ${JJFZF_ATOP: +--at-op $JJFZF_ATOP } show --tool true"
7878JJFZFONELINE=" jj --no-pager --ignore-working-copy log --color=always --no-graph -T builtin_log_oneline"
7979JJFZFPAGER=" less -Rc"
80- JJFZF_SHELL=" ${JJFZF_SHELL:-/ usr/ bin/ env bash -i} "
81- JJSUBSHELL=' T=$(tty 2>/dev/null||tty <&1 2>/dev/null||tty <&2 2>/dev/null)&&test -n "$T"&&echo -e "\n#\n# Type \"exit\" to leave subshell\n#" && unset JJ_CONFIG && exec ' " $JJFZF_SHELL " ' <$T 1>$T 2>$T'
80+ JJSUBSHELL=' T=$(tty 2>/dev/null||tty <&1 2>/dev/null||tty <&2 2>/dev/null)&&test -n "$T"&&echo -e "\n#\n# Type \"exit\" to leave subshell\n#" && unset JJ_CONFIG && exec /usr/bin/env ' " $SHELL " ' <$T 1>$T 2>$T'
8281INFO_BINDING=" fzf </dev/null >/dev/tty 2>&1 --prompt ' ' --disabled --layout=reverse --height 1 --margin 4 --padding 4 --border=block --no-info --no-scrollbar --no-clear --bind=enter:print-query "
8382FZFSETTINGS=(
8483 --ansi --no-mouse -x -e
@@ -97,6 +96,8 @@ FZFSETTINGS=(
9796FZFPOPUP=(fzf " ${FZFSETTINGS[@]} " --margin 0,3%,5%,3% --border)
9897JJLOGCMD=( $SELF fzflog )
9998TEMPD=
99+ # for function exports to work sub-shell must be bash too
100+ export SHELL=bash
100101
101102# == JJ_CONFIG ==
102103# parsable version of builtin_log_oneline; https://github.com/martinvonz/jj/blob/main/cli/src/config/templates.toml
@@ -301,7 +302,7 @@ echo_signoff()
301302 if test " ${JJFZF_SIGNOFF:- true} " == true ; then
302303 echo # separating newline before signoff section
303304 $JJFZFSHOW -T ' format_detailed_signature(author) ++ "\n"' -r @ |
304- sed -e ' s/>.*/>/ ; s/^/Signed-off-by: /'
305+ gsed -e ' s/>.*/>/ ; s/^/Signed-off-by: /'
305306 fi
306307)
307308# Echo current or default message
@@ -317,7 +318,7 @@ echo_commit_msg()
317318 # start with file name prefixes
318319 cd " $JJROOT " # create root relative file names
319320 FILES=()
320- readarray -t FILES < <( jj --ignore-working-copy log --no-graph -r " $R " -T ' ' -s | sed ' s/^\w //' )
321+ readarray -t FILES < <( jj --ignore-working-copy log --no-graph -r " $R " -T ' ' -s | gsed ' s/^\w //' )
321322 test ${# FILES[@]} -gt 0 &&
322323 printf " %s: \n" " ${FILES[@]} " ||
323324 echo " "
@@ -569,7 +570,7 @@ file-editor()
569570 # cd root; otherwise revision file paths will mismatch
570571 cd " $JJROOT "
571572 # read files edited by revision
572- readarray -t FILES < <( jj --ignore-working-copy log --no-graph -r " $R " -T ' ' -s | sed ' s/^\w //' )
573+ readarray -t FILES < <( jj --ignore-working-copy log --no-graph -r " $R " -T ' ' -s | gsed ' s/^\w //' )
573574 # make sure to edit revision
574575 test " $W " == " $R " || (
575576 IMMU=$( $JJFZFSHOW -r " $R " -T ' if(immutable, "true")' )
@@ -595,7 +596,7 @@ help()
595596 JJCMDS=:
596597 for w in $( LANG=C
597598 jj --help |
598- sed -r ' 1,/^Commands:/d; /^\w/{x;q}; s/^ *(\w+)\b.*/\1/' ) ; do
599+ gsed -r ' 1,/^Commands:/d; /^\w/{x;q}; s/^ *(\w+)\b.*/\1/' ) ; do
599600 [[ $w == help ]] && continue
600601 JJCMDS=" $JJCMDS$w :"
601602 done
@@ -623,7 +624,7 @@ split-interactive()
623624 set -Eeuo pipefail #-x
624625 TRUNCATE=y
625626 test $TRUNCATE == y && echo -n > "$1 " || :
626- sed 's/TRUNCATE=./TRUNCATE=n/' -i "$0 "
627+ gsed 's/TRUNCATE=./TRUNCATE=n/' -i "$0 "
627628 __EOF__
628629 chmod +x $TEMPD /trunc1st.sh
629630 export EDITOR=$TEMPD /trunc1st.sh
@@ -671,7 +672,7 @@ if [[ $# == 2 ]] && [[ "${1:0:1}" == + ]] ; then
671672 grep -s -n ' ' " $file " /dev/null |
672673 " ${FZFPOPUP[@]} " \
673674 --border-label ' -[ LINE HISTORY (EXPERIMENTAL) ]-' --color=border:yellow,label:yellow \
674- --preview " git log --graph --no-patch -M -C --find-copies-harder --pretty='%C(blue)%h %C(yellow)%aL %C(reset)%s%n%b' -L{2}:{1} --color $C | sed 's/Signed-off-by:.*//; /^ *$/d' " \
675+ --preview " git log --graph --no-patch -M -C --find-copies-harder --pretty='%C(blue)%h %C(yellow)%aL %C(reset)%s%n%b' -L{2}:{1} --color $C | gsed 's/Signed-off-by:.*//; /^ *$/d' " \
675676 --bind " enter:execute( git log -M -C --find-copies-harder -L{2},+7:{1} --color $C | $JJFZFPAGER )" \
676677 --header " File Line History" \
677678 --no-tac --no-sort +m -d: \
@@ -736,7 +737,7 @@ merging()
736737 --border-label ' -[ MERGING ]-' --color=border:bright-blue,label:bright-blue \
737738 --prompt " Merge +> " \
738739 --header " $H " --header-first \
739- --bind " alt-u:execute-silent( sed 's/0/2/;s/1/0/;s/2/1/' -i $TEMPD /upstream.toggle )+refresh-preview" \
740+ --bind " alt-u:execute-silent( gsed 's/0/2/;s/1/0/;s/2/1/' -i $TEMPD /upstream.toggle )+refresh-preview" \
740741 -m --color=pointer:grey \
741742 --no-tac --no-sort > $TEMPD /selections.txt &&
742743 mapfile -t selections < $TEMPD /selections.txt &&
@@ -764,8 +765,8 @@ merging()
764765 echo -e " \n* Branch '` rev_bookmark1 $c ` ' commit log:" ||
765766 echo -e " \n* Branch commit log:" # "$c ^$MERGE_BASE"
766767 git log --pretty=$' \f %s%+b' $c ^$MERGE_BASE |
767- sed ' /^\(Signed-off-by\|Acked-by\|Tested-by\|Cc\):/d' |
768- sed ' /^$/d ; s/^/\t/ ; s/^\t\f$/ (no description)/ ; s/^\t\f/ /'
768+ gsed ' /^\(Signed-off-by\|Acked-by\|Tested-by\|Cc\):/d' |
769+ gsed ' /^$/d ; s/^/\t/ ; s/^\t\f$/ (no description)/ ; s/^\t\f/ /'
769770 done
770771 echo_signoff
771772 )
@@ -839,7 +840,7 @@ undone_log()
839840 # list all oplog descriptions, find description with "undo operation 123abc"
840841 T=' coalesce( self.description().first_line(), " ") ++ "\n"'
841842 jj --no-pager --ignore-working-copy op log --no-graph --color=never -T " $T " |
842- sed -nr '
843+ gsed -nr '
843844 # turn "undo operation 123abc" into an exact id with 16 characters
844845 /^undo operation [a-f0-9]{16}/s/^undo operation ([a-f0-9]{16}).*/\1/
845846 T; # goto EOS unless the previous s/// matched
@@ -865,12 +866,12 @@ label(if(current_operation, "current_operation"),
865866oplog_oneline ()
866867(
867868 temp_dir
868- # turn each undone and undo operation on "123abc" into a new sed commands that replaces this operations graph character
869+ # turn each undone and undo operation on "123abc" into a new gsed commands that replaces this operations graph character
869870 undone_log |
870- sed -r ' s/([a-f0-9]+)/ s|○(.*\1)|-\\1| /' > $TEMPD /undone.sed
871+ gsed -r ' s/([a-f0-9]+)/ s|○(.*\1)|-\\1| /' > $TEMPD /undone.sed
871872 # show operation log, filtered through the above sed script to alter markers for undone ops
872873 jj --no-pager --ignore-working-copy op log --color=always -T " $JJ_FZF_OPLOG_ONELINE " |
873- sed -rf $TEMPD /undone.sed # beware, script needs to ignore ANSI color escape sequences
874+ gsed -rf $TEMPD /undone.sed # beware, script needs to ignore ANSI color escape sequences
874875)
875876FUNCTIONS+=( ' oplog_oneline' )
876877
@@ -894,8 +895,8 @@ op-log()
894895 --border-label ' -[ OP-LOG ]-' --color=border:bright-yellow,label:bright-yellow \
895896 --prompt " Operation > " \
896897 --header " $H " --header-first \
897- --bind " ctrl-d:execute-silent( sed 's/^VIEW=.*/VIEW=diff@oplog/' -i $TEMPD /oplog.env )+refresh-preview" \
898- --bind " ctrl-l:execute-silent( sed 's/^VIEW=.*/VIEW=log@oplog/' -i $TEMPD /oplog.env )+refresh-preview" \
898+ --bind " ctrl-d:execute-silent( gsed 's/^VIEW=.*/VIEW=diff@oplog/' -i $TEMPD /oplog.env )+refresh-preview" \
899+ --bind " ctrl-l:execute-silent( gsed 's/^VIEW=.*/VIEW=log@oplog/' -i $TEMPD /oplog.env )+refresh-preview" \
899900 --bind " alt-w:execute-silent( $SELF wdrestore@oplog {} )+abort" \
900901 --bind " alt-z:execute-silent( $SELF undo-op@oplog {} )+abort" \
901902 --bind " enter:execute( [[ {} =~ \$ OPPAT ]] || exit && export JJFZF_ATOP=\"\$ {BASH_REMATCH[1]}\" && $SELF logrev @ {q} )" \
@@ -1099,8 +1100,8 @@ reparenting()
10991100 --preview " . $TEMPD /reparenting.env && reparenting_revs {+} && reparenting_cmd" \
11001101 --prompt " Parents > " \
11011102 --header " $H " --header-first \
1102- --bind " alt-a:execute-silent( sed 's/^OP=.*/OP=\" |\" /' -i $TEMPD /reparenting.env )+refresh-preview" \
1103- --bind " alt-d:execute-silent( sed 's/^OP=.*/OP=\" ~\" /' -i $TEMPD /reparenting.env )+refresh-preview" \
1103+ --bind " alt-a:execute-silent( gsed 's/^OP=.*/OP=\" |\" /' -i $TEMPD /reparenting.env )+refresh-preview" \
1104+ --bind " alt-d:execute-silent( gsed 's/^OP=.*/OP=\" ~\" /' -i $TEMPD /reparenting.env )+refresh-preview" \
11041105 -m --color=pointer:grey \
11051106 --no-tac --no-sort > $TEMPD /selections.txt &&
11061107 mapfile -t selections < $TEMPD /selections.txt &&
@@ -1149,13 +1150,13 @@ rebasing()
11491150 --preview " [[ {} =~ $REVPAT ]] || exit; export REV=\"\$ {BASH_REMATCH[1]}\" ; $PREVIEW " \
11501151 --prompt " Rebase > " \
11511152 --header " $H " --header-first \
1152- --bind " alt-b:execute-silent( sed 's/^FR=.*/FR=--branch/' -i $TEMPD /rebasing.env )+refresh-preview" \
1153- --bind " alt-s:execute-silent( sed 's/^FR=.*/FR=--source/' -i $TEMPD /rebasing.env )+refresh-preview" \
1154- --bind " alt-r:execute-silent( sed 's/^FR=.*/FR=--revisions/' -i $TEMPD /rebasing.env )+refresh-preview" \
1155- --bind " alt-p:execute-silent( sed 's/^SP=false/SP=x/; s/^SP=true/SP=false/; s/^SP=x/SP=true/' -i $TEMPD /rebasing.env )+refresh-preview" \
1156- --bind " ctrl-d:execute-silent( sed 's/^TO=.*/TO=--destination/' -i $TEMPD /rebasing.env )+refresh-preview" \
1157- --bind " ctrl-a:execute-silent( sed 's/^TO=.*/TO=--insert-after/' -i $TEMPD /rebasing.env )+refresh-preview" \
1158- --bind " ctrl-b:execute-silent( sed 's/^TO=.*/TO=--insert-before/' -i $TEMPD /rebasing.env )+refresh-preview" \
1153+ --bind " alt-b:execute-silent( gsed 's/^FR=.*/FR=--branch/' -i $TEMPD /rebasing.env )+refresh-preview" \
1154+ --bind " alt-s:execute-silent( gsed 's/^FR=.*/FR=--source/' -i $TEMPD /rebasing.env )+refresh-preview" \
1155+ --bind " alt-r:execute-silent( gsed 's/^FR=.*/FR=--revisions/' -i $TEMPD /rebasing.env )+refresh-preview" \
1156+ --bind " alt-p:execute-silent( gsed 's/^SP=false/SP=x/; s/^SP=true/SP=false/; s/^SP=x/SP=true/' -i $TEMPD /rebasing.env )+refresh-preview" \
1157+ --bind " ctrl-d:execute-silent( gsed 's/^TO=.*/TO=--destination/' -i $TEMPD /rebasing.env )+refresh-preview" \
1158+ --bind " ctrl-a:execute-silent( gsed 's/^TO=.*/TO=--insert-after/' -i $TEMPD /rebasing.env )+refresh-preview" \
1159+ --bind " ctrl-b:execute-silent( gsed 's/^TO=.*/TO=--insert-before/' -i $TEMPD /rebasing.env )+refresh-preview" \
11591160 --no-tac --no-sort +m ) &&
11601161 [[ " $REV " =~ $REVPAT ]] &&
11611162 REV=" ${BASH_REMATCH[1]} " ||
@@ -1332,12 +1333,12 @@ DOC['undo']='Use `jj op undo` to undo the last operation performed by `jj` that
13321333undo ()
13331334(
13341335 temp_dir
1335- # turn each undone operation "123abc" into an sed delete command
1336+ # turn each undone operation "123abc" into an gsed delete command
13361337 undone_log |
1337- sed -r ' s|([a-f0-9]+)| /\\b\1/d |' > $TEMPD /delops.sed
1338+ gsed -r ' s|([a-f0-9]+)| /\\b\1/d |' > $TEMPD /delops.sed
13381339 # list operation IDs, skipping undone ones
13391340 jj --ignore-working-copy op log --no-graph -T ' self.id().short(16) ++ " " ++ self.description().first_line() ++ "\n"' |
1340- sed -rf $TEMPD /delops.sed > $TEMPD /undoable-ops.lst
1341+ gsed -rf $TEMPD /delops.sed > $TEMPD /undoable-ops.lst
13411342 # fetch first
13421343 read op rest < $TEMPD /undoable-ops.lst
13431344 # read -p "Undo $op? " YN ; [[ "${YN:0:1}" =~ [yY] ]] || exit
@@ -1377,7 +1378,7 @@ if [[ "${1:-}" = --help ]] ; then
13771378 echo " *$k :* **$NAME **"
13781379 D=" ${DOC[$NAME]:- } "
13791380 test -z " $D " ||
1380- echo " $D " | fold -s -w78 | sed ' s/^/ /'
1381+ echo " $D " | fold -s -w78 | gsed ' s/^/ /'
13811382 done
13821383 ) | (
13831384 B=$' \e [1m' # Bold
@@ -1400,7 +1401,7 @@ if [[ "${1:-}" = --help ]] ; then
14001401 s,(\bhttps?://[^ ()\r]+),$U \1$Z ,g # Link
14011402 "
14021403 tr \\ n \\ r |
1403- { $COLOR && sed -re " $SEDSCRIPT " || cat ; } |
1404+ { $COLOR && gsed -re " $SEDSCRIPT " || cat ; } |
14041405 tr \\ r \\ n
14051406 )
14061407 exit 0
0 commit comments