@@ -35,6 +35,7 @@ type model struct {
3535 matchesStyle lipgloss.Style
3636 cursorLineStyle lipgloss.Style
3737 cursorLineMatchesStyle lipgloss.Style
38+ ellipsisStyle lipgloss.Style
3839
3940 matches Matches
4041 choices []int
@@ -78,6 +79,7 @@ func newModel(opt *option) *model {
7879 matchesStyle : opt .styles .option .matches ,
7980 cursorLineStyle : opt .styles .option .cursorLine ,
8081 cursorLineMatchesStyle : lipgloss .NewStyle ().Inherit (opt .styles .option .matches ).Inherit (opt .styles .option .cursorLine ),
82+ ellipsisStyle : lipgloss .NewStyle ().Faint (true ),
8183
8284 choices : []int {},
8385 // window
@@ -238,10 +240,54 @@ func (m *model) itemView(match Match, cursorLine bool) string {
238240 _ , _ = v .WriteString (stringLinesToSpace (m .findOption .itemPrefixFunc (match .Index )))
239241 }
240242
243+ maxItemWidth := m .windowWidth - lipgloss .Width (v .String ())
244+ if maxItemWidth < 1 {
245+ return v .String ()
246+ }
247+
248+ runes := []rune (match .Str )
249+ from := 0
250+ to := len (runes )
251+ ellipsis := ".."
252+
253+ // truncate string
254+ itemWidth := lipgloss .Width (match .Str )
255+ if maxItemWidth < itemWidth {
256+ if maxItemWidth <= len (ellipsis )* 2 {
257+ ellipsis = "."
258+ }
259+ if maxItemWidth <= len (ellipsis )* 2 {
260+ ellipsis = ""
261+ }
262+
263+ if len (match .MatchedIndexes ) == 0 {
264+ // truncate end
265+ to = maxItemWidth - len (ellipsis )
266+ } else {
267+ lastMatchedIndex := match .MatchedIndexes [len (match .MatchedIndexes )- 1 ]
268+
269+ if lastMatchedIndex + 8 + len (ellipsis ) < maxItemWidth {
270+ // truncate end
271+ to = maxItemWidth - len (ellipsis )
272+ } else {
273+ v .WriteString (m .ellipsisStyle .Render (ellipsis ))
274+
275+ if lastMatchedIndex + 1 + 8 + len (ellipsis ) < len (runes ) {
276+ // truncate both start and end
277+ from = lastMatchedIndex + 1 - maxItemWidth + 8 + len (ellipsis )* 2
278+ to = from + maxItemWidth - len (ellipsis )* 2
279+ } else {
280+ // truncate start
281+ from = len (runes ) - maxItemWidth + len (ellipsis )
282+ }
283+ }
284+ }
285+ }
286+
241287 // write item
242- for ci , c := range [] rune ( match . Str ) {
288+ for ci , c := range runes [ from : to ] {
243289 // matches
244- if intContains (match .MatchedIndexes , ci ) {
290+ if intContains (match .MatchedIndexes , ci + from ) {
245291 if cursorLine {
246292 _ , _ = v .WriteString (m .cursorLineMatchesStyle .Render (string (c )))
247293 } else {
@@ -254,6 +300,10 @@ func (m *model) itemView(match Match, cursorLine bool) string {
254300 }
255301 }
256302
303+ if to != len (runes ) {
304+ v .WriteString (m .ellipsisStyle .Render (ellipsis ))
305+ }
306+
257307 return v .String ()
258308}
259309
0 commit comments