1080 lines
44 KiB
Awk
Executable File
1080 lines
44 KiB
Awk
Executable File
#!/usr/bin/env -S awk -f
|
|
|
|
BEGIN {
|
|
|
|
###################
|
|
# Configuration #
|
|
###################
|
|
|
|
OPENER = ( ENVIRON["FMAWK_OPENER"] == "" ? ( ENVIRON["OSTYPE"] ~ /darwin.*/ ? "open" : "xdg-open" ) : ENVIRON["FMAWK_OPENER"] )
|
|
LASTPATH = ( ENVIRON["LASTPATH"] == "" ? ( ENVIRON["HOME"] "/.cache/lastpath" ) : ENVIRON["LASTPATH"] )
|
|
HISTORY = ( ENVIRON["HISTORY"] == "" ? ( ENVIRON["HOME"] "/.cache/history" ) : ENVIRON["HISTORY"] )
|
|
CMDHIST = ( ENVIRON["CMDHIST"] == "" ? ( ENVIRON["HOME"] "/.cache/cmdhist" ) : ENVIRON["CMDHIST"] )
|
|
CACHE = ( ENVIRON["CACHE"] == "" ? ( ENVIRON["HOME"] "/.cache/imagecache" ) : ENVIRON["CACHE"] )
|
|
FIFO_UEBERZUG = ENVIRON["FIFO_UEBERZUG"]
|
|
FMAWK_PREVIEWER = ENVIRON["FMAWK_PREVIEWER"]
|
|
PREVIEW = 0
|
|
HIDDEN = 0
|
|
RATIO = 0.35
|
|
HIST_MAX = 5000
|
|
SUBSEP = ","
|
|
|
|
####################
|
|
# Initialization #
|
|
####################
|
|
|
|
# Credit: https://unix.stackexchange.com/questions/224969/current-date-in-awk/225463#225463
|
|
srand(); old_time = srand();
|
|
init()
|
|
RS = "\a"
|
|
dir = ( ENVIRON["PWD"] == "/" ? "/" : ENVIRON["PWD"] "/" )
|
|
cursor = 1; curpage = 1;
|
|
|
|
# load alias
|
|
cmd = "${SHELL:=/bin/sh} -c \". ~/.${SHELL##*/}rc && alias\""
|
|
cmd | getline alias
|
|
close(cmd)
|
|
split(alias, aliasarr, "\n")
|
|
for (line in aliasarr) {
|
|
key = aliasarr[line]; gsub(/=.*/, "", key); gsub(/^alias /, "", key)
|
|
cmd = aliasarr[line]; gsub(/.*=/, "", cmd); gsub(/^'|'$/, "", cmd)
|
|
cmdalias[key] = cmd
|
|
}
|
|
|
|
# defind [a]ttributes, [b]ackground and [f]oreground
|
|
a_bold = "\033\1331m"
|
|
a_reverse = "\033\1337m"
|
|
a_clean = "\033\1332K"
|
|
a_reset = "\033\133m"
|
|
b_red = "\033\13341m"
|
|
f_red = "\033\13331m"
|
|
f_green = "\033\13332m"
|
|
f_yellow = "\033\13333m"
|
|
f_blue = "\033\13334m"
|
|
f_magenta = "\033\13335m"
|
|
f_cyan = "\033\13336m"
|
|
f_white = "\033\13337m"
|
|
|
|
#############
|
|
# Actions #
|
|
#############
|
|
|
|
# action = "History" RS \
|
|
# "mv" RS \
|
|
# "cp -R" RS \
|
|
# "ln -sf" RS \
|
|
# "rm -rf"
|
|
action = "History"
|
|
|
|
help = "\n" \
|
|
"NUMBERS: \n" \
|
|
"\t[num] - move cursor to entry [num] \n" \
|
|
"\t[num]+G - Go to page [num] \n" \
|
|
"\n" \
|
|
"NAVIGATION: \n" \
|
|
"\tk/↑ - up j/↓ - down \n" \
|
|
"\tl/→ - right h/← - left \n" \
|
|
"\tCtrl-f - Half Page Down Ctrl-u - Half Page Up\n" \
|
|
"\tn/PageDown - PageDown p/PageUp - PageUp \n" \
|
|
"\tg/Home - first page G/End - last page \n" \
|
|
"\tH - first entry L - last entry \n" \
|
|
"\tM - middle entry\n" \
|
|
"\n" \
|
|
"MODES: \n" \
|
|
"\t/ - search \n" \
|
|
"\t: - commandline mode \n" \
|
|
"\t commandline mode special function: \n" \
|
|
"\t {}: represent selected files/directories\n" \
|
|
"\t tab completion on path: start with ' /', use tab to complete on that path \n" \
|
|
"\t tab completion on cmd: completion based on command history \n" \
|
|
"\t ><: enter selecting mode for directory (choose ./ to confirm destination)\n" \
|
|
"\n" \
|
|
"SELECTION: \n" \
|
|
"\t␣ - bulk (de-)selection S - bulk (de-)selection all \n" \
|
|
"\ts - show selected\n" \
|
|
"\n" \
|
|
"PREVIEW: \n" \
|
|
"\tv - toggle preview \n" \
|
|
"\t> - more directory ratio < - less directory ratio \n" \
|
|
"\n" \
|
|
"MISC: \n" \
|
|
"\tr - refresh a - actions \n" \
|
|
"\t- - previous directory ! - spawn shell \n" \
|
|
"\t. - toggle hidden ? - show keybinds\n" \
|
|
"\tq - quit \n" \
|
|
|
|
main();
|
|
}
|
|
|
|
END {
|
|
finale();
|
|
hist_clean();
|
|
cmd_clean();
|
|
system("[ -f " CACHE ".jpg ] && rm " CACHE ".jpg 2>/dev/null")
|
|
if (list != "empty") {
|
|
printf("%s", dir) > "/dev/stdout"; close("/dev/stdout")
|
|
printf("%s", dir) > LASTPATH; close(LASTPATH)
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
|
|
do {
|
|
|
|
list = ( sind == 1 && openind == 1 ? slist : gen_content(dir, HIDDEN) )
|
|
delim = "\f"; num = 1; tmsg = dir; bmsg = ( bmsg == "" ? "Browsing" : bmsg );
|
|
menu_TUI(list, delim, num, tmsg, bmsg)
|
|
response = result[1]
|
|
bmsg = result[2]
|
|
|
|
#######################
|
|
# Matching: Actions #
|
|
#######################
|
|
|
|
if (bmsg == "Actions") {
|
|
if (response == "History") { hist_act(); sind = 0; response = result[1]; bmsg = "";}
|
|
}
|
|
|
|
########################
|
|
# Matching: Browsing #
|
|
########################
|
|
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", response)
|
|
|
|
if (response == "../") {
|
|
parent = ( dir == "/" ? "/" : dir )
|
|
old_dir = parent
|
|
if (hist != 1) {
|
|
gsub(/[^\/]*\/?$/, "", dir)
|
|
gsub(dir, "", parent)
|
|
}
|
|
# empty_selected()
|
|
dir = ( dir == "" ? "/" : dir ); hist = 0; sind = 0; openind = 0;
|
|
printf("%s\n", dir) >> HISTORY; close(HISTORY)
|
|
continue
|
|
}
|
|
|
|
if (response == "./") {
|
|
finale()
|
|
system("cd \"" dir "\" && ${SHELL:=/bin/sh}")
|
|
init()
|
|
sind = 0; openind = 0;
|
|
continue
|
|
}
|
|
|
|
if (response ~ /.*\/$/) {
|
|
# empty_selected()
|
|
old_dir = dir
|
|
dir = ( hist == 1 ? response : dir response )
|
|
printf("%s\n", dir) >> HISTORY; close(HISTORY)
|
|
cursor = 1; curpage = 1; hist = 0; sind = 0; openind = 0;
|
|
continue
|
|
}
|
|
|
|
finale()
|
|
system("cd \"" dir "\" && " OPENER " \"" dir response "\"")
|
|
init()
|
|
openind = 1; old_dir = ""; parent = "";
|
|
|
|
} while (1)
|
|
|
|
}
|
|
|
|
function hist_act() {
|
|
list = ""
|
|
getline hisfile < HISTORY; close(HISTORY);
|
|
N = split(hisfile, hisarr, "\n")
|
|
# for (i = N; i in hisarr; i--) {
|
|
for (i = N; i >= 1; i--) {
|
|
list = list "\n" hisarr[i]
|
|
}
|
|
list = substr(list, 3)
|
|
list = list "\n../"; delim = "\n"; num = 1; tmsg = "Choose history: "; bmsg = "Action: " response; hist = 1;
|
|
menu_TUI(list, delim, num, tmsg, bmsg)
|
|
}
|
|
|
|
function cmd_clean() { # act like uniq
|
|
tmp = "";
|
|
getline cmdhist < CMDHIST; close(CMDHIST);
|
|
N = split(cmdhist, cmdarr, "\n")
|
|
for (i = 1; i in cmdarr; i++) { # collect items not seen
|
|
if (! (cmdarr[i] in seen)) { seen[cmdarr[i]]++ }
|
|
}
|
|
for (key in seen) { # expand seen array into string
|
|
if (key != "") { tmp = tmp "\n" key }
|
|
}
|
|
tmp = substr(tmp, 2)
|
|
printf("%s", tmp) > CMDHIST; close(CMDHIST)
|
|
}
|
|
|
|
function hist_clean() {
|
|
getline hisfile < HISTORY; close(HISTORY);
|
|
N = split(hisfile, hisarr, "\n")
|
|
if (N > HIST_MAX) {
|
|
for (i = N-HIST_MAX+1; i in hisarr; i++) {
|
|
histmp = histmp "\n" hisarr[i]
|
|
}
|
|
hisfile = substr(histmp, 2)
|
|
printf("%s", hisfile) > HISTORY; close(HISTORY)
|
|
}
|
|
}
|
|
|
|
|
|
function gen_content(dir, HIDDEN) {
|
|
|
|
if (HIDDEN == 0) {
|
|
cmd = "for f in \"" dir "\"*; do "\
|
|
"test -L \"$f\" && test -f \"$f\" && symFileList=\"$symFileList$(printf '\f" a_bold f_cyan "%s" a_reset "' \"$f\")\" && continue; "\
|
|
"test -L \"$f\" && test -d \"$f\" && symDirList=\"$symDirList$(printf '\f" a_bold f_cyan "%s" a_reset "' \"$f\"/)\" && continue; "\
|
|
"test -x \"$f\" && test -f \"$f\" && execList=\"$execList$(printf '\f" a_bold f_green "%s" a_reset "' \"$f\")\" && continue; "\
|
|
"test -f \"$f\" && fileList=\"$fileList$(printf '\f%s' \"$f\")\" && continue; "\
|
|
"test -d \"$f\" && dirList=\"$dirList$(printf '\f" a_bold f_blue "%s" a_reset "' \"$f\"/)\" ; "\
|
|
"done; "\
|
|
"printf '%s' \"$dirList\" \"$symDirList\" \"$fileList\" \"$execList\" \"$symFileList\""
|
|
|
|
}
|
|
else if (HIDDEN == 1) {
|
|
cmd = "for f in \"" dir "\"* \"" dir "\".* ; do "\
|
|
"test -L \"$f\" && test -f \"$f\" && symFileList=\"$symFileList$(printf '\f" a_bold f_cyan "%s" a_reset "' \"$f\")\" && continue; "\
|
|
"test -L \"$f\" && test -d \"$f\" && symDirList=\"$symDirList$(printf '\f" a_bold f_cyan "%s" a_reset "' \"$f\"/)\" && continue; "\
|
|
"test -x \"$f\" && test -f \"$f\" && execList=\"$execList$(printf '\f" a_bold f_green "%s" a_reset "' \"$f\")\" && continue; "\
|
|
"test -f \"$f\" && fileList=\"$fileList$(printf '\f%s' \"$f\")\" && continue; "\
|
|
"test -d \"$f\" && dirList=\"$dirList$(printf '\f" a_bold f_blue "%s" a_reset "' \"$f\"/)\" ; "\
|
|
"done; "\
|
|
"printf '%s' \"$dirList\" \"$symDirList\" \"$fileList\" \"$execList\" \"$symFileList\""
|
|
}
|
|
|
|
code = cmd | getline dirlist
|
|
close(cmd)
|
|
if (code <= 0) {
|
|
dirlist = "empty"
|
|
}
|
|
else if (dir != "/") {
|
|
gsub(/[\\.^$(){}\[\]|*+?]/, "\\\\&", dir) # escape special char
|
|
gsub(dir, "", dirlist)
|
|
dirlist = substr(dirlist, 2)
|
|
}
|
|
else {
|
|
Narr = split(dirlist, dirlistarr, "\f")
|
|
delete dirlistarr[1]
|
|
dirlist = ""
|
|
for (entry = 2; entry in dirlistarr; entry++) {
|
|
sub(/\//, "", dirlistarr[entry])
|
|
dirlist = dirlist "\f" dirlistarr[entry]
|
|
}
|
|
dirlist = substr(dirlist, 2)
|
|
}
|
|
return dirlist
|
|
|
|
}
|
|
|
|
# Credit: https://stackoverflow.com/a/20078022
|
|
function isEmpty(arr) { for (idx in arr) return 0; return 1 }
|
|
|
|
function len(arr, i) { for (idx in arr) { ++i }; return i }
|
|
|
|
function maxidx(arr, idx) { for (idx in selorder) { pidx = (pidx <= idx ? idx : pidx ) }; return pidx }
|
|
|
|
##################
|
|
# Start of TUI #
|
|
##################
|
|
|
|
function finale() {
|
|
clean_preview()
|
|
printf "\033\1332J\033\133H" >> "/dev/stderr" # clear screen
|
|
printf "\033\133?7h" >> "/dev/stderr" # line wrap
|
|
printf "\033\1338" >> "/dev/stderr" # restore cursor
|
|
printf "\033\133?25h" >> "/dev/stderr" # show cursor
|
|
printf "\033\133?1049l" >> "/dev/stderr" # back from alternate buffer
|
|
system("stty isig icanon echo")
|
|
ENVIRON["LANG"] = LANG; # restore LANG
|
|
}
|
|
|
|
function init() {
|
|
system("stty -isig -icanon -echo")
|
|
printf "\033\1332J\033\133H" >> "/dev/stderr" # clear screen
|
|
printf "\033\133?1049h" >> "/dev/stderr" # alternate buffer
|
|
printf "\033\1337" >> "/dev/stderr" # save cursor
|
|
printf "\033\133?25l" >> "/dev/stderr" # hide cursor
|
|
printf "\033\1335 q" >> "/dev/stderr" # blinking bar
|
|
printf "\033\133?7l" >> "/dev/stderr" # line unwrap
|
|
LANG = ENVIRON["LANG"]; # save LANG
|
|
ENVIRON["LANG"] = C; # simplest locale setting
|
|
}
|
|
|
|
|
|
function CUP(lines, cols) {
|
|
printf("\033\133%s;%sH", lines, cols) >> "/dev/stderr"
|
|
}
|
|
|
|
function draw_selected() {
|
|
for (sel in selected) {
|
|
if (selpage[sel] != curpage || selected[sel] != dir seldisp[sel]) continue
|
|
selN = selnum[sel]
|
|
CUP(top + (selN-dispnum*(curpage-1))*num - num, 1)
|
|
for (i = 1; i <= num; i++) {
|
|
printf "\033\1332K" >> "/dev/stderr" # clear line
|
|
CUP(top + cursor*num - num + i, 1)
|
|
}
|
|
CUP(top + (selN-dispnum*(curpage-1))*num - num, 1)
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", seldisp[sel])
|
|
|
|
if (cursor == selN-dispnum*(curpage-1)) {
|
|
printf "%s %s%s%s%s%s", a_clean, a_reverse, f_red, selN ". ", seldisp[sel], a_reset >> "/dev/stderr"
|
|
}
|
|
else {
|
|
printf "%s %s%s%s%s%s", a_clean, a_bold, f_red, selN ". ", seldisp[sel], a_reset >> "/dev/stderr"
|
|
}
|
|
}
|
|
}
|
|
|
|
function empty_selected() {
|
|
split("", selected, ":"); split("", seldisp, ":");
|
|
split("", selpage, ":"); split("", selorder, ":")
|
|
sellist = ""; order = 0
|
|
}
|
|
|
|
function dim_setup() {
|
|
cmd = "stty size"
|
|
cmd | getline d
|
|
close(cmd)
|
|
split(d, dim, " ")
|
|
top = 3; bottom = dim[1] - 4;
|
|
fin = bottom - ( bottom - (top - 1) ) % num; end = fin + 1;
|
|
dispnum = (end - top) / num
|
|
}
|
|
|
|
function menu_TUI_page(list, delim) {
|
|
answer = ""; page = 0; split("", pagearr, ":") # delete saved array
|
|
dim_setup()
|
|
Narr = split(list, disp, delim)
|
|
dispnum = (dispnum <= Narr ? dispnum : Narr)
|
|
move = int( ( dispnum <= Narr ? dispnum * 0.5 : Narr * 0.5 ) )
|
|
|
|
# generate display content for each page (pagearr)
|
|
for (entry = 1; entry in disp; entry++) {
|
|
if ((+entry) % (+dispnum) == 1 || Narr == 1) { # if first item in each page
|
|
pagearr[++page] = entry ". " disp[entry]
|
|
}
|
|
else {
|
|
pagearr[page] = pagearr[page] "\n" entry ". " disp[entry]
|
|
}
|
|
loc = disp[entry]
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", loc)
|
|
if (parent != "" && loc == parent) {
|
|
cursor = entry - dispnum*(page - 1); curpage = page
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function search(list, delim, str, mode) {
|
|
find = ""; str = tolower(str);
|
|
if (mode == "dir") { regex = "^" str ".*/" }
|
|
else if (mode == "begin") {regex = "^" str ".*"}
|
|
else { regex = ".*" str ".*" }
|
|
gsub(/[(){}\[\]]/, "\\\\&", regex) # escape special char
|
|
|
|
# get rid of coloring to avoid find irrelevant item
|
|
tmplist = list
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", tmplist)
|
|
split(list, sdisp, delim); split(tmplist, tmpsdisp, delim)
|
|
|
|
for (entry = 1; entry in tmpsdisp; entry++) {
|
|
match(tolower(tmpsdisp[entry]), regex)
|
|
if (RSTART) { find = find delim sdisp[entry]; }
|
|
}
|
|
|
|
slist = substr(find, 2)
|
|
return slist
|
|
}
|
|
|
|
function key_collect(list, pagerind) {
|
|
key = ""; rep = 0
|
|
do {
|
|
|
|
cmd = "trap 'printf WINCH' WINCH; dd ibs=1 count=1 2>/dev/null"
|
|
cmd | getline ans;
|
|
close(cmd)
|
|
|
|
if (++rep == 1) {
|
|
srand(); time = srand()
|
|
if (time - old_time == 0) { sec++ }
|
|
else { sec = 0 }
|
|
old_time = time
|
|
}
|
|
|
|
gsub(/[\\^\[\]]/, "\\\\&", ans) # escape special char
|
|
# if (ans ~ /.*WINCH/ && pagerind == 0) { # trap SIGWINCH
|
|
if (ans ~ /.*WINCH/) { # trap SIGWINCH
|
|
cursor = 1; curpage = 1;
|
|
if (pagerind == 0) {
|
|
menu_TUI_page(list, delim)
|
|
redraw(tmsg, bmsg)
|
|
}
|
|
else if (pagerind == 1) {
|
|
printf "\033\1332J\033\133H" >> "/dev/stderr"
|
|
dim_setup()
|
|
Npager = (Nmsgarr >= dim[1] ? dim[1] : Nmsgarr)
|
|
for (i = 1; i <= Npager; i++) {
|
|
CUP(i, 1)
|
|
printf "%s", msgarr[i] >> "/dev/stderr"
|
|
}
|
|
}
|
|
gsub(/WINCH/, "", ans);
|
|
}
|
|
if (ans ~ /\033/ && rep == 1) { ans = ""; continue; } # first char of escape seq
|
|
else { key = key ans; }
|
|
if (key ~ /[^\x00-\x7f]/) { break } # print non-ascii char
|
|
if (key ~ /^\\\[5$|^\\\[6$$/) { ans = ""; continue; } # PageUp / PageDown
|
|
} while (ans !~ /[\x00-\x5a]|[\x5f-\x7f]/)
|
|
# } while (ans !~ /[\006\025\033\003\177[:space:][:alnum:]><\}\{.~\/:!?*+-]|"|[|_$()]/)
|
|
return key
|
|
}
|
|
|
|
function cmd_mode(list, answer) {
|
|
|
|
### comment for scrollable cmd mode:
|
|
# |------------b1--------------------b2-------------length(reply)
|
|
# b1 to b2 is the show-able region in the whole reply.
|
|
# b1 and b2 update according to keyboard inputs.
|
|
# keyboard inputs:
|
|
# - Left arrow, right arrow, tab completion
|
|
|
|
cmd_trigger = answer;
|
|
cc = 0; dd = 0;
|
|
# b1 = 1; b2 = dim[2] - 50; bb = b2 - b1 - 1; curloc = 0;
|
|
b1 = 1; b2 = dim[2]; bb = b2 - b1 - 1; curloc = 0;
|
|
while (key = key_collect(list, pagerind)) {
|
|
if (key == "\003" || key == "\033" || key == "\n") {
|
|
split("", comparr, ":")
|
|
if (key == "\003" || key == "\033") { reply = "\003"; break } # cancelled
|
|
# if Double enter as confirm current path and exit
|
|
if (key_last !~ /\t|\[Z/) break
|
|
}
|
|
if (key == "\177") { # backspace
|
|
reply = substr(reply, 1, length(reply) + cc - 1) substr(reply, length(reply) + cc + 1);
|
|
if (length(reply) + cc < b1 && b1 > 1) { b1 = b1 - 1; b2 = b1 + bb; }
|
|
else if (curloc > 1) { curloc--; }
|
|
split("", comparr, ":")
|
|
}
|
|
# path completion: $HOME
|
|
else if (cmd_trigger reply ~ /:cd |:.* / && key == "~") { reply = reply ENVIRON["HOME"] "/" }
|
|
# path completion
|
|
else if (cmd_trigger reply ~ /:cd .*|:.* \.?\.?\// && key ~ /\t|\[Z/) { # Tab / Shift-Tab
|
|
cc = 0; dd = 0;
|
|
if (isEmpty(comparr)) {
|
|
comp = reply;
|
|
if (cmd_trigger reply ~ /:cd .*/) gsub(/cd /, "", comp)
|
|
else {
|
|
if (comp ~ /.* \.\.\//) {
|
|
match(comp, /.* \.\.\//)
|
|
cmd_run = substr(comp, RSTART, RLENGTH-3)
|
|
comp = substr(comp, RLENGTH-2)
|
|
}
|
|
if (comp ~ /.* \.\//) {
|
|
match(comp, /.* \.\//)
|
|
cmd_run = substr(comp, RSTART, RLENGTH-2)
|
|
comp = substr(comp, RLENGTH-1)
|
|
}
|
|
if (comp ~ /.* \//) {
|
|
match(comp, /.* \//)
|
|
cmd_run = substr(comp, RSTART, RLENGTH-1)
|
|
comp = substr(comp, RLENGTH)
|
|
}
|
|
}
|
|
compdir = comp;
|
|
if (compdir ~ /^\.\.\/.*/) {
|
|
tmpdir = dir
|
|
while (compdir ~ /^\.\.\/.*/) { # relative path
|
|
gsub(/[^\/]*\/?$/, "", tmpdir)
|
|
gsub(/^\.\.\//, "", compdir)
|
|
tmpdir = ( tmpdir == "" ? "/" : tmpdir )
|
|
}
|
|
compdir = tmpdir
|
|
}
|
|
else {
|
|
# allow single Enter to confirm current reply
|
|
# as completion dir (compdir)
|
|
if (key_last ~ /~|\n/) {
|
|
comp = ""
|
|
}
|
|
else {
|
|
gsub(/[^\/]*\/?$/, "", compdir);
|
|
gsub(compdir, "", comp)
|
|
}
|
|
}
|
|
compdir = (compdir == "" ? dir : compdir);
|
|
tmplist = gen_content(compdir, 1)
|
|
complist = ( cmd_trigger reply ~ /:cd .*/ ?
|
|
search(tmplist, delim, comp, "dir") :
|
|
search(tmplist, delim, comp, "begin") )
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", complist)
|
|
Ncomp = split(complist, comparr, delim)
|
|
|
|
## save space for completion
|
|
space = length(comparr[1])
|
|
for (item in comparr) {
|
|
space = ( space < length(comparr[item]) ? length(comparr[item]) : space )
|
|
}
|
|
if (length(compdir) + space > b2) { b2 = b2 + space; b1 = b2 - bb; }
|
|
|
|
c = ( key == "\t" ? 1 : Ncomp )
|
|
}
|
|
else {
|
|
if (key == "\t") c = (c == Ncomp ? 1 : c + 1)
|
|
else c = (c == 1 ? Ncomp : c - 1)
|
|
}
|
|
if (cmd_trigger reply ~ /:cd .*/) reply = "cd " compdir comparr[c]
|
|
else reply = cmd_run compdir comparr[c]
|
|
CUP(dim[1] - 2, 1)
|
|
printf("%s%s%s%s%s", a_clean, a_reverse, f_yellow, "looping through completion", a_reset)
|
|
}
|
|
# command completion
|
|
else if (cmd_trigger == ":" && key ~ /\t|\[Z/) {
|
|
if (isEmpty(comparr)) {
|
|
getline cmdhist < CMDHIST; close(CMDHIST);
|
|
comp = reply;
|
|
complist = search(cmdhist, "\n", comp, "begin")
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", complist)
|
|
Ncomp = split(complist, comparr, "\n")
|
|
c = ( key == "\t" ? 1 : Ncomp )
|
|
}
|
|
else {
|
|
if (key == "\t") c = (c == Ncomp ? 1 : c + 1)
|
|
else c = (c == 1 ? Ncomp : c - 1)
|
|
}
|
|
reply = comparr[c]
|
|
CUP(dim[1] - 2, 1)
|
|
printf("%s%s%s%s%s", a_clean, a_reverse, f_yellow, "looping through completion", a_reset)
|
|
}
|
|
else if (cmd_trigger == ":" && key ~ /\[A|\[B/) {
|
|
getline cmdhist < CMDHIST; close(CMDHIST);
|
|
Ncmd = split(cmdhist, cmdarr, "\n")
|
|
reply = cmdarr[Ncmd - dd]
|
|
if (key ~ /\[A/) { dd = (dd < Ncmd - 1 ? dd + 1 : dd) }
|
|
if (key ~ /\[B/) { dd = (dd == 0 ? dd : dd - 1) }
|
|
}
|
|
# search
|
|
else if (cmd_trigger == "/" && key ~ /\t|\[Z/) {
|
|
cc = 0; dd = 0;
|
|
if (isEmpty(comparr)) {
|
|
comp = reply; complist = search(list, delim, comp, "begin")
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", complist)
|
|
Ncomp = split(complist, comparr, delim)
|
|
c = ( key == "\t" ? 1 : Ncomp )
|
|
}
|
|
else {
|
|
if (key == "\t") c = (c == Ncomp ? 1 : c + 1)
|
|
else c = (c == 1 ? Ncomp : c - 1)
|
|
}
|
|
reply = comparr[c]
|
|
}
|
|
|
|
else if (key ~ /\[C/) { # Right arrow
|
|
if (cc < 0) {
|
|
cc++
|
|
if (length(reply) + cc > b2 && b2 < length(reply)) { b2 = b2 + 1; b1 = b2 - bb; }
|
|
else if (curloc < bb) { curloc++; }
|
|
}
|
|
}
|
|
else if (key ~ /\[D/) { # Left arrow
|
|
if (-cc < length(reply)) {
|
|
cc--
|
|
if (length(reply) + cc < b1 && b1 > 1) { b1 = b1 - 1; b2 = b1 + bb; }
|
|
else if (curloc > 1) { curloc--; }
|
|
}
|
|
}
|
|
# single Enter clear the completion array (comparr)
|
|
else if (key ~ /\n/) {
|
|
CUP(dim[1] - 2, 1)
|
|
printf("%s%s%s%s%s", a_clean, a_reverse, f_yellow, "confirm current completion", a_reset)
|
|
curloc = ( length(reply) > bb ? bb : length(reply) )
|
|
split("", comparr, ":")
|
|
}
|
|
# Reject other escape sequence
|
|
else if (key ~ /\[.+/) {
|
|
continue
|
|
}
|
|
else {
|
|
reply = substr(reply, 1, length(reply) + cc) key substr(reply, length(reply) + cc + 1);
|
|
if (length(reply) + cc > b2) { b2 = b2 + 1; b1 = b2 - bb }
|
|
else if (curloc < bb) { curloc++; }
|
|
split("", comparr, ":")
|
|
}
|
|
|
|
if (cmd_trigger == "/") {
|
|
slist = search(list, delim, reply, "")
|
|
for (i = top; i <= end; i++) {
|
|
CUP(i, 1)
|
|
printf "\033\133K" >> "/dev/stderr" # clear line
|
|
}
|
|
if (slist != "") {
|
|
Nsarr = split(slist, sarr, delim)
|
|
Nsarr = (Nsarr > dispnum ? dispnum : Nsarr)
|
|
for (i = 1; i <= Nsarr; i++) {
|
|
CUP(i + 2, 1)
|
|
printf "%d. %s", i, sarr[i] >> "/dev/stderr"
|
|
}
|
|
}
|
|
}
|
|
if (cmd_trigger ~ /^[[:digit:]]$/) {
|
|
status = sprintf("%sChoose [%s1-%d%s], current page num is %s%d%s, total page num is %s%d%s: %s%s", a_clean, a_bold, Narr, a_reset, a_bold, curpage, a_reset, a_bold, page, a_reset, cmd_trigger, reply)
|
|
if (cmd_trigger reply ~ /^[[:digit:]]+[Gjk]$/) { split("", comparr, ":"); break; }
|
|
}
|
|
else {
|
|
# status = sprintf("%s%s%s", a_clean, cmd_trigger, reply)
|
|
status = sprintf("%s%s%s", a_clean, cmd_trigger, substr(reply, b1, bb))
|
|
}
|
|
CUP(dim[1], 1)
|
|
# printf(status) >> "/dev/stderr"
|
|
# if (cc < 0) { CUP(dim[1], length(status) + cc - 3) } # adjust cursor
|
|
# printf(status ", " b1 ", " b2 ", " curloc ", " cc ", " length(reply) ", " space) >> "/dev/stderr"
|
|
printf(status) >> "/dev/stderr"
|
|
if (cc < 0) { CUP(dim[1], curloc + 2) } # adjust cursor
|
|
key_last = key
|
|
}
|
|
|
|
}
|
|
|
|
function yesno(command) {
|
|
CUP(dim[1], 1)
|
|
printf("%s%s %s? (y/n) ", a_clean, "Really execute command", command) >> "/dev/stderr"
|
|
printf "\033\133?25h" >> "/dev/stderr" # show cursor
|
|
key = key_collect(list, pagerind)
|
|
printf "\033\133?25l" >> "/dev/stderr" # hide cursor
|
|
if (key ~ /[Yy]/) return 1
|
|
}
|
|
|
|
function redraw(tmsg, bmsg) {
|
|
printf "\033\1332J\033\133H" >> "/dev/stderr" # clear screen and move cursor to 0, 0
|
|
CUP(top, 1); print pagearr[curpage] >> "/dev/stderr"
|
|
CUP(top + cursor*num - num, 1); printf "%s%s%s%s", Ncursor ". ", a_reverse, disp[Ncursor], a_reset >> "/dev/stderr"
|
|
CUP(top - 2, 1); print tmsg >> "/dev/stderr"
|
|
CUP(dim[1] - 2, 1); print bmsg >> "/dev/stderr"
|
|
CUP(dim[1], 1)
|
|
# printf "Choose [\033\1331m1-%d\033\133m], current page num is \033\133;1m%d\033\133m, total page num is \033\133;1m%d\033\133m: ", Narr, curpage, page >> "/dev/stderr"
|
|
printf "%sChoose [%s1-%d%s], current page num is %s%d%s, total page num is %s%d%s: ", a_clean, a_bold, Narr, a_reset, a_bold, curpage, a_reset, a_bold, page, a_reset >> "/dev/stderr"
|
|
if (bmsg !~ /Action.*|Selecting\.\.\./ && ! isEmpty(selected)) draw_selected()
|
|
if (bmsg !~ /Action.*|Selecting\.\.\./ && PREVIEW == 1) draw_preview(disp[Ncursor])
|
|
}
|
|
|
|
function menu_TUI(list, delim, num, tmsg, bmsg) {
|
|
|
|
menu_TUI_page(list, delim)
|
|
while (answer !~ /^[[:digit:]]+$|\.\.\//) {
|
|
|
|
oldCursor = 1;
|
|
|
|
## calculate cursor and Ncursor
|
|
cursor = ( cursor+dispnum*(curpage-1) > Narr ? Narr - dispnum*(curpage-1) : cursor )
|
|
Ncursor = cursor+dispnum*(curpage-1)
|
|
|
|
clean_preview()
|
|
redraw(tmsg, bmsg)
|
|
|
|
while (1) {
|
|
|
|
answer = key_collect(list, pagerind)
|
|
|
|
#######################################
|
|
# Key: entry choosing and searching #
|
|
#######################################
|
|
|
|
if ( answer ~ /^[[:digit:]]$/ || answer == "/" || answer == ":" ) {
|
|
CUP(dim[1], 1)
|
|
if (answer ~ /^[[:digit:]]$/) {
|
|
# printf "Choose [\033\1331m1-%d\033\133m], current page num is \033\133;1m%d\033\133m, total page num is \033\133;1m%d\033\133m: %s", Narr, curpage, page, answer >> "/dev/stderr"
|
|
|
|
printf "%sChoose [%s1-%d%s], current page num is %s%d%s, total page num is %s%d%s: %s", a_clean, a_bold, Narr, a_reset, a_bold, curpage, a_reset, a_bold, page, a_reset, answer >> "/dev/stderr"
|
|
}
|
|
else {
|
|
printf "%s%s", a_clean, answer >> "/dev/stderr" # clear line
|
|
}
|
|
printf "\033\133?25h" >> "/dev/stderr" # show cursor
|
|
|
|
cmd_mode(list, answer)
|
|
|
|
printf "\033\133?25l" >> "/dev/stderr" # hide cursor
|
|
if (reply == "\003") { answer = ""; key = ""; reply = ""; break; }
|
|
answer = cmd_trigger reply; reply = ""; split("", comparr, ":"); cc = 0; dd = 0;
|
|
|
|
|
|
## cd
|
|
if (answer ~ /:cd .*/) {
|
|
old_dir = dir
|
|
gsub(/:cd /, "", answer)
|
|
if (answer ~ /^\/.*/) { # full path
|
|
dir = ( answer ~ /.*\/$/ ? answer : answer "/" )
|
|
}
|
|
else {
|
|
while (answer ~ /^\.\.\/.*/) { # relative path
|
|
gsub(/[^\/]*\/?$/, "", dir)
|
|
gsub(/^\.\.\//, "", answer)
|
|
dir = ( dir == "" ? "/" : dir )
|
|
}
|
|
dir = ( answer ~ /.*\/$/ || answer == "" ? dir answer : dir answer "/" )
|
|
}
|
|
# empty_selected()
|
|
tmplist = gen_content(dir, HIDDEN)
|
|
if (tmplist == "empty") {
|
|
dir = old_dir
|
|
# bmsg = sprintf("\033\13338;5;15m\033\13348;5;9m%s\033\133m", "Error: Path Not Exist")
|
|
bmsg = sprintf("%s%s%s%s", b_red, f_white, "Error: Path Not Exist", a_reset)
|
|
}
|
|
else {
|
|
list = tmplist
|
|
}
|
|
menu_TUI_page(list, delim)
|
|
tmsg = dir;
|
|
cursor = 1; curpage = (+curpage > +page ? page : curpage);
|
|
break
|
|
}
|
|
|
|
## cmd mode
|
|
if (answer ~ /:[^[:cntrl:]*]/) {
|
|
command = substr(answer, 2)
|
|
savecmd = command; post = ""
|
|
match(command, /\{\}/)
|
|
if (RSTART) {
|
|
post = substr(command, RSTART+RLENGTH+1);
|
|
command = substr(command, 1, RSTART-2)
|
|
}
|
|
if (command ~ /.*\$@.*/) {
|
|
idx = maxidx(selorder)
|
|
for (j = 1; j <= idx; j++) {
|
|
if (selorder[j] == "") continue
|
|
sellist = sellist " \"" selected[selorder[j]] "\" "
|
|
}
|
|
gsub(/\$@/, sellist, command)
|
|
empty_selected()
|
|
}
|
|
if (command in cmdalias) { command = cmdalias[command] }
|
|
|
|
if (command ~ /^rm$|rm .*/) { suc = yesno(command); if (suc == 0) break }
|
|
|
|
gsub(/["]/, "\\\\&", command) # escape special char
|
|
finale()
|
|
if (isEmpty(selected)) {
|
|
# code = system("cd \"" dir "\" && eval \"" command "\" 2>/dev/null")
|
|
code = system("cd \"" dir "\" && eval \"" command "\"")
|
|
}
|
|
else {
|
|
idx = maxidx(selorder)
|
|
for (j = 1; j <= idx; j++) {
|
|
if (selorder[j] == "") continue
|
|
sel = selorder[j]
|
|
match(post, /\{\}/)
|
|
if (RSTART) {
|
|
post = substr(post, 1, RSTART-1) selected[sel] substr(post, RSTART+RLENGTH)
|
|
}
|
|
if (post) {
|
|
# code = system("cd \"" dir "\" && eval \"" command " \\\"" selected[sel] "\\\" \\\"" post "\\\"\" 2>/dev/null")
|
|
code = system("cd \"" dir "\" && eval \"" command " \\\"" selected[sel] "\\\" \\\"" post "\\\"\"")
|
|
}
|
|
else {
|
|
# code = system("cd \"" dir "\" && eval \"" command " \\\"" selected[sel] "\\\"\" 2>/dev/null")
|
|
code = system("cd \"" dir "\" && eval \"" command " \\\"" selected[sel] "\\\"\"")
|
|
}
|
|
}
|
|
empty_selected()
|
|
}
|
|
init()
|
|
|
|
list = gen_content(dir, HIDDEN); tmsg = dir;
|
|
menu_TUI_page(list, delim)
|
|
if (code > 0) { printf("\n%s", savecmd) >> CMDHIST; close(CMDHIST) }
|
|
break
|
|
}
|
|
|
|
## search
|
|
if (answer ~ /\/[^[:cntrl:]*]/) {
|
|
slist = search(list, delim, substr(answer, 2), "")
|
|
if (slist != "") {
|
|
menu_TUI_page(slist, delim)
|
|
cursor = 1; curpage = 1; sind = 1
|
|
}
|
|
break
|
|
}
|
|
|
|
## go to page
|
|
if (answer ~ /[[:digit:]]+G$/) {
|
|
ans = answer; gsub(/G/, "", ans);
|
|
curpage = (+ans <= +page ? ans : page)
|
|
break
|
|
}
|
|
|
|
|
|
if (answer ~ /[[:digit:]]+$/) {
|
|
if (+answer > +Narr) answer = Narr
|
|
if (+answer < 1) answer = 1
|
|
curpage = answer / dispnum
|
|
curpage = sprintf("%.0f", (curpage == int(curpage)) ? curpage : int(curpage)+1)
|
|
cursor = answer - dispnum*(curpage-1); answer = ""
|
|
break
|
|
}
|
|
}
|
|
|
|
if (answer ~ /[?]/) { pager(help); break; }
|
|
|
|
if (answer == "!") {
|
|
finale()
|
|
system("cd \"" dir "\" && ${SHELL:=/bin/sh}")
|
|
init()
|
|
list = gen_content(dir, HIDDEN)
|
|
menu_TUI_page(list, delim)
|
|
break
|
|
}
|
|
|
|
if (answer == "-") {
|
|
if (old_dir == "") break
|
|
TMP = dir; dir = old_dir; old_dir = TMP;
|
|
list = gen_content(dir, HIDDEN)
|
|
menu_TUI_page(list, delim)
|
|
tmsg = dir; bmsg = "Browsing"
|
|
cursor = 1; curpage = (+curpage > +page ? page : curpage);
|
|
break
|
|
}
|
|
|
|
|
|
########################
|
|
# Key: Total Redraw #
|
|
########################
|
|
|
|
if ( answer == "v" ) { PREVIEW = (PREVIEW == 1 ? 0 : 1); break }
|
|
if ( answer == ">" ) { RATIO = (RATIO > 0.8 ? RATIO : RATIO + 0.05); break }
|
|
if ( answer == "<" ) { RATIO = (RATIO < 0.2 ? RATIO : RATIO - 0.05); break }
|
|
if ( answer == "r" || answer == "." ||
|
|
( answer == "h" && ( bmsg == "Actions" || sind == 1 ) ) ||
|
|
( answer ~ /^[[:digit:]]$/ && (+answer > +Narr || +answer < 1 ) ) ) {
|
|
if (answer == ".") { HIDDEN = (HIDDEN == 1 ? 0 : 1); }
|
|
list = gen_content(dir, HIDDEN)
|
|
delim = "\f"; num = 1; tmsg = dir; bmsg = "Browsing"; sind = 0; openind = 0;
|
|
menu_TUI_page(list, delim)
|
|
empty_selected()
|
|
cursor = 1; curpage = (+curpage > +page ? page : curpage);
|
|
break
|
|
}
|
|
if ( answer == "\n" || answer == "l" || answer ~ /\[C/ ) { answer = Ncursor; break }
|
|
if ( answer == "a" ) {
|
|
menu_TUI_page(action, RS)
|
|
tmsg = "Choose an action"; bmsg = "Actions"
|
|
cursor = 1; curpage = 1;
|
|
break
|
|
}
|
|
if ( answer ~ /q|\003/ ) exit
|
|
if ( (answer == "h" || answer ~ /\[D/) && dir != "/" ) { answer = "../"; disp[answer] = "../"; bmsg = ""; break }
|
|
if ( (answer == "h" || answer ~ /\[D/) && dir = "/" ) continue
|
|
if ( (answer == "n" || answer ~ /\[6~/) && +curpage < +page ) { curpage++; break }
|
|
if ( (answer == "n" || answer ~ /\[6~/) && +curpage == +page && cursor != Narr - dispnum*(curpage-1) ) { cursor = ( +curpage == +page ? Narr - dispnum*(curpage-1) : dispnum ); break }
|
|
if ( (answer == "n" || answer ~ /\[6~/) && +curpage == +page && cursor == Narr - dispnum*(curpage-1) ) continue
|
|
if ( (answer == "p" || answer ~ /\[5~/) && +curpage > 1) { curpage--; break }
|
|
if ( (answer == "p" || answer ~ /\[5~/) && +curpage == 1 && cursor != 1 ) { cursor = 1; break }
|
|
if ( (answer == "p" || answer ~ /\[5~/) && +curpage == 1 && cursor == 1) continue
|
|
if ( (answer == "g" || answer ~ /\[H/) && ( curpage != 1 || cursor != 1 ) ) { curpage = 1; cursor = 1; break }
|
|
if ( (answer == "g" || answer ~ /\[H/) && curpage = 1 && cursor == 1 ) continue
|
|
if ( (answer == "G" || answer ~ /\[F/) && ( curpage != page || cursor != Narr - dispnum*(curpage-1) ) ) { curpage = page; cursor = Narr - dispnum*(curpage-1); break }
|
|
if ( (answer == "G" || answer ~ /\[F/) && curpage == page && cursor = Narr - dispnum*(curpage-1) ) continue
|
|
|
|
#########################
|
|
# Key: Partial Redraw #
|
|
#########################
|
|
|
|
if ( (answer == "j" || answer ~ /\[B/) && +cursor <= +dispnum ) { oldCursor = cursor; cursor++; }
|
|
if ( (answer == "j" || answer ~ /\[B/) && +cursor > +dispnum && +curpage < +page && +page > 1 ) { cursor = 1; curpage++; break }
|
|
if ( (answer == "k" || answer ~ /\[A/) && +cursor == 1 && +curpage > 1 && +page > 1 ) { cursor = dispnum; curpage--; break }
|
|
if ( (answer == "k" || answer ~ /\[A/) && +cursor > 1 ) { oldCursor = cursor; cursor--; }
|
|
|
|
if ( (answer == "\006") && cursor <= +dispnum ) { oldCursor = cursor; cursor = cursor + move }
|
|
if ( (answer == "\006") && +cursor > +dispnum && +curpage < +page && +page > 1 ) { cursor = cursor - dispnum; curpage++; break }
|
|
if ( (answer == "\006") && +cursor > Narr - dispnum*(curpage-1) && +curpage == +page ) { cursor = ( +curpage == +page ? Narr - dispnum*(curpage-1) : dispnum ); break }
|
|
if ( (answer == "\006") && +cursor == Narr - dispnum*(curpage-1) && +curpage == +page ) break
|
|
|
|
if ( (answer == "\025") && cursor >= 1 ) { oldCursor = cursor; cursor = cursor - move }
|
|
if ( (answer == "\025") && +cursor < 1 && +curpage > 1 ) { cursor = dispnum + cursor; curpage--; break }
|
|
if ( (answer == "\025") && +cursor < 1 && +curpage == 1 ) { cursor = 1; break }
|
|
if ( (answer == "\025") && +cursor == 1 && +curpage == 1 ) break
|
|
|
|
if ( answer == "H" ) { oldCursor = cursor; cursor = 1; }
|
|
if ( answer == "M" ) { oldCursor = cursor; cursor = ( +curpage == +page ? int((Narr - dispnum*(curpage-1))*0.5) : int(dispnum*0.5) ); }
|
|
if ( answer == "L" ) { oldCursor = cursor; cursor = ( +curpage == +page ? Narr - dispnum*(curpage-1) : dispnum ); }
|
|
|
|
####################
|
|
# Key: Selection #
|
|
####################
|
|
|
|
if ( answer == " " ) {
|
|
if (selected[dir,Ncursor] == "") {
|
|
TMP = disp[Ncursor];
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", TMP)
|
|
selected[dir,Ncursor] = dir TMP;
|
|
seldisp[dir,Ncursor] = TMP;
|
|
selpage[dir,Ncursor] = curpage;
|
|
selnum[dir,Ncursor] = Ncursor;
|
|
selorder[++order] = dir SUBSEP Ncursor
|
|
bmsg = disp[Ncursor] " selected"
|
|
}
|
|
else {
|
|
for (idx in selorder) { if (selorder[idx] == dir SUBSEP Ncursor) { delete selorder[idx]; break } }
|
|
delete selected[dir,Ncursor];
|
|
delete seldisp[dir,Ncursor];
|
|
delete selpage[dir,Ncursor];
|
|
delete selnum[dir,Ncursor];
|
|
bmsg = disp[Ncursor] " cancelled"
|
|
}
|
|
if (+Narr == 1) { break }
|
|
if (+cursor <= +dispnum || +cursor <= +Narr) { cursor++ }
|
|
if (+cursor > +dispnum || +cursor > +Narr) { cursor = 1; curpage = ( +curpage == +page ? 1 : curpage + 1 ) }
|
|
break
|
|
}
|
|
|
|
if (answer == "S") {
|
|
if (isEmpty(selected)) {
|
|
selp = 0
|
|
for (entry = 1; entry in disp; entry++) {
|
|
TMP = disp[entry];
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", TMP)
|
|
if (TMP != "./" && TMP != "../") {
|
|
selected[dir,entry] = dir TMP;
|
|
seldisp[dir,entry] = TMP;
|
|
selpage[dir,entry] = ((+entry) % (+dispnum) == 1 ? ++selp : selp)
|
|
selnum[dir,entry] = entry;
|
|
selorder[++order] = dir SUBSEP entry
|
|
}
|
|
}
|
|
bmsg = "All selected"
|
|
}
|
|
else {
|
|
empty_selected()
|
|
bmsg = "All cancelled"
|
|
}
|
|
break
|
|
}
|
|
|
|
if (answer == "s") {
|
|
# for (sel in selected) {
|
|
# selcontent = selcontent "\n" selected[sel]
|
|
# }
|
|
idx = maxidx(selorder)
|
|
for (j = 1; j <= idx; j++) {
|
|
if (selorder[j] == "") continue
|
|
selcontent = selcontent "\n" j ". " selected[selorder[j]]
|
|
}
|
|
pager("Selected item: \n" selcontent); selcontent = ""; break;
|
|
}
|
|
|
|
####################################################################
|
|
# Partial redraw: tmsg, bmsg, old entry, new entry, and selected #
|
|
####################################################################
|
|
|
|
Ncursor = cursor+dispnum*(curpage-1); oldNcursor = oldCursor+dispnum*(curpage-1);
|
|
if (Ncursor > Narr) { Ncursor = Narr; cursor = Narr - dispnum*(curpage-1); continue }
|
|
if (Ncursor < 1) { Ncursor = 1; cursor = 1; continue }
|
|
|
|
CUP(dim[1] - 2, 1); # bmsg
|
|
printf a_clean >> "/dev/stderr" # clear line
|
|
print bmsg >> "/dev/stderr"
|
|
|
|
CUP(top + oldCursor*num - num, 1); # old entry
|
|
for (i = 1; i <= num; i++) {
|
|
printf a_clean >> "/dev/stderr" # clear line
|
|
CUP(top + oldCursor*num - num + i, 1)
|
|
}
|
|
CUP(top + oldCursor*num - num, 1);
|
|
printf "%s", oldNcursor ". " disp[oldNcursor] >> "/dev/stderr"
|
|
|
|
CUP(top + cursor*num - num, 1); # new entry
|
|
for (i = 1; i <= num; i++) {
|
|
printf a_clean >> "/dev/stderr" # clear line
|
|
CUP(top + cursor*num - num + i, 1)
|
|
}
|
|
CUP(top + cursor*num - num, 1);
|
|
printf "%s%s%s%s", Ncursor ". ", a_reverse, disp[Ncursor], a_reset >> "/dev/stderr"
|
|
|
|
if (bmsg !~ /Action.*|Selecting\.\.\./ && ! isEmpty(selected)) draw_selected()
|
|
if (bmsg !~ /Action.*|Selecting\.\.\./ && PREVIEW == 1) draw_preview(disp[Ncursor])
|
|
}
|
|
|
|
}
|
|
|
|
result[1] = disp[answer]
|
|
result[2] = bmsg
|
|
}
|
|
|
|
function pager(msg) { # pager to print out stuff and navigate
|
|
printf "\033\1332J\033\133H" >> "/dev/stderr"
|
|
if (PREVIEW == 1) { printf "{\"action\": \"remove\", \"identifier\": \"PREVIEW\"}\n" > FIFO_UEBERZUG; close(FIFO_UEBERZUG) }
|
|
Nmsgarr = split(msg, msgarr, "\n")
|
|
Npager = (Nmsgarr >= dim[1] ? dim[1] : Nmsgarr)
|
|
for (i = 1; i <= Npager; i++) {
|
|
CUP(i, 1)
|
|
printf "%s", msgarr[i] >> "/dev/stderr"
|
|
}
|
|
|
|
pagerind = 1;
|
|
while (key = key_collect(list, pagerind)) {
|
|
if (key == "\003" || key == "\033" || key == "q" || key == "h") break
|
|
if ((key == "j" || key ~ /\[B/) && i < Nmsgarr) { printf "\033\133%d;H\n", Npager >> "/dev/stderr"; printf msgarr[i++] >> "/dev/stderr" }
|
|
if ((key == "k" || key ~ /\[A/) && i > dim[1] + 1) { printf "\033\133H\033\133L" >> "/dev/stderr"; i--; printf msgarr[i-dim[1]] >> "/dev/stderr" }
|
|
}
|
|
pagerind = 0;
|
|
}
|
|
|
|
######################
|
|
# Start of Preview #
|
|
######################
|
|
|
|
function draw_preview(item) {
|
|
|
|
border = int(dim[2]*RATIO) # for preview
|
|
|
|
# clear RHS of screen based on border
|
|
clean_preview()
|
|
|
|
gsub(/\033\[[0-9][0-9]m|\033\[[0-9]m|\033\[m/, "", item)
|
|
path = dir item
|
|
if (path ~ /.*\/$/) { # dir
|
|
content = gen_content(path)
|
|
split(content, prev, "\f")
|
|
for (i = 1; i <= ((end - top) / num); i++) {
|
|
CUP(top + i - 1, border + 1)
|
|
print prev[i] >> "/dev/stderr"
|
|
}
|
|
}
|
|
else { # Standard file
|
|
if (FMAWK_PREVIEWER == "") {
|
|
cmd = "file " path
|
|
cmd | getline props
|
|
if (props ~ /text/) {
|
|
getline content < path
|
|
close(path)
|
|
split(content, prev, "\n")
|
|
for (i = 1; i <= ((end - top) / num); i++) {
|
|
CUP(top + i - 1, border + 1)
|
|
code = gsub(/\000/, "", prev[i])
|
|
if (code > 0) {
|
|
# printf "\033\13338;5;0m\033\13348;5;15m%s\033\133m", "binary" >> "/dev/stderr"
|
|
printf "%s%s%s%s", a_reverse, f_white, "binary", a_reset >> "/dev/stderr"
|
|
break
|
|
}
|
|
print prev[i] >> "/dev/stderr"
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
system(FMAWK_PREVIEWER " \"" path "\" \"" CACHE "\" \"" border+1 "\" \"" ((end - top)/num) "\" \"" top "\" \"" dim[2]-border-1 "\"")
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function clean_preview() {
|
|
for (i = top; i <= end; i++) {
|
|
CUP(i, border - 1)
|
|
printf "\033\133K" >> "/dev/stderr" # clear line
|
|
}
|
|
if (FIFO_UEBERZUG == "") return
|
|
printf "{\"action\": \"remove\", \"identifier\": \"PREVIEW\"}\n" > FIFO_UEBERZUG
|
|
close(FIFO_UEBERZUG)
|
|
}
|