Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ List named views and switch the active view from scripts:
dispatch views
dispatch views --json
dispatch views --csv
dispatch views --markdown
dispatch views use Work
dispatch views use default
```
Expand Down
2 changes: 1 addition & 1 deletion cmd/dispatch/man.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ var manCommands = []manEntry{
{"aliases [--json]", "List session aliases with orphan detection."},
{"alias list [--json]", "List session aliases."},
{"alias <id> <name>", "Set, reassign, clear (--clear), or remove (--remove) a session alias."},
{"views [list] [--json|--csv]", "List configured named views."},
{"views [list] [--json|--csv|--markdown]", "List configured named views."},
{"views use <name|default>", "Set or clear the active named view."},
{"notes [command]", "List, get, set, or clear session notes."},
{"config <get|set|unset|list|edit|path|validate|schema|export|import>", "Read, change, validate, document, or transfer preferences."},
Expand Down
34 changes: 31 additions & 3 deletions cmd/dispatch/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func runViews(w io.Writer, args []string) error {
if len(rest) > 0 {
rest = rest[1:]
}
if len(rest) == 0 || rest[0] == "list" || rest[0] == "--json" || rest[0] == "--csv" {
if len(rest) == 0 || rest[0] == "list" || rest[0] == "--json" || rest[0] == "--csv" || rest[0] == "--markdown" {
return runViewsList(w, rest)
}

Expand All @@ -39,6 +39,7 @@ func runViews(w io.Writer, args []string) error {
func runViewsList(w io.Writer, args []string) error {
jsonOut := false
csvOut := false
markdownOut := false
if len(args) > 0 && args[0] == "list" {
args = args[1:]
}
Expand All @@ -48,12 +49,14 @@ func runViewsList(w io.Writer, args []string) error {
jsonOut = true
case "--csv":
csvOut = true
case "--markdown":
markdownOut = true
default:
return fmt.Errorf("views list does not take arguments, got %q", arg)
}
}
if jsonOut && csvOut {
return fmt.Errorf("--json and --csv cannot be combined")
if (jsonOut && csvOut) || (jsonOut && markdownOut) || (csvOut && markdownOut) {
return fmt.Errorf("--json, --csv, and --markdown cannot be combined")
}

cfg, err := configLoadFn()
Expand All @@ -69,6 +72,10 @@ func runViewsList(w io.Writer, args []string) error {
if csvOut {
return writeViewsCSV(w, report)
}
if markdownOut {
writeViewsMarkdown(w, report)
return nil
}
writeViewsText(w, report)
return nil
}
Expand Down Expand Up @@ -157,6 +164,27 @@ func writeViewsCSV(w io.Writer, report viewsReport) error {
return cw.Error()
}

func writeViewsMarkdown(w io.Writer, report viewsReport) {
fmt.Fprintln(w, "# Dispatch views")
fmt.Fprintln(w)
fmt.Fprintf(w, "Active: %s\n", markdownCell(report.ActiveView))
if len(report.Views) == 0 {
fmt.Fprintln(w)
fmt.Fprintln(w, "No named views found.")
return
}
fmt.Fprintln(w)
fmt.Fprintln(w, "| Active | Name | Settings |")
fmt.Fprintln(w, "|---|---|---|")
for _, v := range report.Views {
active := ""
if v.Name == report.ActiveView {
active = "*"
}
fmt.Fprintf(w, "| %s | %s | %s |\n", active, markdownCell(v.Name), markdownCell(describeView(v)))
}
}

func describeView(v config.NamedView) string {
parts := make([]string, 0, 8)
if v.Search != "" {
Expand Down
54 changes: 48 additions & 6 deletions cmd/dispatch/views_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,56 @@ func TestRunViewsListCSVEmpty(t *testing.T) {
}
}

func TestRunViewsListCSVAndJSONConflict(t *testing.T) {
func TestRunViewsListMarkdown(t *testing.T) {
withConfigSeams(t, viewsConfig())
err := runViews(&bytes.Buffer{}, []string{"views", "list", "--json", "--csv"})
if err == nil {
t.Fatal("expected error for --csv + --json conflict")
var buf bytes.Buffer
if err := runViews(&buf, []string{"views", "--markdown"}); err != nil {
t.Fatalf("runViews markdown: %v", err)
}
out := buf.String()
for _, want := range []string{
"# Dispatch views",
"Active: Work",
"| Active | Name | Settings |",
"| * | Work |",
"repo:jongio/dispatch",
"| Personal |",
"show_hidden",
} {
if !strings.Contains(out, want) {
t.Errorf("markdown output missing %q:\n%s", want, out)
}
}
if strings.Contains(out, "Broken") {
t.Fatalf("invalid view should not appear:\n%s", out)
}
}

func TestRunViewsListMarkdownEmpty(t *testing.T) {
withConfigSeams(t, config.Default())
var buf bytes.Buffer
if err := runViews(&buf, []string{"views", "list", "--markdown"}); err != nil {
t.Fatalf("runViews list markdown: %v", err)
}
if !strings.Contains(err.Error(), "--json and --csv cannot be combined") {
t.Errorf("wrong error: %v", err)
if !strings.Contains(buf.String(), "No named views found.") {
t.Fatalf("expected empty note, got:\n%s", buf.String())
}
}

func TestRunViewsListFormatConflicts(t *testing.T) {
withConfigSeams(t, viewsConfig())
for _, args := range [][]string{
{"views", "list", "--json", "--csv"},
{"views", "list", "--json", "--markdown"},
{"views", "list", "--csv", "--markdown"},
} {
err := runViews(&bytes.Buffer{}, args)
if err == nil {
t.Fatalf("expected error for args %v", args)
}
if !strings.Contains(err.Error(), "cannot be combined") {
t.Errorf("wrong error for %v: %v", args, err)
}
}
}

Expand Down
Loading