@timmy6942025/cli-timer 1.1.13 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,7 @@ By default, timer and stopwatch output is centered in the terminal.
49
49
 
50
50
  - `p` or `Spacebar`: Pause/Resume
51
51
  - `r`: Restart
52
- - `f`: Change style/font
52
+ - `f`: Random style/font
53
53
  - `q`, `e` or `Ctrl+C`: Exit
54
54
 
55
55
  ## Font Styles
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmy6942025/cli-timer",
3
- "version": "1.1.13",
3
+ "version": "1.1.15",
4
4
  "description": "Simple customizable terminal timer and stopwatch",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -83,6 +83,14 @@ function showCursor() {
83
83
  process.stdout.write("\x1b[?25h");
84
84
  }
85
85
 
86
+ function enterAlternateScreen() {
87
+ process.stdout.write("\x1b[?1049h");
88
+ }
89
+
90
+ function exitAlternateScreen() {
91
+ process.stdout.write("\x1b[?1049l");
92
+ }
93
+
86
94
  function formatHms(totalSeconds) {
87
95
  const hours = Math.floor(totalSeconds / 3600);
88
96
  const minutes = Math.floor((totalSeconds % 3600) / 60);
@@ -436,6 +444,30 @@ function setFontInConfig(requestedFont) {
436
444
  return { ok: true, reason: null, font: updated.font };
437
445
  }
438
446
 
447
+ function pickRandomFont(fonts, currentFont) {
448
+ if (!Array.isArray(fonts) || fonts.length === 0) {
449
+ return null;
450
+ }
451
+ if (fonts.length === 1) {
452
+ return fonts[0];
453
+ }
454
+
455
+ let candidate = currentFont;
456
+ for (let attempt = 0; attempt < 8 && candidate === currentFont; attempt += 1) {
457
+ candidate = fonts[Math.floor(Math.random() * fonts.length)];
458
+ }
459
+
460
+ if (candidate === currentFont) {
461
+ const currentIndex = fonts.findIndex((fontName) => fontName === currentFont);
462
+ if (currentIndex >= 0) {
463
+ return fonts[(currentIndex + 1) % fonts.length];
464
+ }
465
+ return fonts[0];
466
+ }
467
+
468
+ return candidate;
469
+ }
470
+
439
471
  function parseDurationArgs(args) {
440
472
  if (args.length === 0 || args.length % 2 !== 0) {
441
473
  return { ok: false, error: "Duration must be in <number> <unit> pairs." };
@@ -525,7 +557,7 @@ function controlsHelpLine(keybindings) {
525
557
  const restart = keyTokenToLabel(keybindings.restartKey);
526
558
  const style = keyTokenToLabel(keybindings.styleKey);
527
559
  const exit = `${keyTokenToLabel(keybindings.exitKey)}/${keyTokenToLabel(keybindings.exitAltKey)}/Ctrl+C`;
528
- return `Controls: ${pause} Pause-Resume | ${restart} Restart | ${style} Style | ${exit} Exit`;
560
+ return `Controls: ${pause} Pause-Resume | ${restart} Restart | ${style} Random Style | ${exit} Exit`;
529
561
  }
530
562
 
531
563
  function keyTokenFromInput(chunk) {
@@ -934,6 +966,7 @@ function runClock({ mode, initialSeconds, config }) {
934
966
  let tick = null;
935
967
  let lastDrawState = "";
936
968
  let hasExited = false;
969
+ let didEnterAlternateScreen = false;
937
970
 
938
971
  const stdin = process.stdin;
939
972
 
@@ -993,9 +1026,10 @@ function runClock({ mode, initialSeconds, config }) {
993
1026
  if (fonts.length === 0) {
994
1027
  return;
995
1028
  }
996
- const currentIndex = fonts.findIndex((fontName) => fontName === config.font);
997
- const nextIndex = currentIndex >= 0 ? (currentIndex + 1) % fonts.length : 0;
998
- const nextFont = fonts[nextIndex];
1029
+ const nextFont = pickRandomFont(fonts, config.font);
1030
+ if (!nextFont) {
1031
+ return;
1032
+ }
999
1033
  const updated = setFontInConfig(nextFont);
1000
1034
  config.font = updated.ok ? updated.font : nextFont;
1001
1035
  lastDrawState = "";
@@ -1028,7 +1062,11 @@ function runClock({ mode, initialSeconds, config }) {
1028
1062
  }
1029
1063
  stdin.pause();
1030
1064
  showCursor();
1031
- clearScreen();
1065
+ if (didEnterAlternateScreen) {
1066
+ exitAlternateScreen();
1067
+ } else {
1068
+ clearScreen();
1069
+ }
1032
1070
  process.exit(code);
1033
1071
  }
1034
1072
 
@@ -1087,6 +1125,8 @@ function runClock({ mode, initialSeconds, config }) {
1087
1125
  stdin.resume();
1088
1126
  stdin.setEncoding("utf8");
1089
1127
  stdin.on("data", onKeypress);
1128
+ enterAlternateScreen();
1129
+ didEnterAlternateScreen = true;
1090
1130
  hideCursor();
1091
1131
 
1092
1132
  draw(true);
@@ -1216,7 +1256,7 @@ function printUsage() {
1216
1256
  process.stdout.write("Settings\n");
1217
1257
  process.stdout.write(" timer settings\n\n");
1218
1258
  process.stdout.write("Controls\n");
1219
- process.stdout.write(" Defaults: p/Space Pause-Resume | r Restart | f Style | q/e/Ctrl+C Exit\n");
1259
+ process.stdout.write(" Defaults: p/Space Pause-Resume | r Restart | f Random Style | q/e/Ctrl+C Exit\n");
1220
1260
  process.stdout.write(" Keybindings are customizable in `timer settings`.\n\n");
1221
1261
  process.stdout.write("Font Styles\n");
1222
1262
  process.stdout.write(" timer style\n");
@@ -1276,7 +1316,12 @@ function runTimer(args) {
1276
1316
  process.exitCode = 1;
1277
1317
  return;
1278
1318
  }
1279
- const randomFont = fonts[Math.floor(Math.random() * fonts.length)];
1319
+ const randomFont = pickRandomFont(fonts, getFontFromConfig());
1320
+ if (!randomFont) {
1321
+ process.stderr.write("No fonts are available.\n");
1322
+ process.exitCode = 1;
1323
+ return;
1324
+ }
1280
1325
  const result = setFontInConfig(randomFont);
1281
1326
  if (!result.ok) {
1282
1327
  process.stderr.write(`Failed to set random font: ${randomFont}\n`);