Skip to content

Add support for pacman's progress bar Easter egg#59

Open
omentic wants to merge 3 commits into
kitsunyan:masterfrom
omentic:master
Open

Add support for pacman's progress bar Easter egg#59
omentic wants to merge 3 commits into
kitsunyan:masterfrom
omentic:master

Conversation

@omentic

@omentic omentic commented Nov 12, 2020

Copy link
Copy Markdown

This pull request implements replacing the ###--- progress bar with the -C o o style, based on /etc/pacman.conf. Since pakku wraps pacman in places, this will make both outputs look the same.

It also includes two commits I made to get Nim building that are probably poorly and unsafely done, and can be trashed if need be.

@zqqw

zqqw commented Dec 23, 2020

Copy link
Copy Markdown

Could you make a PR for the Easter Egg patch here for pakku-git:
https://github.com/zqqw/pakku
Although I could add it myself, it would make it easier to keep the history right with you as the author then. I don't think I can easily merge it as it is due to some minor changes in related areas. Sorry I didn't spot this sooner, fantastic idea!
There are no warnings building pakku-git. Benjamin Shirley-Quirk's patch has fixed it and it builds with the current nim-git.
I had to manually merge it in some places, here is the diff I ended up with if it makes it a bit easier, hope it's OK, apparently working anyway:

diff --git a/src/config.nim b/src/config.nim
index 1afa89a..c43890a 100644
--- a/src/config.nim
+++ b/src/config.nim
@@ -18,6 +18,7 @@ type
     arch: string,
     debug: bool,
     progressBar: bool,
+    chomp: bool,
     verbosePkgLists: bool,
     downloadTimeout: bool,
     pgpKeyserver: Option[string],
