From bbf3683406929248ecbb8dd83e1e1ce9fff8b4fb Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 18 Oct 2026 19:46:00 -0700 Subject: [PATCH 1/4] ls: print one entry per line in short mode Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_011KiQ74PLNJ2h77HwcPwbGr --- cmd/ls.go | 9 +++------ cmd/ls_test.go | 35 +++++------------------------------ 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index 44020d7..12c8600 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -346,10 +346,10 @@ func renderLsResults(out io.Writer, entries []files.IsMetadata, opts listOptions itemCounter := 0 printItem := func(message string) { itemCounter = itemCounter + 1 - _, _ = fmt.Fprint(w, message) - if (itemCounter%4 == 0) || opts.long { - _, _ = fmt.Fprintln(w) + if !opts.long { + message = strings.TrimSuffix(message, "\t") } + _, _ = fmt.Fprintln(w, message) } if opts.long { @@ -387,9 +387,6 @@ func isListRevisionsNotFileError(err error) bool { } func finishListOutput(w *tabwriter.Writer, itemCounter int, opts listOptions) error { - if itemCounter > 0 && !opts.long && itemCounter%4 != 0 { - _, _ = fmt.Fprintln(w) - } return w.Flush() } diff --git a/cmd/ls_test.go b/cmd/ls_test.go index 5170a41..80ebb12 100644 --- a/cmd/ls_test.go +++ b/cmd/ls_test.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" "testing" - "text/tabwriter" "time" "github.com/dropbox/dropbox-sdk-go-unofficial/v6/dropbox" @@ -137,28 +136,11 @@ func TestGetFileMetadataNotCalledForRoot(t *testing.T) { } } -func TestFinishListOutputAddsTrailingNewlineForPartialShortRows(t *testing.T) { - var out strings.Builder - w := new(tabwriter.Writer) - w.Init(&out, 4, 8, 1, ' ', 0) - - fmt.Fprint(w, "/one\t") - if err := finishListOutput(w, 1, listOptions{}); err != nil { - t.Fatalf("finishListOutput returned error: %v", err) - } - - if got := out.String(); !strings.HasSuffix(got, "\n") { - t.Fatalf("output %q does not end with newline", got) - } -} - -func TestRenderLsResultsShortModeUsesFourColumns(t *testing.T) { +func TestRenderLsResultsShortModeUsesOneEntryPerLine(t *testing.T) { entries := []files.IsMetadata{ &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/one"}}, - &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/two"}}, - &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/three"}}, - &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/four"}}, - &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/five"}}, + &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/two words"}}, + &files.FileMetadata{Metadata: files.Metadata{PathDisplay: "/three.zip"}}, } var out bytes.Buffer @@ -166,15 +148,8 @@ func TestRenderLsResultsShortModeUsesFourColumns(t *testing.T) { t.Fatalf("renderLsResults returned error: %v", err) } - lines := strings.Split(strings.TrimSuffix(out.String(), "\n"), "\n") - if len(lines) != 2 { - t.Fatalf("output = %q, want two short-mode rows", out.String()) - } - if !strings.Contains(lines[0], "/one") || !strings.Contains(lines[0], "/four") { - t.Fatalf("first row = %q, want first four entries", lines[0]) - } - if !strings.Contains(lines[1], "/five") { - t.Fatalf("second row = %q, want fifth entry", lines[1]) + if want := "/one\n/two words\n/three.zip\n"; out.String() != want { + t.Fatalf("output = %q, want %q", out.String(), want) } } From 823e44ba93cf32bed0062d178c08d11096761637 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 18 Oct 2026 19:46:31 -0700 Subject: [PATCH 2/4] Remove trailing tab padding from path output Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_011KiQ74PLNJ2h77HwcPwbGr --- cmd/format_test.go | 2 +- cmd/ls.go | 9 +++------ cmd/ls_test.go | 12 ++++++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/cmd/format_test.go b/cmd/format_test.go index 172d494..2227b93 100644 --- a/cmd/format_test.go +++ b/cmd/format_test.go @@ -174,7 +174,7 @@ func TestFormatFileMetadataWithOptsShort(t *testing.T) { } got := formatFileMetadataWithOpts(meta, listOptions{long: false}) - want := "/test.txt\t" + want := "/test.txt" if got != want { t.Errorf("short format = %q, want %q", got, want) } diff --git a/cmd/ls.go b/cmd/ls.go index 12c8600..d48a420 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -65,7 +65,7 @@ func printFolderMetadata(w io.Writer, e *files.FolderMetadata, longFormat bool) } func formatFolderMetadata(e *files.FolderMetadata, longFormat bool) string { - text := fmt.Sprintf("%s\t", e.PathDisplay) + text := e.PathDisplay if longFormat { text = "-\t-\t-\t" + text } @@ -77,7 +77,7 @@ func formatFileMetadata(e *files.FileMetadata, longFormat bool) string { } func formatFileMetadataWithOpts(e *files.FileMetadata, opts listOptions) string { - text := fmt.Sprintf("%s\t", e.PathDisplay) + text := e.PathDisplay if opts.long { t := getTime(e, opts) text = fmt.Sprintf("%s\t%s\t%s\t", e.Rev, humanize.IBytes(e.Size), formatTime(t, opts)) + text @@ -86,7 +86,7 @@ func formatFileMetadataWithOpts(e *files.FileMetadata, opts listOptions) string } func formatDeletedMetadata(e *files.DeletedMetadata, longFormat bool) string { - text := fmt.Sprintf("%s\t", e.PathDisplay) + text := e.PathDisplay if longFormat { text = "-\t-\t-\t" + text } @@ -346,9 +346,6 @@ func renderLsResults(out io.Writer, entries []files.IsMetadata, opts listOptions itemCounter := 0 printItem := func(message string) { itemCounter = itemCounter + 1 - if !opts.long { - message = strings.TrimSuffix(message, "\t") - } _, _ = fmt.Fprintln(w, message) } diff --git a/cmd/ls_test.go b/cmd/ls_test.go index 80ebb12..632df5e 100644 --- a/cmd/ls_test.go +++ b/cmd/ls_test.go @@ -20,13 +20,13 @@ func TestFormatFolderMetadata(t *testing.T) { } got := formatFolderMetadata(meta, false) - want := "/Documents\t" + want := "/Documents" if got != want { t.Errorf("formatFolderMetadata(short) = %q, want %q", got, want) } got = formatFolderMetadata(meta, true) - want = "-\t-\t-\t/Documents\t" + want = "-\t-\t-\t/Documents" if got != want { t.Errorf("formatFolderMetadata(long) = %q, want %q", got, want) } @@ -42,7 +42,7 @@ func TestFormatFileMetadata(t *testing.T) { } got := formatFileMetadata(meta, false) - want := "/test.txt\t" + want := "/test.txt" if got != want { t.Errorf("formatFileMetadata(short) = %q, want %q", got, want) } @@ -51,7 +51,7 @@ func TestFormatFileMetadata(t *testing.T) { if got == "" { t.Error("formatFileMetadata(long) returned empty string") } - if len(got) <= len("/test.txt\t") { + if len(got) <= len("/test.txt") { t.Errorf("formatFileMetadata(long) should include rev/size/time, got %q", got) } } @@ -64,13 +64,13 @@ func TestFormatDeletedMetadata(t *testing.T) { } got := formatDeletedMetadata(meta, false) - want := "/removed.txt\t" + want := "/removed.txt" if got != want { t.Errorf("formatDeletedMetadata(short) = %q, want %q", got, want) } got = formatDeletedMetadata(meta, true) - want = "-\t-\t-\t/removed.txt\t" + want = "-\t-\t-\t/removed.txt" if got != want { t.Errorf("formatDeletedMetadata(long) = %q, want %q", got, want) } From 891270b658b923d793dfad5de9c77d6297d45cb2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 18 Oct 2026 19:47:23 -0700 Subject: [PATCH 3/4] Sort ls/search results by name by default Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_011KiQ74PLNJ2h77HwcPwbGr --- cmd/format.go | 2 +- cmd/format_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/format.go b/cmd/format.go index cef9857..68d9435 100644 --- a/cmd/format.go +++ b/cmd/format.go @@ -52,7 +52,7 @@ func getTime(e *files.FileMetadata, opts listOptions) time.Time { func sortEntries(entries []files.IsMetadata, opts listOptions) { if opts.sortBy == "" { - return + opts.sortBy = "name" } sort.SliceStable(entries, func(i, j int) bool { diff --git a/cmd/format_test.go b/cmd/format_test.go index 2227b93..ffdcffb 100644 --- a/cmd/format_test.go +++ b/cmd/format_test.go @@ -151,7 +151,7 @@ func TestSortEntriesReverse(t *testing.T) { } } -func TestSortEntriesNoSort(t *testing.T) { +func TestSortEntriesDefaultsToName(t *testing.T) { entries := []files.IsMetadata{ &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/z"}}, &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/a"}}, @@ -159,8 +159,8 @@ func TestSortEntriesNoSort(t *testing.T) { sortEntries(entries, listOptions{}) - if entryPath(entries[0]) != "/z" || entryPath(entries[1]) != "/a" { - t.Error("with no sort, order should be preserved") + if entryPath(entries[0]) != "/a" || entryPath(entries[1]) != "/z" { + t.Error("with no sort, entries should be sorted by name") } } From 32a162367dd5c906c15cc5c3b8624db3ebacad31 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 18 Oct 2026 21:31:42 -0700 Subject: [PATCH 4/4] revert sorting results --- cmd/format.go | 2 +- cmd/format_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/format.go b/cmd/format.go index 68d9435..cef9857 100644 --- a/cmd/format.go +++ b/cmd/format.go @@ -52,7 +52,7 @@ func getTime(e *files.FileMetadata, opts listOptions) time.Time { func sortEntries(entries []files.IsMetadata, opts listOptions) { if opts.sortBy == "" { - opts.sortBy = "name" + return } sort.SliceStable(entries, func(i, j int) bool { diff --git a/cmd/format_test.go b/cmd/format_test.go index ffdcffb..2227b93 100644 --- a/cmd/format_test.go +++ b/cmd/format_test.go @@ -151,7 +151,7 @@ func TestSortEntriesReverse(t *testing.T) { } } -func TestSortEntriesDefaultsToName(t *testing.T) { +func TestSortEntriesNoSort(t *testing.T) { entries := []files.IsMetadata{ &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/z"}}, &files.FolderMetadata{Metadata: files.Metadata{PathDisplay: "/a"}}, @@ -159,8 +159,8 @@ func TestSortEntriesDefaultsToName(t *testing.T) { sortEntries(entries, listOptions{}) - if entryPath(entries[0]) != "/a" || entryPath(entries[1]) != "/z" { - t.Error("with no sort, entries should be sorted by name") + if entryPath(entries[0]) != "/z" || entryPath(entries[1]) != "/a" { + t.Error("with no sort, order should be preserved") } }