pi-diff-review 0.1.10 → 0.1.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-diff-review",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Local diff review TUI extension for pi",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,3 +1,7 @@
1
+ import {
2
+ getLanguageFromPath,
3
+ highlightCode,
4
+ } from "@earendil-works/pi-coding-agent";
1
5
  import {
2
6
  Editor,
3
7
  matchesKey,
@@ -58,6 +62,7 @@ export class ReviewComponent {
58
62
  private commentLineKeys = new Map<number, string[]>();
59
63
  private commentsRevision = 0;
60
64
  private commentLineKeysRevision = -1;
65
+ private highlightedLineCache = new Map<string, string>();
61
66
 
62
67
  constructor(
63
68
  private tui: ReviewTui,
@@ -389,7 +394,9 @@ export class ReviewComponent {
389
394
  return { diffHeight, commentsHeight };
390
395
  }
391
396
 
392
- invalidate(): void {}
397
+ invalidate(): void {
398
+ this.highlightedLineCache.clear();
399
+ }
393
400
 
394
401
  dispose(): void {
395
402
  this.explanationAbort?.abort();
@@ -728,22 +735,8 @@ export class ReviewComponent {
728
735
  const commentMark = hasComment ? this.theme.fg("warning", "●") : " ";
729
736
  const lineNumber =
730
737
  side === "left" ? line.oldLineNumber : line.newLineNumber;
731
- const raw = `${commentMark} ${lineNumberCell(lineNumber)} ${this.getDisplayText(line)}`;
732
-
733
- let styled: string;
734
- switch (line.kind) {
735
- case "add":
736
- styled = this.theme.fg("toolDiffAdded", raw);
737
- break;
738
- case "remove":
739
- styled = this.theme.fg("toolDiffRemoved", raw);
740
- break;
741
- case "context":
742
- styled = this.theme.fg("toolDiffContext", raw);
743
- break;
744
- default:
745
- styled = this.theme.fg("muted", raw);
746
- }
738
+ const prefix = `${commentMark} ${lineNumberCell(lineNumber)} `;
739
+ let styled = this.renderDiffRowContent(line, prefix);
747
740
 
748
741
  styled = truncateToWidth(styled, width);
749
742
  const selection = this.getSelectionBounds();
@@ -752,7 +745,7 @@ export class ReviewComponent {
752
745
  if (index === this.selected || inSelection) {
753
746
  return this.theme.bg("selectedBg", padToWidth(styled, width));
754
747
  }
755
- return styled;
748
+ return this.applyDiffBackground(line, styled, width);
756
749
  }
757
750
 
758
751
  private ensureScroll(viewportHeight: number): void {
@@ -779,43 +772,75 @@ export class ReviewComponent {
779
772
  : line.text;
780
773
  }
781
774
 
782
- private renderDiffLine(
775
+ private applyDiffBackground(
783
776
  line: ReviewLine,
784
- index: number,
777
+ styled: string,
785
778
  width: number,
786
- selected: boolean,
787
- selection?: SelectionBounds,
788
779
  ): string {
789
- const hasComment = this.getCommentKeysForLine(index).length > 0;
790
- const commentMark = hasComment ? this.theme.fg("warning", "●") : " ";
791
- const numbers = `${lineNumberCell(line.oldLineNumber)} ${lineNumberCell(line.newLineNumber)}`;
792
- const raw = `${commentMark} ${numbers} ${this.getDisplayText(line)}`;
780
+ if (line.kind === "add") {
781
+ return this.theme.bg("toolSuccessBg", padToWidth(styled, width));
782
+ }
783
+ if (line.kind === "remove") {
784
+ return this.theme.bg("toolErrorBg", padToWidth(styled, width));
785
+ }
786
+ return styled;
787
+ }
793
788
 
794
- let styled: string;
789
+ private renderDiffRowContent(line: ReviewLine, prefix: string): string {
795
790
  switch (line.kind) {
796
791
  case "add":
797
- styled = this.theme.fg("toolDiffAdded", raw);
798
- break;
792
+ return `${this.theme.fg("toolDiffAdded", prefix)}${this.getHighlightedDisplayText(line)}`;
799
793
  case "remove":
800
- styled = this.theme.fg("toolDiffRemoved", raw);
801
- break;
794
+ return `${this.theme.fg("toolDiffRemoved", prefix)}${this.getHighlightedDisplayText(line)}`;
802
795
  case "context":
803
- styled = this.theme.fg("toolDiffContext", raw);
804
- break;
796
+ return `${this.theme.fg("toolDiffContext", prefix)}${this.getHighlightedDisplayText(line)}`;
805
797
  case "hunk":
806
- styled = this.theme.fg("accent", raw);
807
- break;
798
+ return this.theme.fg("accent", `${prefix}${this.getDisplayText(line)}`);
808
799
  default:
809
- styled = this.theme.fg("muted", raw);
800
+ return this.theme.fg("muted", `${prefix}${this.getDisplayText(line)}`);
801
+ }
802
+ }
803
+
804
+ private getHighlightedDisplayText(line: ReviewLine): string {
805
+ const code = this.getDisplayText(line);
806
+ if (!code) return code;
807
+
808
+ const lang = line.filePath ? getLanguageFromPath(line.filePath) : undefined;
809
+ const cacheKey = `${line.id}\0${lang ?? ""}\0${code}`;
810
+ const cached = this.highlightedLineCache.get(cacheKey);
811
+ if (cached != null) return cached;
812
+
813
+ let highlighted = code;
814
+ try {
815
+ highlighted = highlightCode(code, lang)[0] ?? code;
816
+ } catch {
817
+ highlighted = code;
810
818
  }
811
819
 
820
+ this.highlightedLineCache.set(cacheKey, highlighted);
821
+ return highlighted;
822
+ }
823
+
824
+ private renderDiffLine(
825
+ line: ReviewLine,
826
+ index: number,
827
+ width: number,
828
+ selected: boolean,
829
+ selection?: SelectionBounds,
830
+ ): string {
831
+ const hasComment = this.getCommentKeysForLine(index).length > 0;
832
+ const commentMark = hasComment ? this.theme.fg("warning", "●") : " ";
833
+ const numbers = `${lineNumberCell(line.oldLineNumber)} ${lineNumberCell(line.newLineNumber)}`;
834
+ const prefix = `${commentMark} ${numbers} `;
835
+ let styled = this.renderDiffRowContent(line, prefix);
836
+
812
837
  styled = truncateToWidth(styled, width);
813
838
  const inSelection =
814
839
  selection != null && index >= selection.start && index <= selection.end;
815
840
  if (selected || inSelection) {
816
841
  return this.theme.bg("selectedBg", padToWidth(styled, width));
817
842
  }
818
- return styled;
843
+ return this.applyDiffBackground(line, styled, width);
819
844
  }
820
845
 
821
846
  private renderRightPane(