Skip to content

Commit

Permalink
✨ introducing fsfs
Browse files Browse the repository at this point in the history
  • Loading branch information
jcaillon committed Apr 15, 2024
1 parent 5c8b905 commit e506eb8
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 150 deletions.
6 changes: 3 additions & 3 deletions tests.d/1002-lib-kurl/results.approved.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,13 @@ stack:
├─ In function testKurl::toVar() $GLOBAL_VALET_HOME/tests.d/1002-lib-kurl/00.kurl.sh:73
├─ In function main() $GLOBAL_VALET_HOME/tests.d/1002-lib-kurl/00.kurl.sh:101
├─ In function source() $GLOBAL_VALET_HOME/tests.d/1002-lib-kurl/00.kurl.sh:131
├─ In function source() $GLOBAL_VALET_HOME/valet.d/core:443
├─ In function source() $GLOBAL_VALET_HOME/valet.d/core:447
├─ In function runTest() valet.d/commands.d/self-test-utils:241
├─ In function runTestSuites() valet.d/commands.d/self-test-utils:195
├─ In function runCoreTests() valet.d/commands.d/self-test-utils:107
├─ In function selfTest() valet.d/commands.d/self-test.sh:110
├─ In function main::runFunction() $GLOBAL_VALET_HOME/valet.d/main:585
├─ In function main::parseMainArguments() $GLOBAL_VALET_HOME/valet.d/main:537
├─ In function main::runFunction() $GLOBAL_VALET_HOME/valet.d/main:589
├─ In function main::parseMainArguments() $GLOBAL_VALET_HOME/valet.d/main:541
└─ In function main() $GLOBAL_VALET_HOME/valet:99
```

Expand Down
6 changes: 3 additions & 3 deletions tests.d/1005-lib-io/results.approved.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,13 +349,13 @@ stack:
├─ In function testIo::invoke() $GLOBAL_VALET_HOME/tests.d/1005-lib-io/01.invoke.sh:61
├─ In function main() $GLOBAL_VALET_HOME/tests.d/1005-lib-io/01.invoke.sh:115
├─ In function source() $GLOBAL_VALET_HOME/tests.d/1005-lib-io/01.invoke.sh:120
├─ In function source() $GLOBAL_VALET_HOME/valet.d/core:443
├─ In function source() $GLOBAL_VALET_HOME/valet.d/core:447
├─ In function runTest() valet.d/commands.d/self-test-utils:241
├─ In function runTestSuites() valet.d/commands.d/self-test-utils:195
├─ In function runCoreTests() valet.d/commands.d/self-test-utils:107
├─ In function selfTest() valet.d/commands.d/self-test.sh:110
├─ In function main::runFunction() $GLOBAL_VALET_HOME/valet.d/main:585
├─ In function main::parseMainArguments() $GLOBAL_VALET_HOME/valet.d/main:537
├─ In function main::runFunction() $GLOBAL_VALET_HOME/valet.d/main:589
├─ In function main::parseMainArguments() $GLOBAL_VALET_HOME/valet.d/main:541
└─ In function main() $GLOBAL_VALET_HOME/valet:99
```