@@ -178,8 +179,8 @@ proc obtainConfig*(config: PacmanConfig): Config =
       [aurRepo, tra"wrong or NULL argument passed"], colorNeeded = some(color))
 
   ((config.common.dbs, config.common.arch, config.common.debug, config.common.progressBar,
-    config.common.verbosePkgLists, config.common.downloadTimeout, config.common.pgpKeyserver,
-    config.common.defaultRoot and config.sysrootOption.isNone,
+    config.common.chomp, config.common.verbosePkgLists, config.common.downloadTimeout,
+    config.common.pgpKeyserver, config.common.defaultRoot and config.sysrootOption.isNone,
     config.common.ignorePkgs, config.common.ignoreGroups),
     root, db, cache, userCacheInitial, userCacheCurrent, tmpRootInitial, tmpRootCurrent,
     color, aurRepo, aurComments, checkIgnored, ignoreArch, printAurNotFound, printLocalIsNewer,
diff --git a/src/feature/syncinstall.nim b/src/feature/syncinstall.nim
index 8f26d0d..68c0f27 100644
--- a/src/feature/syncinstall.nim
+++ b/src/feature/syncinstall.nim
@@ -42,7 +42,7 @@ proc createCloneProgress(config: Config, count: int, flexible: bool, printMode:
   (proc (update: int, terminate: int) {.closure.}, proc {.closure.}) =
   if count >= 1 and not printMode:
     let (update, terminate) = printProgressShare(config.common.progressBar,
-      tr"cloning repositories")
+      config.common.chomp, tr"cloning repositories")
     update(0, count)
 
     if flexible:
diff --git a/src/feature/syncsource.nim b/src/feature/syncsource.nim
index f966085..f16f7c6 100644
--- a/src/feature/syncsource.nim
+++ b/src/feature/syncsource.nim
@@ -130,7 +130,7 @@ proc cloneAndCopy(config: Config, quiet: bool, fullTargets: seq[FullPackageTarge
     newSeq[BaseTarget]())
 
   let (update, terminate) = if not quiet:
-      printProgressShare(config.common.progressBar, tr"cloning repositories")
+      printProgressShare(config.common.progressBar, config.common.chomp, tr"cloning repositories")
     else:
       (proc (i0: int, i1: int) {.sideEffect,closure.} = discard, proc () {.sideEffect,closure.} = discard)
 
diff --git a/src/format.nim b/src/format.nim
index bd6d393..a7be554 100644
--- a/src/format.nim
+++ b/src/format.nim
@@ -1,6 +1,6 @@
 import
   macros, options, posix, sequtils, strutils, sugar, times, unicode,
-  utils
+  utils, terminal
 
 type
   PackageLineFormat* = tuple[
@@ -299,7 +299,7 @@ macro choices*(choices: varargs[untyped]): untyped =
       else:
         error("error")
 
-proc printProgressFull*(bar: bool, title: string): ((string, float) -> void, () -> void) =
+proc printProgressFull*(bar: bool, chomp: bool, title: string): ((string, float) -> void, () -> void) =
   let width = getWindowSize().width
 
   if not bar or width <= 0:
@@ -313,16 +313,32 @@ proc printProgressFull*(bar: bool, title: string): ((string, float) -> void, ()
     var lastTime = startTime
     var lastProgress = 0f
     var averageSpeed = -1f
+    var mouth = "c"
 
     proc update(prefix: string, progress: float) {.sideEffect,closure.} =
       let progressTrim = max(min(1, progress + 0.005), 0)
       let progressStr = $(progressTrim * 100).int & "%"
       let paddedProgressStr = ' '.repeat(5 - progressStr.len) & progressStr
 
-      let indicator = if progressLen > 8: (block:
+      let indicator = if progressLen > 8:
           let fullLen = progressLen - 8
           let barLen = (fullLen.float * progressTrim).int
-          " [" & '#'.repeat(barLen) & '-'.repeat(fullLen - barLen) & "]")
+          if chomp: # This disregards the "Color" setting - but, so does pacman
+            var t: string
+            t.add(" [")
+            for i in countdown(fullLen, 1):
+              if i > fullLen - barLen:
+                t.add("-")
+              elif i == fullLen - barLen:
+                t.add(ansiForegroundColorCode(fgYellow) & mouth & ansiForegroundColorCode(fgWhite))
+              elif i mod 3 == 0:
+                t.add("o")
+              else:
+                t.add(" ")
+            t.add(ansiForegroundColorCode(fgDefault) & "]")
+            t
+          else:
+            " [" & '#'.repeat(barLen) & '-'.repeat(fullLen - barLen) & "]"
         else:
           ""
 
@@ -331,6 +347,10 @@ proc printProgressFull*(bar: bool, title: string): ((string, float) -> void, ()
         let speed = (progress - lastProgress) / (time - lastTime).float
         lastTime = time
         lastProgress = progress
+        if mouth == "c":
+          mouth = "C"
+        else:
+          mouth = "c"
         if averageSpeed < 0:
           averageSpeed = speed
         else:
@@ -347,9 +367,9 @@ proc printProgressFull*(bar: bool, title: string): ((string, float) -> void, ()
         else:
           "--:--"
 
-      stdout.write(prefix, title,
+      stdout.styledWrite(prefix, title,
         ' '.repeat(infoLen - prefix.runeLen - title.runeLen - 1 - timeLeft.len),
-        ' ', timeLeft, indicator, paddedProgressStr, "\x1b[0K\r")
+        " ", timeLeft, indicator, paddedProgressStr, "\x1b[0K\r")
       stdout.flushFile()
 
     proc terminate() {.sideEffect,closure.} =
@@ -359,8 +379,8 @@ proc printProgressFull*(bar: bool, title: string): ((string, float) -> void, ()
 
     (update, terminate)
 
-proc printProgressShare*(bar: bool, title: string): ((int, int) -> void, () -> void) =
-  let (updateFull, terminate) = printProgressFull(bar, title)
+proc printProgressShare*(bar: bool, chomp: bool, title: string): ((int, int) -> void, () -> void) =
+  let (updateFull, terminate) = printProgressFull(bar, chomp, title)
 
   proc update(current: int, total: int) {.sideEffect,closure.} =
     let prefix = if total > 0:
diff --git a/src/pacman.nim b/src/pacman.nim
index 5f1cb4a..561d2cb 100644
--- a/src/pacman.nim
+++ b/src/pacman.nim
@@ -350,6 +350,7 @@ proc createConfigFromTable(table: Table[string, string], dbs: seq[string]): Pacm
   let cacheRel = table.opt("CacheDir")
   let gpgRel = table.opt("GPGDir")
   let color = if table.hasKey("Color"): ColorMode.colorAuto else: ColorMode.colorNever
+  let chomp = table.hasKey("ILoveCandy")
   let verbosePkgLists = table.hasKey("VerbosePkgLists")
   let downloadTimeout = not table.hasKey("DisableDownloadTimeout")
   let arch = table.opt("Architecture").get("auto")
@@ -361,7 +362,7 @@ proc createConfigFromTable(table: Table[string, string], dbs: seq[string]): Pacm
     raise commandError(tr"can not get the architecture",
       colorNeeded = some(color.get))
 
-  ((dbs, archFinal, false, true, verbosePkgLists, downloadTimeout, none(string), true,
+  ((dbs, archFinal, false, true, chomp, verbosePkgLists, downloadTimeout, none(string), true,
     ignorePkgs, ignoreGroups), none(string), rootRel, dbRel, cacheRel, gpgRel, color)
 
 proc obtainPacmanConfig*(args: seq[Argument]): PacmanConfig =
@@ -440,7 +441,7 @@ proc obtainPacmanConfig*(args: seq[Argument]): PacmanConfig =
   let argsRootRel = rootRel.get("/")
   let defaultRoot = defaultRootRel == argsRootRel
 
-  let config: PacmanConfig = ((defaultConfig.common.dbs, arch, debug, progressBar,
+  let config: PacmanConfig = ((defaultConfig.common.dbs, arch, debug, progressBar, defaultConfig.common.chomp,
     defaultConfig.common.verbosePkgLists, defaultConfig.common.downloadTimeout and downloadTimeout,
     pgpKeyserver, defaultRoot, ignorePkgs + defaultConfig.common.ignorePkgs,
     ignoreGroups + defaultConfig.common.ignoreGroups),

@omentic

omentic commented Dec 23, 2020

Copy link
Copy Markdown
Author

Sure thing, let me know if the pull request I just opened works. I'm going to leave this one open too, just in case kitsunyan checks back in and decides to merge some stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants