Commit Diff


commit - 2b650bbafb20bb7ab50ebf01fe8df71ac2b15466
commit + 0c961f7d3321f7810f6e45b6581762b5ed0fd2e1
blob - a02b9856bef290df3e828e9902cffaa26ac24240
blob + 8e50a14952c1ad2f7fede9fe4a9dd1a10efd62a3
--- ChangeLog.md
+++ ChangeLog.md
@@ -9,12 +9,14 @@ and this project adheres to [Semantic Versioning](http
 ### Added
 - Options:
   - `-a` print all fields
+  - `-i` don't print fancy unicode characters
   
 ### Changed
 - Merge "LABEL" and "MOUNT" fields into "LABEL/MOUNT"
   because disks can't be mounted but partitions can,
   and disks can have a label but partitions don't
   (at least through the disklabel interface).
+- Print fancy unicode characters by default.
 
 ### Removed
 - Options:
blob - 8e263e611381f89b75158489e87a707e66504496
blob + f554478425f50bfa22c7f7bdbc1be9b058aac0c6
--- README.md
+++ README.md
@@ -18,5 +18,4 @@ doas make unroot
   Workaround: `make unroot`
 
 ## TODO
-- [ ] Fancy unicodes: `├─` & `└─`
 - [ ] `lsblk sd0`
blob - 947e92a5ce56e2605e5dd19c0016587a2b7fe4ca
blob + 2dfb9afa94e135119b69a482672e1fc6d8122f44
--- lsblk.8
+++ lsblk.8
@@ -15,7 +15,7 @@
 .SH NAME
 lsblk \- list block devices
 .SH SYNOPSIS
-.B lsblk [-Valnu]
+.B lsblk [-Vainu]
 .SH DESCRIPTION
 The
 .B lsblk
@@ -28,6 +28,9 @@ prints version information to stdout, then exit.
 .B \-a
 print all fields.
 .TP
+.B \-i
+don't print fancy unicode characters, only print ASCII.
+.TP
 .B \-n
 don't print the header.
 .TP
blob - 136f6741171ab966b7f00d656702373e038a37b3
blob + d23484030f2a1d2f549768a3c62824cb2926de70
--- lsblk.c
+++ lsblk.c
@@ -132,16 +132,21 @@ static void print_size (uint64_t sz)
 }
 
 enum {
-    FIELD_NAME  = 0x01,
-    FIELD_SIZE  = 0x02,
-    FIELD_USED  = 0x04,
-    FIELD_FREE  = 0x08,
-    FIELD_TYPE  = 0x10,
-    FIELD_LMNT  = 0x20,
+    FIELD_NAME      = 0x01,
+    FIELD_SIZE      = 0x02,
+    FIELD_USED      = 0x04,
+    FIELD_FREE      = 0x08,
+    FIELD_TYPE      = 0x10,
+    FIELD_LMNT      = 0x20,
 
     FIELD_DEFAULT   = FIELD_NAME | FIELD_SIZE | FIELD_TYPE | FIELD_LMNT,
 };
 
+enum {
+    OPT_NOHEADER    = 0x01,
+    OPT_NOUNICODE   = 0x02,
+};
+
 struct my_partinfo {
     char name[5];
     uint64_t size;
@@ -184,10 +189,12 @@ static void print_header (int fields)
     putchar ('\n');
 }
 
-static void print_part (const struct my_partinfo *part, int fields)
+static void print_part (const struct my_partinfo *part, int fields, int options, bool last)
 {
-    if (fields & FIELD_NAME)
-        printf ("  %s ", part->name);
+    if (fields & FIELD_NAME) {
+        const char *prefix = (options & OPT_NOUNICODE) ? "  " : (last ? "└─" : "├─");
+        printf ("%s%s ", prefix, part->name);
+    }
 
     if (fields & FIELD_SIZE)
         print_size (part->size);
@@ -217,7 +224,7 @@ static void print_part (const struct my_partinfo *part
     putchar ('\n');
 }
 
-static void print_disk (const struct my_diskinfo *disk, int fields)
+static void print_disk (const struct my_diskinfo *disk, int fields, int options)
 {
     if (fields & FIELD_NAME)
         printf ("%s    ", disk->name);
@@ -241,7 +248,7 @@ static void print_disk (const struct my_diskinfo *disk
     putchar ('\n');
 
     for (uint8_t i = 0; i < disk->num_parts; ++i)
-        print_part (&disk->parts[i], fields);
+        print_part (&disk->parts[i], fields, options, i == (disk->num_parts - 1));
 }
 
 static const struct statfs *find_mount (const char *dev)
@@ -329,15 +336,15 @@ static struct my_diskinfo read_disk (const char *name)
 
 static int usage (void)
 {
-    fputs ("Usage: lsblk [-Vanu]\n", stderr);
+    fputs ("Usage: lsblk [-Vainu]\n", stderr);
     return 1;
 }
 
 int main (int argc, char *argv[])
 {
     int option;
-    bool header = true;
     int fields = FIELD_DEFAULT;
+    int options = 0;
 
     if (unveil ("/dev", "r") == -1)
         die ("unveil(/dev)");
@@ -345,7 +352,7 @@ int main (int argc, char *argv[])
     if (unveil (NULL, NULL) == -1)
         die ("unveil()");
 
-    while ((option = getopt (argc, argv, ":Vanu")) != -1) {
+    while ((option = getopt (argc, argv, ":Vainu")) != -1) {
         switch (option) {
         case 'V':
             puts ("lsblk-" VERSION);
@@ -353,8 +360,11 @@ int main (int argc, char *argv[])
         case 'a':
             fields = -1;
             break;
+        case 'i':
+            options |= OPT_NOUNICODE;
+            break;
         case 'n':
-            header = false;
+            options |= OPT_NOHEADER;
             break;
         case 'u':
             fields |= FIELD_USED | FIELD_FREE;
@@ -391,11 +401,11 @@ int main (int argc, char *argv[])
 
     free (names);
 
-    if (header)
+    if (!(options & OPT_NOHEADER))
         print_header (fields);
 
     for (size_t i = 0; i < num_disks; ++i) {
-        print_disk (&disks[i], fields);
+        print_disk (&disks[i], fields, options);
     }
     return 0;
 }