# Keep case-insensitive highlighting on truncated lines

`a1d2dea`→[main](/content/gh/entireio/cli/commits/main/index.html)·

evisdren·4d ago·2 files·+32 added/-4 removed

The truncation ellipsis is non-ASCII, so appending it before
highlighting made isASCII reject the whole line and silently drop
case-insensitive highlights on long lines. Highlight the truncated
ASCII text first, then append the ellipsis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

## Changes

2

- cmd/entire/cli

- Msearch_cmd.go+8/-4

- Msearch_cmd_test.go+24

```
866 unmodified lines

867
868
869
870
871
872
873
871
872
873
874
875
876
877
878
879
876
880
881
882
883

866 unmodified lines

if mi == maxCodeSearchFileMatches {
			break
		}
		// Truncate before highlighting but append the ellipsis after,
		// so the non-ASCII "…" doesn't disable case-insensitive
		// highlighting (isASCII) for the rest of the line.
		line := r.ContextLine
		runes := []rune(line)
		if len(runes) > maxContextLineLen {
			line = string(runes[:maxContextLineLen]) + "…"
		}
		ellipsis := ""
		if runes := []rune(line); len(runes) > maxContextLineLen {
			line = string(runes[:maxContextLineLen])
			ellipsis = "…"
		}
		lineNo := styles.render(styles.dim, fmt.Sprintf("%d:", r.Line))
		fmt.Fprintf(w, "  %s %s\n", lineNo, highlightCodeMatches(line, resp.Query, styles, caseSensitive))
		fmt.Fprintf(w, "  %s %s%s\n", lineNo, highlightCodeMatches(line, resp.Query, styles, caseSensitive), ellipsis)
		shown++
	}
	// ponytail: overflow counts only what this page fetched (peregrine
```

Mcmd/entire/cli/search_cmd.go+8/-4

```
338 unmodified lines

339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

338 unmodified lines

}
}

func TestWriteCodeSearchText_HighlightsTruncatedLines(t *testing.T) {
	t.Parallel()

// The appended "…" is non-ASCII; it must not disable case-insensitive
	// highlighting for an otherwise ASCII line.
	longLine := "FooBar " + strings.Repeat("x", 300)
	resp := &codesearch.SearchResponse{
		Query:   "foobar",
		Stats:   codesearch.Stats{TotalMatches: 1, TotalFiles: 1, ReposSearched: 1, DurationMs: 1},
		Results: []codesearch.Result{{Repo: "r", Path: "f.go", Line: 1, ContextLine: longLine}},
	}

var buf bytes.Buffer
	writeCodeSearchText(&buf, resp, statusStyles{colorEnabled: true}, false)

output := buf.String()
	if !strings.Contains(output, "…") {
		t.Errorf("expected truncated line to end with ellipsis:\n%s", output)
	}
	if !strings.Contains(output, "\x1b[") {\
		t.Errorf("expected case-insensitive highlight on truncated line:\n%s", output)\
	}
}
\
func TestWriteCodeSearchText_Empty(t *testing.T) {\
	t.Parallel()\
