33# pfetch - Simple POSIX sh fetch script.
44
55log () {
6+ # The 'log()' function handles the printing of information.
7+ # In 'pfetch' (and 'neofetch'!) the printing of the ascii art and info
8+ # happen independently of each other.
9+ #
10+ # The size of the ascii art is stored and the ascii is printed first.
11+ # Once the ascii is printed, the cursor is located right below the art
12+ # (See marker $[1]).
13+ #
14+ # Using the stored ascii size, the cursor is then moved to marker $[2].
15+ # This is simply a cursor up escape sequence using the "height" of the
16+ # ascii art.
17+ #
18+ # 'log()' then moves the cursor to the right the "width" of the ascii art
19+ # with an additional amount of padding to add a gap between the art and
20+ # the information (See marker $[3]).
21+ #
22+ # When 'log()' has executed, the cursor is then located at marker $[4].
23+ # When 'log()' is run a second time, the next line of information is
24+ # printed, moving the cursor to marker $[5].
25+ #
26+ # Markers $[4] and $[5] repeat all the way down through the ascii art
27+ # until there is no more information left to print.
28+ #
29+ # Every time 'log()' is called the script keeps track of how many lines
30+ # were printed. When printing is complete the cursor is then manually
31+ # placed below the information and the art according to the "heights"
32+ # of both.
33+ #
34+ # The math is simple: move cursor down $((ascii_height - info_height)).
35+ # If the aim is to move the cursor from marker $[5] to marker $[6],
36+ # plus the ascii height is 8 while the info height is 2 it'd be a move
37+ # of 6 lines downwards.
38+ #
39+ # However, if the information printed is "taller" (takes up more lines)
40+ # than the ascii art, the cursor isn't moved at all!
41+ #
42+ # Once the cursor is at marker $[6], the script exits. This is the gist
43+ # of how this "dynamic" printing and layout works.
44+ #
45+ # This method allows ascii art to be stored without markers for info
46+ # and it allows for easy swapping of info order and amount.
47+ #
48+ # $[2] ___ $[3] goldie@KISS
49+ # $[4](.· | $[5] os KISS Linux
50+ # (<> |
51+ # / __ \
52+ # ( / \ /|
53+ # _/\ __)/_)
54+ # \/-____\/
55+ # $[1]
56+ #
57+ # $[6] /home/goldie $
58+
659 # End here if no data was found.
760 [ " $2 " ] || return
861
@@ -22,10 +75,27 @@ log() {
2275 info=$*
2376 }
2477
25- # Construct the information string.
26- out=" [3${PF_COL1-4} ;1m${name} [m"
27- out=" $out ${PF_SEP} [$(( info_length- ${# name} )) C"
28- out=" $out [3${PF_COL2-7} m$info "
78+ # Move the cursor to the right, the width of the ascii art with an
79+ # additional gap for text spacing.
80+ printf ' [%sC' " ${ascii_width--1} "
81+
82+ # Print the info name and color the text.
83+ printf ' [3%s;1m%s[m' " ${PF_COL1-4} " " $name "
84+
85+ # Print the info name and info data separator.
86+ printf %s " $PF_SEP "
87+
88+ # Move the cursor backward the length of the *current* info name and
89+ # then move it forwards the length of the *longest* info name. This
90+ # aligns each info data line.
91+ printf ' [%sD[%sC' " ${# name} " " ${PF_ALIGN-$info_length } "
92+
93+ # Print the info data, color it and strip all leading whitespace
94+ # from the string.
95+ printf ' [3%sm%s[m\n' " ${PF_COL2-7} " " $info "
96+
97+ # Keep track of the number of times 'log()' has been run.
98+ info_height=$(( ${info_height:- 0} + 1 ))
2999}
30100
31101get_title () {
@@ -42,7 +112,7 @@ get_title() {
42112 # shellcheck disable=SC2039
43113 hostname=${HOSTNAME:- ${hostname:- $(hostname)} }
44114
45- log " [3${PF_COL3:- 1} m${user}${c7} @[3${PF_COL3:- 1} m${hostname} " " "
115+ log " [3${PF_COL3:- 1} m${user}${c7} @[3${PF_COL3:- 1} m${hostname} " " " >&6
46116}
47117
48118get_os () {
@@ -53,7 +123,7 @@ get_os() {
53123 # On first run, this function displays _nothing_, only on the second
54124 # invocation is 'log()' called.
55125 [ " $distro " ] && {
56- log os " $distro "
126+ log os " $distro " >&6
57127 return
58128 }
59129
@@ -216,18 +286,13 @@ get_kernel() {
216286 case $os in
217287 # Don't print kernel output on some systems as the
218288 # OS name includes it.
219- * BSD* |Haiku|Minix) ;;
220-
221- IRIX)
222- kernel=$( uname -vR)
223- kernel=${kernel#* }
289+ * BSD* |Haiku|Minix)
290+ return
224291 ;;
292+ esac
225293
226- * )
227- # '$kernel' is the cached output of 'uname -r'.
228- log kernel " $kernel "
229- ;;
230- esac
294+ # '$kernel' is the cached output of 'uname -r'.
295+ log kernel " $kernel " >&6
231296}
232297
233298get_host () {
@@ -296,7 +361,7 @@ get_host() {
296361 done
297362
298363 # '$arch' is the cached output from 'uname -m'.
299- log host " ${host:- $arch } "
364+ log host " ${host:- $arch } " >&6
300365}
301366
302367get_uptime () {
@@ -370,7 +435,7 @@ get_uptime() {
370435 [ " $h " = 0 ] || uptime=" ${uptime}${h} h "
371436 [ " $m " = 0 ] || uptime=" ${uptime}${m} m "
372437
373- log uptime " ${uptime:- 0m} "
438+ log uptime " ${uptime:- 0m} " >&6
374439}
375440
376441get_pkgs () {
@@ -482,7 +547,7 @@ get_pkgs() {
482547 IRIX) packages=$(( packages - 3 )) ;;
483548 esac
484549
485- [ " $packages " -gt 1 ] && log pkgs " $packages "
550+ [ " $packages " -gt 1 ] && log pkgs " $packages " >&6
486551}
487552
488553get_memory () {
@@ -685,7 +750,7 @@ get_memory() {
685750 ;;
686751 esac
687752
688- log memory " ${mem_used:- ?} M / ${mem_full:- ?} M"
753+ log memory " ${mem_used:- ?} M / ${mem_full:- ?} M" >&6
689754}
690755
691756get_wm () {
@@ -814,7 +879,7 @@ get_wm() {
814879 ;;
815880 esac
816881
817- log wm " $wm "
882+ log wm " $wm " >&6
818883}
819884
820885
@@ -825,18 +890,18 @@ get_de() {
825890 #
826891 # Display the value of '$XDG_CURRENT_DESKTOP', if it's empty,
827892 # display the value of '$DESKTOP_SESSION'.
828- log de " ${XDG_CURRENT_DESKTOP:- $DESKTOP_SESSION } "
893+ log de " ${XDG_CURRENT_DESKTOP:- $DESKTOP_SESSION } " >&6
829894}
830895
831896get_shell () {
832897 # Display the basename of the '$SHELL' environment variable.
833- log shell " ${SHELL##*/ } "
898+ log shell " ${SHELL##*/ } " >&6
834899}
835900
836901get_editor () {
837902 # Display the value of '$VISUAL', if it's empty, display the
838903 # value of '$EDITOR'.
839- log editor " ${VISUAL:- $EDITOR } "
904+ log editor " ${VISUAL:- $EDITOR } " >&6
840905}
841906
842907get_palette () {
@@ -850,8 +915,8 @@ get_palette() {
850915
851916 # Print the palette with a new-line before and afterwards.
852917 printf ' \n' >&6
853- log " $palette
854- " " "
918+ log " $palette
919+ " " " >&6
855920}
856921
857922get_ascii () {
@@ -1363,6 +1428,8 @@ get_ascii() {
13631428 # information. The 'sed' is used to strip '[3Xm' color codes from
13641429 # the ascii art so they don't affect the width variable.
13651430 while read -r line; do
1431+ ascii_height=$(( ${ascii_height:- 0} + 1 ))
1432+
13661433 # This was a ternary operation but they aren't supported in
13671434 # Minix's shell.
13681435 [ " ${# line} " -gt " ${ascii_width:- 0} " ] &&
@@ -1378,6 +1445,13 @@ get_ascii() {
13781445
13791446 # Add a gap between the ascii art and the information.
13801447 ascii_width=$(( ascii_width + 4 ))
1448+
1449+ # Print the ascii art and position the cursor back where we
1450+ # started prior to printing it.
1451+ # '[1m': Print the ascii in bold.
1452+ # '[m': Clear bold.
1453+ # '[%sA': Move the cursor up '$ascii_height' amount of lines.
1454+ printf ' [1m%s[m[%sA' " $ascii " " $ascii_height " >&6
13811455}
13821456
13831457main () {
@@ -1444,10 +1518,6 @@ main() {
14441518 set -f
14451519 set +f ${PF_INFO-ascii title os host kernel uptime pkgs memory}
14461520
1447- # Grab the ascii art if the user has enabled it. This simply
1448- # populates the '$ascii' variable.
1449- case $@ in * ascii* ) get_ascii; shift ; esac
1450-
14511521 # Iterate over the info functions to determine the lengths of the
14521522 # "info names" for output alignment. The option names and subtitles
14531523 # match 1:1 so this is thankfully simple.
@@ -1463,22 +1533,26 @@ main() {
14631533 # Add an additional space of length to act as a gap.
14641534 info_length=$(( info_length + 1 ))
14651535
1466- while IFS= read -r line || [ " $1 " ]; do
1467- # Iterate over the info skipping any lines
1468- # which are blank.
1469- for info; do
1470- " get_$1 "
1471- shift " $(( $# ? 1 : 0 )) "
1472- [ " $out " ] && break
1473- done
1474-
1475- printf ' \033[%sC%s\033[m\r\033[1m%s\033[m\n' \
1476- " $ascii_width " " $out " " $line " >&6
1477- out=
1478- done << -EOF
1479- $ascii
1480- EOF
1536+ # Iterate over the above list and run any existing "get_" functions.
1537+ for info; do " get_$info " ; done
14811538 }
1539+
1540+ # Position the cursor below both the ascii art and information lines
1541+ # according to the height of both. If the information exceeds the ascii
1542+ # art in height, don't touch the cursor (0/unset), else move it down
1543+ # N lines.
1544+ #
1545+ # This was a ternary operation but they aren't supported in Minix's shell.
1546+ [ " ${info_height:- 0} " -lt " ${ascii_height:- 0} " ] &&
1547+ cursor_pos=$(( ascii_height - info_height))
1548+
1549+ # Print '$cursor_pos' amount of newlines to correctly position the
1550+ # cursor. This used to be a 'printf $(seq X X)' however 'seq' is only
1551+ # typically available (by default) on GNU based systems!
1552+ while [ " ${i:= 0} " -le " ${cursor_pos:- 0} " ]; do
1553+ printf ' \n'
1554+ i=$(( i + 1 ))
1555+ done >&6
14821556}
14831557
14841558main " $@ "
0 commit comments