mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 08:00:59 +00:00
Fix edit diff line number alignment and whitespace preservation
- Fix line numbers showing incorrect values for edits far from file start (e.g., 1,2,3 instead of 336,337,338). Skip count was added after displaying lines instead of before. - Rewrite splitIntoTokensWithAnsi in pi-tui to preserve whitespace as separate tokens instead of discarding it. Wrapped lines now maintain proper alignment and code indentation. - Update mom README: rename title, remove em-dashes for cleaner prose
This commit is contained in:
parent
932f48b0e9
commit
a59553a881
5 changed files with 192 additions and 183 deletions
|
|
@ -75,39 +75,39 @@ function updateTrackerFromText(text: string, tracker: AnsiCodeTracker): void {
|
|||
/**
|
||||
* Split text into words while keeping ANSI codes attached.
|
||||
*/
|
||||
function splitIntoWordsWithAnsi(text: string): string[] {
|
||||
const words: string[] = [];
|
||||
let currentWord = "";
|
||||
function splitIntoTokensWithAnsi(text: string): string[] {
|
||||
const tokens: string[] = [];
|
||||
let current = "";
|
||||
let inWhitespace = false;
|
||||
let i = 0;
|
||||
|
||||
while (i < text.length) {
|
||||
const char = text[i];
|
||||
|
||||
const ansiResult = extractAnsiCode(text, i);
|
||||
if (ansiResult) {
|
||||
currentWord += ansiResult.code;
|
||||
current += ansiResult.code;
|
||||
i += ansiResult.length;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === " ") {
|
||||
if (currentWord) {
|
||||
words.push(currentWord);
|
||||
currentWord = "";
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
const char = text[i];
|
||||
const charIsSpace = char === " ";
|
||||
|
||||
if (charIsSpace !== inWhitespace && current) {
|
||||
// Switching between whitespace and non-whitespace, push current token
|
||||
tokens.push(current);
|
||||
current = "";
|
||||
}
|
||||
|
||||
currentWord += char;
|
||||
inWhitespace = charIsSpace;
|
||||
current += char;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (currentWord) {
|
||||
words.push(currentWord);
|
||||
if (current) {
|
||||
tokens.push(current);
|
||||
}
|
||||
|
||||
return words;
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -149,51 +149,52 @@ function wrapSingleLine(line: string, width: number): string[] {
|
|||
|
||||
const wrapped: string[] = [];
|
||||
const tracker = new AnsiCodeTracker();
|
||||
const words = splitIntoWordsWithAnsi(line);
|
||||
const tokens = splitIntoTokensWithAnsi(line);
|
||||
|
||||
let currentLine = "";
|
||||
let currentVisibleLength = 0;
|
||||
|
||||
for (const word of words) {
|
||||
const wordVisibleLength = visibleWidth(word);
|
||||
for (const token of tokens) {
|
||||
const tokenVisibleLength = visibleWidth(token);
|
||||
const isWhitespace = token.trim() === "";
|
||||
|
||||
// Word itself is too long - break it character by character
|
||||
if (wordVisibleLength > width) {
|
||||
// Token itself is too long - break it character by character
|
||||
if (tokenVisibleLength > width && !isWhitespace) {
|
||||
if (currentLine) {
|
||||
wrapped.push(currentLine);
|
||||
currentLine = "";
|
||||
currentVisibleLength = 0;
|
||||
}
|
||||
|
||||
// Break long word
|
||||
const broken = breakLongWord(word, width, tracker);
|
||||
// Break long token
|
||||
const broken = breakLongWord(token, width, tracker);
|
||||
wrapped.push(...broken.slice(0, -1));
|
||||
currentLine = broken[broken.length - 1];
|
||||
currentVisibleLength = visibleWidth(currentLine);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if adding this word would exceed width
|
||||
const spaceNeeded = currentVisibleLength > 0 ? 1 : 0;
|
||||
const totalNeeded = currentVisibleLength + spaceNeeded + wordVisibleLength;
|
||||
// Check if adding this token would exceed width
|
||||
const totalNeeded = currentVisibleLength + tokenVisibleLength;
|
||||
|
||||
if (totalNeeded > width && currentVisibleLength > 0) {
|
||||
// Wrap to next line
|
||||
// Wrap to next line - don't carry trailing whitespace
|
||||
wrapped.push(currentLine);
|
||||
currentLine = tracker.getActiveCodes() + word;
|
||||
currentVisibleLength = wordVisibleLength;
|
||||
if (isWhitespace) {
|
||||
// Don't start new line with whitespace
|
||||
currentLine = tracker.getActiveCodes();
|
||||
currentVisibleLength = 0;
|
||||
} else {
|
||||
currentLine = tracker.getActiveCodes() + token;
|
||||
currentVisibleLength = tokenVisibleLength;
|
||||
}
|
||||
} else {
|
||||
// Add to current line
|
||||
if (currentVisibleLength > 0) {
|
||||
currentLine += " " + word;
|
||||
currentVisibleLength += 1 + wordVisibleLength;
|
||||
} else {
|
||||
currentLine += word;
|
||||
currentVisibleLength = wordVisibleLength;
|
||||
}
|
||||
currentLine += token;
|
||||
currentVisibleLength += tokenVisibleLength;
|
||||
}
|
||||
|
||||
updateTrackerFromText(word, tracker);
|
||||
updateTrackerFromText(token, tracker);
|
||||
}
|
||||
|
||||
if (currentLine) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue