bopher-ng

A better Gopher client in pure Bash
git clone git://git.luxferre.top/bopher-ng.git
Log | Files | Refs | README | LICENSE

commit 23641831d76a194bee4dac1a15ce61f510f8bcb2
parent 784383c914b9487c501dc00e3dff1282cd34dc53
Author: Luxferre <lux@ferre>
Date:   Wed, 29 Mar 2023 23:26:44 +0300

Made more robust against unwanted escaping

Diffstat:
Mbopher-ng.sh | 27++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/bopher-ng.sh b/bopher-ng.sh @@ -40,6 +40,7 @@ fi # styling used in the TUI ESC=$'\x1b' # use the ANSI literal syntax to support in read prompts as well +LF=$'\x0a' # let's do this ERESET="${ESC}[0m" # reset the styling ERRCOLOR="${ESC}[31;1m" # red bold LINKCOLOR="${ESC}[36;1m" # cyan bold @@ -59,7 +60,7 @@ MOUSEOFF="${ESC}[?1000;1006l" # term command to stop sending mouse input events # button_attr;xcoord;ycoord[Mm] clear_term() { # clear the terminal on Ctrl+C interrupt - printf '%b' "$MOUSEOFF$ERESET$ALTBUFOFF" + printf '%s' "$MOUSEOFF$ERESET$ALTBUFOFF" exit 0 } trap clear_term INT @@ -174,12 +175,12 @@ amrender() { local action="${fields[0]}" # to display an AM entry, we only need two of its fields local desc="${fields[1]}" if [[ 'E' == "$action" ]]; then # plain text - output="${output}$desc\n" + output="${output}${desc}${LF}" else # not plain text if [[ "$idx" == "$FOCUSLINEINDEX" ]]; then # if the current link is focused, then... - output="${output}$FOCUSATTR" # print the focus attribute (the link contains ERESET anyway) + output="${output}${FOCUSATTR}" # print the focus attribute (the link contains ERESET anyway) fi - output="${output}$LINKCOLOR=> ${desc}$ERESET\n" + output="${output}${LINKCOLOR}=> ${desc}${ERESET}${LF}" fi done # final preparations: @@ -187,7 +188,7 @@ amrender() { # - output current resource to the status line # - reset the cursor once again output="${output}$BELOWCLR${ESC}[$TERMROWS;0H$FOCUSATTR$(amtogopher "$CURRENTAM")$ERESET${ESC}[$TERMROWS;0H" - printf '%b' "$output" # finally, print the entire output with a single call + printf '%s' "$output" # finally, print the entire output with a single call } trap 'amrender' WINCH # rerender on terminal size change @@ -221,7 +222,7 @@ jumplink() { # args: delta (usually 1 or -1) amload() { # args: AM line[, forcedl] CURRENTAM="$1" # update current AM value - printf '%b' "${LINECLR}Loading..." + printf '%s' "${LINECLR}Loading..." readarray -t SCREENBUF < <(amclick "$CURRENTAM" "$2") # populate screen buffer by loading the resource from the AM entry NAVIGABLES=() # reset the navigable indexes CURLINKINDEX=0 # reset the link number @@ -258,7 +259,7 @@ goback() { # remove the last AM line from history and go there stashlink() { # stash the link to the currently viewed resource local gopherlink="$(amtogopher "$CURRENTAM")" printf '[%s] %s\n' "$(date -u '+%F %T')" "$gopherlink" >> $BOPHER_LINKSTASH - printf 'Stashed %s%b' "$gopherlink" "$ERESET${ESC}[$TERMROWS;0H" # just reset the cursor to the last line + printf 'Stashed %s%s' "$gopherlink" "$ERESET${ESC}[$TERMROWS;0H" # just reset the cursor to the last line } # Focus and click a link on a Gophermap @@ -296,7 +297,7 @@ readmouseinput() { # correctly read the remaining mouse input in semi-long mode # entry point code starts here -printf '%b' "$ALTBUFON$CLS" # enter ALTBUF mode and clear the screen +printf '%s' "$ALTBUFON$CLS" # enter ALTBUF mode and clear the screen # now, load the resource provided from the command line and start the main loop @@ -311,15 +312,15 @@ mouseY='' mouseStatus='M' while true; do mousecmd='' # mouse command buffer - printf '%b' "$MOUSEON" # enable mouse events before reading + printf '%s' "$MOUSEON" # enable mouse events before reading read -n 1 -s cmdbuf # read the character, tildas will be ignored if [[ "$cmdbuf" == $'\x1b' ]]; then # here's the control character read -n 2 -s cmdbuf # read 2 additional characters - if [[ "$cmdbuf" == "[<" ]]; then # we have a mouse event, read the button attribute and the coordinates + if [[ "$cmdbuf" == '[<' ]]; then # we have a mouse event, read the button attribute and the coordinates read -r -s mousecmd mouseX mouseY mouseStatus < <(readmouseinput) fi fi - printf '%b' "$MOUSEOFF" # don't generate mouse events outside the input sequence + printf '%s' "$MOUSEOFF" # don't generate mouse events outside the input sequence [[ "$mousecmd" == '2' && "$mouseStatus" == 'M' ]] && cmdbuf='b' # right click is automatically assigned to back command [[ "$cmdbuf" == '[A' || "$cmdbuf" == 'k' || "$mousecmd" == '64' ]] && scroll -1 [[ "$cmdbuf" == '[B' || "$cmdbuf" == 'j' || "$mousecmd" == '65' ]] && scroll 1 @@ -327,8 +328,8 @@ while true; do [[ "$cmdbuf" == '[6' || "$cmdbuf" == 'l' ]] && scroll $(( $TERMROWS - 1 )) # PgDn [[ "$cmdbuf" == 's' ]] && jumplink 1 [[ "$cmdbuf" == 'w' ]] && jumplink -1 - [[ "$cmdbuf" == 'q' ]] && printf '%b' "$ERESET$ALTBUFOFF" && exit 0 - [[ "$cmdbuf" == $'\0a' ]] && clicklink + [[ "$cmdbuf" == 'q' ]] && printf '%s' "$ERESET$ALTBUFOFF" && exit 0 + [[ "$cmdbuf" == '' ]] && clicklink # space or enter or tab [[ "$cmdbuf" == 'd' ]] && clicklink 1 # same as click but with force-download flag [[ "$cmdbuf" == 'b' ]] && goback [[ "$cmdbuf" == 'S' ]] && stashlink