Expand Down
8 changes: 7 additions & 1 deletion valet.d/core
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,13 @@ function log::getCallStack() {
if [[ -z "${func}" ]]; then func=MAIN; fi
linen="${BASH_LINENO[$((i - 1))]}"
src="${BASH_SOURCE[${i}]}"
if [[ -z "${src}" ]]; then src=non_file_source; fi
if [[ -z "${src}" ]]; then
src=non_file_source;
elif [[ -f "${src/#.\//"${PWD}"\/}" ]]; then
src="${src/#.\//"${PWD}"\/}"
elif [[ -f "${src/#.\//"${GLOBAL_VALET_HOME}"\/}" ]]; then
src="${src/#.\//"${GLOBAL_VALET_HOME}"\/}"
fi
if [[ ${i} -eq "$((stackSize - 1))" ]]; then
treeString="└─"
fi
Expand Down
160 changes: 160 additions & 0 deletions valet.d/lib-fsfs
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/usr/bin/env bash
set -Eeu -o pipefail
# author: github.com/jcaillon
# description: This script can be sourced by commands to provide convenient functions.
# fsfs stands for full srceen fuzzy search.

# shellcheck source=lib-ansi-codes
source ansi-codes interactive io

#===============================================================
# >>> Events
#===============================================================



#===============================================================
# >>> Custom drawing functions
#===============================================================

function fsfs::searchCommand() {

local originalTraps
io::captureOutput trap -p SIGWINCH EXIT SIGINT SIGQUIT
originalTraps="${LAST_RETURNED_VALUE}"

_CLOSE_INTERACTIVE_SESSION=false

# we still need to export the terminal size but in addition, we need to _drawScreen.
# Note: SIGWINCH does not interrupt a read command and wait for it to complete so we need
# to set a timeout on read to allow this refresh.
trap 'system::exportTerminalSize; _drawScreen' SIGWINCH

# still need to handle the exit, but we also need to reset the terminal when exiting.
trap '_resetTerminal; main::onExitInternal' EXIT

# interrupting closes the interactive session
trap '_interruptSession' SIGINT SIGQUIT

_setupTerminal
_drawScreen

while true; do
read -t 0.1 -srn 1 && key "${REPLY}"

# break if fd 1 is closed or does not refer to a terminal.
if [[ ! -t 1 || ${_CLOSE_INTERACTIVE_SESSION} == "true" ]]; then break; fi
done

# restore the initial traps
eval "${originalTraps}"

_resetTerminal

log::info "Bye!"
}

function _drawScreen() {
writeToStatusBar "Terminal size is: ${GLOBAL_COLUMNS}x${GLOBAL_LINES}"
}

function _setupTerminal() {
if command -v stty &>/dev/null; then
stty -echo &>/dev/null
fi
printf '%s' "${enableAlternateBufferScreen}${cursorHide}${eraseScreen}"
}

function _resetTerminal() {
printf '%s' "${cursorShow}${disableAlternateBufferScreen}"
if command -v stty &>/dev/null; then
stty echo &>/dev/null
fi
}

function _interruptSession() {
_CLOSE_INTERACTIVE_SESSION=true
return 0
}


# Write a message to the status bar.
function writeToStatusBar() {
printf '%s' "${cursorSavePos}${cursorMove}$((GLOBAL_LINES - 1));1${_to}${eraseLine}${textBold}${1}${textReset}${cursorRestorePos}"
}

function key() {
local keyPressed="${1}"
local specialKeyPress=false

# Special key detection.
if [[ ${keyPressed} == $'\e' ]]; then
read -t 0.1 -rsn 2
keyPressed="${keyPressed}${REPLY}"
specialKeyPress=true

local sk2
printf -v sk2 "%q" "${keyPressed}"
writeToStatusBar "Special key pressed: ⌜${sk2}⌝."
fi

case ${keyPressed} in
$'\e[C' | $'\eOC' | "")
writeToStatusBar right or enter
;;
$'\e[D' | $'\eOD' | $'\177' | $'\b')
writeToStatusBar left or backspace
;;
$'\e[B' | $'\eOB')
writeToStatusBar down
;;
$'\e[A' | $'\eOA')
writeToStatusBar up
;;
s)
writeToStatusBar Start search
search "search"
;;
q)
_CLOSE_INTERACTIVE_SESSION=true
;;
*)
if [[ ${specialKeyPress} == "false" ]]; then
writeToStatusBar "Normal key pressed: ⌜${keyPressed}⌝."
fi
;;
esac
}

function search() {
local keyPressed
local searchString=""

printf '%s' "${cursorShow}${cursorMove}$((GLOBAL_LINES));1${_to}${eraseLine}"

while IFS= read -rsn 1 -p "${cursorHide}${_drawScreenPrompt}${cursorShow}${textBold}SEARCH:${textReset} ${searchString}" keyPressed; do
case ${keyPressed} in
# Backspace.
$'\177' | $'\b')
searchString=${searchString%?}
;;
# Escape key.
$'\e')
read -t 0.1 -rsn 2
searchString=
break
;;
# Enter/Return.
"")
writeToStatusBar "You searched: ${searchString}"
break
;;
*)
searchString+=$keyPressed
;;
esac
done

printf '%s' "${cursorHide}${eraseLine}"
}

141 changes: 0 additions & 141 deletions valet.d/lib-interactive
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ set -Eeu -o pipefail
# shellcheck source=lib-ansi-codes
source ansi-codes

#===============================================================
# >>> Events
#===============================================================

# if interactive shell, make sure to restore the cursor and echo when exiting
if [[ -t 1 ]]; then
trap "main::onExitInternal; printf '%s' $'\e[?25h'; stty echo &>/dev/null || true;" EXIT
fi

#===============================================================
# >>> Interactive prompts
#===============================================================
Expand Down Expand Up @@ -375,135 +366,3 @@ function interactive::getCursorPosition() {
# then read line;colR
IFS=';' read -d 'R' -sr CURSOR_LINE CURSOR_COLUMN || true
}



#===============================================================
# >>> Custom drawing functions
#===============================================================

function setupTerminal() {
stty -echo
printf '%s' "${switchScreenBuffer}${disableLineWrapping}${cursorHide}${eraseScreen}${limitScrolling}$((GLOBAL_LINES - 1))${_lines}"
}

