66
77import typer
88
9- from sqlite_rag .models .sentence_result import SentenceResult
10-
119from .models .document_result import DocumentResult
1210
1311
@@ -82,81 +80,6 @@ def _format_uri_display(self, uri: str, icon: str, max_width: int = 75) -> str:
8280 uri_display = f"{ icon } ...{ uri [- available_width :]} "
8381 return uri_display
8482
85- def _build_sentence_preview (
86- self ,
87- chunk_content : str ,
88- sentences : List [SentenceResult ],
89- max_chars : int = 400 ,
90- ) -> str :
91- """Build preview from top 3 ranked sentences with [...] for gaps.
92-
93- Args:
94- chunk_content: The full chunk text
95- sentences: List of SentenceResult objects (should already be sorted by rank)
96- max_chars: Maximum total characters for preview
97-
98- Returns:
99- Preview string with top sentences and [...] separators.
100- Falls back to truncated chunk_content if sentences have no offsets.
101- """
102-
103- # Take top 3 sentences (they should already be sorted by rank/distance)
104- top_sentences = sentences [:3 ] if sentences else []
105-
106- if not top_sentences :
107- # Fallback: no sentences, return truncated chunk content
108- return chunk_content [:max_chars ]
109-
110- # Filter sentences that have offset information
111- sentences_with_offsets = [
112- s
113- for s in top_sentences
114- if s .start_offset is not None and s .end_offset is not None
115- ]
116-
117- if not sentences_with_offsets :
118- # Fallback: sentences exist but no offset information, return truncated chunk content
119- return chunk_content [:max_chars ]
120-
121- # Sort by start_offset to maintain document order
122- sentences_with_offsets .sort (
123- key = lambda s : s .start_offset if s .start_offset is not None else - 1
124- )
125-
126- preview_parts = []
127- total_chars = 0
128- prev_end_offset = None
129-
130- for sentence in sentences_with_offsets :
131- # Extract sentence text using offsets
132- sentence_text = chunk_content [
133- sentence .start_offset : sentence .end_offset
134- ].strip ()
135-
136- # Calculate remaining budget including potential separator
137- separator_len = len (" [...] " ) if preview_parts else 0
138- remaining = max_chars - total_chars - separator_len
139-
140- if remaining <= 0 :
141- break
142-
143- # Truncate sentence if needed
144- if len (sentence_text ) > remaining :
145- sentence_text = sentence_text [: remaining - 3 ] + "..."
146-
147- # Check if there's a gap > 10 chars from previous sentence
148- if prev_end_offset is not None and sentence .start_offset is not None :
149- gap_size = sentence .start_offset - prev_end_offset
150- if gap_size > 10 :
151- preview_parts .append ("[...]" )
152- total_chars += len (" [...] " )
153-
154- preview_parts .append (sentence_text )
155- total_chars += len (sentence_text )
156- prev_end_offset = sentence .end_offset
157-
158- return " " .join (preview_parts )
159-
16083
16184class BoxedFormatter (SearchResultFormatter ):
16285 """Base class for boxed result formatters."""
@@ -176,11 +99,8 @@ def _format_single_result(self, doc: DocumentResult, idx: int) -> None:
17699 """Format a single result with box layout."""
177100 icon = self ._get_file_icon (doc .document .uri or "" )
178101
179- # Use sentence-based preview if sentences are available
180- if doc .sentences :
181- snippet_text = self ._build_sentence_preview (doc .snippet , doc .sentences )
182- else :
183- snippet_text = doc .snippet
102+ # Get snippet from DocumentResult (handles sentence-based preview automatically)
103+ snippet_text = doc .get_preview (max_chars = 400 )
184104
185105 snippet_lines = self ._clean_and_wrap_snippet (
186106 snippet_text , width = 75 , max_length = 400
@@ -250,11 +170,8 @@ def _format_single_result(self, doc: DocumentResult, idx: int) -> None:
250170 """Format a single result with box layout including sentence summary."""
251171 icon = self ._get_file_icon (doc .document .uri or "" )
252172
253- # Use sentence-based preview if sentences are available
254- if doc .sentences :
255- snippet_text = self ._build_sentence_preview (doc .snippet , doc .sentences )
256- else :
257- snippet_text = doc .snippet
173+ # Get snippet from DocumentResult (handles sentence-based preview automatically)
174+ snippet_text = doc .get_preview (max_chars = 400 )
258175
259176 snippet_lines = self ._clean_and_wrap_snippet (
260177 snippet_text , width = 75 , max_length = 400
@@ -305,7 +222,7 @@ def _format_single_result(self, doc: DocumentResult, idx: int) -> None:
305222 sentence .start_offset is not None
306223 and sentence .end_offset is not None
307224 ):
308- sentence_text = doc .snippet [
225+ sentence_text = doc .chunk_content [
309226 sentence .start_offset : sentence .end_offset
310227 ].strip ()
311228 # Truncate and clean for display
@@ -364,13 +281,8 @@ def _print_table_header(self) -> None:
364281
365282 def _print_table_row (self , idx : int , doc : DocumentResult ) -> None :
366283 """Print a single table row."""
367- # Use sentence-based preview if sentences are available
368- if doc .sentences :
369- snippet = self ._build_sentence_preview (
370- doc .snippet , doc .sentences , max_chars = 52
371- )
372- else :
373- snippet = doc .snippet
284+ # Get snippet from DocumentResult (handles sentence-based preview automatically)
285+ snippet = doc .get_preview (max_chars = 52 )
374286
375287 # Clean snippet display
376288 snippet = snippet .replace ("\n " , " " ).replace ("\r " , "" )
0 commit comments