012 --pipe and CSV, TSV, JSON and NUON downloads leave out the rows a filter hides, as Sheets copies a filtered range; XLSX keeps them hidden.
- commit
- a6c6b47d2064f1f4e9de2a9c13d1b823ac003d27
- parent
- 281252f8e0d716553539b0bf144d589613193fee
- author
- Dami <dami.etoile@gmail.com>
- kind
- fix risk score 2.0 of 3, Jev's estimate
| M | docs/ | 4 | ++++ |
| M | docs/ | 6 | +++--- |
| M | internal/ | 17 | +++++++++++++++++ |
| M | internal/ | 7 | +++++-- |
| M | internal/ | 8 | ++++++-- |
@@ -28,6 +28,10 @@ it back in its format.
2828 | JSON `.json` | A list of records (or records one after another, as NDJSON): keys become the header row, numbers, booleans and text keep their types, nested lists and records are their text | The sheet shown as a list of records named by its first row, numbers as numbers |2929 | Nushell `.nuon` | A nushell table with its types: file sizes, durations and dates become numbers in the Size, Duration and Date time formats; see [Nushell](../terminal/nushell.md#types) | The sheet shown as a nushell table, first row as column names, types kept by the cells' formats |3030 31+CSV, TSV, JSON and NUON downloads hold the rows a filter shows, as32+Sheets copies a filtered range; XLSX keeps every row, the hidden ones33+hidden.34+3135 Formats other than XLSX import as one sheet named after the file (or the3236 SQLite table). A table can also come in on standard input, and go back3337 out on standard output: see [Nushell and pipelines](../terminal/nushell.md).@@ -55,9 +55,9 @@ standard output:
5555 without asking. They're in the menus and the palette only with5656 `--pipe`.5757 58-The sheet is its used range from A1: every row, including rows a filter59-hides. A selection is sent as selected, and its first row names the60-columns. Quitting without sending writes nothing and exits with status58+The sheet is its used range from A1. A selection is sent as selected,59+and its first row names the columns. Either way, rows a filter hides60+stay behind, as Sheets copies a filtered range. Quitting without sending writes nothing and exits with status6161 1, so the pipeline stops rather than carrying on with nothing.6262 6363 The table goes out in the format it came in (NUON, JSON, CSV or TSV);@@ -156,6 +156,23 @@ func TestEncodeKeepsTypes(t *testing.T) {
156156 }157157 }158158 159+// Text formats send the rows a filter shows, as Sheets copies a filtered160+// range.161+func TestEncodeFiltered(t *testing.T) {162+ s := build(t, map[string]string{"A1": "name", "B1": "n", "A2": "a", "B2": "1", "A3": "b", "B3": "2", "A4": "c", "B4": "3"})163+ s.CreateFilter(sheet.Rect{To: addr(t, "B4")})164+ s.FilterColumn(0, sheet.Criteria{Hidden: []string{"b"}})165+ if got := encode(t, s, NUON); got != "[[name, n]; [a, 1],\n[c, 3]]\n" {166+ t.Errorf("NUON %q", got)167+ }168+ if got := encode(t, s, CSV); got != "name,n\na,1\nc,3\n" {169+ t.Errorf("CSV %q", got)170+ }171+ if got := encode(t, s, JSON); strings.Contains(got, `"b"`) {172+ t.Errorf("JSON %q", got)173+ }174+}175+159176 // TestNUONRoundTrip reads a table and writes it back as the same NUON.160177 func TestNUONRoundTrip(t *testing.T) {161178 inZone(t, mountain)@@ -124,13 +124,16 @@ func snapColumns(snap *Snapshot) []string {
124124 return cols125125 }126126 127-// snapRecords yields the values of each row after the first. The slice128-// is reused from row to row.127+// snapRecords yields the values of each row after the first that the128+// filter shows. The slice is reused from row to row.129129 func snapRecords(snap *Snapshot, n int) func(yield func([]nuon.Value) bool) {130130 return func(yield func([]nuon.Value) bool) {131131 r, loc := snap.Range, zone()132132 row := make([]nuon.Value, n)133133 for y := r.From.Row + 1; y <= r.To.Row; y++ {134+ if snap.HiddenRows[y] {135+ continue136+ }134137 for x := r.From.Col; x <= r.To.Col; x++ {135138 c, ok := snap.Cells[sheet.Addr{Col: x, Row: y}]136139 row[x-r.From.Col] = nuon.NullValue()@@ -220,13 +220,17 @@ func excelRange(ws string, r sheet.Rect) string {
220220 }221221 222222 // textRows yields the snapshot's displayed text row by row across its223-// range as shown in its locale, for text formats. The slice is reused224-// from row to row.223+// range as shown in its locale, for text formats: the rows the filter224+// shows, as Sheets copies a filtered range. The slice is reused from row225+// to row.225226 func (s *Snapshot) textRows() iter.Seq[[]string] {226227 return func(yield func([]string) bool) {227228 r := s.Range228229 line := make([]string, r.To.Col-r.From.Col+1)229230 for row := r.From.Row; row <= r.To.Row; row++ {231+ if s.HiddenRows[row] {232+ continue233+ }230234 for col := r.From.Col; col <= r.To.Col; col++ {231235 line[col-r.From.Col] = ""232236 if c, ok := s.Cells[sheet.Addr{Col: col, Row: row}]; ok {