Skip to content

Commit b5d981a

Browse files
authored
fix: improve width calculation for ratios option (gokcehan#2347)
* fix: improve width calculation for `ratios` option * Update `CHANGELOG.md` * round window ends instead of floor * grammar
1 parent 48689f9 commit b5d981a

File tree

4 files changed

+74
-39
lines changed

4 files changed

+74
-39
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
3232
- Newline characters are now ignored when drawing the ruler with the `ruler` file configured (#2319).
3333
- A potential crash when using the `scroll-up`/`scroll-down` commands is now fixed (#2320).
3434
- Case-insensitive command-line completions no longer cause user input to be displayed in lowercase (#2336).
35+
- Calculation of window widths for the `ratios` option is now more accurate (#2347).
3536

3637
## [r40](https://github.com/gokcehan/lf/releases/tag/r40)
3738

misc.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,39 @@ func readLines(reader io.ByteReader, maxLines int) (lines []string, binary bool,
513513
}
514514
}
515515

516+
// This function calculates the widths of windows as the result of applying the
517+
// `ratios` option to the screen width. One column is allocated for each divider
518+
// between windows. The `drawbox` option requires an additional two columns to
519+
// draw the left and right borders.
520+
func getWidths(wtot int, ratios []int, drawbox bool) []int {
521+
rlen := len(ratios)
522+
wtot -= rlen - 1
523+
if drawbox {
524+
wtot -= 2
525+
}
526+
wtot = max(wtot, 0)
527+
528+
rtot := 0
529+
for _, r := range ratios {
530+
rtot += r
531+
}
532+
533+
divround := func(x, y int) int {
534+
return (x + y/2) / y
535+
}
536+
537+
widths := make([]int, rlen)
538+
rsum := 0
539+
wsum := 0
540+
for i, r := range ratios {
541+
rsum += r
542+
widths[i] = divround(wtot*rsum, rtot) - wsum
543+
wsum += widths[i]
544+
}
545+
546+
return widths
547+
}
548+
516549
// We don't need no generic code
517550
// We don't need no type control
518551
// No dark templates in compiler

misc_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,30 @@ func TestReadLines(t *testing.T) {
559559
}
560560
}
561561
}
562+
563+
func TestGetWidths(t *testing.T) {
564+
tests := []struct {
565+
wtot int
566+
ratios []int
567+
drawbox bool
568+
exp []int
569+
}{
570+
{0, []int{1}, false, []int{0}},
571+
{0, []int{1}, true, []int{0}},
572+
{0, []int{1, 3, 2}, false, []int{0, 0, 0}},
573+
{0, []int{1, 3, 2}, true, []int{0, 0, 0}},
574+
{14, []int{1, 3, 2}, false, []int{2, 6, 4}},
575+
{16, []int{1, 3, 2}, true, []int{2, 6, 4}},
576+
{23, []int{1, 3, 2, 4}, false, []int{2, 6, 4, 8}}, // windows end at 2.0, 8.0, 12.0, 20.0 respectively
577+
{24, []int{1, 3, 2, 4}, false, []int{2, 6, 5, 8}}, // windows end at 2.1, 8.4, 12.6, 21.0 respectively
578+
{25, []int{1, 3, 2, 4}, false, []int{2, 7, 4, 9}}, // windows end at 2.2, 8.8, 13.2, 22.0 respectively
579+
{26, []int{1, 3, 2, 4}, false, []int{2, 7, 5, 9}}, // windows end at 2.3, 9.2, 13.8, 23.0 respectively
580+
}
581+
582+
for _, test := range tests {
583+
widths := getWidths(test.wtot, test.ratios, test.drawbox)
584+
if !reflect.DeepEqual(widths, test.exp) {
585+
t.Errorf("at input (%v, %v, %v) expected %v but got %v", test.wtot, test.ratios, test.drawbox, test.exp, widths)
586+
}
587+
}
588+
}

ui.go

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,6 @@ func (win *win) printDir(ui *ui, dir *dir, context *dirContext, dirStyle *dirSty
480480

481481
// make space for select marker, and leave another space at the end
482482
maxWidth := win.w - lnwidth - 2
483-
// make extra space to separate windows if drawbox is not enabled
484-
if !gOpts.drawbox {
485-
maxWidth--
486-
}
487483

488484
var icon []rune
489485
var iconDef iconDef
@@ -598,45 +594,23 @@ func getCustomWidth(dir *dir, beg, end int) int {
598594
return maxw
599595
}
600596

601-
func getWidths(wtot int) []int {
602-
rsum := 0
603-
for _, r := range gOpts.ratios {
604-
rsum += r
605-
}
606-
607-
wlen := len(gOpts.ratios)
608-
widths := make([]int, wlen)
609-
610-
if gOpts.drawbox {
611-
wtot -= (wlen + 1)
612-
}
613-
614-
wsum := 0
615-
for i := range wlen - 1 {
616-
widths[i] = gOpts.ratios[i] * wtot / rsum
617-
wsum += widths[i]
618-
}
619-
widths[wlen-1] = wtot - wsum
620-
621-
return widths
622-
}
623-
624597
func getWins(screen tcell.Screen) []*win {
625598
wtot, htot := screen.Size()
626599

627-
widths := getWidths(wtot)
600+
h := max(htot-2, 0)
601+
x := 0
602+
y := 1
603+
if gOpts.drawbox {
604+
h = max(htot-4, 0)
605+
x = 1
606+
y = 2
607+
}
628608

629-
wacc := 0
630-
wlen := len(widths)
631-
wins := make([]*win, 0, wlen)
632-
for i := range wlen {
633-
if gOpts.drawbox {
634-
wacc++
635-
wins = append(wins, newWin(widths[i], max(htot-4, 0), wacc, 2))
636-
} else {
637-
wins = append(wins, newWin(widths[i], max(htot-2, 0), wacc, 1))
638-
}
639-
wacc += widths[i]
609+
widths := getWidths(wtot, gOpts.ratios, gOpts.drawbox)
610+
wins := make([]*win, 0, len(widths))
611+
for _, w := range widths {
612+
wins = append(wins, newWin(w, h, x, y))
613+
x += w + 1
640614
}
641615

642616
return wins

0 commit comments

Comments
 (0)