ccstatusline 2.0.11 → 2.0.13

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/LICENSE CHANGED
@@ -18,8 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-
23
- ---
24
- Original author: Matthew Breedlove (https://github.com/sirmalloc)
25
- Official repository: https://github.com/sirmalloc/ccstatusline
21
+ SOFTWARE.
package/README.md CHANGED
@@ -44,6 +44,12 @@
44
44
 
45
45
  ## 🆕 Recent Updates
46
46
 
47
+ ### v2.0.12 - Custom Text widget now supports emojis
48
+
49
+ - **👾 Emoji Support** - You can now paste emoji into the custom text widget. You can also turn on the merge option to get emoji labels for your widgets like this:
50
+
51
+ ![Emoji Support](https://raw.githubusercontent.com/sirmalloc/ccstatusline/main/screenshots/emojiSupport.png)
52
+
47
53
  ### v2.0.11 - Unlimited Status Lines
48
54
 
49
55
  - **🚀 No Line Limit** - Configure as many status lines as you need - the 3-line limitation has been removed
@@ -51374,7 +51374,7 @@ import { execSync as execSync3 } from "child_process";
51374
51374
  import * as fs5 from "fs";
51375
51375
  import * as path4 from "path";
51376
51376
  var __dirname = "/Users/sirmalloc/Projects/Personal/ccstatusline/src/utils";
51377
- var PACKAGE_VERSION = "2.0.11";
51377
+ var PACKAGE_VERSION = "2.0.13";
51378
51378
  function getPackageVersion() {
51379
51379
  if (/^\d+\.\d+\.\d+/.test(PACKAGE_VERSION)) {
51380
51380
  return PACKAGE_VERSION;
@@ -52619,15 +52619,35 @@ function renderPowerlineStatusLine(widgets, settings, context, lineIndex = 0, gl
52619
52619
  return "";
52620
52620
  const autoAlign = config2.autoAlign;
52621
52621
  if (autoAlign) {
52622
+ let alignmentPos = 0;
52622
52623
  for (let i = 0;i < widgetElements.length; i++) {
52623
52624
  const element = widgetElements[i];
52624
- const maxWidth = preCalculatedMaxWidths[i];
52625
- if (element && maxWidth !== undefined) {
52626
- const currentLength = stringWidth(element.content.replace(ANSI_REGEX, ""));
52627
- const paddingNeeded = maxWidth - currentLength;
52628
- if (paddingNeeded > 0) {
52629
- element.content += " ".repeat(paddingNeeded);
52625
+ if (!element)
52626
+ continue;
52627
+ const prevWidget = i > 0 ? widgetElements[i - 1] : null;
52628
+ const isPreviousMerged = prevWidget?.widget.merge;
52629
+ if (!isPreviousMerged) {
52630
+ const maxWidth = preCalculatedMaxWidths[alignmentPos];
52631
+ if (maxWidth !== undefined) {
52632
+ let combinedLength = stringWidth(element.content.replace(ANSI_REGEX, ""));
52633
+ let j = i;
52634
+ while (j < widgetElements.length - 1 && widgetElements[j]?.widget.merge) {
52635
+ j++;
52636
+ const nextElement = widgetElements[j];
52637
+ if (nextElement) {
52638
+ combinedLength += stringWidth(nextElement.content.replace(ANSI_REGEX, ""));
52639
+ }
52640
+ }
52641
+ const paddingNeeded = maxWidth - combinedLength;
52642
+ if (paddingNeeded > 0) {
52643
+ const lastElement = widgetElements[j];
52644
+ if (lastElement) {
52645
+ lastElement.content += " ".repeat(paddingNeeded);
52646
+ }
52647
+ }
52648
+ i = j;
52630
52649
  }
52650
+ alignmentPos++;
52631
52651
  }
52632
52652
  }
52633
52653
  }
@@ -52826,17 +52846,32 @@ function calculateMaxWidthsFromPreRendered(preRenderedLines, settings) {
52826
52846
  const paddingLength = defaultPadding.length;
52827
52847
  for (const preRenderedLine of preRenderedLines) {
52828
52848
  const filteredWidgets = preRenderedLine.filter((w) => w.widget.type !== "separator" && w.widget.type !== "flex-separator" && w.content);
52829
- for (let pos = 0;pos < filteredWidgets.length; pos++) {
52830
- const widget = filteredWidgets[pos];
52849
+ let alignmentPos = 0;
52850
+ for (let i = 0;i < filteredWidgets.length; i++) {
52851
+ const widget = filteredWidgets[i];
52831
52852
  if (!widget)
52832
52853
  continue;
52833
- const totalWidth = widget.plainLength + paddingLength * 2;
52834
- const currentMax = maxWidths[pos];
52854
+ let totalWidth = widget.plainLength + paddingLength * 2;
52855
+ let j = i;
52856
+ while (j < filteredWidgets.length - 1 && filteredWidgets[j]?.widget.merge) {
52857
+ j++;
52858
+ const nextWidget = filteredWidgets[j];
52859
+ if (nextWidget) {
52860
+ if (filteredWidgets[j - 1]?.widget.merge === "no-padding") {
52861
+ totalWidth += nextWidget.plainLength;
52862
+ } else {
52863
+ totalWidth += nextWidget.plainLength + paddingLength * 2;
52864
+ }
52865
+ }
52866
+ }
52867
+ const currentMax = maxWidths[alignmentPos];
52835
52868
  if (currentMax === undefined) {
52836
- maxWidths[pos] = totalWidth;
52869
+ maxWidths[alignmentPos] = totalWidth;
52837
52870
  } else {
52838
- maxWidths[pos] = Math.max(currentMax, totalWidth);
52871
+ maxWidths[alignmentPos] = Math.max(currentMax, totalWidth);
52839
52872
  }
52873
+ i = j;
52874
+ alignmentPos++;
52840
52875
  }
52841
52876
  }
52842
52877
  return maxWidths;
@@ -52899,7 +52934,17 @@ function renderStatusLine(widgets, settings, context, preRenderedWidgets, preCal
52899
52934
  if (!widget)
52900
52935
  continue;
52901
52936
  if (widget.type === "separator") {
52902
- if (i > 0 && !preRenderedWidgets[i - 1]?.content)
52937
+ let hasContentBefore = false;
52938
+ for (let j = i - 1;j >= 0; j--) {
52939
+ const prevWidget = widgets[j];
52940
+ if (prevWidget && prevWidget.type !== "separator" && prevWidget.type !== "flex-separator") {
52941
+ if (preRenderedWidgets[j]?.content) {
52942
+ hasContentBefore = true;
52943
+ break;
52944
+ }
52945
+ }
52946
+ }
52947
+ if (!hasContentBefore)
52903
52948
  continue;
52904
52949
  const sepChar = widget.character ?? (settings.defaultSeparator ?? "|");
52905
52950
  const formattedSep = formatSeparator(sepChar);
@@ -53481,49 +53526,107 @@ class CustomTextWidget {
53481
53526
  var CustomTextEditor = ({ widget, onComplete, onCancel }) => {
53482
53527
  const [text, setText] = import_react29.useState(widget.customText ?? "");
53483
53528
  const [cursorPos, setCursorPos] = import_react29.useState(text.length);
53529
+ const getGraphemes = (str) => {
53530
+ if ("Segmenter" in Intl) {
53531
+ const segmenter2 = new Intl.Segmenter(undefined, { granularity: "grapheme" });
53532
+ return Array.from(segmenter2.segment(str), (seg) => seg.segment);
53533
+ }
53534
+ return Array.from(str);
53535
+ };
53536
+ const graphemeToStringIndex = (str, graphemeIndex) => {
53537
+ const graphemes2 = getGraphemes(str);
53538
+ let stringIndex = 0;
53539
+ for (let i = 0;i < Math.min(graphemeIndex, graphemes2.length); i++) {
53540
+ const grapheme = graphemes2[i];
53541
+ if (grapheme) {
53542
+ stringIndex += grapheme.length;
53543
+ }
53544
+ }
53545
+ return stringIndex;
53546
+ };
53547
+ const stringToGraphemeIndex = (str, stringIndex) => {
53548
+ const graphemes2 = getGraphemes(str);
53549
+ let currentStringIndex = 0;
53550
+ for (let i = 0;i < graphemes2.length; i++) {
53551
+ if (currentStringIndex >= stringIndex)
53552
+ return i;
53553
+ const grapheme = graphemes2[i];
53554
+ if (grapheme) {
53555
+ currentStringIndex += grapheme.length;
53556
+ }
53557
+ }
53558
+ return graphemes2.length;
53559
+ };
53484
53560
  use_input_default((input, key) => {
53485
53561
  if (key.return) {
53486
53562
  onComplete({ ...widget, customText: text });
53487
53563
  } else if (key.escape) {
53488
53564
  onCancel();
53489
53565
  } else if (key.leftArrow) {
53490
- setCursorPos(Math.max(0, cursorPos - 1));
53566
+ const currentGraphemeIndex2 = stringToGraphemeIndex(text, cursorPos);
53567
+ if (currentGraphemeIndex2 > 0) {
53568
+ const newStringIndex = graphemeToStringIndex(text, currentGraphemeIndex2 - 1);
53569
+ setCursorPos(newStringIndex);
53570
+ }
53491
53571
  } else if (key.rightArrow) {
53492
- setCursorPos(Math.min(text.length, cursorPos + 1));
53572
+ const currentGraphemeIndex2 = stringToGraphemeIndex(text, cursorPos);
53573
+ const graphemeCount = getGraphemes(text).length;
53574
+ if (currentGraphemeIndex2 < graphemeCount) {
53575
+ const newStringIndex = graphemeToStringIndex(text, currentGraphemeIndex2 + 1);
53576
+ setCursorPos(newStringIndex);
53577
+ }
53493
53578
  } else if (key.ctrl && input === "ArrowLeft") {
53494
53579
  setCursorPos(0);
53495
53580
  } else if (key.ctrl && input === "ArrowRight") {
53496
53581
  setCursorPos(text.length);
53497
53582
  } else if (key.backspace) {
53498
53583
  if (cursorPos > 0) {
53499
- setText(text.slice(0, cursorPos - 1) + text.slice(cursorPos));
53500
- setCursorPos(cursorPos - 1);
53584
+ const currentGraphemeIndex2 = stringToGraphemeIndex(text, cursorPos);
53585
+ if (currentGraphemeIndex2 > 0) {
53586
+ const deleteFromIndex = graphemeToStringIndex(text, currentGraphemeIndex2 - 1);
53587
+ const deleteToIndex = graphemeToStringIndex(text, currentGraphemeIndex2);
53588
+ setText(text.slice(0, deleteFromIndex) + text.slice(deleteToIndex));
53589
+ setCursorPos(deleteFromIndex);
53590
+ }
53501
53591
  }
53502
53592
  } else if (key.delete) {
53503
53593
  if (cursorPos < text.length) {
53504
- setText(text.slice(0, cursorPos) + text.slice(cursorPos + 1));
53594
+ const currentGraphemeIndex2 = stringToGraphemeIndex(text, cursorPos);
53595
+ const graphemeCount = getGraphemes(text).length;
53596
+ if (currentGraphemeIndex2 < graphemeCount) {
53597
+ const deleteFromIndex = graphemeToStringIndex(text, currentGraphemeIndex2);
53598
+ const deleteToIndex = graphemeToStringIndex(text, currentGraphemeIndex2 + 1);
53599
+ setText(text.slice(0, deleteFromIndex) + text.slice(deleteToIndex));
53600
+ }
53505
53601
  }
53506
- } else if (input && input.length === 1) {
53507
- setText(text.slice(0, cursorPos) + input + text.slice(cursorPos));
53508
- setCursorPos(cursorPos + 1);
53602
+ } else if (input && !key.ctrl && !key.meta) {
53603
+ const newText = text.slice(0, cursorPos) + input + text.slice(cursorPos);
53604
+ setText(newText);
53605
+ setCursorPos(cursorPos + input.length);
53509
53606
  }
53510
53607
  });
53608
+ const graphemes = getGraphemes(text);
53609
+ const currentGraphemeIndex = stringToGraphemeIndex(text, cursorPos);
53610
+ let display = "Enter custom text: ";
53611
+ for (let i = 0;i < graphemes.length; i++) {
53612
+ const grapheme = graphemes[i];
53613
+ if (grapheme) {
53614
+ if (i === currentGraphemeIndex) {
53615
+ display += `\x1B[7m${grapheme}\x1B[0m`;
53616
+ } else {
53617
+ display += grapheme;
53618
+ }
53619
+ }
53620
+ }
53621
+ if (currentGraphemeIndex >= graphemes.length) {
53622
+ display += "\x1B[7m \x1B[0m";
53623
+ }
53511
53624
  return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
53512
53625
  flexDirection: "column",
53513
53626
  children: [
53514
53627
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
53515
- children: [
53516
- "Enter custom text:",
53517
- " ",
53518
- text.slice(0, cursorPos),
53519
- /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
53520
- backgroundColor: "gray",
53521
- color: "black",
53522
- children: text[cursorPos] ?? " "
53523
- }, undefined, false, undefined, this),
53524
- text.slice(cursorPos + 1)
53525
- ]
53526
- }, undefined, true, undefined, this),
53628
+ children: display
53629
+ }, undefined, false, undefined, this),
53527
53630
  /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
53528
53631
  dimColor: true,
53529
53632
  children: "←→ move cursor, Ctrl+←→ jump to start/end, Enter save, ESC cancel"
@@ -53941,11 +54044,13 @@ class CurrentWorkingDirWidget {
53941
54044
  const segments = item.metadata?.segments ? parseInt(item.metadata.segments, 10) : undefined;
53942
54045
  let displayPath = cwd2;
53943
54046
  if (segments && segments > 0) {
53944
- const pathParts = cwd2.split("/");
54047
+ const useBackslash = cwd2.includes("\\") && !cwd2.includes("/");
54048
+ const outSep = useBackslash ? "\\" : "/";
54049
+ const pathParts = cwd2.split(/[\\/]+/);
53945
54050
  const filteredParts = pathParts.filter((part) => part !== "");
53946
54051
  if (filteredParts.length > segments) {
53947
54052
  const selectedSegments = filteredParts.slice(-segments);
53948
- displayPath = ".../" + selectedSegments.join("/");
54053
+ displayPath = "..." + outSep + selectedSegments.join(outSep);
53949
54054
  }
53950
54055
  }
53951
54056
  return item.rawValue ? displayPath : `cwd: ${displayPath}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccstatusline",
3
- "version": "2.0.11",
3
+ "version": "2.0.13",
4
4
  "description": "A customizable status line formatter for Claude Code CLI",
5
5
  "module": "src/ccstatusline.ts",
6
6
  "type": "module",