function resetTerminal() {
printf '%s' "${enableLineWrapping}${cursorShow}${eraseScreen}${limitScrolling}${_lines}${switchScreenBuffer}"
stty echo
}

# Write a message to the status bar.
function writeToStatusBar() {
printf '%s' "${cursorSavePos}${cursorMove}$((GLOBAL_LINES - 1));1${_to}${eraseLine}${textBold}${1}${textReset}${cursorRestorePos}"
}

function key() {
local keyPressed="${1}"
local specialKeyPress=false

# Special key detection.
if [[ ${keyPressed} == $'\e' ]]; then
read -t 0.1 -rsn 2
keyPressed="${keyPressed}${REPLY}"
specialKeyPress=true

local sk2
printf -v sk2 "%q" "${keyPressed}"
writeToStatusBar "Special key pressed: ⌜${sk2}⌝."
fi

case ${keyPressed} in
$'\e[C' | $'\eOC' | "")
writeToStatusBar right or enter
;;
$'\e[D' | $'\eOD' | $'\177' | $'\b')
writeToStatusBar left or backspace
;;
$'\e[B' | $'\eOB')
writeToStatusBar down
;;
$'\e[A' | $'\eOA')
writeToStatusBar up
;;
s)
writeToStatusBar Start search
search "search"
;;
q)
CLOSE_INTERACTIVE_SESSION=true
;;
*)
if [[ ${specialKeyPress} == "false" ]]; then
writeToStatusBar "Normal key pressed: ⌜${keyPressed}⌝."
fi
;;
esac
}

function search() {
local keyPressed
local searchString=""

printf '%s' "${cursorShow}${cursorMove}$((GLOBAL_LINES));1${_to}${eraseLine}"

while IFS= read -rsn 1 -p "${cursorHide}${redrawPrompt}${cursorShow}${textBold}SEARCH:${textReset} ${searchString}" keyPressed; do
case ${keyPressed} in
# Backspace.
$'\177' | $'\b')
searchString=${searchString%?}
;;
# Escape key.
$'\e')
read -t 0.1 -rsn 2
searchString=
break
;;
# Enter/Return.
"")
writeToStatusBar "You searched: ${searchString}"
break
;;
*)
searchString+=$keyPressed
;;
esac
done

printf '%s' "${cursorHide}${eraseLine}"
}

function redraw() {
writeToStatusBar "Terminal size is: ${GLOBAL_COLUMNS}x${GLOBAL_LINES}"
}

function fullScreenInteractive() {

# TODO: also need to custom trap interrupt because we will use it to close the interactive session in full screen
# Need to figure out how to properly restore the screen buffer and cursor position exactly as it was

# we still need to export the terminal size but in addition, we need to redraw.
# Note: SIGWINCH does not interrupt a read command and wait for it to complete so we need
# to set a timeout on read to allow this refresh.
trap 'system::exportTerminalSize; redraw' SIGWINCH

# still need to handle the exit, but we also need to reset the terminal when exiting.
trap 'resetTerminal; main::onExitInternal' EXIT

setupTerminal
redraw

CLOSE_INTERACTIVE_SESSION=false

while true; do
read -t 0.1 -srn 1 && key "$REPLY"

# break if fd 1 is closed or does not refer to a terminal.
if [[ ! -t 1 || ${CLOSE_INTERACTIVE_SESSION} == "true" ]]; then break; fi
done

trap 'system::exportTerminalSize' SIGWINCH
trap 'main::onExitInternal' EXIT
resetTerminal

log::info "Bye!"
}
6 changes: 5 additions & 1 deletion valet.d/main
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trap 'main::onErrorInternal $?' ERR
function main::onExitInternal() {
local rc=$?

# disable the profiler is still on
# disable the profiler if still on
if [[ ${PROFILING:-} == "1" ]]; then main::disableProfiler; fi

log::debug "Exiting with code ${rc} after ${SECONDS}s."
Expand All @@ -43,6 +43,10 @@ function main::onExitInternal() {
if command -v onExit 1>/dev/null 2>&1; then
onExit
fi
# if we ran an interactive function, make sure to restore the cursor
if [[ -n ${cursorShow:-} ]]; then
printf '%s' "${cursorShow}"
fi
# always call cleanUp before exiting
main::onCleanUpInternal
if [[ "${GLOBAL_ERROR_DISPLAYED:-0}" != "1" && "${rc}" != "0" ]]; then
Expand Down
2 changes: 1 addition & 1 deletion valet.d/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.6.33
0.6.37

0 comments on commit e506eb8

Please sign in to comment.