From 768a19b4d6e9a476d5b7c4da1d788baaf5780c1a Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Thu, 23 Jan 2025 13:59:02 +0100 Subject: [PATCH] fine tuning, added test, which hangs, but yanking works anyway --- Makefile | 2 +- README.md | 2 ++ cmd/tablizer.go | 16 +++++++++++ go.mod | 2 +- lib/printer.go | 28 +------------------ lib/yank.go | 51 +++++++++++++++++++++++++++++++++++ lib/yank_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ tablizer.1 | 20 ++++++++++++-- tablizer.pod | 15 +++++++++++ 9 files changed, 175 insertions(+), 31 deletions(-) create mode 100644 lib/yank.go create mode 100644 lib/yank_test.go diff --git a/Makefile b/Makefile index 2870e99..e4e5175 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ test: singletest: @echo "Call like this: 'make singletest TEST=TestPrepareColumns MOD=lib'" - go test -run $(TEST) github.com/tlinden/tablizer/$(MOD) + go test -run $(TEST) github.com/tlinden/tablizer/$(MOD) $(OPTS) cover-report: go test ./... -cover -coverprofile=coverage.out diff --git a/README.md b/README.md index a66a97d..054ba6d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ Output Flags (mutually exclusive): -C, --csv Enable CSV output -A, --ascii Default output mode, ascii tabular -L, --hightlight-lines Use alternating background colors for tables + -y, --yank-columns Yank specified columns (separated by ,) to clipboard, + space separated Sort Mode Flags (mutually exclusive): -a, --sort-age sort according to age (duration) string diff --git a/cmd/tablizer.go b/cmd/tablizer.go index 71f5b21..e6fb84f 100644 --- a/cmd/tablizer.go +++ b/cmd/tablizer.go @@ -30,6 +30,8 @@ SYNOPSIS -C, --csv Enable CSV output -A, --ascii Default output mode, ascii tabular -L, --hightlight-lines Use alternating background colors for tables + -y, --yank-columns Yank specified columns (separated by ,) to clipboard, + space separated Sort Mode Flags (mutually exclusive): -a, --sort-age sort according to age (duration) string @@ -267,6 +269,18 @@ DESCRIPTION markdown which prints a Markdown table, yaml, which prints yaml encoding and CSV mode, which prints a comma separated value file. + PUT FIELDS TO CLIPBOARD + You can let tablizer put fields to the clipboard using the option "-y". + This best fits the use-case when the result of your filtering yields + just one row. For example: + + cloudctl cluster ls | tablizer -yid matchbox + + If "matchbox" matches one cluster, you can immediately use the id of + that cluster somewhere else and paste it. Of course, if there are + multiple matches, then all id's will be put into the clipboard separated + by one space. + ENVIRONMENT VARIABLES tablizer supports certain environment variables which use can use to influence program behavior. Commandline flags have always precedence @@ -416,6 +430,8 @@ Output Flags (mutually exclusive): -C, --csv Enable CSV output -A, --ascii Default output mode, ascii tabular -L, --hightlight-lines Use alternating background colors for tables + -y, --yank-columns Yank specified columns (separated by ,) to clipboard, + space separated Sort Mode Flags (mutually exclusive): -a, --sort-age sort according to age (duration) string diff --git a/go.mod b/go.mod index 7ae1eeb..568616a 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22 require ( github.com/alecthomas/repr v0.4.0 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de + github.com/atotto/clipboard v0.1.4 github.com/gookit/color v1.5.4 github.com/hashicorp/hcl/v2 v2.23.0 github.com/lithammer/fuzzysearch v1.1.8 @@ -18,7 +19,6 @@ require ( github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/atotto/clipboard v0.1.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect diff --git a/lib/printer.go b/lib/printer.go index 43ee535..0041f85 100644 --- a/lib/printer.go +++ b/lib/printer.go @@ -1,5 +1,5 @@ /* -Copyright © 2022 Thomas von Dein +Copyright © 2022-2025 Thomas von Dein This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,7 +26,6 @@ import ( "strconv" "strings" - "github.com/atotto/clipboard" "github.com/gookit/color" "github.com/olekukonko/tablewriter" "github.com/tlinden/tablizer/cfg" @@ -266,28 +265,3 @@ func printCSVData(writer io.Writer, data *Tabdata) { log.Fatal(err) } } - -func yankColumns(conf cfg.Config, data *Tabdata) { - var yank string - - if len(data.entries) == 0 || len(conf.UseYankColumns) == 0 { - return - } - - for _, row := range data.entries { - for i, field := range row { - for _, idx := range conf.UseYankColumns { - if i == idx-1 { - yank += field + " " - } - } - } - } - - if yank != "" { - setprimary() - if err := clipboard.WriteAll(yank); err != nil { - log.Fatalln("error writing string to clipboard:", err) - } - } -} diff --git a/lib/yank.go b/lib/yank.go new file mode 100644 index 0000000..7f4d755 --- /dev/null +++ b/lib/yank.go @@ -0,0 +1,51 @@ +/* +Copyright © 2022-2025 Thomas von Dein + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package lib + +import ( + "log" + "strings" + + "github.com/atotto/clipboard" + "github.com/tlinden/tablizer/cfg" +) + +func yankColumns(conf cfg.Config, data *Tabdata) { + var yank []string + + if len(data.entries) == 0 || len(conf.UseYankColumns) == 0 { + return + } + + for _, row := range data.entries { + for i, field := range row { + for _, idx := range conf.UseYankColumns { + if i == idx-1 { + yank = append(yank, field) + } + } + } + } + + if len(yank) > 0 { + setprimary() + if err := clipboard.WriteAll(strings.Join(yank, " ")); err != nil { + log.Fatalln("error writing string to clipboard:", err) + } + } +} diff --git a/lib/yank_test.go b/lib/yank_test.go new file mode 100644 index 0000000..b1c057a --- /dev/null +++ b/lib/yank_test.go @@ -0,0 +1,70 @@ +/* +Copyright © 2025 Thomas von Dein + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package lib + +import ( + "bytes" + "fmt" + "testing" + + "github.com/atotto/clipboard" + "github.com/tlinden/tablizer/cfg" +) + +var yanktests = []struct { + name string + yank []int // -y$colum,$column... after processing + filter string + expect string +}{ + { + name: "one", + yank: []int{1}, + filter: "beta", + }, +} + +func DISABLED_TestYankColumns(t *testing.T) { + for _, testdata := range yanktests { + testname := fmt.Sprintf("yank-%s-filter-%s", + testdata.name, testdata.filter) + t.Run(testname, func(t *testing.T) { + conf := cfg.Config{ + OutputMode: cfg.ASCII, + UseYankColumns: testdata.yank, + NoColor: true, + } + + conf.ApplyDefaults() + data := newData() // defined in printer_test.go, reused here + + var writer bytes.Buffer + printData(&writer, conf, &data) + + got, err := clipboard.ReadAll() // hangs indefinetly + if err != nil { + t.Errorf("failed to fetch yanked text from clipboard") + } + + if got != testdata.expect { + t.Errorf("not yanked correctly:\n+++ got:\n%s\n+++ want:\n%s", + got, testdata.expect) + } + }) + } +} diff --git a/tablizer.1 b/tablizer.1 index e3f1aad..01e55d1 100644 --- a/tablizer.1 +++ b/tablizer.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "TABLIZER 1" -.TH TABLIZER 1 "2025-01-22" "1" "User Commands" +.TH TABLIZER 1 "2025-01-23" "1" "User Commands" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -168,6 +168,8 @@ tablizer \- Manipulate tabular output of other programs \& \-C, \-\-csv Enable CSV output \& \-A, \-\-ascii Default output mode, ascii tabular \& \-L, \-\-hightlight\-lines Use alternating background colors for tables +\& \-y, \-\-yank\-columns Yank specified columns (separated by ,) to clipboard, +\& space separated \& \& Sort Mode Flags (mutually exclusive): \& \-a, \-\-sort\-age sort according to age (duration) string @@ -442,6 +444,20 @@ more output modes available: \fBorgtbl\fR which prints an Emacs org-mode table and \fBmarkdown\fR which prints a Markdown table, \fByaml\fR, which prints yaml encoding and \s-1CSV\s0 mode, which prints a comma separated value file. +.SS "\s-1PUT FIELDS TO CLIPBOARD\s0" +.IX Subsection "PUT FIELDS TO CLIPBOARD" +You can let tablizer put fields to the clipboard using the option +\&\f(CW\*(C`\-y\*(C'\fR. This best fits the use-case when the result of your filtering +yields just one row. For example: +.PP +.Vb 1 +\& cloudctl cluster ls | tablizer \-yid matchbox +.Ve +.PP +If \*(L"matchbox\*(R" matches one cluster, you can immediately use the id of +that cluster somewhere else and paste it. Of course, if there are +multiple matches, then all id's will be put into the clipboard +separated by one space. .SS "\s-1ENVIRONMENT VARIABLES\s0" .IX Subsection "ENVIRONMENT VARIABLES" \&\fBtablizer\fR supports certain environment variables which use can use diff --git a/tablizer.pod b/tablizer.pod index 8f170ae..e05a288 100644 --- a/tablizer.pod +++ b/tablizer.pod @@ -29,6 +29,8 @@ tablizer - Manipulate tabular output of other programs -C, --csv Enable CSV output -A, --ascii Default output mode, ascii tabular -L, --hightlight-lines Use alternating background colors for tables + -y, --yank-columns Yank specified columns (separated by ,) to clipboard, + space separated Sort Mode Flags (mutually exclusive): -a, --sort-age sort according to age (duration) string @@ -290,6 +292,19 @@ table and B which prints a Markdown table, B, which prints yaml encoding and CSV mode, which prints a comma separated value file. +=head2 PUT FIELDS TO CLIPBOARD + +You can let tablizer put fields to the clipboard using the option +C<-y>. This best fits the use-case when the result of your filtering +yields just one row. For example: + + cloudctl cluster ls | tablizer -yid matchbox + +If "matchbox" matches one cluster, you can immediately use the id of +that cluster somewhere else and paste it. Of course, if there are +multiple matches, then all id's will be put into the clipboard +separated by one space. + =head2 ENVIRONMENT VARIABLES B supports certain environment variables which use can use