3
3
# pfetch - Simple POSIX sh fetch script.
4
4
5
5
log () {
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
+
6
59
# End here if no data was found.
7
60
[ " $2 " ] || return
8
61
@@ -22,10 +75,27 @@ log() {
22
75
info=$*
23
76
}
24
77
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 ))
29
99
}
30
100
31
101
get_title () {
@@ -42,7 +112,7 @@ get_title() {
42
112
# shellcheck disable=SC2039
43
113
hostname=${HOSTNAME:- ${hostname:- $(hostname)} }
44
114
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
46
116
}
47
117
48
118
get_os () {
@@ -53,7 +123,7 @@ get_os() {
53
123
# On first run, this function displays _nothing_, only on the second
54
124
# invocation is 'log()' called.
55
125
[ " $distro " ] && {
56
- log os " $distro "
126
+ log os " $distro " >&6
57
127
return
58
128
}
59
129
@@ -216,18 +286,13 @@ get_kernel() {
216
286
case $os in
217
287
# Don't print kernel output on some systems as the
218
288
# OS name includes it.
219
- * BSD* |Haiku|Minix) ;;
220
-
221
- IRIX)
222
- kernel=$( uname -vR)
223
- kernel=${kernel#* }
289
+ * BSD* |Haiku|Minix)
290
+ return
224
291
;;
292
+ esac
225
293
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
231
296
}
232
297
233
298
get_host () {
@@ -296,7 +361,7 @@ get_host() {
296
361
done
297
362
298
363
# '$arch' is the cached output from 'uname -m'.
299
- log host " ${host:- $arch } "
364
+ log host " ${host:- $arch } " >&6
300
365
}
301
366
302
367
get_uptime () {
@@ -370,7 +435,7 @@ get_uptime() {
370
435
[ " $h " = 0 ] || uptime=" ${uptime}${h} h "
371
436
[ " $m " = 0 ] || uptime=" ${uptime}${m} m "
372
437
373
- log uptime " ${uptime:- 0m} "
438
+ log uptime " ${uptime:- 0m} " >&6
374
439
}
375
440
376
441
get_pkgs () {
@@ -482,7 +547,7 @@ get_pkgs() {
482
547
IRIX) packages=$(( packages - 3 )) ;;
483
548
esac
484
549
485
- [ " $packages " -gt 1 ] && log pkgs " $packages "
550
+ [ " $packages " -gt 1 ] && log pkgs " $packages " >&6
486
551
}
487
552
488
553
get_memory () {
@@ -685,7 +750,7 @@ get_memory() {
685
750
;;
686
751
esac
687
752
688
- log memory " ${mem_used:- ?} M / ${mem_full:- ?} M"
753
+ log memory " ${mem_used:- ?} M / ${mem_full:- ?} M" >&6
689
754
}
690
755
691
756
get_wm () {
@@ -814,7 +879,7 @@ get_wm() {
814
879
;;
815
880
esac
816
881
817
- log wm " $wm "
882
+ log wm " $wm " >&6
818
883
}
819
884
820
885
@@ -825,18 +890,18 @@ get_de() {
825
890
#
826
891
# Display the value of '$XDG_CURRENT_DESKTOP', if it's empty,
827
892
# display the value of '$DESKTOP_SESSION'.
828
- log de " ${XDG_CURRENT_DESKTOP:- $DESKTOP_SESSION } "
893
+ log de " ${XDG_CURRENT_DESKTOP:- $DESKTOP_SESSION } " >&6
829
894
}
830
895
831
896
get_shell () {
832
897
# Display the basename of the '$SHELL' environment variable.
833
- log shell " ${SHELL##*/ } "
898
+ log shell " ${SHELL##*/ } " >&6
834
899
}
835
900
836
901
get_editor () {
837
902
# Display the value of '$VISUAL', if it's empty, display the
838
903
# value of '$EDITOR'.
839
- log editor " ${VISUAL:- $EDITOR } "
904
+ log editor " ${VISUAL:- $EDITOR } " >&6
840
905
}
841
906
842
907
get_palette () {
@@ -850,8 +915,8 @@ get_palette() {
850
915
851
916
# Print the palette with a new-line before and afterwards.
852
917
printf ' \n' >&6
853
- log " $palette
854
- " " "
918
+ log " $palette
919
+ " " " >&6
855
920
}
856
921
857
922
get_ascii () {
@@ -1363,6 +1428,8 @@ get_ascii() {
1363
1428
# information. The 'sed' is used to strip '[3Xm' color codes from
1364
1429
# the ascii art so they don't affect the width variable.
1365
1430
while read -r line; do
1431
+ ascii_height=$(( ${ascii_height:- 0} + 1 ))
1432
+
1366
1433
# This was a ternary operation but they aren't supported in
1367
1434
# Minix's shell.
1368
1435
[ " ${# line} " -gt " ${ascii_width:- 0} " ] &&
@@ -1378,6 +1445,13 @@ get_ascii() {
1378
1445
1379
1446
# Add a gap between the ascii art and the information.
1380
1447
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
1381
1455
}
1382
1456
1383
1457
main () {
@@ -1444,10 +1518,6 @@ main() {
1444
1518
set -f
1445
1519
set +f ${PF_INFO-ascii title os host kernel uptime pkgs memory}
1446
1520
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
-
1451
1521
# Iterate over the info functions to determine the lengths of the
1452
1522
# "info names" for output alignment. The option names and subtitles
1453
1523
# match 1:1 so this is thankfully simple.
@@ -1463,22 +1533,26 @@ main() {
1463
1533
# Add an additional space of length to act as a gap.
1464
1534
info_length=$(( info_length + 1 ))
1465
1535
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
1481
1538
}
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
1482
1556
}
1483
1557
1484
1558
main " $@ "
0 commit comments