Skip to content
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## 0.20.1 - Unreleased

### Added

- Docs: add `docs table-column-width` to set fixed native table column widths or reset columns to evenly distributed sizing. (#631) — thanks @sebsnyk.

### Fixed

## 0.20.0 - 2026-05-30
Expand Down
1 change: 1 addition & 0 deletions docs/commands.generated.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ Generated from `gog schema --json`.
- [`gog docs (doc) rename-tab <docId> [flags]`](commands/gog-docs-rename-tab.md) - Rename a tab in a Google Doc
- [`gog docs (doc) sed <docId> [<expression>] [flags]`](commands/gog-docs-sed.md) - Regex find/replace (sed-style: s/pattern/replacement/g)
- [`gog docs (doc) structure (struct) <docId> [flags]`](commands/gog-docs-structure.md) - Show document structure with numbered paragraphs
- [`gog docs (doc) table-column-width (table-width,column-width) <docId> [flags]`](commands/gog-docs-table-column-width.md) - Set or reset native table column widths
- [`gog docs (doc) tabs <command>`](commands/gog-docs-tabs.md) - Manage Google Doc tabs
- [`gog docs (doc) tabs add (create,new) <docId> [flags]`](commands/gog-docs-tabs-add.md) - Add a tab to a Google Doc
- [`gog docs (doc) tabs delete (rm,remove,del) <docId> [flags]`](commands/gog-docs-tabs-delete.md) - Delete a tab from a Google Doc
Expand Down
3 changes: 2 additions & 1 deletion docs/commands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Every `gog` command has a generated docs page. The source of truth is the live CLI schema; run `make docs-commands` after changing command names, flags, help text, aliases, or arguments.

Generated pages: 581.
Generated pages: 582.

## Top-level Commands

Expand Down Expand Up @@ -304,6 +304,7 @@ Generated pages: 581.
- [gog docs rename-tab](gog-docs-rename-tab.md) - Rename a tab in a Google Doc
- [gog docs sed](gog-docs-sed.md) - Regex find/replace (sed-style: s/pattern/replacement/g)
- [gog docs structure](gog-docs-structure.md) - Show document structure with numbered paragraphs
- [gog docs table-column-width](gog-docs-table-column-width.md) - Set or reset native table column widths
- [gog docs tabs](gog-docs-tabs.md) - Manage Google Doc tabs
- [gog docs tabs add](gog-docs-tabs-add.md) - Add a tab to a Google Doc
- [gog docs tabs delete](gog-docs-tabs-delete.md) - Delete a tab from a Google Doc
Expand Down
50 changes: 50 additions & 0 deletions docs/commands/gog-docs-table-column-width.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# `gog docs table-column-width`

> Generated from `gog schema --json`. Do not edit this page by hand; run `make docs-commands`.

Set or reset native table column widths

## Usage

```bash
gog docs (doc) table-column-width (table-width,column-width) <docId> [flags]
```

## Parent

- [gog docs](gog-docs.md)

## Flags

| Flag | Type | Default | Help |
| --- | --- | --- | --- |
| `--access-token` | `string` | | Use provided access token directly (bypasses stored refresh tokens; token expires in ~1h) |
| `-a`<br>`--account`<br>`--acct` | `string` | | Account email for API commands (gmail/calendar/chat/classroom/drive/drivelabels/docs/slides/contacts/tasks/people/sheets/forms/sites/appscript/analytics/searchconsole/ads/photos) |
| `--client` | `string` | | OAuth client name (selects stored credentials + token bucket) |
| `--col` | `int` | | 1-based column number. Omit with --evenly-distributed to reset all columns. |
| `--color` | `string` | auto | Color output: auto\|always\|never |
| `--disable-commands` | `string` | | Comma-separated list of disabled commands; dot paths allowed |
| `-n`<br>`--dry-run`<br>`--dryrun`<br>`--noop`<br>`--preview` | `bool` | | Do not make changes; print intended actions and exit successfully |
| `--enable-commands` | `string` | | Comma-separated list of enabled command prefixes; dot paths allowed (restricts CLI) |
| `--enable-commands-exact` | `string` | | Comma-separated list of exact enabled commands; dot paths allowed and parent commands do not enable children |
| `--evenly-distributed`<br>`--even` | `bool` | | Reset selected column, or all columns when --col is omitted, to Docs-managed equal width |
| `-y`<br>`--force`<br>`--assume-yes`<br>`--yes` | `bool` | | Skip confirmations for destructive commands |
| `--gmail-no-send` | `bool` | false | Block Gmail send operations (agent safety) |
| `-h`<br>`--help` | `kong.helpFlag` | | Show context-sensitive help. |
| `--home` | `string` | | Override gogcli config/data/state/cache root (equivalent to GOG_HOME) |
| `-j`<br>`--json`<br>`--machine` | `bool` | false | Output JSON to stdout (best for scripting) |
| `--no-input`<br>`--non-interactive`<br>`--noninteractive` | `bool` | | Never prompt; fail instead (useful for CI) |
| `-p`<br>`--plain`<br>`--tsv` | `bool` | false | Output stable, parseable text to stdout (TSV; no colors) |
| `--results-only` | `bool` | | In JSON mode, emit only the primary result (drops envelope fields like nextPageToken) |
| `--select`<br>`--pick`<br>`--project` | `string` | | In JSON mode, select comma-separated fields (best-effort; supports dot paths). Desire path: use --fields for most commands. |
| `--tab` | `string` | | Target a specific tab by title or ID (see docs list-tabs) |
| `--table-index` | `int` | 1 | 1-based table index in document order; negative indexes count from the end |
| `-v`<br>`--verbose` | `bool` | | Enable verbose logging |
| `--version` | `kong.VersionFlag` | | Print version and exit |
| `--width` | `float64` | | Fixed column width in points (minimum 5pt) |
| `--wrap-untrusted` | `bool` | false | In JSON/raw output, wrap fetched text fields in external untrusted-content markers |

## See Also

- [gog docs](gog-docs.md)
- [Command index](README.md)
1 change: 1 addition & 0 deletions docs/commands/gog-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ gog docs (doc) <command> [flags]
- [gog docs rename-tab](gog-docs-rename-tab.md) - Rename a tab in a Google Doc
- [gog docs sed](gog-docs-sed.md) - Regex find/replace (sed-style: s/pattern/replacement/g)
- [gog docs structure](gog-docs-structure.md) - Show document structure with numbered paragraphs
- [gog docs table-column-width](gog-docs-table-column-width.md) - Set or reset native table column widths
- [gog docs tabs](gog-docs-tabs.md) - Manage Google Doc tabs
- [gog docs update](gog-docs-update.md) - Insert or replace text at a specific index or range in a Google Doc
- [gog docs write](gog-docs-write.md) - Write content to a Google Doc
Expand Down
11 changes: 11 additions & 0 deletions docs/docs-editing.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,21 @@ gog docs cell-update <docId> --table-index 1 --row 2 --col 3 \
Coordinates are 1-based. `--tab` targets a specific tab, and `--append` inserts
at the end of the cell instead of replacing its current content.

Set or reset native table column widths after inserting or importing tables:

```bash
gog docs table-column-width <docId> --table-index 1 --col 1 --width 120
gog docs table-column-width <docId> --table-index 1 --evenly-distributed
```

`--width` uses points and requires `--col`. `--evenly-distributed` resets one
column when `--col` is supplied, or all columns when it is omitted.

Command page:

- [`gog docs insert-table`](commands/gog-docs-insert-table.md)
- [`gog docs cell-update`](commands/gog-docs-cell-update.md)
- [`gog docs table-column-width`](commands/gog-docs-table-column-width.md)

## Tabs

Expand Down
63 changes: 32 additions & 31 deletions internal/cmd/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,38 @@ import (
var newDocsService = googleapi.NewDocs

type DocsCmd struct {
Export DocsExportCmd `cmd:"" name:"export" aliases:"download,dl" help:"Export a Google Doc (pdf|docx|txt|md|html)"`
Info DocsInfoCmd `cmd:"" name:"info" aliases:"get,show" help:"Get Google Doc metadata"`
Create DocsCreateCmd `cmd:"" name:"create" aliases:"add,new" help:"Create a Google Doc"`
Copy DocsCopyCmd `cmd:"" name:"copy" aliases:"cp,duplicate" help:"Copy a Google Doc"`
Cat DocsCatCmd `cmd:"" name:"cat" aliases:"text,read" help:"Print a Google Doc as plain text"`
Comments DocsCommentsCmd `cmd:"" name:"comments" help:"Manage comments on files"`
Tabs DocsTabsCmd `cmd:"" name:"tabs" help:"Manage Google Doc tabs"`
AddTab DocsAddTabCmd `cmd:"" name:"add-tab" help:"Add a tab to a Google Doc"`
RenameTab DocsRenameTabCmd `cmd:"" name:"rename-tab" help:"Rename a tab in a Google Doc"`
DeleteTab DocsDeleteTabCmd `cmd:"" name:"delete-tab" help:"Delete a tab from a Google Doc"`
ListTabs DocsListTabsCmd `cmd:"" name:"list-tabs" help:"List all tabs in a Google Doc"`
Write DocsWriteCmd `cmd:"" name:"write" help:"Write content to a Google Doc"`
Insert DocsInsertCmd `cmd:"" name:"insert" help:"Insert text at a specific position"`
InsertTable DocsInsertTableCmd `cmd:"" name:"insert-table" help:"Insert a native table at a specific position (or end-of-doc with --at-end), optionally populated via --values-json"`
CellUpdate DocsCellUpdateCmd `cmd:"" name:"cell-update" aliases:"update-cell" help:"Replace or append content inside a specific table cell"`
CellStyle DocsCellStyleCmd `cmd:"" name:"cell-style" help:"Apply table cell background and text styling"`
InsertImage DocsInsertImageCmd `cmd:"" name:"insert-image" help:"Upload a local image and insert it into a Google Doc"`
InsertPerson DocsInsertPersonCmd `cmd:"" name:"insert-person" help:"Insert a native person smart chip"`
InsertFileChip DocsInsertFileChipCmd `cmd:"" name:"insert-file-chip" aliases:"insert-rich-link" help:"Insert a native Drive file smart chip"`
InsertDateChip DocsInsertDateChipCmd `cmd:"" name:"insert-date-chip" help:"Insert a native date smart chip"`
InsertPageBreak DocsInsertPageBreakCmd `cmd:"" name:"insert-page-break" aliases:"page-break,pb" help:"Insert a page break at a specific position (or end-of-doc with --at-end)"`
Delete DocsDeleteCmd `cmd:"" name:"delete" help:"Delete text range from document"`
FindReplace DocsFindReplaceCmd `cmd:"" name:"find-replace" help:"Find and replace text. Supports plain text or markdown with images; use --first for a single occurrence."`
Update DocsUpdateCmd `cmd:"" name:"update" help:"Insert or replace text at a specific index or range in a Google Doc"`
Edit DocsEditCmd `cmd:"" name:"edit" help:"Find and replace text in a Google Doc"`
Format DocsFormatCmd `cmd:"" name:"format" help:"Apply text or paragraph formatting to a Google Doc"`
Sed DocsSedCmd `cmd:"" name:"sed" help:"Regex find/replace (sed-style: s/pattern/replacement/g)"`
Clear DocsClearCmd `cmd:"" name:"clear" help:"Clear all content from a Google Doc"`
Structure DocsStructureCmd `cmd:"" name:"structure" aliases:"struct" help:"Show document structure with numbered paragraphs"`
Raw DocsRawCmd `cmd:"" name:"raw" help:"Dump raw Google Docs API response as JSON (Documents.Get; lossless; for scripting and LLM consumption)"`
PageLayout DocsPageLayoutCmd `cmd:"" name:"page-layout" aliases:"set-page-layout,page-setup" help:"Set page layout (pageless|pages) on an existing Google Doc"`
Export DocsExportCmd `cmd:"" name:"export" aliases:"download,dl" help:"Export a Google Doc (pdf|docx|txt|md|html)"`
Info DocsInfoCmd `cmd:"" name:"info" aliases:"get,show" help:"Get Google Doc metadata"`
Create DocsCreateCmd `cmd:"" name:"create" aliases:"add,new" help:"Create a Google Doc"`
Copy DocsCopyCmd `cmd:"" name:"copy" aliases:"cp,duplicate" help:"Copy a Google Doc"`
Cat DocsCatCmd `cmd:"" name:"cat" aliases:"text,read" help:"Print a Google Doc as plain text"`
Comments DocsCommentsCmd `cmd:"" name:"comments" help:"Manage comments on files"`
Tabs DocsTabsCmd `cmd:"" name:"tabs" help:"Manage Google Doc tabs"`
AddTab DocsAddTabCmd `cmd:"" name:"add-tab" help:"Add a tab to a Google Doc"`
RenameTab DocsRenameTabCmd `cmd:"" name:"rename-tab" help:"Rename a tab in a Google Doc"`
DeleteTab DocsDeleteTabCmd `cmd:"" name:"delete-tab" help:"Delete a tab from a Google Doc"`
ListTabs DocsListTabsCmd `cmd:"" name:"list-tabs" help:"List all tabs in a Google Doc"`
Write DocsWriteCmd `cmd:"" name:"write" help:"Write content to a Google Doc"`
Insert DocsInsertCmd `cmd:"" name:"insert" help:"Insert text at a specific position"`
InsertTable DocsInsertTableCmd `cmd:"" name:"insert-table" help:"Insert a native table at a specific position (or end-of-doc with --at-end), optionally populated via --values-json"`
CellUpdate DocsCellUpdateCmd `cmd:"" name:"cell-update" aliases:"update-cell" help:"Replace or append content inside a specific table cell"`
CellStyle DocsCellStyleCmd `cmd:"" name:"cell-style" help:"Apply table cell background and text styling"`
TableColumnWidth DocsTableColumnWidthCmd `cmd:"" name:"table-column-width" aliases:"table-width,column-width" help:"Set or reset native table column widths"`
InsertImage DocsInsertImageCmd `cmd:"" name:"insert-image" help:"Upload a local image and insert it into a Google Doc"`
InsertPerson DocsInsertPersonCmd `cmd:"" name:"insert-person" help:"Insert a native person smart chip"`
InsertFileChip DocsInsertFileChipCmd `cmd:"" name:"insert-file-chip" aliases:"insert-rich-link" help:"Insert a native Drive file smart chip"`
InsertDateChip DocsInsertDateChipCmd `cmd:"" name:"insert-date-chip" help:"Insert a native date smart chip"`
InsertPageBreak DocsInsertPageBreakCmd `cmd:"" name:"insert-page-break" aliases:"page-break,pb" help:"Insert a page break at a specific position (or end-of-doc with --at-end)"`
Delete DocsDeleteCmd `cmd:"" name:"delete" help:"Delete text range from document"`
FindReplace DocsFindReplaceCmd `cmd:"" name:"find-replace" help:"Find and replace text. Supports plain text or markdown with images; use --first for a single occurrence."`
Update DocsUpdateCmd `cmd:"" name:"update" help:"Insert or replace text at a specific index or range in a Google Doc"`
Edit DocsEditCmd `cmd:"" name:"edit" help:"Find and replace text in a Google Doc"`
Format DocsFormatCmd `cmd:"" name:"format" help:"Apply text or paragraph formatting to a Google Doc"`
Sed DocsSedCmd `cmd:"" name:"sed" help:"Regex find/replace (sed-style: s/pattern/replacement/g)"`
Clear DocsClearCmd `cmd:"" name:"clear" help:"Clear all content from a Google Doc"`
Structure DocsStructureCmd `cmd:"" name:"structure" aliases:"struct" help:"Show document structure with numbered paragraphs"`
Raw DocsRawCmd `cmd:"" name:"raw" help:"Dump raw Google Docs API response as JSON (Documents.Get; lossless; for scripting and LLM consumption)"`
PageLayout DocsPageLayoutCmd `cmd:"" name:"page-layout" aliases:"set-page-layout,page-setup" help:"Set page layout (pageless|pages) on an existing Google Doc"`
}

type DocsTabsCmd struct {
Expand Down
80 changes: 80 additions & 0 deletions internal/cmd/docs_remaining_features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,86 @@ func TestDocsCellStyleBuildsTableAndTextRequests(t *testing.T) {
}
}

func TestDocsTableColumnWidthBuildsFixedRequest(t *testing.T) {
cmd := &DocsTableColumnWidthCmd{Col: 2, Width: 120}
req, err := cmd.buildRequest(5, 3, "tab-1")
if err != nil {
t.Fatalf("buildRequest: %v", err)
}
got := req.UpdateTableColumnProperties
if got == nil {
t.Fatalf("missing update request: %#v", req)
}
if got.TableStartLocation.Index != 5 || got.TableStartLocation.TabId != "tab-1" {
t.Fatalf("table start = %#v", got.TableStartLocation)
}
if len(got.ColumnIndices) != 1 || got.ColumnIndices[0] != 1 {
t.Fatalf("column indices = %#v", got.ColumnIndices)
}
if got.Fields != "width,widthType" {
t.Fatalf("fields = %q", got.Fields)
}
props := got.TableColumnProperties
if props.WidthType != "FIXED_WIDTH" || props.Width == nil || props.Width.Magnitude != 120 || props.Width.Unit != "PT" {
t.Fatalf("properties = %#v", props)
}
}

func TestDocsTableColumnWidthBuildsEvenAllColumnsRequest(t *testing.T) {
cmd := &DocsTableColumnWidthCmd{EvenlyDistributed: true}
req, err := cmd.buildRequest(7, 2, "")
if err != nil {
t.Fatalf("buildRequest: %v", err)
}
got := req.UpdateTableColumnProperties
if got == nil {
t.Fatalf("missing update request: %#v", req)
}
if len(got.ColumnIndices) != 0 {
t.Fatalf("column indices = %#v", got.ColumnIndices)
}
if got.Fields != "widthType" || got.TableColumnProperties.WidthType != "EVENLY_DISTRIBUTED" {
t.Fatalf("unexpected request: %#v", got)
}
}

func TestDocsTableColumnWidthValidation(t *testing.T) {
tests := []struct {
name string
cmd DocsTableColumnWidthCmd
want string
}{
{
name: "missing mode",
cmd: DocsTableColumnWidthCmd{TableIndex: 1, Col: 1},
want: "set --width or --evenly-distributed",
},
{
name: "conflicting mode",
cmd: DocsTableColumnWidthCmd{TableIndex: 1, Col: 1, Width: 120, EvenlyDistributed: true},
want: "mutually exclusive",
},
{
name: "fixed requires column",
cmd: DocsTableColumnWidthCmd{TableIndex: 1, Width: 120},
want: "--col is required",
},
{
name: "minimum width",
cmd: DocsTableColumnWidthCmd{TableIndex: 1, Col: 1, Width: 4.9},
want: "--width must be >= 5pt",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.cmd.validate()
if err == nil || !strings.Contains(err.Error(), tt.want) {
t.Fatalf("expected %q error, got %v", tt.want, err)
}
})
}
}

func TestDocsSmartChipCommandsBuildRequests(t *testing.T) {
person := &docs.Request{InsertPerson: &docs.InsertPersonRequest{PersonProperties: &docs.PersonProperties{Email: "a@example.com"}}}
setDocsInsertRequestLocation(person, 7, "tab-1")
Expand Down
Loading
Loading