merge main

bashbunni created

Change summary

.gitattributes                                                                              |   1 
.github/workflows/nightly.yml                                                               |  19 
.gitignore                                                                                  |   1 
.goreleaser.yml                                                                             |   4 
cmd/root.go                                                                                 | 165 
go.mod                                                                                      |  32 
go.sum                                                                                      |  24 
internal/app/app.go                                                                         | 230 
internal/app/lsp.go                                                                         |   9 
internal/config/config.go                                                                   | 126 
internal/config/init.go                                                                     |   8 
internal/config/load.go                                                                     | 122 
internal/config/load_test.go                                                                |   9 
internal/config/resolve.go                                                                  |   6 
internal/format/format.go                                                                   |  99 
internal/format/spinner.go                                                                  | 102 
internal/fsext/fileutil.go                                                                  |  13 
internal/fur/client/client.go                                                               |   2 
internal/llm/agent/agent.go                                                                 |   6 
internal/llm/prompt/initialize.go                                                           |  14 
internal/llm/prompt/prompt.go                                                               |  53 
internal/llm/prompt/prompt_test.go                                                          | 113 
internal/llm/provider/openai.go                                                             |  50 
internal/llm/tools/bash.go                                                                  | 127 
internal/lsp/transport.go                                                                   |  41 
internal/lsp/watcher/watcher.go                                                             | 153 
internal/shell/command_block_test.go                                                        | 123 
internal/shell/shell.go                                                                     |  82 
internal/tui/components/chat/chat.go                                                        |  38 
internal/tui/components/chat/editor/editor.go                                               |  75 
internal/tui/components/chat/editor/keys.go                                                 |  13 
internal/tui/components/chat/header/header.go                                               |  17 
internal/tui/components/chat/messages/messages.go                                           |  12 
internal/tui/components/chat/messages/renderer.go                                           |  31 
internal/tui/components/chat/messages/tool.go                                               |   9 
internal/tui/components/chat/sidebar/sidebar.go                                             |  62 
internal/tui/components/chat/splash/keys.go                                                 |  41 
internal/tui/components/chat/splash/splash.go                                               | 584 
internal/tui/components/completions/completions.go                                          |  33 
internal/tui/components/completions/item.go                                                 |   1 
internal/tui/components/completions/keys.go                                                 |   2 
internal/tui/components/core/core.go                                                        |  59 
internal/tui/components/core/layout/container.go                                            | 263 
internal/tui/components/core/layout/layout.go                                               |   7 
internal/tui/components/core/layout/split.go                                                | 380 
internal/tui/components/core/list/list.go                                                   |   6 
internal/tui/components/core/status/status.go                                               |   3 
internal/tui/components/dialogs/commands/commands.go                                        |  11 
internal/tui/components/dialogs/commands/item.go                                            |  20 
internal/tui/components/dialogs/init/init.go                                                | 214 
internal/tui/components/dialogs/init/keys.go                                                |  69 
internal/tui/components/dialogs/models/apikey.go                                            |  96 
internal/tui/components/dialogs/models/list.go                                              | 202 
internal/tui/components/dialogs/models/models.go                                            | 153 
internal/tui/components/dialogs/permissions/keys.go                                         |   4 
internal/tui/components/dialogs/permissions/permissions.go                                  |  26 
internal/tui/components/logo/logo.go                                                        |  13 
internal/tui/exp/diffview/diffview.go                                                       |   6 
internal/tui/exp/diffview/testdata/TestDiffView/Split/CustomContextLines/DarkMode.golden    |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Split/CustomContextLines/LightMode.golden   |  13 
internal/tui/exp/diffview/testdata/TestDiffView/Split/Default/DarkMode.golden               |  14 
internal/tui/exp/diffview/testdata/TestDiffView/Split/Default/LightMode.golden              |  14 
internal/tui/exp/diffview/testdata/TestDiffView/Split/LargeWidth/DarkMode.golden            |  30 
internal/tui/exp/diffview/testdata/TestDiffView/Split/LargeWidth/LightMode.golden           |  12 
internal/tui/exp/diffview/testdata/TestDiffView/Split/MultipleHunks/DarkMode.golden         |  30 
internal/tui/exp/diffview/testdata/TestDiffView/Split/MultipleHunks/LightMode.golden        |  12 
internal/tui/exp/diffview/testdata/TestDiffView/Split/Narrow/DarkMode.golden                |   8 
internal/tui/exp/diffview/testdata/TestDiffView/Split/Narrow/LightMode.golden               |   8 
internal/tui/exp/diffview/testdata/TestDiffView/Split/NoSyntaxHighlight/DarkMode.golden     |  30 
internal/tui/exp/diffview/testdata/TestDiffView/Split/NoSyntaxHighlight/LightMode.golden    |  30 
internal/tui/exp/diffview/testdata/TestDiffView/Split/SmallWidth/DarkMode.golden            |  30 
internal/tui/exp/diffview/testdata/TestDiffView/Split/SmallWidth/LightMode.golden           |  30 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/CustomContextLines/DarkMode.golden  |  34 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/CustomContextLines/LightMode.golden |  34 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/Default/DarkMode.golden             |  16 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/Default/LightMode.golden            |  16 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/LargeWidth/DarkMode.golden          |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/LargeWidth/LightMode.golden         |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/MultipleHunks/DarkMode.golden       |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/MultipleHunks/LightMode.golden      |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/Narrow/DarkMode.golden              |  14 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/Narrow/LightMode.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/NoSyntaxHighlight/DarkMode.golden   |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/NoSyntaxHighlight/LightMode.golden  |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/SmallWidth/DarkMode.golden          |  32 
internal/tui/exp/diffview/testdata/TestDiffView/Unified/SmallWidth/LightMode.golden         |  32 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf001.golden              |   2 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf002.golden              |   4 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf003.golden              |   6 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf004.golden              |   8 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf005.golden              |  10 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf006.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf007.golden              |  14 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf008.golden              |  16 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf009.golden              |  18 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf010.golden              |  20 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf011.golden              |  22 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf012.golden              |  24 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf013.golden              |  26 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf014.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf015.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf016.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf017.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf018.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf019.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf020.golden              |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf001.golden            |   2 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf002.golden            |   4 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf003.golden            |   6 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf004.golden            |   8 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf005.golden            |  10 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf006.golden            |  12 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf007.golden            |  14 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf008.golden            |  16 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf009.golden            |  18 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf010.golden            |  20 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf011.golden            |  22 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf012.golden            |  24 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf013.golden            |  26 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf014.golden            |  28 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf015.golden            |  30 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf016.golden            |  32 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf017.golden            |  34 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf018.golden            |  36 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf019.golden            |  38 
internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf020.golden            |  40 
internal/tui/exp/diffview/testdata/TestDiffViewTabs/Split.golden                            |  12 
internal/tui/exp/diffview/testdata/TestDiffViewTabs/Unified.golden                          |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf001.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf002.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf003.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf004.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf005.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf006.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf007.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf008.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf009.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf010.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf011.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf012.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf013.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf014.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf015.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf016.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf017.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf018.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf019.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf020.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf021.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf022.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf023.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf024.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf025.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf026.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf027.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf028.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf029.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf030.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf031.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf032.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf033.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf034.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf035.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf036.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf037.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf038.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf039.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf040.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf041.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf042.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf043.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf044.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf045.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf046.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf047.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf048.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf049.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf050.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf051.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf052.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf053.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf054.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf055.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf056.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf057.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf058.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf059.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf060.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf061.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf062.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf063.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf064.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf065.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf066.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf067.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf068.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf069.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf070.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf071.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf072.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf073.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf074.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf075.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf076.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf077.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf078.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf079.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf080.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf081.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf082.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf083.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf084.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf085.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf086.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf087.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf088.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf089.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf090.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf091.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf092.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf093.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf094.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf095.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf096.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf097.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf098.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf099.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf100.golden                |  30 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf101.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf102.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf103.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf104.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf105.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf106.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf107.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf108.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf109.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf110.golden                |  12 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf001.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf002.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf003.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf004.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf005.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf006.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf007.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf008.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf009.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf010.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf011.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf012.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf013.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf014.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf015.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf016.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf017.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf018.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf019.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf020.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf021.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf022.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf023.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf024.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf025.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf026.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf027.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf028.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf029.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf030.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf031.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf032.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf033.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf034.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf035.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf036.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf037.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf038.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf039.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf040.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf041.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf042.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf043.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf044.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf045.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf046.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf047.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf048.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf049.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf050.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf051.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf052.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf053.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf054.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf055.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf056.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf057.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf058.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf059.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf060.golden              |  32 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf00.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf01.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf02.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf03.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf04.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf05.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf06.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf07.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf08.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf09.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf10.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf11.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf12.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf13.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf14.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf15.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf16.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf17.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf18.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf19.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf20.golden             |  14 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf00.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf01.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf02.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf03.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf04.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf05.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf06.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf07.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf08.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf09.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf10.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf11.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf12.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf13.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf14.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf15.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf16.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf17.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf18.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf19.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf20.golden           |  16 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf00.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf01.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf02.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf03.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf04.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf05.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf06.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf07.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf08.golden             |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf09.golden             |   3 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf10.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf11.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf12.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf13.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf14.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf15.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf16.golden             |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf00.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf01.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf02.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf03.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf04.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf05.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf06.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf07.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf08.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf09.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf10.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf11.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf12.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf13.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf14.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf15.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf16.golden           |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf00.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf01.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf02.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf03.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf04.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf05.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf06.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf07.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf08.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf09.golden     |   3 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf10.golden     |   2 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf11.golden     |   1 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf12.golden     |   0 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf13.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf14.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf15.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf16.golden     |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf00.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf01.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf02.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf03.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf04.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf05.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf06.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf07.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf08.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf09.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf10.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf11.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf12.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf13.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf14.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf15.golden   |  10 
internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf16.golden   |  10 
internal/tui/keys.go                                                                        |  63 
internal/tui/page/chat/chat.go                                                              | 918 
internal/tui/styles/crush.go                                                                |   2 
internal/tui/tui.go                                                                         |  49 
internal/tui/util/util.go                                                                   |   2 
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work.sum                         |  60 
vendor/github.com/charmbracelet/bubbles/v2/textarea/textarea.go                             |  28 
vendor/github.com/charmbracelet/bubbletea/v2/tea.go                                         |  19 
vendor/github.com/charmbracelet/fang/README.md                                              |   7 
vendor/github.com/charmbracelet/fang/fang.go                                                | 119 
vendor/github.com/charmbracelet/fang/help.go                                                | 298 
vendor/github.com/charmbracelet/fang/theme.go                                               |  52 
vendor/github.com/charmbracelet/lipgloss/v2/get.go                                          |  33 
vendor/github.com/charmbracelet/lipgloss/v2/set.go                                          |  27 
vendor/github.com/charmbracelet/lipgloss/v2/style.go                                        |  26 
vendor/github.com/charmbracelet/lipgloss/v2/unset.go                                        |   7 
vendor/github.com/charmbracelet/x/exp/charmtone/charmtone.go                                |  58 
vendor/github.com/mark3labs/mcp-go/client/client.go                                         | 102 
vendor/github.com/mark3labs/mcp-go/client/http.go                                           |   7 
vendor/github.com/mark3labs/mcp-go/client/sampling.go                                       |  20 
vendor/github.com/mark3labs/mcp-go/client/stdio.go                                          |  22 
vendor/github.com/mark3labs/mcp-go/client/transport/inprocess.go                            |   4 
vendor/github.com/mark3labs/mcp-go/client/transport/interface.go                            |  20 
vendor/github.com/mark3labs/mcp-go/client/transport/sse.go                                  |   6 
vendor/github.com/mark3labs/mcp-go/client/transport/stdio.go                                | 204 
vendor/github.com/mark3labs/mcp-go/client/transport/streamable_http.go                      | 343 
vendor/github.com/mark3labs/mcp-go/mcp/tools.go                                             | 106 
vendor/github.com/mark3labs/mcp-go/mcp/types.go                                             |  21 
vendor/github.com/mark3labs/mcp-go/mcp/utils.go                                             |  21 
vendor/github.com/mark3labs/mcp-go/server/sampling.go                                       |  37 
vendor/github.com/mark3labs/mcp-go/server/stdio.go                                          | 180 
vendor/github.com/mark3labs/mcp-go/server/streamable_http.go                                |   6 
vendor/modules.txt                                                                          |  20 
441 files changed, 8,015 insertions(+), 6,518 deletions(-)

Detailed changes

.github/workflows/nightly.yml 🔗

@@ -6,7 +6,26 @@ on:
   workflow_dispatch: # allows manual triggering
 
 jobs:
+  check:
+    runs-on: ubuntu-latest
+    outputs:
+      should_run: ${{ steps.check.outputs.should_run }}
+    steps:
+      - uses: actions/checkout@v4
+        with:
+          fetch-depth: 1
+      - id: check
+        env:
+          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+        run: |
+          if gh run list --workflow nightly.yml -c $(git rev-parse HEAD) -s success | grep 'completed'; then
+            echo "should_run=false" >> $GITHUB_OUTPUT
+          else
+            echo "should_run=true" >> $GITHUB_OUTPUT
+          fi
   nightly:
+    needs: check
+    if: needs.check.outputs.should_run == 'true'
     uses: charmbracelet/meta/.github/workflows/nightly.yml@main
     secrets:
       goreleaser_key: ${{ secrets.GORELEASER_KEY }}

.gitignore 🔗

@@ -16,6 +16,7 @@
 
 # Go workspace file
 go.work
+go.work.sum
 
 # IDE specific files
 .idea/

.goreleaser.yml 🔗

@@ -36,8 +36,8 @@ before:
     - sh -c 'go run . completion fish >./completions/crush.fish'
     - sh -c 'go run . man | gzip -c >./manpages/crush.1.gz'
 
-gomod:
-  proxy: true
+# gomod:
+#   proxy: true
 
 builds:
   - env:

cmd/root.go 🔗

@@ -6,17 +6,14 @@ import (
 	"io"
 	"log/slog"
 	"os"
-	"sync"
 	"time"
 
 	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/charmbracelet/crush/internal/app"
 	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/db"
-	"github.com/charmbracelet/crush/internal/format"
 	"github.com/charmbracelet/crush/internal/llm/agent"
 	"github.com/charmbracelet/crush/internal/log"
-	"github.com/charmbracelet/crush/internal/pubsub"
 	"github.com/charmbracelet/crush/internal/tui"
 	"github.com/charmbracelet/crush/internal/version"
 	"github.com/charmbracelet/fang"
@@ -54,14 +51,8 @@ to assist developers in writing, debugging, and understanding code directly from
 		debug, _ := cmd.Flags().GetBool("debug")
 		cwd, _ := cmd.Flags().GetString("cwd")
 		prompt, _ := cmd.Flags().GetString("prompt")
-		outputFormat, _ := cmd.Flags().GetString("output-format")
 		quiet, _ := cmd.Flags().GetBool("quiet")
 
-		// Validate format option
-		if !format.IsValid(outputFormat) {
-			return fmt.Errorf("invalid format option: %s\n%s", outputFormat, format.GetHelpText())
-		}
-
 		if cwd != "" {
 			err := os.Chdir(cwd)
 			if err != nil {
@@ -81,9 +72,7 @@ to assist developers in writing, debugging, and understanding code directly from
 			return err
 		}
 
-		// Create main context for the application
-		ctx, cancel := context.WithCancel(context.Background())
-		defer cancel()
+		ctx := cmd.Context()
 
 		// Connect DB, this will also run migrations
 		conn, err := db.Connect(ctx, cfg.Options.DataDirectory)
@@ -111,7 +100,7 @@ to assist developers in writing, debugging, and understanding code directly from
 		// Non-interactive mode
 		if prompt != "" {
 			// Run non-interactive flow using the App method
-			return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
+			return app.RunNonInteractive(ctx, prompt, quiet)
 		}
 
 		// Set up the TUI
@@ -124,76 +113,17 @@ to assist developers in writing, debugging, and understanding code directly from
 			tea.WithFilter(tui.MouseEventFilter), // Filter mouse events based on focus state
 		)
 
-		// Setup the subscriptions, this will send services events to the TUI
-		ch, cancelSubs := setupSubscriptions(app, ctx)
-
-		// Create a context for the TUI message handler
-		tuiCtx, tuiCancel := context.WithCancel(ctx)
-		var tuiWg sync.WaitGroup
-		tuiWg.Add(1)
-
-		// Set up message handling for the TUI
-		go func() {
-			defer tuiWg.Done()
-			defer log.RecoverPanic("TUI-message-handler", func() {
-				attemptTUIRecovery(program)
-			})
-
-			for {
-				select {
-				case <-tuiCtx.Done():
-					slog.Info("TUI message handler shutting down")
-					return
-				case msg, ok := <-ch:
-					if !ok {
-						slog.Info("TUI message channel closed")
-						return
-					}
-					program.Send(msg)
-				}
-			}
-		}()
-
-		// Cleanup function for when the program exits
-		cleanup := func() {
-			// Shutdown the app
-			app.Shutdown()
-
-			// Cancel subscriptions first
-			cancelSubs()
-
-			// Then cancel TUI message handler
-			tuiCancel()
+		go app.Subscribe(program)
 
-			// Wait for TUI message handler to finish
-			tuiWg.Wait()
-
-			slog.Info("All goroutines cleaned up")
-		}
-
-		// Run the TUI
-		result, err := program.Run()
-		cleanup()
-
-		if err != nil {
+		if _, err := program.Run(); err != nil {
 			slog.Error(fmt.Sprintf("TUI run error: %v", err))
 			return fmt.Errorf("TUI error: %v", err)
 		}
-
-		slog.Info(fmt.Sprintf("TUI exited with result: %v", result))
+		app.Shutdown()
 		return nil
 	},
 }
 
-// attemptTUIRecovery tries to recover the TUI after a panic
-func attemptTUIRecovery(program *tea.Program) {
-	slog.Info("Attempting to recover TUI after panic")
-
-	// We could try to restart the TUI or gracefully exit
-	// For now, we'll just quit the program to avoid further issues
-	program.Quit()
-}
-
 func initMCPTools(ctx context.Context, app *app.App, cfg *config.Config) {
 	go func() {
 		defer log.RecoverPanic("MCP-goroutine", nil)
@@ -208,86 +138,12 @@ func initMCPTools(ctx context.Context, app *app.App, cfg *config.Config) {
 	}()
 }
 
-func setupSubscriber[T any](
-	ctx context.Context,
-	wg *sync.WaitGroup,
-	name string,
-	subscriber func(context.Context) <-chan pubsub.Event[T],
-	outputCh chan<- tea.Msg,
-) {
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		defer log.RecoverPanic(fmt.Sprintf("subscription-%s", name), nil)
-
-		subCh := subscriber(ctx)
-
-		for {
-			select {
-			case event, ok := <-subCh:
-				if !ok {
-					slog.Info("subscription channel closed", "name", name)
-					return
-				}
-
-				var msg tea.Msg = event
-
-				select {
-				case outputCh <- msg:
-				case <-time.After(2 * time.Second):
-					slog.Warn("message dropped due to slow consumer", "name", name)
-				case <-ctx.Done():
-					slog.Info("subscription cancelled", "name", name)
-					return
-				}
-			case <-ctx.Done():
-				slog.Info("subscription cancelled", "name", name)
-				return
-			}
-		}
-	}()
-}
-
-func setupSubscriptions(app *app.App, parentCtx context.Context) (chan tea.Msg, func()) {
-	ch := make(chan tea.Msg, 100)
-
-	wg := sync.WaitGroup{}
-	ctx, cancel := context.WithCancel(parentCtx) // Inherit from parent context
-
-	setupSubscriber(ctx, &wg, "sessions", app.Sessions.Subscribe, ch)
-	setupSubscriber(ctx, &wg, "messages", app.Messages.Subscribe, ch)
-	setupSubscriber(ctx, &wg, "permissions", app.Permissions.Subscribe, ch)
-	setupSubscriber(ctx, &wg, "coderAgent", app.CoderAgent.Subscribe, ch)
-	setupSubscriber(ctx, &wg, "history", app.History.Subscribe, ch)
-
-	cleanupFunc := func() {
-		slog.Info("Cancelling all subscriptions")
-		cancel() // Signal all goroutines to stop
-
-		waitCh := make(chan struct{})
-		go func() {
-			defer log.RecoverPanic("subscription-cleanup", nil)
-			wg.Wait()
-			close(waitCh)
-		}()
-
-		select {
-		case <-waitCh:
-			slog.Info("All subscription goroutines completed successfully")
-			close(ch) // Only close after all writers are confirmed done
-		case <-time.After(5 * time.Second):
-			slog.Warn("Timed out waiting for some subscription goroutines to complete")
-			close(ch)
-		}
-	}
-	return ch, cleanupFunc
-}
-
 func Execute() {
 	if err := fang.Execute(
 		context.Background(),
 		rootCmd,
 		fang.WithVersion(version.Version),
+		fang.WithNotifySignal(os.Interrupt),
 	); err != nil {
 		os.Exit(1)
 	}
@@ -300,17 +156,8 @@ func init() {
 	rootCmd.Flags().BoolP("debug", "d", false, "Debug")
 	rootCmd.Flags().StringP("prompt", "p", "", "Prompt to run in non-interactive mode")
 
-	// Add format flag with validation logic
-	rootCmd.Flags().StringP("output-format", "f", format.Text.String(),
-		"Output format for non-interactive mode (text, json)")
-
 	// Add quiet flag to hide spinner in non-interactive mode
 	rootCmd.Flags().BoolP("quiet", "q", false, "Hide spinner in non-interactive mode")
-
-	// Register custom validation for the format flag
-	rootCmd.RegisterFlagCompletionFunc("output-format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
-		return format.SupportedFormats, cobra.ShellCompDirectiveNoFileComp
-	})
 }
 
 func maybePrependStdin(prompt string) (string, error) {

go.mod 🔗

@@ -2,9 +2,9 @@ module github.com/charmbracelet/crush
 
 go 1.24.3
 
-replace github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891
+replace github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595
 
-replace github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093
+replace github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb
 
 require (
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0
@@ -16,20 +16,20 @@ require (
 	github.com/aymanbagabas/go-udiff v0.3.1
 	github.com/bmatcuk/doublestar/v4 v4.8.1
 	github.com/charlievieth/fastwalk v1.0.11
-	github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e
+	github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198
 	github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1
-	github.com/charmbracelet/fang v0.1.0
+	github.com/charmbracelet/fang v0.3.1-0.20250711140230-d5ebb8c1d674
 	github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe
-	github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.2.0.20250703152125-8e1c474f8a71
+	github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.3
 	github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706
 	github.com/charmbracelet/x/ansi v0.9.3
-	github.com/charmbracelet/x/exp/charmtone v0.0.0-20250627134340-c144409e381c
+	github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3
 	github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a
 	github.com/disintegration/imageorient v0.0.0-20180920195336-8147d86e83ec
 	github.com/fsnotify/fsnotify v1.8.0
 	github.com/google/uuid v1.6.0
 	github.com/joho/godotenv v1.5.1
-	github.com/mark3labs/mcp-go v0.32.0
+	github.com/mark3labs/mcp-go v0.33.0
 	github.com/muesli/termenv v0.16.0
 	github.com/ncruces/go-sqlite3 v0.25.0
 	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
@@ -43,22 +43,12 @@ require (
 	github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c
 	github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef
 	github.com/stretchr/testify v1.10.0
+	github.com/tidwall/sjson v1.2.5
 	golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1
 	mvdan.cc/sh/v3 v3.11.0
 )
 
-require (
-	github.com/go-logfmt/logfmt v0.6.0 // indirect
-	github.com/spf13/cast v1.7.1 // indirect
-	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
-)
-
-require (
-	github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9 // indirect
-	github.com/charmbracelet/x/termios v0.1.1 // indirect
-)
-
 require (
 	cloud.google.com/go v0.116.0 // indirect
 	cloud.google.com/go/auth v0.13.0 // indirect
@@ -85,15 +75,18 @@ require (
 	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
 	github.com/aymerick/douceur v0.2.0 // indirect
 	github.com/charmbracelet/colorprofile v0.3.1 // indirect
+	github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9 // indirect
 	github.com/charmbracelet/x/cellbuf v0.0.14-0.20250516160309-24eee56f89fa // indirect
 	github.com/charmbracelet/x/exp/slice v0.0.0-20250611152503-f53cdd7e01ef
 	github.com/charmbracelet/x/term v0.2.1
+	github.com/charmbracelet/x/termios v0.1.1 // indirect
 	github.com/charmbracelet/x/windows v0.2.1 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/disintegration/gift v1.1.2 // indirect
 	github.com/dlclark/regexp2 v1.11.4 // indirect
 	github.com/dustin/go-humanize v1.0.1 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
+	github.com/go-logfmt/logfmt v0.6.0 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
 	github.com/go-logr/stdr v1.2.2 // indirect
 	github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
@@ -121,12 +114,12 @@ require (
 	github.com/rivo/uniseg v0.4.7
 	github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
 	github.com/sethvargo/go-retry v0.3.0 // indirect
+	github.com/spf13/cast v1.7.1 // indirect
 	github.com/spf13/pflag v1.0.6 // indirect
 	github.com/tetratelabs/wazero v1.9.0 // indirect
 	github.com/tidwall/gjson v1.18.0 // indirect
 	github.com/tidwall/match v1.1.1 // indirect
 	github.com/tidwall/pretty v1.2.1 // indirect
-	github.com/tidwall/sjson v1.2.5 // indirect
 	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
 	github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
 	github.com/yuin/goldmark v1.7.8 // indirect
@@ -148,5 +141,6 @@ require (
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
 	google.golang.org/grpc v1.71.0 // indirect
 	google.golang.org/protobuf v1.36.6 // indirect
+	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

go.sum 🔗

@@ -68,18 +68,18 @@ github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR
 github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
 github.com/charlievieth/fastwalk v1.0.11 h1:5sLT/q9+d9xMdpKExawLppqvXFZCVKf6JHnr2u/ufj8=
 github.com/charlievieth/fastwalk v1.0.11/go.mod h1:yGy1zbxog41ZVMcKA/i8ojXLFsuayX5VvwhQVoj9PBI=
-github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e h1:99Ugtt633rqauFsXjZobZmtkNpeaWialfj8dl6COC6A=
-github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
-github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891 h1:wh6N1dR4XkDh6XsiZh1/tImJAZvYB0yVLmaUKvJXvK0=
-github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891/go.mod h1:SwBB+WoaQVMMOM9hknbN/7FNT86kgKG0LSHGTmLphX8=
+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198 h1:CkMS9Ah9ac1Ego5JDC5NJyZyAAqu23Z+O0yDwsa3IxM=
+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
+github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595 h1:wLMjzOqrwoM7Em9UR9sGbn4375G8WuxcwFB3kjZiqHo=
+github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595/go.mod h1:+Tl7rePElw6OKt382t04zXwtPFoPXxAaJzNrYmtsLds=
 github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
 github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
-github.com/charmbracelet/fang v0.1.0 h1:SlZS2crf3/zQh7Mr4+W+7QR1k+L08rrPX5rm5z3d7Wg=
-github.com/charmbracelet/fang v0.1.0/go.mod h1:Zl/zeUQ8EtQuGyiV0ZKZlZPDowKRTzu8s/367EpN/fc=
+github.com/charmbracelet/fang v0.3.1-0.20250711140230-d5ebb8c1d674 h1:+Cz+VfxD5DO+JT1LlswXWhre0HYLj6l2HW8HVGfMuC0=
+github.com/charmbracelet/fang v0.3.1-0.20250711140230-d5ebb8c1d674/go.mod h1:9gCUAHmVx5BwSafeyNr3GI0GgvlB1WYjL21SkPp1jyU=
 github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe h1:i6ce4CcAlPpTj2ER69m1DBeLZ3RRcHnKExuwhKa3GfY=
 github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe/go.mod h1:p3Q+aN4eQKeM5jhrmXPMgPrlKbmc59rWSnMsSA3udhk=
-github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093 h1:c9vOmNJQUwy/lp/pNOB5ZDMhOuXJ3Y2LL9uZMYGgJxQ=
-github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093/go.mod h1:XmxjFJcMEfYIHa4Mw4ra+uMjploDkTlkKIs7wLt9v4Q=
+github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb h1:lswj7CYZVYbLn2OhYJsXOMRQQGdRIfyuSnh5FdVSMr0=
+github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb/go.mod h1:wEc/TRrTAIDJYjVCg3+y8WeKaN+F88gpYfGbUuP6W3A=
 github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706 h1:WkwO6Ks3mSIGnGuSdKl9qDSyfbYK50z2wc2gGMggegE=
 github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706/go.mod h1:mjJGp00cxcfvD5xdCa+bso251Jt4owrQvuimJtVmEmM=
 github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9 h1:+LLFCLxtb/sHegwY3zYdFAbaOgI/I9pv/pxdUlI1Q9s=
@@ -88,8 +88,8 @@ github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh
 github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
 github.com/charmbracelet/x/cellbuf v0.0.14-0.20250516160309-24eee56f89fa h1:lphz0Z3rsiOtMYiz8axkT24i9yFiueDhJbzyNUADmME=
 github.com/charmbracelet/x/cellbuf v0.0.14-0.20250516160309-24eee56f89fa/go.mod h1:xBlh2Yi3DL3zy/2n15kITpg0YZardf/aa/hgUaIM6Rk=
-github.com/charmbracelet/x/exp/charmtone v0.0.0-20250627134340-c144409e381c h1:2GELBLPgfSbHU53bsQhR9XIgNuVZ6w+Rz8RWV5Lq+A4=
-github.com/charmbracelet/x/exp/charmtone v0.0.0-20250627134340-c144409e381c/go.mod h1:T9jr8CzFpjhFVHjNjKwbAD7KwBNyFnj2pntAO7F2zw0=
+github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3 h1:1xwHZg6eMZ9Wv5TE1UGub6ARubyOd1Lo5kPUI/6VL50=
+github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3/go.mod h1:T9jr8CzFpjhFVHjNjKwbAD7KwBNyFnj2pntAO7F2zw0=
 github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a h1:FsHEJ52OC4VuTzU8t+n5frMjLvpYWEznSr/u8tnkCYw=
 github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
 github.com/charmbracelet/x/exp/slice v0.0.0-20250611152503-f53cdd7e01ef h1:v7qwsZ2OxzlwvpKwz8dtZXp7fIJlcDEUOyFBNE4fz4Q=
@@ -165,8 +165,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
-github.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7MU8=
-github.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
+github.com/mark3labs/mcp-go v0.33.0 h1:naxhjnTIs/tyPZmWUZFuG0lDmdA6sUyYGGf3gsHvTCc=
+github.com/mark3labs/mcp-go v0.33.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=

internal/app/app.go 🔗

@@ -10,11 +10,14 @@ import (
 	"sync"
 	"time"
 
+	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/db"
 	"github.com/charmbracelet/crush/internal/format"
 	"github.com/charmbracelet/crush/internal/history"
 	"github.com/charmbracelet/crush/internal/llm/agent"
+	"github.com/charmbracelet/crush/internal/log"
+	"github.com/charmbracelet/crush/internal/pubsub"
 
 	"github.com/charmbracelet/crush/internal/lsp"
 	"github.com/charmbracelet/crush/internal/message"
@@ -36,9 +39,18 @@ type App struct {
 
 	watcherCancelFuncs []context.CancelFunc
 	cancelFuncsMutex   sync.Mutex
-	watcherWG          sync.WaitGroup
+	lspWatcherWG       sync.WaitGroup
 
 	config *config.Config
+
+	serviceEventsWG *sync.WaitGroup
+	eventsCtx       context.Context
+	events          chan tea.Msg
+	tuiWG           *sync.WaitGroup
+
+	// global context and cleanup functions
+	globalCtx    context.Context
+	cleanupFuncs []func()
 }
 
 func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) {
@@ -53,46 +65,53 @@ func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) {
 		History:     files,
 		Permissions: permission.NewPermissionService(cfg.WorkingDir()),
 		LSPClients:  make(map[string]*lsp.Client),
-		config:      cfg,
+
+		globalCtx: ctx,
+
+		config: cfg,
+
+		events:          make(chan tea.Msg, 100),
+		serviceEventsWG: &sync.WaitGroup{},
+		tuiWG:           &sync.WaitGroup{},
 	}
 
+	app.setupEvents()
+
 	// Initialize LSP clients in the background
 	go app.initLSPClients(ctx)
 
 	// TODO: remove the concept of agent config most likely
-	coderAgentCfg := cfg.Agents["coder"]
-	if coderAgentCfg.ID == "" {
-		return nil, fmt.Errorf("coder agent configuration is missing")
-	}
-
-	var err error
-	app.CoderAgent, err = agent.NewAgent(
-		coderAgentCfg,
-		app.Permissions,
-		app.Sessions,
-		app.Messages,
-		app.History,
-		app.LSPClients,
-	)
-	if err != nil {
-		slog.Error("Failed to create coder agent", "err", err)
-		return nil, err
+	if cfg.IsConfigured() {
+		if err := app.InitCoderAgent(); err != nil {
+			return nil, fmt.Errorf("failed to initialize coder agent: %w", err)
+		}
+	} else {
+		slog.Warn("No agent configuration found")
 	}
-
 	return app, nil
 }
 
 // RunNonInteractive handles the execution flow when a prompt is provided via CLI flag.
-func (a *App) RunNonInteractive(ctx context.Context, prompt string, outputFormat string, quiet bool) error {
+func (a *App) RunNonInteractive(ctx context.Context, prompt string, quiet bool) error {
 	slog.Info("Running in non-interactive mode")
 
+	ctx, cancel := context.WithCancel(ctx)
+	defer cancel()
+
 	// Start spinner if not in quiet mode
 	var spinner *format.Spinner
 	if !quiet {
-		spinner = format.NewSpinner("Thinking...")
+		spinner = format.NewSpinner(ctx, cancel, "Generating")
 		spinner.Start()
-		defer spinner.Stop()
 	}
+	// Helper function to stop spinner once
+	stopSpinner := func() {
+		if !quiet && spinner != nil {
+			spinner.Stop()
+			spinner = nil
+		}
+	}
+	defer stopSpinner()
 
 	const maxPromptLengthForTitle = 100
 	titlePrefix := "Non-interactive: "
@@ -119,59 +138,176 @@ func (a *App) RunNonInteractive(ctx context.Context, prompt string, outputFormat
 		return fmt.Errorf("failed to start agent processing stream: %w", err)
 	}
 
-	result := <-done
-	if result.Error != nil {
-		if errors.Is(result.Error, context.Canceled) || errors.Is(result.Error, agent.ErrRequestCancelled) {
-			slog.Info("Agent processing cancelled", "session_id", sess.ID)
+	messageEvents := a.Messages.Subscribe(ctx)
+	readBts := 0
+
+	for {
+		select {
+		case result := <-done:
+			stopSpinner()
+
+			if result.Error != nil {
+				if errors.Is(result.Error, context.Canceled) || errors.Is(result.Error, agent.ErrRequestCancelled) {
+					slog.Info("Agent processing cancelled", "session_id", sess.ID)
+					return nil
+				}
+				return fmt.Errorf("agent processing failed: %w", result.Error)
+			}
+
+			part := result.Message.Content().String()[readBts:]
+			fmt.Println(part)
+
+			slog.Info("Non-interactive run completed", "session_id", sess.ID)
 			return nil
+
+		case event := <-messageEvents:
+			msg := event.Payload
+			if msg.SessionID == sess.ID && msg.Role == message.Assistant && len(msg.Parts) > 0 {
+				stopSpinner()
+				part := msg.Content().String()[readBts:]
+				fmt.Print(part)
+				readBts += len(part)
+			}
+
+		case <-ctx.Done():
+			stopSpinner()
+			return ctx.Err()
 		}
-		return fmt.Errorf("agent processing failed: %w", result.Error)
 	}
+}
 
-	// Stop spinner before printing output
-	if !quiet && spinner != nil {
-		spinner.Stop()
-	}
+func (app *App) UpdateAgentModel() error {
+	return app.CoderAgent.UpdateModel()
+}
 
-	// Get the text content from the response
-	content := "No content available"
-	if result.Message.Content().String() != "" {
-		content = result.Message.Content().String()
+func (app *App) setupEvents() {
+	ctx, cancel := context.WithCancel(app.globalCtx)
+	app.eventsCtx = ctx
+	setupSubscriber(ctx, app.serviceEventsWG, "sessions", app.Sessions.Subscribe, app.events)
+	setupSubscriber(ctx, app.serviceEventsWG, "messages", app.Messages.Subscribe, app.events)
+	setupSubscriber(ctx, app.serviceEventsWG, "permissions", app.Permissions.Subscribe, app.events)
+	setupSubscriber(ctx, app.serviceEventsWG, "history", app.History.Subscribe, app.events)
+	cleanupFunc := func() {
+		cancel()
+		app.serviceEventsWG.Wait()
 	}
+	app.cleanupFuncs = append(app.cleanupFuncs, cleanupFunc)
+}
 
-	fmt.Println(format.FormatOutput(content, outputFormat))
-
-	slog.Info("Non-interactive run completed", "session_id", sess.ID)
+func setupSubscriber[T any](
+	ctx context.Context,
+	wg *sync.WaitGroup,
+	name string,
+	subscriber func(context.Context) <-chan pubsub.Event[T],
+	outputCh chan<- tea.Msg,
+) {
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		subCh := subscriber(ctx)
+		for {
+			select {
+			case event, ok := <-subCh:
+				if !ok {
+					slog.Debug("subscription channel closed", "name", name)
+					return
+				}
+				var msg tea.Msg = event
+				select {
+				case outputCh <- msg:
+				case <-time.After(2 * time.Second):
+					slog.Warn("message dropped due to slow consumer", "name", name)
+				case <-ctx.Done():
+					slog.Debug("subscription cancelled", "name", name)
+					return
+				}
+			case <-ctx.Done():
+				slog.Debug("subscription cancelled", "name", name)
+				return
+			}
+		}
+	}()
+}
 
+func (app *App) InitCoderAgent() error {
+	coderAgentCfg := app.config.Agents["coder"]
+	if coderAgentCfg.ID == "" {
+		return fmt.Errorf("coder agent configuration is missing")
+	}
+	var err error
+	app.CoderAgent, err = agent.NewAgent(
+		coderAgentCfg,
+		app.Permissions,
+		app.Sessions,
+		app.Messages,
+		app.History,
+		app.LSPClients,
+	)
+	if err != nil {
+		slog.Error("Failed to create coder agent", "err", err)
+		return err
+	}
+	setupSubscriber(app.eventsCtx, app.serviceEventsWG, "coderAgent", app.CoderAgent.Subscribe, app.events)
 	return nil
 }
 
+func (app *App) Subscribe(program *tea.Program) {
+	defer log.RecoverPanic("app.Subscribe", func() {
+		slog.Info("TUI subscription panic - attempting graceful shutdown")
+		program.Quit()
+	})
+
+	app.tuiWG.Add(1)
+	tuiCtx, tuiCancel := context.WithCancel(app.globalCtx)
+	app.cleanupFuncs = append(app.cleanupFuncs, func() {
+		slog.Debug("Cancelling TUI message handler")
+		tuiCancel()
+		app.tuiWG.Wait()
+	})
+	defer app.tuiWG.Done()
+	for {
+		select {
+		case <-tuiCtx.Done():
+			slog.Debug("TUI message handler shutting down")
+			return
+		case msg, ok := <-app.events:
+			if !ok {
+				slog.Debug("TUI message channel closed")
+				return
+			}
+			program.Send(msg)
+		}
+	}
+}
+
 // Shutdown performs a clean shutdown of the application
 func (app *App) Shutdown() {
-	// Cancel all watcher goroutines
 	app.cancelFuncsMutex.Lock()
 	for _, cancel := range app.watcherCancelFuncs {
 		cancel()
 	}
 	app.cancelFuncsMutex.Unlock()
-	app.watcherWG.Wait()
+	app.lspWatcherWG.Wait()
 
-	// Perform additional cleanup for LSP clients
 	app.clientsMutex.RLock()
 	clients := make(map[string]*lsp.Client, len(app.LSPClients))
 	maps.Copy(clients, app.LSPClients)
 	app.clientsMutex.RUnlock()
 
 	for name, client := range clients {
-		shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+		shutdownCtx, cancel := context.WithTimeout(app.globalCtx, 5*time.Second)
 		if err := client.Shutdown(shutdownCtx); err != nil {
 			slog.Error("Failed to shutdown LSP client", "name", name, "error", err)
 		}
 		cancel()
 	}
-	app.CoderAgent.CancelAll()
-}
+	if app.CoderAgent != nil {
+		app.CoderAgent.CancelAll()
+	}
 
-func (app *App) UpdateAgentModel() error {
-	return app.CoderAgent.UpdateModel()
+	for _, cleanup := range app.cleanupFuncs {
+		if cleanup != nil {
+			cleanup()
+		}
+	}
 }

internal/app/lsp.go 🔗

@@ -59,11 +59,8 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
 	// Create a child context that can be canceled when the app is shutting down
 	watchCtx, cancelFunc := context.WithCancel(ctx)
 
-	// Create a context with the server name for better identification
-	watchCtx = context.WithValue(watchCtx, "serverName", name)
-
 	// Create the workspace watcher
-	workspaceWatcher := watcher.NewWorkspaceWatcher(lspClient)
+	workspaceWatcher := watcher.NewWorkspaceWatcher(name, lspClient)
 
 	// Store the cancel function to be called during cleanup
 	app.cancelFuncsMutex.Lock()
@@ -71,7 +68,7 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
 	app.cancelFuncsMutex.Unlock()
 
 	// Add the watcher to a WaitGroup to track active goroutines
-	app.watcherWG.Add(1)
+	app.lspWatcherWG.Add(1)
 
 	// Add to map with mutex protection before starting goroutine
 	app.clientsMutex.Lock()
@@ -83,7 +80,7 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
 
 // runWorkspaceWatcher executes the workspace watcher for an LSP client
 func (app *App) runWorkspaceWatcher(ctx context.Context, name string, workspaceWatcher *watcher.WorkspaceWatcher) {
-	defer app.watcherWG.Done()
+	defer app.lspWatcherWG.Done()
 	defer log.RecoverPanic("LSP-"+name, func() {
 		// Try to restart the client
 		app.restartLSPClient(ctx, name)

internal/config/config.go 🔗

@@ -2,10 +2,12 @@ package config
 
 import (
 	"fmt"
+	"os"
 	"slices"
 	"strings"
 
 	"github.com/charmbracelet/crush/internal/fur/provider"
+	"github.com/tidwall/sjson"
 )
 
 const (
@@ -58,6 +60,8 @@ type SelectedModel struct {
 type ProviderConfig struct {
 	// The provider's id.
 	ID string `json:"id,omitempty"`
+	// The provider's name, used for display purposes.
+	Name string `json:"name,omitempty"`
 	// The provider's API endpoint.
 	BaseURL string `json:"base_url,omitempty"`
 	// The provider type, e.g. "openai", "anthropic", etc. if empty it defaults to openai.
@@ -68,7 +72,7 @@ type ProviderConfig struct {
 	Disable bool `json:"disable,omitempty"`
 
 	// Extra headers to send with each request to the provider.
-	ExtraHeaders map[string]string
+	ExtraHeaders map[string]string `json:"extra_headers,omitempty"`
 
 	// Used to pass extra parameters to the provider.
 	ExtraParams map[string]string `json:"-"`
@@ -207,7 +211,9 @@ type Config struct {
 	// TODO: most likely remove this concept when I come back to it
 	Agents map[string]Agent `json:"-"`
 	// TODO: find a better way to do this this should probably not be part of the config
-	resolver VariableResolver
+	resolver       VariableResolver
+	dataConfigDir  string              `json:"-"`
+	knownProviders []provider.Provider `json:"-"`
 }
 
 func (c *Config) WorkingDir() string {
@@ -275,6 +281,14 @@ func (c *Config) SmallModel() *provider.Model {
 	return c.GetModel(model.Provider, model.Model)
 }
 
+func (c *Config) SetCompactMode(enabled bool) error {
+	if c.Options == nil {
+		c.Options = &Options{}
+	}
+	c.Options.TUI.CompactMode = enabled
+	return c.SetConfigField("options.tui.compact_mode", enabled)
+}
+
 func (c *Config) Resolve(key string) (string, error) {
 	if c.resolver == nil {
 		return "", fmt.Errorf("no variable resolver configured")
@@ -282,9 +296,109 @@ func (c *Config) Resolve(key string) (string, error) {
 	return c.resolver.ResolveValue(key)
 }
 
-// TODO: maybe handle this better
-func UpdatePreferredModel(modelType SelectedModelType, model SelectedModel) error {
-	cfg := Get()
-	cfg.Models[modelType] = model
+func (c *Config) UpdatePreferredModel(modelType SelectedModelType, model SelectedModel) error {
+	c.Models[modelType] = model
+	if err := c.SetConfigField(fmt.Sprintf("models.%s", modelType), model); err != nil {
+		return fmt.Errorf("failed to update preferred model: %w", err)
+	}
+	return nil
+}
+
+func (c *Config) SetConfigField(key string, value any) error {
+	// read the data
+	data, err := os.ReadFile(c.dataConfigDir)
+	if err != nil {
+		if os.IsNotExist(err) {
+			data = []byte("{}")
+		} else {
+			return fmt.Errorf("failed to read config file: %w", err)
+		}
+	}
+
+	newValue, err := sjson.Set(string(data), key, value)
+	if err != nil {
+		return fmt.Errorf("failed to set config field %s: %w", key, err)
+	}
+	if err := os.WriteFile(c.dataConfigDir, []byte(newValue), 0o644); err != nil {
+		return fmt.Errorf("failed to write config file: %w", err)
+	}
+	return nil
+}
+
+func (c *Config) SetProviderAPIKey(providerID, apiKey string) error {
+	// First save to the config file
+	err := c.SetConfigField("providers."+providerID+".api_key", apiKey)
+	if err != nil {
+		return fmt.Errorf("failed to save API key to config file: %w", err)
+	}
+
+	if c.Providers == nil {
+		c.Providers = make(map[string]ProviderConfig)
+	}
+
+	providerConfig, exists := c.Providers[providerID]
+	if exists {
+		providerConfig.APIKey = apiKey
+		c.Providers[providerID] = providerConfig
+		return nil
+	}
+
+	var foundProvider *provider.Provider
+	for _, p := range c.knownProviders {
+		if string(p.ID) == providerID {
+			foundProvider = &p
+			break
+		}
+	}
+
+	if foundProvider != nil {
+		// Create new provider config based on known provider
+		providerConfig = ProviderConfig{
+			ID:           providerID,
+			Name:         foundProvider.Name,
+			BaseURL:      foundProvider.APIEndpoint,
+			Type:         foundProvider.Type,
+			APIKey:       apiKey,
+			Disable:      false,
+			ExtraHeaders: make(map[string]string),
+			ExtraParams:  make(map[string]string),
+			Models:       foundProvider.Models,
+		}
+	} else {
+		return fmt.Errorf("provider with ID %s not found in known providers", providerID)
+	}
+	// Store the updated provider config
+	c.Providers[providerID] = providerConfig
 	return nil
 }
+
+func (c *Config) SetupAgents() {
+	agents := map[string]Agent{
+		"coder": {
+			ID:           "coder",
+			Name:         "Coder",
+			Description:  "An agent that helps with executing coding tasks.",
+			Model:        SelectedModelTypeLarge,
+			ContextPaths: c.Options.ContextPaths,
+			// All tools allowed
+		},
+		"task": {
+			ID:           "task",
+			Name:         "Task",
+			Description:  "An agent that helps with searching for context and finding implementation details.",
+			Model:        SelectedModelTypeLarge,
+			ContextPaths: c.Options.ContextPaths,
+			AllowedTools: []string{
+				"glob",
+				"grep",
+				"ls",
+				"sourcegraph",
+				"view",
+			},
+			// NO MCPs or LSPs by default
+			AllowedMCP: map[string][]string{},
+			AllowedLSP: []string{},
+		},
+	}
+	c.Agents = agents
+}

internal/config/init.go 🔗

@@ -103,3 +103,11 @@ func MarkProjectInitialized() error {
 
 	return nil
 }
+
+func HasInitialDataConfig() bool {
+	cfgPath := GlobalConfigData()
+	if _, err := os.Stat(cfgPath); err != nil {
+		return false
+	}
+	return true
+}

internal/config/load.go 🔗

@@ -37,7 +37,7 @@ func Load(workingDir string, debug bool) (*Config, error) {
 	// uses default config paths
 	configPaths := []string{
 		globalConfig(),
-		globalConfigData(),
+		GlobalConfigData(),
 		filepath.Join(workingDir, fmt.Sprintf("%s.json", appName)),
 		filepath.Join(workingDir, fmt.Sprintf(".%s.json", appName)),
 	}
@@ -46,6 +46,8 @@ func Load(workingDir string, debug bool) (*Config, error) {
 		return nil, fmt.Errorf("failed to load config from paths %v: %w", configPaths, err)
 	}
 
+	cfg.dataConfigDir = GlobalConfigData()
+
 	cfg.setDefaults(workingDir)
 
 	if debug {
@@ -63,6 +65,7 @@ func Load(workingDir string, debug bool) (*Config, error) {
 	if err != nil || len(providers) == 0 {
 		return nil, fmt.Errorf("failed to load providers: %w", err)
 	}
+	cfg.knownProviders = providers
 
 	env := env.New()
 	// Configure providers
@@ -80,37 +83,7 @@ func Load(workingDir string, debug bool) (*Config, error) {
 	if err := cfg.configureSelectedModels(providers); err != nil {
 		return nil, fmt.Errorf("failed to configure selected models: %w", err)
 	}
-
-	// TODO: remove the agents concept from the config
-	agents := map[string]Agent{
-		"coder": {
-			ID:           "coder",
-			Name:         "Coder",
-			Description:  "An agent that helps with executing coding tasks.",
-			Model:        SelectedModelTypeLarge,
-			ContextPaths: cfg.Options.ContextPaths,
-			// All tools allowed
-		},
-		"task": {
-			ID:           "task",
-			Name:         "Task",
-			Description:  "An agent that helps with searching for context and finding implementation details.",
-			Model:        SelectedModelTypeLarge,
-			ContextPaths: cfg.Options.ContextPaths,
-			AllowedTools: []string{
-				"glob",
-				"grep",
-				"ls",
-				"sourcegraph",
-				"view",
-			},
-			// NO MCPs or LSPs by default
-			AllowedMCP: map[string][]string{},
-			AllowedLSP: []string{},
-		},
-	}
-	cfg.Agents = agents
-
+	cfg.SetupAgents()
 	return cfg, nil
 }
 
@@ -162,6 +135,7 @@ func (cfg *Config) configureProviders(env env.Env, resolver VariableResolver, kn
 		}
 		prepared := ProviderConfig{
 			ID:           string(p.ID),
+			Name:         p.Name,
 			BaseURL:      p.APIEndpoint,
 			APIKey:       p.APIKey,
 			Type:         p.Type,
@@ -218,6 +192,9 @@ func (cfg *Config) configureProviders(env env.Env, resolver VariableResolver, kn
 
 		// Make sure the provider ID is set
 		providerConfig.ID = id
+		if providerConfig.Name == "" {
+			providerConfig.Name = id // Use ID as name if not set
+		}
 		// default to OpenAI if not set
 		if providerConfig.Type == "" {
 			providerConfig.Type = provider.TypeOpenAI
@@ -229,9 +206,7 @@ func (cfg *Config) configureProviders(env env.Env, resolver VariableResolver, kn
 			continue
 		}
 		if providerConfig.APIKey == "" {
-			slog.Warn("Skipping custom provider due to missing API key", "provider", id)
-			delete(cfg.Providers, id)
-			continue
+			slog.Warn("Provider is missing API key, this might be OK for local providers", "provider", id)
 		}
 		if providerConfig.BaseURL == "" {
 			slog.Warn("Skipping custom provider due to missing API endpoint", "provider", id)
@@ -251,9 +226,7 @@ func (cfg *Config) configureProviders(env env.Env, resolver VariableResolver, kn
 
 		apiKey, err := resolver.ResolveValue(providerConfig.APIKey)
 		if apiKey == "" || err != nil {
-			slog.Warn("Skipping custom provider due to missing API key", "provider", id, "error", err)
-			delete(cfg.Providers, id)
-			continue
+			slog.Warn("Provider is missing API key, this might be OK for local providers", "provider", id)
 		}
 		baseURL, err := resolver.ResolveValue(providerConfig.BaseURL)
 		if baseURL == "" || err != nil {
@@ -328,6 +301,7 @@ func (cfg *Config) defaultModelSelection(knownProviders []provider.Provider) (la
 		defaultSmallModel := cfg.GetModel(string(p.ID), p.DefaultSmallModelID)
 		if defaultSmallModel == nil {
 			err = fmt.Errorf("default small model %s not found for provider %s", p.DefaultSmallModelID, p.ID)
+			return
 		}
 		smallModel = SelectedModel{
 			Provider:        string(p.ID),
@@ -369,10 +343,11 @@ func (cfg *Config) defaultModelSelection(knownProviders []provider.Provider) (la
 }
 
 func (cfg *Config) configureSelectedModels(knownProviders []provider.Provider) error {
-	large, small, err := cfg.defaultModelSelection(knownProviders)
+	defaultLarge, defaultSmall, err := cfg.defaultModelSelection(knownProviders)
 	if err != nil {
 		return fmt.Errorf("failed to select default models: %w", err)
 	}
+	large, small := defaultLarge, defaultSmall
 
 	largeModelSelected, largeModelConfigured := cfg.Models[SelectedModelTypeLarge]
 	if largeModelConfigured {
@@ -384,17 +359,23 @@ func (cfg *Config) configureSelectedModels(knownProviders []provider.Provider) e
 		}
 		model := cfg.GetModel(large.Provider, large.Model)
 		if model == nil {
-			return fmt.Errorf("large model %s not found for provider %s", large.Model, large.Provider)
-		}
-		if largeModelSelected.MaxTokens > 0 {
-			large.MaxTokens = largeModelSelected.MaxTokens
+			large = defaultLarge
+			// override the model type to large
+			err := cfg.UpdatePreferredModel(SelectedModelTypeLarge, large)
+			if err != nil {
+				return fmt.Errorf("failed to update preferred large model: %w", err)
+			}
 		} else {
-			large.MaxTokens = model.DefaultMaxTokens
-		}
-		if largeModelSelected.ReasoningEffort != "" {
-			large.ReasoningEffort = largeModelSelected.ReasoningEffort
+			if largeModelSelected.MaxTokens > 0 {
+				large.MaxTokens = largeModelSelected.MaxTokens
+			} else {
+				large.MaxTokens = model.DefaultMaxTokens
+			}
+			if largeModelSelected.ReasoningEffort != "" {
+				large.ReasoningEffort = largeModelSelected.ReasoningEffort
+			}
+			large.Think = largeModelSelected.Think
 		}
-		large.Think = largeModelSelected.Think
 	}
 	smallModelSelected, smallModelConfigured := cfg.Models[SelectedModelTypeSmall]
 	if smallModelConfigured {
@@ -407,25 +388,21 @@ func (cfg *Config) configureSelectedModels(knownProviders []provider.Provider) e
 
 		model := cfg.GetModel(small.Provider, small.Model)
 		if model == nil {
-			return fmt.Errorf("large model %s not found for provider %s", large.Model, large.Provider)
-		}
-		if smallModelSelected.MaxTokens > 0 {
-			small.MaxTokens = smallModelSelected.MaxTokens
+			small = defaultSmall
+			// override the model type to small
+			err := cfg.UpdatePreferredModel(SelectedModelTypeSmall, small)
+			if err != nil {
+				return fmt.Errorf("failed to update preferred small model: %w", err)
+			}
 		} else {
-			small.MaxTokens = model.DefaultMaxTokens
+			if smallModelSelected.MaxTokens > 0 {
+				small.MaxTokens = smallModelSelected.MaxTokens
+			} else {
+				small.MaxTokens = model.DefaultMaxTokens
+			}
+			small.ReasoningEffort = smallModelSelected.ReasoningEffort
+			small.Think = smallModelSelected.Think
 		}
-		small.ReasoningEffort = smallModelSelected.ReasoningEffort
-		small.Think = smallModelSelected.Think
-	}
-
-	// validate the selected models
-	largeModel := cfg.GetModel(large.Provider, large.Model)
-	if largeModel == nil {
-		return fmt.Errorf("large model %s not found for provider %s", large.Model, large.Provider)
-	}
-	smallModel := cfg.GetModel(small.Provider, small.Model)
-	if smallModel == nil {
-		return fmt.Errorf("small model %s not found for provider %s", small.Model, small.Provider)
 	}
 	cfg.Models[SelectedModelTypeLarge] = large
 	cfg.Models[SelectedModelTypeSmall] = small
@@ -512,9 +489,9 @@ func globalConfig() string {
 	return filepath.Join(os.Getenv("HOME"), ".config", appName, fmt.Sprintf("%s.json", appName))
 }
 
-// globalConfigData returns the path to the main data directory for the application.
+// GlobalConfigData returns the path to the main data directory for the application.
 // this config is used when the app overrides configurations instead of updating the global config.
-func globalConfigData() string {
+func GlobalConfigData() string {
 	xdgDataHome := os.Getenv("XDG_DATA_HOME")
 	if xdgDataHome != "" {
 		return filepath.Join(xdgDataHome, appName, fmt.Sprintf("%s.json", appName))
@@ -533,3 +510,14 @@ func globalConfigData() string {
 
 	return filepath.Join(os.Getenv("HOME"), ".local", "share", appName, fmt.Sprintf("%s.json", appName))
 }
+
+func HomeDir() string {
+	homeDir := os.Getenv("HOME")
+	if homeDir == "" {
+		homeDir = os.Getenv("USERPROFILE") // For Windows compatibility
+	}
+	if homeDir == "" {
+		homeDir = os.Getenv("HOMEPATH") // Fallback for some environments
+	}
+	return homeDir
+}

internal/config/load_test.go 🔗

@@ -484,7 +484,7 @@ func TestConfig_configureProvidersWithDisabledProvider(t *testing.T) {
 }
 
 func TestConfig_configureProvidersCustomProviderValidation(t *testing.T) {
-	t.Run("custom provider with missing API key is removed", func(t *testing.T) {
+	t.Run("custom provider with missing API key is allowed, but not known providers", func(t *testing.T) {
 		cfg := &Config{
 			Providers: map[string]ProviderConfig{
 				"custom": {
@@ -493,6 +493,9 @@ func TestConfig_configureProvidersCustomProviderValidation(t *testing.T) {
 						ID: "test-model",
 					}},
 				},
+				"openai": {
+					APIKey: "$MISSING",
+				},
 			},
 		}
 		cfg.setDefaults("/tmp")
@@ -502,9 +505,9 @@ func TestConfig_configureProvidersCustomProviderValidation(t *testing.T) {
 		err := cfg.configureProviders(env, resolver, []provider.Provider{})
 		assert.NoError(t, err)
 
-		assert.Len(t, cfg.Providers, 0)
+		assert.Len(t, cfg.Providers, 1)
 		_, exists := cfg.Providers["custom"]
-		assert.False(t, exists)
+		assert.True(t, exists)
 	})
 
 	t.Run("custom provider with missing BaseURL is removed", func(t *testing.T) {

internal/config/resolve.go 🔗

@@ -44,7 +44,7 @@ func (r *shellVariableResolver) ResolveValue(value string) (string, error) {
 
 	if strings.HasPrefix(value, "$(") && strings.HasSuffix(value, ")") {
 		command := strings.TrimSuffix(strings.TrimPrefix(value, "$("), ")")
-		ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
 		defer cancel()
 
 		stdout, _, err := r.shell.Exec(ctx, command)
@@ -54,8 +54,8 @@ func (r *shellVariableResolver) ResolveValue(value string) (string, error) {
 		return strings.TrimSpace(stdout), nil
 	}
 
-	if strings.HasPrefix(value, "$") {
-		varName := strings.TrimPrefix(value, "$")
+	if after, ok := strings.CutPrefix(value, "$"); ok {
+		varName := after
 		value = r.env.Get(varName)
 		if value == "" {
 			return "", fmt.Errorf("environment variable %q not set", varName)

internal/format/format.go 🔗

@@ -1,99 +0,0 @@
-package format
-
-import (
-	"encoding/json"
-	"fmt"
-	"strings"
-)
-
-// OutputFormat represents the output format type for non-interactive mode
-type OutputFormat string
-
-const (
-	// Text format outputs the AI response as plain text.
-	Text OutputFormat = "text"
-
-	// JSON format outputs the AI response wrapped in a JSON object.
-	JSON OutputFormat = "json"
-)
-
-// String returns the string representation of the OutputFormat
-func (f OutputFormat) String() string {
-	return string(f)
-}
-
-// SupportedFormats is a list of all supported output formats as strings
-var SupportedFormats = []string{
-	string(Text),
-	string(JSON),
-}
-
-// Parse converts a string to an OutputFormat
-func Parse(s string) (OutputFormat, error) {
-	s = strings.ToLower(strings.TrimSpace(s))
-
-	switch s {
-	case string(Text):
-		return Text, nil
-	case string(JSON):
-		return JSON, nil
-	default:
-		return "", fmt.Errorf("invalid format: %s", s)
-	}
-}
-
-// IsValid checks if the provided format string is supported
-func IsValid(s string) bool {
-	_, err := Parse(s)
-	return err == nil
-}
-
-// GetHelpText returns a formatted string describing all supported formats
-func GetHelpText() string {
-	return fmt.Sprintf(`Supported output formats:
-- %s: Plain text output (default)
-- %s: Output wrapped in a JSON object`,
-		Text, JSON)
-}
-
-// FormatOutput formats the AI response according to the specified format
-func FormatOutput(content string, formatStr string) string {
-	format, err := Parse(formatStr)
-	if err != nil {
-		// Default to text format on error
-		return content
-	}
-
-	switch format {
-	case JSON:
-		return formatAsJSON(content)
-	case Text:
-		fallthrough
-	default:
-		return content
-	}
-}
-
-// formatAsJSON wraps the content in a simple JSON object
-func formatAsJSON(content string) string {
-	// Use the JSON package to properly escape the content
-	response := struct {
-		Response string `json:"response"`
-	}{
-		Response: content,
-	}
-
-	jsonBytes, err := json.MarshalIndent(response, "", "  ")
-	if err != nil {
-		// In case of an error, return a manually formatted JSON
-		jsonEscaped := strings.ReplaceAll(content, "\\", "\\\\")
-		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\"", "\\\"")
-		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\n", "\\n")
-		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\r", "\\r")
-		jsonEscaped = strings.ReplaceAll(jsonEscaped, "\t", "\\t")
-
-		return fmt.Sprintf("{\n  \"response\": \"%s\"\n}", jsonEscaped)
-	}
-
-	return string(jsonBytes)
-}

internal/format/spinner.go 🔗

@@ -2,81 +2,69 @@ package format
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"os"
 
-	"github.com/charmbracelet/bubbles/v2/spinner"
 	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/crush/internal/tui/components/anim"
+	"github.com/charmbracelet/crush/internal/tui/styles"
+	"github.com/charmbracelet/x/ansi"
 )
 
 // Spinner wraps the bubbles spinner for non-interactive mode
 type Spinner struct {
-	model  spinner.Model
-	done   chan struct{}
-	prog   *tea.Program
-	ctx    context.Context
-	cancel context.CancelFunc
+	done chan struct{}
+	prog *tea.Program
 }
 
-// spinnerModel is the tea.Model for the spinner
-type spinnerModel struct {
-	spinner  spinner.Model
-	message  string
-	quitting bool
+type model struct {
+	cancel context.CancelFunc
+	anim   anim.Anim
 }
 
-func (m spinnerModel) Init() tea.Cmd {
-	return m.spinner.Tick
-}
+func (m model) Init() tea.Cmd { return m.anim.Init() }
+func (m model) View() string  { return m.anim.View() }
 
-func (m spinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+// Update implements tea.Model.
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
 	case tea.KeyPressMsg:
-		m.quitting = true
-		return m, tea.Quit
-	case spinner.TickMsg:
-		var cmd tea.Cmd
-		m.spinner, cmd = m.spinner.Update(msg)
-		return m, cmd
-	case quitMsg:
-		m.quitting = true
-		return m, tea.Quit
-	default:
-		return m, nil
-	}
-}
-
-func (m spinnerModel) View() string {
-	if m.quitting {
-		return ""
+		switch msg.String() {
+		case "ctrl+c", "esc":
+			m.cancel()
+			return m, tea.Quit
+		}
 	}
-	return fmt.Sprintf("%s %s", m.spinner.View(), m.message)
+	mm, cmd := m.anim.Update(msg)
+	m.anim = mm.(anim.Anim)
+	return m, cmd
 }
 
-// quitMsg is sent when we want to quit the spinner
-type quitMsg struct{}
-
 // NewSpinner creates a new spinner with the given message
-func NewSpinner(message string) *Spinner {
-	s := spinner.New()
-	s.Spinner = spinner.Dot
-	s.Style = s.Style.Foreground(s.Style.GetForeground())
-
-	ctx, cancel := context.WithCancel(context.Background())
-
-	model := spinnerModel{
-		spinner: s,
-		message: message,
+func NewSpinner(ctx context.Context, cancel context.CancelFunc, message string) *Spinner {
+	t := styles.CurrentTheme()
+	model := model{
+		anim: anim.New(anim.Settings{
+			Size:        10,
+			Label:       message,
+			LabelColor:  t.FgBase,
+			GradColorA:  t.Primary,
+			GradColorB:  t.Secondary,
+			CycleColors: true,
+		}),
+		cancel: cancel,
 	}
 
-	prog := tea.NewProgram(model, tea.WithOutput(os.Stderr), tea.WithoutCatchPanics())
+	prog := tea.NewProgram(
+		model,
+		tea.WithOutput(os.Stderr),
+		tea.WithContext(ctx),
+	)
 
 	return &Spinner{
-		model:  s,
-		done:   make(chan struct{}),
-		prog:   prog,
-		ctx:    ctx,
-		cancel: cancel,
+		prog: prog,
+		done: make(chan struct{}, 1),
 	}
 }
 
@@ -84,12 +72,10 @@ func NewSpinner(message string) *Spinner {
 func (s *Spinner) Start() {
 	go func() {
 		defer close(s.done)
-		go func() {
-			<-s.ctx.Done()
-			s.prog.Send(quitMsg{})
-		}()
 		_, err := s.prog.Run()
-		if err != nil {
+		// ensures line is cleared
+		fmt.Fprint(os.Stderr, ansi.EraseEntireLine)
+		if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, tea.ErrInterrupted) {
 			fmt.Fprintf(os.Stderr, "Error running spinner: %v\n", err)
 		}
 	}()
@@ -97,6 +83,6 @@ func (s *Spinner) Start() {
 
 // Stop ends the spinner animation
 func (s *Spinner) Stop() {
-	s.cancel()
+	s.prog.Quit()
 	<-s.done
 }

internal/fsext/fileutil.go 🔗

@@ -17,23 +17,14 @@ import (
 	ignore "github.com/sabhiram/go-gitignore"
 )
 
-var (
-	rgPath  string
-	fzfPath string
-)
+var rgPath string
 
 func init() {
 	var err error
 	rgPath, err = exec.LookPath("rg")
 	if err != nil {
 		if log.Initialized() {
-			slog.Warn("Ripgrep (rg) not found in $PATH. Some features might be limited or slower.")
-		}
-	}
-	fzfPath, err = exec.LookPath("fzf")
-	if err != nil {
-		if log.Initialized() {
-			slog.Warn("FZF not found in $PATH. Some features might be limited or slower.")
+			slog.Warn("Ripgrep (rg) not found in $PATH. Some grep features might be limited or slower.")
 		}
 	}
 }

internal/fur/client/client.go 🔗

@@ -10,7 +10,7 @@ import (
 	"github.com/charmbracelet/crush/internal/fur/provider"
 )
 
-const defaultURL = "https://fur.charmcli.dev"
+const defaultURL = "https://fur.charm.sh"
 
 // Client represents a client for the fur service.
 type Client struct {

internal/llm/agent/agent.go 🔗

@@ -26,7 +26,7 @@ import (
 
 // Common errors
 var (
-	ErrRequestCancelled = errors.New("request cancelled by user")
+	ErrRequestCancelled = errors.New("request canceled by user")
 	ErrSessionBusy      = errors.New("session is currently processing another request")
 )
 
@@ -149,7 +149,7 @@ func NewAgent(
 	}
 	opts := []provider.ProviderClientOption{
 		provider.WithModel(agentCfg.Model),
-		provider.WithSystemMessage(prompt.GetPrompt(promptID, providerCfg.ID)),
+		provider.WithSystemMessage(prompt.GetPrompt(promptID, providerCfg.ID, config.Get().Options.ContextPaths...)),
 	}
 	agentProvider, err := provider.NewProvider(*providerCfg, opts...)
 	if err != nil {
@@ -827,7 +827,7 @@ func (a *agent) UpdateModel() error {
 
 		opts := []provider.ProviderClientOption{
 			provider.WithModel(a.agentCfg.Model),
-			provider.WithSystemMessage(prompt.GetPrompt(promptID, currentProviderCfg.ID)),
+			provider.WithSystemMessage(prompt.GetPrompt(promptID, currentProviderCfg.ID, cfg.Options.ContextPaths...)),
 		}
 
 		newProvider, err := provider.NewProvider(*currentProviderCfg, opts...)

internal/llm/prompt/initialize.go 🔗

@@ -0,0 +1,14 @@
+package prompt
+
+func Initialize() string {
+	return `Please analyze this codebase and create a **CRUSH.md** file containing:
+
+- Build/lint/test commands - especially for running a single test
+- Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
+
+The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20-30 lines long.
+If there's already a **CRUSH.md**, improve it.
+
+If there are Cursor rules` + " (in `.cursor/rules/` or `.cursorrules`) or Copilot rules (in `.github/copilot-instructions.md`), make sure to include them.\n" +
+		"Add the `.crush` directory to the `.gitignore` file if it's not already there."
+}

internal/llm/prompt/prompt.go 🔗

@@ -5,6 +5,9 @@ import (
 	"path/filepath"
 	"strings"
 	"sync"
+
+	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/env"
 )
 
 type PromptID string
@@ -21,7 +24,7 @@ func GetPrompt(promptID PromptID, provider string, contextPaths ...string) strin
 	basePrompt := ""
 	switch promptID {
 	case PromptCoder:
-		basePrompt = CoderPrompt(provider)
+		basePrompt = CoderPrompt(provider, contextPaths...)
 	case PromptTitle:
 		basePrompt = TitlePrompt()
 	case PromptTask:
@@ -38,6 +41,32 @@ func getContextFromPaths(workingDir string, contextPaths []string) string {
 	return processContextPaths(workingDir, contextPaths)
 }
 
+// expandPath expands ~ and environment variables in file paths
+func expandPath(path string) string {
+	// Handle tilde expansion
+	if strings.HasPrefix(path, "~/") {
+		homeDir, err := os.UserHomeDir()
+		if err == nil {
+			path = filepath.Join(homeDir, path[2:])
+		}
+	} else if path == "~" {
+		homeDir, err := os.UserHomeDir()
+		if err == nil {
+			path = homeDir
+		}
+	}
+
+	// Handle environment variable expansion using the same pattern as config
+	if strings.HasPrefix(path, "$") {
+		resolver := config.NewEnvironmentVariableResolver(env.New())
+		if expanded, err := resolver.ResolveValue(path); err == nil {
+			path = expanded
+		}
+	}
+
+	return path
+}
+
 func processContextPaths(workDir string, paths []string) string {
 	var (
 		wg       sync.WaitGroup
@@ -53,8 +82,23 @@ func processContextPaths(workDir string, paths []string) string {
 		go func(p string) {
 			defer wg.Done()
 
-			if strings.HasSuffix(p, "/") {
-				filepath.WalkDir(filepath.Join(workDir, p), func(path string, d os.DirEntry, err error) error {
+			// Expand ~ and environment variables before processing
+			p = expandPath(p)
+
+			// Use absolute path if provided, otherwise join with workDir
+			fullPath := p
+			if !filepath.IsAbs(p) {
+				fullPath = filepath.Join(workDir, p)
+			}
+
+			// Check if the path is a directory using os.Stat
+			info, err := os.Stat(fullPath)
+			if err != nil {
+				return // Skip if path doesn't exist or can't be accessed
+			}
+
+			if info.IsDir() {
+				filepath.WalkDir(fullPath, func(path string, d os.DirEntry, err error) error {
 					if err != nil {
 						return err
 					}
@@ -78,8 +122,7 @@ func processContextPaths(workDir string, paths []string) string {
 					return nil
 				})
 			} else {
-				fullPath := filepath.Join(workDir, p)
-
+				// It's a file, process it directly
 				// Check if we've already processed this file (case-insensitive)
 				lowerPath := strings.ToLower(fullPath)
 

internal/llm/prompt/prompt_test.go 🔗

@@ -0,0 +1,113 @@
+package prompt
+
+import (
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func TestExpandPath(t *testing.T) {
+	tests := []struct {
+		name     string
+		input    string
+		expected func() string
+	}{
+		{
+			name:  "regular path unchanged",
+			input: "/absolute/path",
+			expected: func() string {
+				return "/absolute/path"
+			},
+		},
+		{
+			name:  "tilde expansion",
+			input: "~/documents",
+			expected: func() string {
+				home, _ := os.UserHomeDir()
+				return filepath.Join(home, "documents")
+			},
+		},
+		{
+			name:  "tilde only",
+			input: "~",
+			expected: func() string {
+				home, _ := os.UserHomeDir()
+				return home
+			},
+		},
+		{
+			name:  "environment variable expansion",
+			input: "$HOME",
+			expected: func() string {
+				return os.Getenv("HOME")
+			},
+		},
+		{
+			name:  "relative path unchanged",
+			input: "relative/path",
+			expected: func() string {
+				return "relative/path"
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			result := expandPath(tt.input)
+			expected := tt.expected()
+
+			// Skip test if environment variable is not set
+			if strings.HasPrefix(tt.input, "$") && expected == "" {
+				t.Skip("Environment variable not set")
+			}
+
+			if result != expected {
+				t.Errorf("expandPath(%q) = %q, want %q", tt.input, result, expected)
+			}
+		})
+	}
+}
+
+func TestProcessContextPaths(t *testing.T) {
+	// Create a temporary directory and file for testing
+	tmpDir := t.TempDir()
+	testFile := filepath.Join(tmpDir, "test.txt")
+	testContent := "test content"
+
+	err := os.WriteFile(testFile, []byte(testContent), 0o644)
+	if err != nil {
+		t.Fatalf("Failed to create test file: %v", err)
+	}
+
+	// Test with absolute path to file
+	result := processContextPaths("", []string{testFile})
+	expected := "# From:" + testFile + "\n" + testContent
+
+	if result != expected {
+		t.Errorf("processContextPaths with absolute path failed.\nGot: %q\nWant: %q", result, expected)
+	}
+
+	// Test with directory path (should process all files in directory)
+	result = processContextPaths("", []string{tmpDir})
+	if !strings.Contains(result, testContent) {
+		t.Errorf("processContextPaths with directory path failed to include file content")
+	}
+
+	// Test with tilde expansion (if we can create a file in home directory)
+	tmpDir = t.TempDir()
+	t.Setenv("HOME", tmpDir)
+	homeTestFile := filepath.Join(tmpDir, "crush_test_file.txt")
+	err = os.WriteFile(homeTestFile, []byte(testContent), 0o644)
+	if err == nil {
+		defer os.Remove(homeTestFile) // Clean up
+
+		tildeFile := "~/crush_test_file.txt"
+		result = processContextPaths("", []string{tildeFile})
+		expected = "# From:" + homeTestFile + "\n" + testContent
+
+		if result != expected {
+			t.Errorf("processContextPaths with tilde expansion failed.\nGot: %q\nWant: %q", result, expected)
+		}
+	}
+}

internal/llm/provider/openai.go 🔗

@@ -38,7 +38,10 @@ func createOpenAIClient(opts providerClientOptions) openai.Client {
 		openaiClientOptions = append(openaiClientOptions, option.WithAPIKey(opts.apiKey))
 	}
 	if opts.baseURL != "" {
-		openaiClientOptions = append(openaiClientOptions, option.WithBaseURL(opts.baseURL))
+		resolvedBaseURL, err := config.Get().Resolve(opts.baseURL)
+		if err == nil {
+			openaiClientOptions = append(openaiClientOptions, option.WithBaseURL(resolvedBaseURL))
+		}
 	}
 
 	if opts.extraHeaders != nil {
@@ -269,10 +272,13 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
 			currentContent := ""
 			toolCalls := make([]message.ToolCall, 0)
 
+			var currentToolCallID string
+			var currentToolCall openai.ChatCompletionMessageToolCall
+			var msgToolCalls []openai.ChatCompletionMessageToolCall
 			for openaiStream.Next() {
 				chunk := openaiStream.Current()
 				acc.AddChunk(chunk)
-
+				// This fixes multiple tool calls for some providers
 				for _, choice := range chunk.Choices {
 					if choice.Delta.Content != "" {
 						eventChan <- ProviderEvent{
@@ -280,6 +286,45 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
 							Content: choice.Delta.Content,
 						}
 						currentContent += choice.Delta.Content
+					} else if len(choice.Delta.ToolCalls) > 0 {
+						toolCall := choice.Delta.ToolCalls[0]
+						// Detect tool use start
+						if currentToolCallID == "" {
+							if toolCall.ID != "" {
+								currentToolCallID = toolCall.ID
+								currentToolCall = openai.ChatCompletionMessageToolCall{
+									ID:   toolCall.ID,
+									Type: "function",
+									Function: openai.ChatCompletionMessageToolCallFunction{
+										Name:      toolCall.Function.Name,
+										Arguments: toolCall.Function.Arguments,
+									},
+								}
+							}
+						} else {
+							// Delta tool use
+							if toolCall.ID == "" {
+								currentToolCall.Function.Arguments += toolCall.Function.Arguments
+							} else {
+								// Detect new tool use
+								if toolCall.ID != currentToolCallID {
+									msgToolCalls = append(msgToolCalls, currentToolCall)
+									currentToolCallID = toolCall.ID
+									currentToolCall = openai.ChatCompletionMessageToolCall{
+										ID:   toolCall.ID,
+										Type: "function",
+										Function: openai.ChatCompletionMessageToolCallFunction{
+											Name:      toolCall.Function.Name,
+											Arguments: toolCall.Function.Arguments,
+										},
+									}
+								}
+							}
+						}
+					}
+					if choice.FinishReason == "tool_calls" {
+						msgToolCalls = append(msgToolCalls, currentToolCall)
+						acc.Choices[0].Message.ToolCalls = msgToolCalls
 					}
 				}
 			}
@@ -290,6 +335,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
 					jsonData, _ := json.Marshal(acc.ChatCompletion)
 					slog.Debug("Response", "messages", string(jsonData))
 				}
+
 				resultFinishReason := acc.ChatCompletion.Choices[0].FinishReason
 				if resultFinishReason == "" {
 					// If the finish reason is empty, we assume it was a successful completion

internal/llm/tools/bash.go 🔗

@@ -4,6 +4,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"log/slog"
 	"runtime"
 	"strings"
 	"time"
@@ -41,9 +42,74 @@ const (
 )
 
 var bannedCommands = []string{
-	"alias", "curl", "curlie", "wget", "axel", "aria2c",
-	"nc", "telnet", "lynx", "w3m", "links", "httpie", "xh",
-	"http-prompt", "chrome", "firefox", "safari",
+	// Network/Download tools
+	"alias",
+	"aria2c",
+	"axel",
+	"chrome",
+	"curl",
+	"curlie",
+	"firefox",
+	"http-prompt",
+	"httpie",
+	"links",
+	"lynx",
+	"nc",
+	"safari",
+	"telnet",
+	"w3m",
+	"wget",
+	"xh",
+
+	// System administration
+	"doas",
+	"su",
+	"sudo",
+
+	// Package managers
+	"apk",
+	"apt",
+	"apt-cache",
+	"apt-get",
+	"dnf",
+	"dpkg",
+	"emerge",
+	"home-manager",
+	"makepkg",
+	"opkg",
+	"pacman",
+	"paru",
+	"pkg",
+	"pkg_add",
+	"pkg_delete",
+	"portage",
+	"rpm",
+	"yay",
+	"yum",
+	"zypper",
+
+	// System modification
+	"at",
+	"batch",
+	"chkconfig",
+	"crontab",
+	"fdisk",
+	"mkfs",
+	"mount",
+	"parted",
+	"service",
+	"systemctl",
+	"umount",
+
+	// Network configuration
+	"firewall-cmd",
+	"ifconfig",
+	"ip",
+	"iptables",
+	"netstat",
+	"pfctl",
+	"route",
+	"ufw",
 }
 
 // getSafeReadOnlyCommands returns platform-appropriate safe commands
@@ -244,7 +310,42 @@ Important:
 - Never update git config`, bannedCommandsStr, MaxOutputLength)
 }
 
+func blockFuncs() []shell.BlockFunc {
+	return []shell.BlockFunc{
+		shell.CommandsBlocker(bannedCommands),
+		shell.ArgumentsBlocker([][]string{
+			// System package managers
+			{"apk", "add"},
+			{"apt", "install"},
+			{"apt-get", "install"},
+			{"dnf", "install"},
+			{"emerge"},
+			{"pacman", "-S"},
+			{"pkg", "install"},
+			{"yum", "install"},
+			{"zypper", "install"},
+
+			// Language-specific package managers
+			{"brew", "install"},
+			{"cargo", "install"},
+			{"gem", "install"},
+			{"go", "install"},
+			{"npm", "install", "-g"},
+			{"npm", "install", "--global"},
+			{"pip", "install", "--user"},
+			{"pip3", "install", "--user"},
+			{"pnpm", "add", "-g"},
+			{"pnpm", "add", "--global"},
+			{"yarn", "global", "add"},
+		}),
+	}
+}
+
 func NewBashTool(permission permission.Service, workingDir string) BaseTool {
+	// Set up command blocking on the persistent shell
+	persistentShell := shell.GetPersistentShell(workingDir)
+	persistentShell.SetBlockFuncs(blockFuncs())
+
 	return &bashTool{
 		permissions: permission,
 		workingDir:  workingDir,
@@ -289,13 +390,6 @@ func (b *bashTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error)
 		return NewTextErrorResponse("missing command"), nil
 	}
 
-	baseCmd := strings.Fields(params.Command)[0]
-	for _, banned := range bannedCommands {
-		if strings.EqualFold(baseCmd, banned) {
-			return NewTextErrorResponse(fmt.Sprintf("command '%s' is not allowed", baseCmd)), nil
-		}
-	}
-
 	isSafeReadOnly := false
 	cmdLower := strings.ToLower(params.Command)
 
@@ -349,7 +443,20 @@ func (b *bashTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error)
 	stdout = truncateOutput(stdout)
 	stderr = truncateOutput(stderr)
 
+	slog.Info("Bash command executed",
+		"command", params.Command,
+		"stdout", stdout,
+		"stderr", stderr,
+		"exit_code", exitCode,
+		"interrupted", interrupted,
+		"err", err,
+	)
+
 	errorMessage := stderr
+	if errorMessage == "" && err != nil {
+		errorMessage = err.Error()
+	}
+
 	if interrupted {
 		if errorMessage != "" {
 			errorMessage += "\n"

internal/lsp/transport.go 🔗

@@ -222,29 +222,32 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any
 	}
 
 	// Wait for response
-	resp := <-ch
-
-	if cfg.Options.DebugLSP {
-		slog.Debug("Received response", "id", id)
-	}
-
-	if resp.Error != nil {
-		return fmt.Errorf("request failed: %s (code: %d)", resp.Error.Message, resp.Error.Code)
-	}
+	select {
+	case <-ctx.Done():
+		return ctx.Err()
+	case resp := <-ch:
+		if cfg.Options.DebugLSP {
+			slog.Debug("Received response", "id", id)
+		}
 
-	if result != nil {
-		// If result is a json.RawMessage, just copy the raw bytes
-		if rawMsg, ok := result.(*json.RawMessage); ok {
-			*rawMsg = resp.Result
-			return nil
+		if resp.Error != nil {
+			return fmt.Errorf("request failed: %s (code: %d)", resp.Error.Message, resp.Error.Code)
 		}
-		// Otherwise unmarshal into the provided type
-		if err := json.Unmarshal(resp.Result, result); err != nil {
-			return fmt.Errorf("failed to unmarshal result: %w", err)
+
+		if result != nil {
+			// If result is a json.RawMessage, just copy the raw bytes
+			if rawMsg, ok := result.(*json.RawMessage); ok {
+				*rawMsg = resp.Result
+				return nil
+			}
+			// Otherwise unmarshal into the provided type
+			if err := json.Unmarshal(resp.Result, result); err != nil {
+				return fmt.Errorf("failed to unmarshal result: %w", err)
+			}
 		}
-	}
 
-	return nil
+		return nil
+	}
 }
 
 // Notify sends a notification (a request without an ID that doesn't expect a response)

internal/lsp/watcher/watcher.go 🔗

@@ -21,6 +21,7 @@ import (
 // WorkspaceWatcher manages LSP file watching
 type WorkspaceWatcher struct {
 	client        *lsp.Client
+	name          string
 	workspacePath string
 
 	debounceTime time.Duration
@@ -33,8 +34,9 @@ type WorkspaceWatcher struct {
 }
 
 // NewWorkspaceWatcher creates a new workspace watcher
-func NewWorkspaceWatcher(client *lsp.Client) *WorkspaceWatcher {
+func NewWorkspaceWatcher(name string, client *lsp.Client) *WorkspaceWatcher {
 	return &WorkspaceWatcher{
+		name:          name,
 		client:        client,
 		debounceTime:  300 * time.Millisecond,
 		debounceMap:   make(map[string]*time.Timer),
@@ -95,7 +97,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 	}
 
 	// Determine server type for specialized handling
-	serverName := getServerNameFromContext(ctx)
+	serverName := w.name
 	slog.Debug("Server type detected", "serverName", serverName)
 
 	// Check if this server has sent file watchers
@@ -325,17 +327,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
 	cfg := config.Get()
 	w.workspacePath = workspacePath
 
-	// Store the watcher in the context for later use
-	ctx = context.WithValue(ctx, "workspaceWatcher", w)
-
-	// If the server name isn't already in the context, try to detect it
-	if _, ok := ctx.Value("serverName").(string); !ok {
-		serverName := getServerNameFromContext(ctx)
-		ctx = context.WithValue(ctx, "serverName", serverName)
-	}
-
-	serverName := getServerNameFromContext(ctx)
-	slog.Debug("Starting workspace watcher", "workspacePath", workspacePath, "serverName", serverName)
+	slog.Debug("Starting workspace watcher", "workspacePath", workspacePath, "serverName", w.name)
 
 	// Register handler for file watcher registrations from the server
 	lsp.RegisterFileWatchHandler(func(id string, watchers []protocol.FileSystemWatcher) {
@@ -697,40 +689,6 @@ func (w *WorkspaceWatcher) notifyFileEvent(ctx context.Context, uri string, chan
 	return w.client.DidChangeWatchedFiles(ctx, params)
 }
 
-// getServerNameFromContext extracts the server name from the context
-// This is a best-effort function that tries to identify which LSP server we're dealing with
-func getServerNameFromContext(ctx context.Context) string {
-	// First check if the server name is directly stored in the context
-	if serverName, ok := ctx.Value("serverName").(string); ok && serverName != "" {
-		return strings.ToLower(serverName)
-	}
-
-	// Otherwise, try to extract server name from the client command path
-	if w, ok := ctx.Value("workspaceWatcher").(*WorkspaceWatcher); ok && w != nil && w.client != nil && w.client.Cmd != nil {
-		path := strings.ToLower(w.client.Cmd.Path)
-
-		// Extract server name from path
-		if strings.Contains(path, "typescript") || strings.Contains(path, "tsserver") || strings.Contains(path, "vtsls") {
-			return "typescript"
-		} else if strings.Contains(path, "gopls") {
-			return "gopls"
-		} else if strings.Contains(path, "rust-analyzer") {
-			return "rust-analyzer"
-		} else if strings.Contains(path, "pyright") || strings.Contains(path, "pylsp") || strings.Contains(path, "python") {
-			return "python"
-		} else if strings.Contains(path, "clangd") {
-			return "clangd"
-		} else if strings.Contains(path, "jdtls") || strings.Contains(path, "java") {
-			return "java"
-		}
-
-		// Return the base name as fallback
-		return filepath.Base(path)
-	}
-
-	return "unknown"
-}
-
 // shouldPreloadFiles determines if we should preload files for a specific language server
 // Some servers work better with preloaded files, others don't need it
 func shouldPreloadFiles(serverName string) bool {
@@ -884,64 +842,63 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
 	}
 
 	// Check if this path should be watched according to server registrations
-	if watched, _ := w.isPathWatched(path); watched {
-		// Get server name for specialized handling
-		serverName := getServerNameFromContext(ctx)
+	if watched, _ := w.isPathWatched(path); !watched {
+		return
+	}
 
-		// Check if the file is a high-priority file that should be opened immediately
-		// This helps with project initialization for certain language servers
-		if isHighPriorityFile(path, serverName) {
-			if cfg.Options.DebugLSP {
-				slog.Debug("Opening high-priority file", "path", path, "serverName", serverName)
-			}
-			if err := w.client.OpenFile(ctx, path); err != nil && cfg.Options.DebugLSP {
-				slog.Error("Error opening high-priority file", "path", path, "error", err)
-			}
-			return
-		}
+	serverName := w.name
 
-		// For non-high-priority files, we'll use different strategies based on server type
-		if shouldPreloadFiles(serverName) {
-			// For servers that benefit from preloading, open files but with limits
+	// Get server name for specialized handling
+	// Check if the file is a high-priority file that should be opened immediately
+	// This helps with project initialization for certain language servers
+	if isHighPriorityFile(path, serverName) {
+		if cfg.Options.DebugLSP {
+			slog.Debug("Opening high-priority file", "path", path, "serverName", serverName)
+		}
+		if err := w.client.OpenFile(ctx, path); err != nil && cfg.Options.DebugLSP {
+			slog.Error("Error opening high-priority file", "path", path, "error", err)
+		}
+		return
+	}
 
-			// Check file size - for preloading we're more conservative
-			if info.Size() > (1 * 1024 * 1024) { // 1MB limit for preloaded files
-				if cfg.Options.DebugLSP {
-					slog.Debug("Skipping large file for preloading", "path", path, "size", info.Size())
-				}
-				return
-			}
+	// For non-high-priority files, we'll use different strategies based on server type
+	if !shouldPreloadFiles(serverName) {
+		return
+	}
+	// For servers that benefit from preloading, open files but with limits
 
-			// Check file extension for common source files
-			ext := strings.ToLower(filepath.Ext(path))
+	// Check file size - for preloading we're more conservative
+	if info.Size() > (1 * 1024 * 1024) { // 1MB limit for preloaded files
+		if cfg.Options.DebugLSP {
+			slog.Debug("Skipping large file for preloading", "path", path, "size", info.Size())
+		}
+		return
+	}
 
-			// Only preload source files for the specific language
-			shouldOpen := false
+	// Check file extension for common source files
+	ext := strings.ToLower(filepath.Ext(path))
 
-			switch serverName {
-			case "typescript", "typescript-language-server", "tsserver", "vtsls":
-				shouldOpen = ext == ".ts" || ext == ".js" || ext == ".tsx" || ext == ".jsx"
-			case "gopls":
-				shouldOpen = ext == ".go"
-			case "rust-analyzer":
-				shouldOpen = ext == ".rs"
-			case "python", "pyright", "pylsp":
-				shouldOpen = ext == ".py"
-			case "clangd":
-				shouldOpen = ext == ".c" || ext == ".cpp" || ext == ".h" || ext == ".hpp"
-			case "java", "jdtls":
-				shouldOpen = ext == ".java"
-			default:
-				// For unknown servers, be conservative
-				shouldOpen = false
-			}
+	// Only preload source files for the specific language
+	var shouldOpen bool
+	switch serverName {
+	case "typescript", "typescript-language-server", "tsserver", "vtsls":
+		shouldOpen = ext == ".ts" || ext == ".js" || ext == ".tsx" || ext == ".jsx"
+	case "gopls":
+		shouldOpen = ext == ".go"
+	case "rust-analyzer":
+		shouldOpen = ext == ".rs"
+	case "python", "pyright", "pylsp":
+		shouldOpen = ext == ".py"
+	case "clangd":
+		shouldOpen = ext == ".c" || ext == ".cpp" || ext == ".h" || ext == ".hpp"
+	case "java", "jdtls":
+		shouldOpen = ext == ".java"
+	}
 
-			if shouldOpen {
-				// Don't need to check if it's already open - the client.OpenFile handles that
-				if err := w.client.OpenFile(ctx, path); err != nil && cfg.Options.DebugLSP {
-					slog.Error("Error opening file", "path", path, "error", err)
-				}
-			}
+	if shouldOpen {
+		// Don't need to check if it's already open - the client.OpenFile handles that
+		if err := w.client.OpenFile(ctx, path); err != nil && cfg.Options.DebugLSP {
+			slog.Error("Error opening file", "path", path, "error", err)
 		}
 	}
 }

internal/shell/command_block_test.go 🔗

@@ -0,0 +1,123 @@
+package shell
+
+import (
+	"context"
+	"os"
+	"strings"
+	"testing"
+)
+
+func TestCommandBlocking(t *testing.T) {
+	tests := []struct {
+		name        string
+		blockFuncs  []BlockFunc
+		command     string
+		shouldBlock bool
+	}{
+		{
+			name: "block simple command",
+			blockFuncs: []BlockFunc{
+				func(args []string) bool {
+					return len(args) > 0 && args[0] == "curl"
+				},
+			},
+			command:     "curl https://example.com",
+			shouldBlock: true,
+		},
+		{
+			name: "allow non-blocked command",
+			blockFuncs: []BlockFunc{
+				func(args []string) bool {
+					return len(args) > 0 && args[0] == "curl"
+				},
+			},
+			command:     "echo hello",
+			shouldBlock: false,
+		},
+		{
+			name: "block subcommand",
+			blockFuncs: []BlockFunc{
+				func(args []string) bool {
+					return len(args) >= 2 && args[0] == "brew" && args[1] == "install"
+				},
+			},
+			command:     "brew install wget",
+			shouldBlock: true,
+		},
+		{
+			name: "allow different subcommand",
+			blockFuncs: []BlockFunc{
+				func(args []string) bool {
+					return len(args) >= 2 && args[0] == "brew" && args[1] == "install"
+				},
+			},
+			command:     "brew list",
+			shouldBlock: false,
+		},
+		{
+			name: "block npm global install with -g",
+			blockFuncs: []BlockFunc{
+				ArgumentsBlocker([][]string{
+					{"npm", "install", "-g"},
+					{"npm", "install", "--global"},
+				}),
+			},
+			command:     "npm install -g typescript",
+			shouldBlock: true,
+		},
+		{
+			name: "block npm global install with --global",
+			blockFuncs: []BlockFunc{
+				ArgumentsBlocker([][]string{
+					{"npm", "install", "-g"},
+					{"npm", "install", "--global"},
+				}),
+			},
+			command:     "npm install --global typescript",
+			shouldBlock: true,
+		},
+		{
+			name: "allow npm local install",
+			blockFuncs: []BlockFunc{
+				ArgumentsBlocker([][]string{
+					{"npm", "install", "-g"},
+					{"npm", "install", "--global"},
+				}),
+			},
+			command:     "npm install typescript",
+			shouldBlock: false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			// Create a temporary directory for each test
+			tmpDir, err := os.MkdirTemp("", "shell-test-*")
+			if err != nil {
+				t.Fatalf("Failed to create temp dir: %v", err)
+			}
+			defer os.RemoveAll(tmpDir)
+
+			shell := NewShell(&Options{
+				WorkingDir: tmpDir,
+				BlockFuncs: tt.blockFuncs,
+			})
+
+			_, _, err = shell.Exec(context.Background(), tt.command)
+
+			if tt.shouldBlock {
+				if err == nil {
+					t.Errorf("Expected command to be blocked, but it was allowed")
+				} else if !strings.Contains(err.Error(), "not allowed for security reasons") {
+					t.Errorf("Expected security error, got: %v", err)
+				}
+			} else {
+				// For non-blocked commands, we might get other errors (like command not found)
+				// but we shouldn't get the security error
+				if err != nil && strings.Contains(err.Error(), "not allowed for security reasons") {
+					t.Errorf("Command was unexpectedly blocked: %v", err)
+				}
+			}
+		})
+	}
+}

internal/shell/shell.go 🔗

@@ -44,12 +44,16 @@ type noopLogger struct{}
 
 func (noopLogger) InfoPersist(msg string, keysAndValues ...interface{}) {}
 
+// BlockFunc is a function that determines if a command should be blocked
+type BlockFunc func(args []string) bool
+
 // Shell provides cross-platform shell execution with optional state persistence
 type Shell struct {
-	env    []string
-	cwd    string
-	mu     sync.Mutex
-	logger Logger
+	env        []string
+	cwd        string
+	mu         sync.Mutex
+	logger     Logger
+	blockFuncs []BlockFunc
 }
 
 // Options for creating a new shell
@@ -57,6 +61,7 @@ type Options struct {
 	WorkingDir string
 	Env        []string
 	Logger     Logger
+	BlockFuncs []BlockFunc
 }
 
 // NewShell creates a new shell instance with the given options
@@ -81,9 +86,10 @@ func NewShell(opts *Options) *Shell {
 	}
 
 	return &Shell{
-		cwd:    cwd,
-		env:    env,
-		logger: logger,
+		cwd:        cwd,
+		env:        env,
+		logger:     logger,
+		blockFuncs: opts.BlockFuncs,
 	}
 }
 
@@ -152,6 +158,13 @@ func (s *Shell) SetEnv(key, value string) {
 	s.env = append(s.env, keyPrefix+value)
 }
 
+// SetBlockFuncs sets the command block functions for the shell
+func (s *Shell) SetBlockFuncs(blockFuncs []BlockFunc) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.blockFuncs = blockFuncs
+}
+
 // Windows-specific commands that should use native shell
 var windowsNativeCommands = map[string]bool{
 	"dir":      true,
@@ -203,6 +216,60 @@ func (s *Shell) determineShellType(command string) ShellType {
 	return ShellTypePOSIX
 }
 
+// CommandsBlocker creates a BlockFunc that blocks exact command matches
+func CommandsBlocker(bannedCommands []string) BlockFunc {
+	bannedSet := make(map[string]bool)
+	for _, cmd := range bannedCommands {
+		bannedSet[cmd] = true
+	}
+
+	return func(args []string) bool {
+		if len(args) == 0 {
+			return false
+		}
+		return bannedSet[args[0]]
+	}
+}
+
+// ArgumentsBlocker creates a BlockFunc that blocks specific subcommands
+func ArgumentsBlocker(blockedSubCommands [][]string) BlockFunc {
+	return func(args []string) bool {
+		for _, blocked := range blockedSubCommands {
+			if len(args) >= len(blocked) {
+				match := true
+				for i, part := range blocked {
+					if args[i] != part {
+						match = false
+						break
+					}
+				}
+				if match {
+					return true
+				}
+			}
+		}
+		return false
+	}
+}
+
+func (s *Shell) blockHandler() func(next interp.ExecHandlerFunc) interp.ExecHandlerFunc {
+	return func(next interp.ExecHandlerFunc) interp.ExecHandlerFunc {
+		return func(ctx context.Context, args []string) error {
+			if len(args) == 0 {
+				return next(ctx, args)
+			}
+
+			for _, blockFunc := range s.blockFuncs {
+				if blockFunc(args) {
+					return fmt.Errorf("command is not allowed for security reasons: %s", strings.Join(args, " "))
+				}
+			}
+
+			return next(ctx, args)
+		}
+	}
+}
+
 // execWindows executes commands using native Windows shells (cmd.exe or PowerShell)
 func (s *Shell) execWindows(ctx context.Context, command string, shell string) (string, string, error) {
 	var cmd *exec.Cmd
@@ -291,6 +358,7 @@ func (s *Shell) execPOSIX(ctx context.Context, command string) (string, string,
 		interp.Interactive(false),
 		interp.Env(expand.ListEnviron(s.env...)),
 		interp.Dir(s.cwd),
+		interp.ExecHandlers(s.blockHandler()),
 	)
 	if err != nil {
 		return "", "", fmt.Errorf("could not run command: %w", err)

internal/tui/components/chat/chat.go 🔗

@@ -14,8 +14,8 @@ import (
 	"github.com/charmbracelet/crush/internal/tui/components/chat/messages"
 	"github.com/charmbracelet/crush/internal/tui/components/core/layout"
 	"github.com/charmbracelet/crush/internal/tui/components/core/list"
+	"github.com/charmbracelet/crush/internal/tui/styles"
 	"github.com/charmbracelet/crush/internal/tui/util"
-	"github.com/charmbracelet/lipgloss/v2"
 )
 
 type SendMsg struct {
@@ -37,6 +37,9 @@ type MessageListCmp interface {
 	util.Model
 	layout.Sizeable
 	layout.Focusable
+	layout.Help
+
+	SetSession(session.Session) tea.Cmd
 }
 
 // messageListCmp implements MessageListCmp, providing a virtualized list
@@ -53,9 +56,9 @@ type messageListCmp struct {
 	defaultListKeyMap   list.KeyMap
 }
 
-// NewMessagesListCmp creates a new message list component with custom keybindings
+// New creates a new message list component with custom keybindings
 // and reverse ordering (newest messages at bottom).
-func NewMessagesListCmp(app *app.App) MessageListCmp {
+func New(app *app.App) MessageListCmp {
 	defaultListKeyMap := list.DefaultKeyMap()
 	listCmp := list.New(
 		list.WithGapSize(1),
@@ -70,7 +73,7 @@ func NewMessagesListCmp(app *app.App) MessageListCmp {
 	}
 }
 
-// Init initializes the component (no initialization needed).
+// Init initializes the component.
 func (m *messageListCmp) Init() tea.Cmd {
 	return tea.Sequence(m.listCmp.Init(), m.listCmp.Blur())
 }
@@ -102,16 +105,20 @@ func (m *messageListCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 // View renders the message list or an initial screen if empty.
 func (m *messageListCmp) View() string {
-	return lipgloss.JoinVertical(
-		lipgloss.Left,
-		m.listCmp.View(),
-	)
+	t := styles.CurrentTheme()
+	return t.S().Base.
+		Padding(1).
+		Width(m.width).
+		Height(m.height).
+		Render(
+			m.listCmp.View(),
+		)
 }
 
 // handleChildSession handles messages from child sessions (agent tools).
 func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message]) tea.Cmd {
 	var cmds []tea.Cmd
-	if len(event.Payload.ToolCalls()) == 0 {
+	if len(event.Payload.ToolCalls()) == 0 && len(event.Payload.ToolResults()) == 0 {
 		return nil
 	}
 	items := m.listCmp.Items()
@@ -151,6 +158,15 @@ func (m *messageListCmp) handleChildSession(event pubsub.Event[message.Message])
 			)
 		}
 	}
+	for _, tr := range event.Payload.ToolResults() {
+		for nestedInx, nestedTC := range nestedToolCalls {
+			if nestedTC.GetToolCall().ID == tr.ToolCallID {
+				nestedToolCalls[nestedInx].SetToolResult(tr)
+				break
+			}
+		}
+	}
+
 	toolCall.SetNestedToolCalls(nestedToolCalls)
 	m.listCmp.UpdateItem(
 		toolCallInx,
@@ -487,8 +503,8 @@ func (m *messageListCmp) GetSize() (int, int) {
 // SetSize updates the component dimensions and propagates to the list component.
 func (m *messageListCmp) SetSize(width int, height int) tea.Cmd {
 	m.width = width
-	m.height = height - 1
-	return m.listCmp.SetSize(width, height-1)
+	m.height = height
+	return m.listCmp.SetSize(width-2, height-2) // for padding
 }
 
 // Blur implements MessageListCmp.

internal/tui/components/chat/editor/editor.go 🔗

@@ -18,6 +18,7 @@ import (
 	"github.com/charmbracelet/crush/internal/session"
 	"github.com/charmbracelet/crush/internal/tui/components/chat"
 	"github.com/charmbracelet/crush/internal/tui/components/completions"
+	"github.com/charmbracelet/crush/internal/tui/components/core/layout"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/filepicker"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/quit"
@@ -26,6 +27,18 @@ import (
 	"github.com/charmbracelet/lipgloss/v2"
 )
 
+type Editor interface {
+	util.Model
+	layout.Sizeable
+	layout.Focusable
+	layout.Help
+	layout.Positional
+
+	SetSession(session session.Session) tea.Cmd
+	IsCompletionsOpen() bool
+	Cursor() *tea.Cursor
+}
+
 type FileCompletionItem struct {
 	Path string // The file path
 }
@@ -67,7 +80,11 @@ const (
 	maxAttachments = 5
 )
 
-func (m *editorCmp) openEditor() tea.Cmd {
+type openEditorMsg struct {
+	Text string
+}
+
+func (m *editorCmp) openEditor(value string) tea.Cmd {
 	editor := os.Getenv("EDITOR")
 	if editor == "" {
 		// Use platform-appropriate default editor
@@ -82,7 +99,10 @@ func (m *editorCmp) openEditor() tea.Cmd {
 	if err != nil {
 		return util.ReportError(err)
 	}
-	tmpfile.Close()
+	defer tmpfile.Close() //nolint:errcheck
+	if _, err := tmpfile.WriteString(value); err != nil {
+		return util.ReportError(err)
+	}
 	c := exec.Command(editor, tmpfile.Name())
 	c.Stdin = os.Stdin
 	c.Stdout = os.Stdout
@@ -99,11 +119,8 @@ func (m *editorCmp) openEditor() tea.Cmd {
 			return util.ReportWarn("Message is empty")
 		}
 		os.Remove(tmpfile.Name())
-		attachments := m.attachments
-		m.attachments = nil
-		return chat.SendMsg{
-			Text:        string(content),
-			Attachments: attachments,
+		return openEditorMsg{
+			Text: strings.TrimSpace(string(content)),
 		}
 	})
 }
@@ -145,11 +162,6 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	var cmd tea.Cmd
 	var cmds []tea.Cmd
 	switch msg := msg.(type) {
-	case chat.SessionSelectedMsg:
-		if msg.ID != m.session.ID {
-			m.session = msg
-		}
-		return m, nil
 	case filepicker.FilePickedMsg:
 		if len(m.attachments) >= maxAttachments {
 			return m, util.ReportError(fmt.Errorf("cannot add more than %d images", maxAttachments))
@@ -178,6 +190,9 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			m.completionsStartIndex = 0
 			return m, nil
 		}
+	case openEditorMsg:
+		m.textarea.SetValue(msg.Text)
+		m.textarea.MoveToEnd()
 	case tea.KeyPressMsg:
 		switch {
 		// Completions
@@ -239,19 +254,21 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			if m.app.CoderAgent.IsSessionBusy(m.session.ID) {
 				return m, util.ReportWarn("Agent is working, please wait...")
 			}
-			return m, m.openEditor()
+			return m, m.openEditor(m.textarea.Value())
 		}
 		if key.Matches(msg, DeleteKeyMaps.Escape) {
 			m.deleteMode = false
 			return m, nil
 		}
-		// Hanlde Enter key
+		if key.Matches(msg, m.keyMap.Newline) {
+			m.textarea.InsertRune('\n')
+		}
+		// Handle Enter key
 		if m.textarea.Focused() && key.Matches(msg, m.keyMap.SendMessage) {
 			value := m.textarea.Value()
 			if len(value) > 0 && value[len(value)-1] == '\\' {
 				// If the last character is a backslash, remove it and add a newline
-				m.textarea.SetValue(value[:len(value)-1] + "\n")
-				return m, nil
+				m.textarea.SetValue(value[:len(value)-1])
 			} else {
 				// Otherwise, send the message
 				return m, m.send()
@@ -344,8 +361,9 @@ func (m *editorCmp) startCompletions() tea.Msg {
 		})
 	}
 
-	x := m.textarea.Cursor().X + m.x + 1
-	y := m.textarea.Cursor().Y + m.y + 1
+	cur := m.textarea.Cursor()
+	x := cur.X + m.x // adjust for padding
+	y := cur.Y + m.y + 1
 	return completions.OpenCompletionsMsg{
 		Completions: completionItems,
 		X:           x,
@@ -369,19 +387,31 @@ func (c *editorCmp) IsFocused() bool {
 	return c.textarea.Focused()
 }
 
+// Bindings implements Container.
 func (c *editorCmp) Bindings() []key.Binding {
 	return c.keyMap.KeyBindings()
 }
 
-func NewEditorCmp(app *app.App) util.Model {
+// TODO: most likely we do not need to have the session here
+// we need to move some functionality to the page level
+func (c *editorCmp) SetSession(session session.Session) tea.Cmd {
+	c.session = session
+	return nil
+}
+
+func (c *editorCmp) IsCompletionsOpen() bool {
+	return c.isCompletionsOpen
+}
+
+func New(app *app.App) Editor {
 	t := styles.CurrentTheme()
 	ta := textarea.New()
 	ta.SetStyles(t.S().TextArea)
-	ta.SetPromptFunc(4, func(lineIndex int, focused bool) string {
-		if lineIndex == 0 {
+	ta.SetPromptFunc(4, func(info textarea.PromptInfo) string {
+		if info.LineNumber == 0 {
 			return "  > "
 		}
-		if focused {
+		if info.Focused {
 			return t.S().Base.Foreground(t.GreenDark).Render("::: ")
 		} else {
 			return t.S().Muted.Render("::: ")
@@ -394,6 +424,7 @@ func NewEditorCmp(app *app.App) util.Model {
 	ta.Focus()
 
 	return &editorCmp{
+		// TODO: remove the app instance from here
 		app:      app,
 		textarea: ta,
 		keyMap:   DefaultEditorKeyMap(),

internal/tui/components/chat/editor/keys.go 🔗

@@ -8,6 +8,7 @@ type EditorKeyMap struct {
 	AddFile     key.Binding
 	SendMessage key.Binding
 	OpenEditor  key.Binding
+	Newline     key.Binding
 }
 
 func DefaultEditorKeyMap() EditorKeyMap {
@@ -21,8 +22,15 @@ func DefaultEditorKeyMap() EditorKeyMap {
 			key.WithHelp("enter", "send"),
 		),
 		OpenEditor: key.NewBinding(
-			key.WithKeys("ctrl+e"),
-			key.WithHelp("ctrl+e", "open editor"),
+			key.WithKeys("ctrl+v"),
+			key.WithHelp("ctrl+v", "open editor"),
+		),
+		Newline: key.NewBinding(
+			key.WithKeys("shift+enter", "ctrl+j"),
+			// "ctrl+j" is a common keybinding for newline in many editors. If
+			// the terminal supports "shift+enter", we substitute the help text
+			// to reflect that.
+			key.WithHelp("ctrl+j", "newline"),
 		),
 	}
 }
@@ -33,6 +41,7 @@ func (k EditorKeyMap) KeyBindings() []key.Binding {
 		k.AddFile,
 		k.SendMessage,
 		k.OpenEditor,
+		k.Newline,
 	}
 }
 

internal/tui/components/chat/header/header.go 🔗

@@ -11,7 +11,6 @@ import (
 	"github.com/charmbracelet/crush/internal/lsp/protocol"
 	"github.com/charmbracelet/crush/internal/pubsub"
 	"github.com/charmbracelet/crush/internal/session"
-	"github.com/charmbracelet/crush/internal/tui/components/chat"
 	"github.com/charmbracelet/crush/internal/tui/styles"
 	"github.com/charmbracelet/crush/internal/tui/util"
 	"github.com/charmbracelet/lipgloss/v2"
@@ -19,7 +18,8 @@ import (
 
 type Header interface {
 	util.Model
-	SetSession(session session.Session)
+	SetSession(session session.Session) tea.Cmd
+	SetWidth(width int) tea.Cmd
 	SetDetailsOpen(open bool)
 }
 
@@ -43,10 +43,6 @@ func (h *header) Init() tea.Cmd {
 
 func (p *header) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
-	case tea.WindowSizeMsg:
-		p.width = msg.Width - 2
-	case chat.SessionSelectedMsg:
-		p.session = msg
 	case pubsub.Event[session.Session]:
 		if msg.Type == pubsub.UpdatedEvent {
 			if p.session.ID == msg.Payload.ID {
@@ -131,6 +127,13 @@ func (h *header) SetDetailsOpen(open bool) {
 }
 
 // SetSession implements Header.
-func (h *header) SetSession(session session.Session) {
+func (h *header) SetSession(session session.Session) tea.Cmd {
 	h.session = session
+	return nil
+}
+
+// SetWidth implements Header.
+func (h *header) SetWidth(width int) tea.Cmd {
+	h.width = width
+	return nil
 }

internal/tui/components/chat/messages/messages.go 🔗

@@ -10,6 +10,7 @@ import (
 	"github.com/charmbracelet/lipgloss/v2"
 
 	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/fur/provider"
 	"github.com/charmbracelet/crush/internal/message"
 	"github.com/charmbracelet/crush/internal/tui/components/anim"
 	"github.com/charmbracelet/crush/internal/tui/components/core"
@@ -65,10 +66,7 @@ func NewMessageCmp(msg message.Message) MessageCmp {
 // Returns a command to start the animation for spinning messages.
 func (m *messageCmp) Init() tea.Cmd {
 	m.spinning = m.shouldSpin()
-	if m.spinning {
-		return m.anim.Init()
-	}
-	return nil
+	return m.anim.Init()
 }
 
 // Update handles incoming messages and updates the component state.
@@ -296,6 +294,12 @@ func (m *assistantSectionModel) View() string {
 	infoMsg := t.S().Subtle.Render(duration.String())
 	icon := t.S().Subtle.Render(styles.ModelIcon)
 	model := config.Get().GetModel(m.message.Provider, m.message.Model)
+	if model == nil {
+		// This means the model is not configured anymore
+		model = &provider.Model{
+			Model: "Unknown Model",
+		}
+	}
 	modelFormatted := t.S().Muted.Render(model.Model)
 	assistant := fmt.Sprintf("%s %s %s", icon, modelFormatted, infoMsg)
 	return t.S().Base.PaddingLeft(2).Render(

internal/tui/components/chat/messages/renderer.go 🔗

@@ -112,10 +112,21 @@ func (br baseRenderer) unmarshalParams(input string, target any) error {
 }
 
 // makeHeader builds the tool call header with status icon and parameters for a nested tool call.
-func (br baseRenderer) makeNestedHeader(_ *toolCallCmp, tool string, width int, params ...string) string {
+func (br baseRenderer) makeNestedHeader(v *toolCallCmp, tool string, width int, params ...string) string {
 	t := styles.CurrentTheme()
+	icon := t.S().Base.Foreground(t.GreenDark).Render(styles.ToolPending)
+	if v.result.ToolCallID != "" {
+		if v.result.IsError {
+			icon = t.S().Base.Foreground(t.RedDark).Render(styles.ToolError)
+		} else {
+			icon = t.S().Base.Foreground(t.Green).Render(styles.ToolSuccess)
+		}
+	} else if v.cancelled {
+		icon = t.S().Muted.Render(styles.ToolPending)
+	}
 	tool = t.S().Base.Foreground(t.FgHalfMuted).Render(tool) + " "
-	return tool + renderParamList(true, width-lipgloss.Width(tool), params...)
+	prefix := fmt.Sprintf("%s %s ", icon, tool)
+	return prefix + renderParamList(true, width-lipgloss.Width(tool), params...)
 }
 
 // makeHeader builds "<Tool>: param (key=value)" and truncates as needed.
@@ -196,6 +207,7 @@ func (br bashRenderer) Render(v *toolCallCmp) string {
 	}
 
 	cmd := strings.ReplaceAll(params.Command, "\n", " ")
+	cmd = strings.ReplaceAll(cmd, "\t", "    ")
 	args := newParamBuilder().addMain(cmd).build()
 
 	return br.renderWithParams(v, "Bash", args, func() string {
@@ -542,7 +554,7 @@ func (tr agentRenderer) Render(v *toolCallCmp) string {
 
 	if v.result.ToolCallID == "" {
 		v.spinning = true
-		parts = append(parts, v.anim.View())
+		parts = append(parts, "", v.anim.View())
 	} else {
 		v.spinning = false
 	}
@@ -567,8 +579,8 @@ func renderParamList(nested bool, paramsWidth int, params ...string) string {
 		return ""
 	}
 	mainParam := params[0]
-	if len(mainParam) > paramsWidth {
-		mainParam = mainParam[:paramsWidth-3] + "…"
+	if paramsWidth >= 0 && lipgloss.Width(mainParam) > paramsWidth {
+		mainParam = ansi.Truncate(mainParam, paramsWidth, "…")
 	}
 
 	if len(params) == 1 {
@@ -621,9 +633,9 @@ func earlyState(header string, v *toolCallCmp) (string, bool) {
 	case v.result.IsError:
 		message = v.renderToolError()
 	case v.cancelled:
-		message = t.S().Base.Padding(0, 1).Background(t.Border).Render("Cancelled")
+		message = t.S().Base.Foreground(t.FgSubtle).Render("Canceled.")
 	case v.result.ToolCallID == "":
-		message = t.S().Base.Padding(0, 1).Background(t.Accent).Foreground(t.FgSubtle).Render("Waiting for tool to start...")
+		message = t.S().Base.Foreground(t.FgSubtle).Render("Waiting for tool to start...")
 	default:
 		return "", false
 	}
@@ -634,8 +646,11 @@ func earlyState(header string, v *toolCallCmp) (string, bool) {
 
 func joinHeaderBody(header, body string) string {
 	t := styles.CurrentTheme()
+	if body == "" {
+		return header
+	}
 	body = t.S().Base.PaddingLeft(2).Render(body)
-	return lipgloss.JoinVertical(lipgloss.Left, header, "", body, "")
+	return lipgloss.JoinVertical(lipgloss.Left, header, "", body)
 }
 
 func renderPlainContent(v *toolCallCmp, content string) string {

internal/tui/components/chat/messages/tool.go 🔗

@@ -114,10 +114,7 @@ func NewToolCallCmp(parentMessageID string, tc message.ToolCall, opts ...ToolCal
 // Returns a command to start the animation for pending tool calls.
 func (m *toolCallCmp) Init() tea.Cmd {
 	m.spinning = m.shouldSpin()
-	if m.spinning {
-		return m.anim.Init()
-	}
-	return nil
+	return m.anim.Init()
 }
 
 // Update handles incoming messages and updates the component state.
@@ -219,11 +216,11 @@ func (m *toolCallCmp) SetIsNested(isNested bool) {
 // renderPending displays the tool name with a loading animation for pending tool calls
 func (m *toolCallCmp) renderPending() string {
 	t := styles.CurrentTheme()
+	icon := t.S().Base.Foreground(t.GreenDark).Render(styles.ToolPending)
 	if m.isNested {
 		tool := t.S().Base.Foreground(t.FgHalfMuted).Render(prettifyToolName(m.call.Name))
-		return fmt.Sprintf("%s %s", tool, m.anim.View())
+		return fmt.Sprintf("%s %s %s", icon, tool, m.anim.View())
 	}
-	icon := t.S().Base.Foreground(t.GreenDark).Render(styles.ToolPending)
 	tool := t.S().Base.Foreground(t.Blue).Render(prettifyToolName(m.call.Name))
 	return fmt.Sprintf("%s %s %s", icon, tool, m.anim.View())
 }

internal/tui/components/chat/sidebar/sidebar.go 🔗

@@ -13,7 +13,6 @@ import (
 	"github.com/charmbracelet/crush/internal/diff"
 	"github.com/charmbracelet/crush/internal/fsext"
 	"github.com/charmbracelet/crush/internal/history"
-
 	"github.com/charmbracelet/crush/internal/lsp"
 	"github.com/charmbracelet/crush/internal/lsp/protocol"
 	"github.com/charmbracelet/crush/internal/pubsub"
@@ -29,10 +28,6 @@ import (
 	"github.com/charmbracelet/x/ansi"
 )
 
-const (
-	logoBreakpoint = 65
-)
-
 type FileHistory struct {
 	initialVersion history.File
 	latestVersion  history.File
@@ -52,6 +47,7 @@ type Sidebar interface {
 	util.Model
 	layout.Sizeable
 	SetSession(session session.Session) tea.Cmd
+	SetCompactMode(bool)
 }
 
 type sidebarCmp struct {
@@ -66,7 +62,7 @@ type sidebarCmp struct {
 	files sync.Map
 }
 
-func NewSidebarCmp(history history.Service, lspClients map[string]*lsp.Client, compact bool) Sidebar {
+func New(history history.Service, lspClients map[string]*lsp.Client, compact bool) Sidebar {
 	return &sidebarCmp{
 		lspClients:  lspClients,
 		history:     history,
@@ -75,15 +71,11 @@ func NewSidebarCmp(history history.Service, lspClients map[string]*lsp.Client, c
 }
 
 func (m *sidebarCmp) Init() tea.Cmd {
-	m.logo = m.logoBlock(false)
-	m.cwd = cwd()
 	return nil
 }
 
 func (m *sidebarCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
-	case chat.SessionSelectedMsg:
-		return m, m.SetSession(msg)
 	case SessionFilesMsg:
 		m.files = sync.Map{}
 		for _, file := range msg.Files {
@@ -137,7 +129,16 @@ func (m *sidebarCmp) View() string {
 		m.mcpBlock(),
 	)
 
-	return lipgloss.JoinVertical(lipgloss.Left, parts...)
+	style := t.S().Base.
+		Width(m.width).
+		Height(m.height).
+		Padding(1)
+	if m.compactMode {
+		style = style.PaddingTop(0)
+	}
+	return style.Render(
+		lipgloss.JoinVertical(lipgloss.Left, parts...),
+	)
 }
 
 func (m *sidebarCmp) handleFileHistoryEvent(event pubsub.Event[history.File]) tea.Cmd {
@@ -230,12 +231,8 @@ func (m *sidebarCmp) loadSessionFiles() tea.Msg {
 }
 
 func (m *sidebarCmp) SetSize(width, height int) tea.Cmd {
-	if width < logoBreakpoint && (m.width == 0 || m.width >= logoBreakpoint) {
-		m.logo = m.logoBlock(true)
-	} else if width >= logoBreakpoint && (m.width == 0 || m.width < logoBreakpoint) {
-		m.logo = m.logoBlock(false)
-	}
-
+	m.logo = m.logoBlock()
+	m.cwd = cwd()
 	m.width = width
 	m.height = height
 	return nil
@@ -245,23 +242,27 @@ func (m *sidebarCmp) GetSize() (int, int) {
 	return m.width, m.height
 }
 
-func (m *sidebarCmp) logoBlock(compact bool) string {
+func (m *sidebarCmp) logoBlock() string {
 	t := styles.CurrentTheme()
-	return logo.Render(version.Version, compact, logo.Opts{
+	return logo.Render(version.Version, true, logo.Opts{
 		FieldColor:   t.Primary,
 		TitleColorA:  t.Secondary,
 		TitleColorB:  t.Primary,
 		CharmColor:   t.Secondary,
 		VersionColor: t.Primary,
+		Width:        m.width - 2,
 	})
 }
 
+func (m *sidebarCmp) getMaxWidth() int {
+	return min(m.width-2, 58) // -2 for padding
+}
+
 func (m *sidebarCmp) filesBlock() string {
-	maxWidth := min(m.width, 58)
 	t := styles.CurrentTheme()
 
 	section := t.S().Subtle.Render(
-		core.Section("Modified Files", maxWidth),
+		core.Section("Modified Files", m.getMaxWidth()),
 	)
 
 	files := make([]SessionFile, 0)
@@ -302,7 +303,7 @@ func (m *sidebarCmp) filesBlock() string {
 		filePath := file.FilePath
 		filePath = strings.TrimPrefix(filePath, cwd)
 		filePath = fsext.DirTrim(fsext.PrettyPath(filePath), 2)
-		filePath = ansi.Truncate(filePath, maxWidth-lipgloss.Width(extraContent)-2, "…")
+		filePath = ansi.Truncate(filePath, m.getMaxWidth()-lipgloss.Width(extraContent)-2, "…")
 		fileList = append(fileList,
 			core.Status(
 				core.StatusOpts{
@@ -311,7 +312,7 @@ func (m *sidebarCmp) filesBlock() string {
 					Title:        filePath,
 					ExtraContent: extraContent,
 				},
-				m.width,
+				m.getMaxWidth(),
 			),
 		)
 	}
@@ -323,11 +324,10 @@ func (m *sidebarCmp) filesBlock() string {
 }
 
 func (m *sidebarCmp) lspBlock() string {
-	maxWidth := min(m.width, 58)
 	t := styles.CurrentTheme()
 
 	section := t.S().Subtle.Render(
-		core.Section("LSPs", maxWidth),
+		core.Section("LSPs", m.getMaxWidth()),
 	)
 
 	lspList := []string{section, ""}
@@ -385,7 +385,7 @@ func (m *sidebarCmp) lspBlock() string {
 					Description:  l.LSP.Command,
 					ExtraContent: strings.Join(errs, " "),
 				},
-				m.width,
+				m.getMaxWidth(),
 			),
 		)
 	}
@@ -397,11 +397,10 @@ func (m *sidebarCmp) lspBlock() string {
 }
 
 func (m *sidebarCmp) mcpBlock() string {
-	maxWidth := min(m.width, 58)
 	t := styles.CurrentTheme()
 
 	section := t.S().Subtle.Render(
-		core.Section("MCPs", maxWidth),
+		core.Section("MCPs", m.getMaxWidth()),
 	)
 
 	mcpList := []string{section, ""}
@@ -428,7 +427,7 @@ func (m *sidebarCmp) mcpBlock() string {
 					Title:       l.Name,
 					Description: l.MCP.Command,
 				},
-				m.width,
+				m.getMaxWidth(),
 			),
 		)
 	}
@@ -511,6 +510,11 @@ func (m *sidebarCmp) SetSession(session session.Session) tea.Cmd {
 	return m.loadSessionFiles
 }
 
+// SetCompactMode sets the compact mode for the sidebar.
+func (m *sidebarCmp) SetCompactMode(compact bool) {
+	m.compactMode = compact
+}
+
 func cwd() string {
 	cwd := config.Get().WorkingDir()
 	t := styles.CurrentTheme()

internal/tui/components/chat/splash/keys.go 🔗

@@ -5,14 +5,49 @@ import (
 )
 
 type KeyMap struct {
-	Cancel key.Binding
+	Select,
+	Next,
+	Previous,
+	Yes,
+	No,
+	Tab,
+	LeftRight,
+	Back key.Binding
 }
 
 func DefaultKeyMap() KeyMap {
 	return KeyMap{
-		Cancel: key.NewBinding(
+		Select: key.NewBinding(
+			key.WithKeys("enter", "ctrl+y"),
+			key.WithHelp("enter", "confirm"),
+		),
+		Next: key.NewBinding(
+			key.WithKeys("down", "ctrl+n"),
+			key.WithHelp("↓", "next item"),
+		),
+		Previous: key.NewBinding(
+			key.WithKeys("up", "ctrl+p"),
+			key.WithHelp("↑", "previous item"),
+		),
+		Yes: key.NewBinding(
+			key.WithKeys("y", "Y"),
+			key.WithHelp("y", "yes"),
+		),
+		No: key.NewBinding(
+			key.WithKeys("n", "N"),
+			key.WithHelp("n", "no"),
+		),
+		Tab: key.NewBinding(
+			key.WithKeys("tab"),
+			key.WithHelp("tab", "switch"),
+		),
+		LeftRight: key.NewBinding(
+			key.WithKeys("left", "right"),
+			key.WithHelp("←/→", "switch"),
+		),
+		Back: key.NewBinding(
 			key.WithKeys("esc"),
-			key.WithHelp("esc", "cancel"),
+			key.WithHelp("esc", "back"),
 		),
 	}
 }

internal/tui/components/chat/splash/splash.go 🔗

@@ -1,9 +1,22 @@
 package splash
 
 import (
+	"fmt"
+	"os"
+	"slices"
+	"strings"
+
 	"github.com/charmbracelet/bubbles/v2/key"
 	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/fur/provider"
+	"github.com/charmbracelet/crush/internal/llm/prompt"
+	"github.com/charmbracelet/crush/internal/tui/components/chat"
+	"github.com/charmbracelet/crush/internal/tui/components/completions"
+	"github.com/charmbracelet/crush/internal/tui/components/core"
 	"github.com/charmbracelet/crush/internal/tui/components/core/layout"
+	"github.com/charmbracelet/crush/internal/tui/components/core/list"
+	"github.com/charmbracelet/crush/internal/tui/components/dialogs/models"
 	"github.com/charmbracelet/crush/internal/tui/components/logo"
 	"github.com/charmbracelet/crush/internal/tui/styles"
 	"github.com/charmbracelet/crush/internal/tui/util"
@@ -15,23 +28,98 @@ type Splash interface {
 	util.Model
 	layout.Sizeable
 	layout.Help
+	Cursor() *tea.Cursor
+	// SetOnboarding controls whether the splash shows model selection UI
+	SetOnboarding(bool)
+	// SetProjectInit controls whether the splash shows project initialization prompt
+	SetProjectInit(bool)
+
+	// Showing API key input
+	IsShowingAPIKey() bool
 }
 
+const (
+	SplashScreenPaddingY = 1 // Padding Y for the splash screen
+
+	LogoGap = 6
+)
+
+// OnboardingCompleteMsg is sent when onboarding is complete
+type OnboardingCompleteMsg struct{}
+
 type splashCmp struct {
 	width, height int
 	keyMap        KeyMap
 	logoRendered  string
+
+	// State
+	isOnboarding     bool
+	needsProjectInit bool
+	needsAPIKey      bool
+	selectedNo       bool
+
+	listHeight    int
+	modelList     *models.ModelListComponent
+	apiKeyInput   *models.APIKeyInput
+	selectedModel *models.ModelOption
 }
 
 func New() Splash {
+	keyMap := DefaultKeyMap()
+	listKeyMap := list.DefaultKeyMap()
+	listKeyMap.Down.SetEnabled(false)
+	listKeyMap.Up.SetEnabled(false)
+	listKeyMap.HalfPageDown.SetEnabled(false)
+	listKeyMap.HalfPageUp.SetEnabled(false)
+	listKeyMap.Home.SetEnabled(false)
+	listKeyMap.End.SetEnabled(false)
+	listKeyMap.DownOneItem = keyMap.Next
+	listKeyMap.UpOneItem = keyMap.Previous
+
+	t := styles.CurrentTheme()
+	inputStyle := t.S().Base.Padding(0, 1, 0, 1)
+	modelList := models.NewModelListComponent(listKeyMap, inputStyle, "Find your fave")
+	apiKeyInput := models.NewAPIKeyInput()
+
 	return &splashCmp{
 		width:        0,
 		height:       0,
-		keyMap:       DefaultKeyMap(),
+		keyMap:       keyMap,
 		logoRendered: "",
+		modelList:    modelList,
+		apiKeyInput:  apiKeyInput,
+		selectedNo:   false,
 	}
 }
 
+func (s *splashCmp) SetOnboarding(onboarding bool) {
+	s.isOnboarding = onboarding
+	if onboarding {
+		providers, err := config.Providers()
+		if err != nil {
+			return
+		}
+		filteredProviders := []provider.Provider{}
+		simpleProviders := []string{
+			"anthropic",
+			"openai",
+			"gemini",
+			"xai",
+			"openrouter",
+		}
+		for _, p := range providers {
+			if slices.Contains(simpleProviders, string(p.ID)) {
+				filteredProviders = append(filteredProviders, p)
+			}
+		}
+		s.modelList.SetProviders(filteredProviders)
+	}
+}
+
+func (s *splashCmp) SetProjectInit(needsInit bool) {
+	s.needsProjectInit = needsInit
+}
+
 // GetSize implements SplashPage.
 func (s *splashCmp) GetSize() (int, int) {
 	return s.width, s.height
@@ -39,15 +127,20 @@ func (s *splashCmp) GetSize() (int, int) {
 
 // Init implements SplashPage.
 func (s *splashCmp) Init() tea.Cmd {
-	return nil
+	return tea.Batch(s.modelList.Init(), s.apiKeyInput.Init())
 }
 
 // SetSize implements SplashPage.
 func (s *splashCmp) SetSize(width int, height int) tea.Cmd {
-	s.width = width
 	s.height = height
-	s.logoRendered = s.logoBlock()
-	return nil
+	if width != s.width {
+		s.width = width
+		s.logoRendered = s.logoBlock()
+	}
+	// remove padding, logo height, gap, title space
+	s.listHeight = s.height - lipgloss.Height(s.logoRendered) - (SplashScreenPaddingY * 2) - s.logoGap() - 2
+	listWidth := min(60, width)
+	return s.modelList.SetSize(listWidth, s.listHeight)
 }
 
 // Update implements SplashPage.
@@ -55,32 +148,485 @@ func (s *splashCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
 	case tea.WindowSizeMsg:
 		return s, s.SetSize(msg.Width, msg.Height)
+	case tea.KeyPressMsg:
+		switch {
+		case key.Matches(msg, s.keyMap.Back):
+			if s.needsAPIKey {
+				// Go back to model selection
+				s.needsAPIKey = false
+				s.selectedModel = nil
+				return s, nil
+			}
+		case key.Matches(msg, s.keyMap.Select):
+			if s.isOnboarding && !s.needsAPIKey {
+				modelInx := s.modelList.SelectedIndex()
+				items := s.modelList.Items()
+				selectedItem := items[modelInx].(completions.CompletionItem).Value().(models.ModelOption)
+				if s.isProviderConfigured(string(selectedItem.Provider.ID)) {
+					cmd := s.setPreferredModel(selectedItem)
+					s.isOnboarding = false
+					return s, tea.Batch(cmd, util.CmdHandler(OnboardingCompleteMsg{}))
+				} else {
+					// Provider not configured, show API key input
+					s.needsAPIKey = true
+					s.selectedModel = &selectedItem
+					s.apiKeyInput.SetProviderName(selectedItem.Provider.Name)
+					return s, nil
+				}
+			} else if s.needsAPIKey {
+				// Handle API key submission
+				apiKey := s.apiKeyInput.Value()
+				if apiKey != "" {
+					return s, s.saveAPIKeyAndContinue(apiKey)
+				}
+			} else if s.needsProjectInit {
+				return s, s.initializeProject()
+			}
+		case key.Matches(msg, s.keyMap.Tab, s.keyMap.LeftRight):
+			if s.needsProjectInit {
+				s.selectedNo = !s.selectedNo
+				return s, nil
+			}
+		case key.Matches(msg, s.keyMap.Yes):
+			if s.needsProjectInit {
+				return s, s.initializeProject()
+			}
+		case key.Matches(msg, s.keyMap.No):
+			if s.needsProjectInit {
+				s.needsProjectInit = false
+				return s, util.CmdHandler(OnboardingCompleteMsg{})
+			}
+		default:
+			if s.needsAPIKey {
+				u, cmd := s.apiKeyInput.Update(msg)
+				s.apiKeyInput = u.(*models.APIKeyInput)
+				return s, cmd
+			} else if s.isOnboarding {
+				u, cmd := s.modelList.Update(msg)
+				s.modelList = u
+				return s, cmd
+			}
+		}
+	case tea.PasteMsg:
+		if s.needsAPIKey {
+			u, cmd := s.apiKeyInput.Update(msg)
+			s.apiKeyInput = u.(*models.APIKeyInput)
+			return s, cmd
+		} else if s.isOnboarding {
+			var cmd tea.Cmd
+			s.modelList, cmd = s.modelList.Update(msg)
+			return s, cmd
+		}
 	}
 	return s, nil
 }
 
-// View implements SplashPage.
+func (s *splashCmp) saveAPIKeyAndContinue(apiKey string) tea.Cmd {
+	if s.selectedModel == nil {
+		return util.ReportError(fmt.Errorf("no model selected"))
+	}
+
+	cfg := config.Get()
+	err := cfg.SetProviderAPIKey(string(s.selectedModel.Provider.ID), apiKey)
+	if err != nil {
+		return util.ReportError(fmt.Errorf("failed to save API key: %w", err))
+	}
+
+	// Reset API key state and continue with model selection
+	s.needsAPIKey = false
+	cmd := s.setPreferredModel(*s.selectedModel)
+	s.isOnboarding = false
+	s.selectedModel = nil
+
+	return tea.Batch(cmd, util.CmdHandler(OnboardingCompleteMsg{}))
+}
+
+func (s *splashCmp) initializeProject() tea.Cmd {
+	s.needsProjectInit = false
+
+	if err := config.MarkProjectInitialized(); err != nil {
+		return util.ReportError(err)
+	}
+	var cmds []tea.Cmd
+
+	cmds = append(cmds, util.CmdHandler(OnboardingCompleteMsg{}))
+	if !s.selectedNo {
+		cmds = append(cmds,
+			util.CmdHandler(chat.SessionClearedMsg{}),
+			util.CmdHandler(chat.SendMsg{
+				Text: prompt.Initialize(),
+			}),
+		)
+	}
+	return tea.Sequence(cmds...)
+}
+
+func (s *splashCmp) setPreferredModel(selectedItem models.ModelOption) tea.Cmd {
+	cfg := config.Get()
+	model := cfg.GetModel(string(selectedItem.Provider.ID), selectedItem.Model.ID)
+	if model == nil {
+		return util.ReportError(fmt.Errorf("model %s not found for provider %s", selectedItem.Model.ID, selectedItem.Provider.ID))
+	}
+
+	selectedModel := config.SelectedModel{
+		Model:           selectedItem.Model.ID,
+		Provider:        string(selectedItem.Provider.ID),
+		ReasoningEffort: model.DefaultReasoningEffort,
+		MaxTokens:       model.DefaultMaxTokens,
+	}
+
+	err := cfg.UpdatePreferredModel(config.SelectedModelTypeLarge, selectedModel)
+	if err != nil {
+		return util.ReportError(err)
+	}
+
+	// Now lets automatically setup the small model
+	knownProvider, err := s.getProvider(selectedItem.Provider.ID)
+	if err != nil {
+		return util.ReportError(err)
+	}
+	if knownProvider == nil {
+		// for local provider we just use the same model
+		err = cfg.UpdatePreferredModel(config.SelectedModelTypeSmall, selectedModel)
+		if err != nil {
+			return util.ReportError(err)
+		}
+	} else {
+		smallModel := knownProvider.DefaultSmallModelID
+		model := cfg.GetModel(string(selectedItem.Provider.ID), smallModel)
+		// should never happen
+		if model == nil {
+			err = cfg.UpdatePreferredModel(config.SelectedModelTypeSmall, selectedModel)
+			if err != nil {
+				return util.ReportError(err)
+			}
+			return nil
+		}
+		smallSelectedModel := config.SelectedModel{
+			Model:           smallModel,
+			Provider:        string(selectedItem.Provider.ID),
+			ReasoningEffort: model.DefaultReasoningEffort,
+			MaxTokens:       model.DefaultMaxTokens,
+		}
+		err = cfg.UpdatePreferredModel(config.SelectedModelTypeSmall, smallSelectedModel)
+		if err != nil {
+			return util.ReportError(err)
+		}
+	}
+	cfg.SetupAgents()
+	return nil
+}
+
+func (s *splashCmp) getProvider(providerID provider.InferenceProvider) (*provider.Provider, error) {
+	providers, err := config.Providers()
+	if err != nil {
+		return nil, err
+	}
+	for _, p := range providers {
+		if p.ID == providerID {
+			return &p, nil
+		}
+	}
+	return nil, nil
+}
+
+func (s *splashCmp) isProviderConfigured(providerID string) bool {
+	cfg := config.Get()
+	if _, ok := cfg.Providers[providerID]; ok {
+		return true
+	}
+	return false
+}
+
 func (s *splashCmp) View() string {
-	content := lipgloss.JoinVertical(lipgloss.Left, s.logoRendered)
-	return content
+	t := styles.CurrentTheme()
+	var content string
+	if s.needsAPIKey {
+		remainingHeight := s.height - lipgloss.Height(s.logoRendered) - (SplashScreenPaddingY * 2)
+		apiKeyView := t.S().Base.PaddingLeft(1).Render(s.apiKeyInput.View())
+		apiKeySelector := t.S().Base.AlignVertical(lipgloss.Bottom).Height(remainingHeight).Render(
+			lipgloss.JoinVertical(
+				lipgloss.Left,
+				apiKeyView,
+			),
+		)
+		content = lipgloss.JoinVertical(
+			lipgloss.Left,
+			s.logoRendered,
+			apiKeySelector,
+		)
+	} else if s.isOnboarding {
+		modelListView := s.modelList.View()
+		remainingHeight := s.height - lipgloss.Height(s.logoRendered) - (SplashScreenPaddingY * 2)
+		modelSelector := t.S().Base.AlignVertical(lipgloss.Bottom).Height(remainingHeight).Render(
+			lipgloss.JoinVertical(
+				lipgloss.Left,
+				t.S().Base.PaddingLeft(1).Foreground(t.Primary).Render("Choose a Model"),
+				"",
+				modelListView,
+			),
+		)
+		content = lipgloss.JoinVertical(
+			lipgloss.Left,
+			s.logoRendered,
+			modelSelector,
+		)
+	} else if s.needsProjectInit {
+		titleStyle := t.S().Base.Foreground(t.FgBase)
+		bodyStyle := t.S().Base.Foreground(t.FgMuted)
+		shortcutStyle := t.S().Base.Foreground(t.Success)
+
+		initText := lipgloss.JoinVertical(
+			lipgloss.Left,
+			titleStyle.Render("Would you like to initialize this project?"),
+			"",
+			bodyStyle.Render("When I initialize your codebase I examine the project and put the"),
+			bodyStyle.Render("result into a CRUSH.md file which serves as general context."),
+			"",
+			bodyStyle.Render("You can also initialize anytime via ")+shortcutStyle.Render("ctrl+p")+bodyStyle.Render("."),
+			"",
+			bodyStyle.Render("Would you like to initialize now?"),
+		)
+
+		yesButton := core.SelectableButton(core.ButtonOpts{
+			Text:           "Yep!",
+			UnderlineIndex: 0,
+			Selected:       !s.selectedNo,
+		})
+
+		noButton := core.SelectableButton(core.ButtonOpts{
+			Text:           "Nope",
+			UnderlineIndex: 0,
+			Selected:       s.selectedNo,
+		})
+
+		buttons := lipgloss.JoinHorizontal(lipgloss.Left, yesButton, "  ", noButton)
+		infoSection := s.infoSection()
+
+		remainingHeight := s.height - lipgloss.Height(s.logoRendered) - (SplashScreenPaddingY * 2) - lipgloss.Height(infoSection)
+
+		initContent := t.S().Base.AlignVertical(lipgloss.Bottom).PaddingLeft(1).Height(remainingHeight).Render(
+			lipgloss.JoinVertical(
+				lipgloss.Left,
+				initText,
+				"",
+				buttons,
+			),
+		)
+
+		content = lipgloss.JoinVertical(
+			lipgloss.Left,
+			s.logoRendered,
+			infoSection,
+			initContent,
+		)
+	} else {
+		parts := []string{
+			s.logoRendered,
+			s.infoSection(),
+		}
+		content = lipgloss.JoinVertical(lipgloss.Left, parts...)
+	}
+
+	return t.S().Base.
+		Width(s.width).
+		Height(s.height).
+		PaddingTop(SplashScreenPaddingY).
+		PaddingBottom(SplashScreenPaddingY).
+		Render(content)
+}
+
+func (s *splashCmp) Cursor() *tea.Cursor {
+	if s.needsAPIKey {
+		cursor := s.apiKeyInput.Cursor()
+		if cursor != nil {
+			return s.moveCursor(cursor)
+		}
+	} else if s.isOnboarding {
+		cursor := s.modelList.Cursor()
+		if cursor != nil {
+			return s.moveCursor(cursor)
+		}
+	} else {
+		return nil
+	}
+	return nil
+}
+
+func (s *splashCmp) infoSection() string {
+	t := styles.CurrentTheme()
+	return t.S().Base.PaddingLeft(2).Render(
+		lipgloss.JoinVertical(
+			lipgloss.Left,
+			s.cwd(),
+			"",
+			lipgloss.JoinHorizontal(lipgloss.Left, s.lspBlock(), s.mcpBlock()),
+			"",
+		),
+	)
 }
 
 func (s *splashCmp) logoBlock() string {
 	t := styles.CurrentTheme()
-	const padding = 2
-	return logo.Render(version.Version, false, logo.Opts{
-		FieldColor:   t.Primary,
-		TitleColorA:  t.Secondary,
-		TitleColorB:  t.Primary,
-		CharmColor:   t.Secondary,
-		VersionColor: t.Primary,
-		Width:        s.width - padding,
-	})
+	return t.S().Base.Padding(0, 2).Width(s.width).Render(
+		logo.Render(version.Version, false, logo.Opts{
+			FieldColor:   t.Primary,
+			TitleColorA:  t.Secondary,
+			TitleColorB:  t.Primary,
+			CharmColor:   t.Secondary,
+			VersionColor: t.Primary,
+			Width:        s.width - 4,
+		}),
+	)
+}
+
+func (s *splashCmp) moveCursor(cursor *tea.Cursor) *tea.Cursor {
+	if cursor == nil {
+		return nil
+	}
+	// Calculate the correct Y offset based on current state
+	logoHeight := lipgloss.Height(s.logoRendered)
+	if s.needsAPIKey {
+		infoSectionHeight := lipgloss.Height(s.infoSection())
+		baseOffset := logoHeight + SplashScreenPaddingY + infoSectionHeight
+		remainingHeight := s.height - baseOffset - lipgloss.Height(s.apiKeyInput.View()) - SplashScreenPaddingY
+		offset := baseOffset + remainingHeight
+		cursor.Y += offset
+		cursor.X = cursor.X + 1
+	} else if s.isOnboarding {
+		offset := logoHeight + SplashScreenPaddingY + s.logoGap() + 3
+		cursor.Y += offset
+		cursor.X = cursor.X + 1
+	}
+
+	return cursor
+}
+
+func (s *splashCmp) logoGap() int {
+	if s.height > 35 {
+		return LogoGap
+	}
+	return 0
 }
 
 // Bindings implements SplashPage.
 func (s *splashCmp) Bindings() []key.Binding {
-	return []key.Binding{
-		s.keyMap.Cancel,
+	if s.needsAPIKey {
+		return []key.Binding{
+			s.keyMap.Select,
+			s.keyMap.Back,
+		}
+	} else if s.isOnboarding {
+		return []key.Binding{
+			s.keyMap.Select,
+			s.keyMap.Next,
+			s.keyMap.Previous,
+		}
+	} else if s.needsProjectInit {
+		return []key.Binding{
+			s.keyMap.Select,
+			s.keyMap.Yes,
+			s.keyMap.No,
+			s.keyMap.Tab,
+			s.keyMap.LeftRight,
+		}
 	}
+	return []key.Binding{}
+}
+
+func (s *splashCmp) getMaxInfoWidth() int {
+	return min(s.width-2, 40) // 2 for left padding
+}
+
+func (s *splashCmp) cwd() string {
+	cwd := config.Get().WorkingDir()
+	t := styles.CurrentTheme()
+	homeDir, err := os.UserHomeDir()
+	if err == nil && cwd != homeDir {
+		cwd = strings.ReplaceAll(cwd, homeDir, "~")
+	}
+	maxWidth := s.getMaxInfoWidth()
+	return t.S().Muted.Width(maxWidth).Render(cwd)
+}
+
+func LSPList(maxWidth int) []string {
+	t := styles.CurrentTheme()
+	lspList := []string{}
+	lsp := config.Get().LSP.Sorted()
+	if len(lsp) == 0 {
+		return []string{t.S().Base.Foreground(t.Border).Render("None")}
+	}
+	for _, l := range lsp {
+		iconColor := t.Success
+		if l.LSP.Disabled {
+			iconColor = t.FgMuted
+		}
+		lspList = append(lspList,
+			core.Status(
+				core.StatusOpts{
+					IconColor:   iconColor,
+					Title:       l.Name,
+					Description: l.LSP.Command,
+				},
+				maxWidth,
+			),
+		)
+	}
+	return lspList
+}
+
+func (s *splashCmp) lspBlock() string {
+	t := styles.CurrentTheme()
+	maxWidth := s.getMaxInfoWidth() / 2
+	section := t.S().Subtle.Render("LSPs")
+	lspList := append([]string{section, ""}, LSPList(maxWidth-1)...)
+	return t.S().Base.Width(maxWidth).PaddingRight(1).Render(
+		lipgloss.JoinVertical(
+			lipgloss.Left,
+			lspList...,
+		),
+	)
+}
+
+func MCPList(maxWidth int) []string {
+	t := styles.CurrentTheme()
+	mcpList := []string{}
+	mcps := config.Get().MCP.Sorted()
+	if len(mcps) == 0 {
+		return []string{t.S().Base.Foreground(t.Border).Render("None")}
+	}
+	for _, l := range mcps {
+		iconColor := t.Success
+		if l.MCP.Disabled {
+			iconColor = t.FgMuted
+		}
+		mcpList = append(mcpList,
+			core.Status(
+				core.StatusOpts{
+					IconColor:   iconColor,
+					Title:       l.Name,
+					Description: l.MCP.Command,
+				},
+				maxWidth,
+			),
+		)
+	}
+	return mcpList
+}
+
+func (s *splashCmp) mcpBlock() string {
+	t := styles.CurrentTheme()
+	maxWidth := s.getMaxInfoWidth() / 2
+	section := t.S().Subtle.Render("MCPs")
+	mcpList := append([]string{section, ""}, MCPList(maxWidth-1)...)
+	return t.S().Base.Width(maxWidth).PaddingRight(1).Render(
+		lipgloss.JoinVertical(
+			lipgloss.Left,
+			mcpList...,
+		),
+	)
+}
+
+func (s *splashCmp) IsShowingAPIKey() bool {
+	return s.needsAPIKey
 }

internal/tui/components/completions/completions.go 🔗

@@ -9,6 +9,8 @@ import (
 	"github.com/charmbracelet/lipgloss/v2"
 )
 
+const maxCompletionsHeight = 10
+
 type Completion struct {
 	Title string // The title of the completion item
 	Value any    // The value of the completion item
@@ -43,7 +45,7 @@ type Completions interface {
 type completionsCmp struct {
 	width  int
 	height int  // Height of the completions component`
-	x      int  // X position for the completions popup\
+	x      int  // X position for the completions popup
 	y      int  // Y position for the completions popup
 	open   bool // Indicates if the completions are open
 	keyMap KeyMap
@@ -70,8 +72,8 @@ func New() Completions {
 		list.WithHideFilterInput(true),
 	)
 	return &completionsCmp{
-		width:  30,
-		height: 10,
+		width:  0,
+		height: 0,
 		list:   l,
 		query:  "",
 		keyMap: completionsKeyMap,
@@ -89,6 +91,10 @@ func (c *completionsCmp) Init() tea.Cmd {
 // Update implements Completions.
 func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	switch msg := msg.(type) {
+	case tea.WindowSizeMsg:
+		c.width = min(msg.Width-c.x, 80)
+		c.height = min(msg.Height-c.y, 15)
+		return c, nil
 	case tea.KeyPressMsg:
 		switch {
 		case key.Matches(msg, c.keyMap.Up):
@@ -135,7 +141,7 @@ func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			item := NewCompletionItem(completion.Title, completion.Value, WithBackgroundColor(t.BgSubtle))
 			items = append(items, item)
 		}
-		c.height = max(min(10, len(items)), 1) // Ensure at least 1 item height
+		c.height = max(min(c.height, len(items)), 1) // Ensure at least 1 item height
 		cmds := []tea.Cmd{
 			c.list.SetSize(c.width, c.height),
 			c.list.SetItems(items),
@@ -146,18 +152,25 @@ func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		if !c.open {
 			return c, nil // If completions are not open, do nothing
 		}
-		cmd := c.list.Filter(msg.Query)
-		c.height = max(min(10, len(c.list.Items())), 1)
-		return c, tea.Batch(
-			cmd,
-			c.list.SetSize(c.width, c.height),
-		)
+		var cmds []tea.Cmd
+		cmds = append(cmds, c.list.Filter(msg.Query))
+		itemsLen := len(c.list.Items())
+		c.height = max(min(maxCompletionsHeight, itemsLen), 1)
+		cmds = append(cmds, c.list.SetSize(c.width, c.height))
+		if itemsLen == 0 {
+			// Close completions if no items match the query
+			cmds = append(cmds, util.CmdHandler(CloseCompletionsMsg{}))
+		}
+		return c, tea.Batch(cmds...)
 	}
 	return c, nil
 }
 
 // View implements Completions.
 func (c *completionsCmp) View() string {
+	if !c.open {
+		return ""
+	}
 	if len(c.list.Items()) == 0 {
 		return c.style().Render("No completions found")
 	}

internal/tui/components/completions/item.go 🔗

@@ -90,6 +90,7 @@ func (c *completionItemCmp) View() string {
 	if c.bgColor != nil {
 		titleStyle = titleStyle.Background(c.bgColor)
 		titleMatchStyle = titleMatchStyle.Background(c.bgColor)
+		itemStyle = itemStyle.Background(c.bgColor)
 	}
 
 	if c.focus {

internal/tui/components/completions/keys.go 🔗

@@ -22,7 +22,7 @@ func DefaultKeyMap() KeyMap {
 			key.WithHelp("up", "move up"),
 		),
 		Select: key.NewBinding(
-			key.WithKeys("enter"),
+			key.WithKeys("enter", "tab", "ctrl+y"),
 			key.WithHelp("enter", "select"),
 		),
 		Cancel: key.NewBinding(

internal/tui/components/core/helpers.go → internal/tui/components/core/core.go 🔗

@@ -5,12 +5,40 @@ import (
 	"strings"
 
 	"github.com/alecthomas/chroma/v2"
+	"github.com/charmbracelet/bubbles/v2/help"
+	"github.com/charmbracelet/bubbles/v2/key"
 	"github.com/charmbracelet/crush/internal/tui/exp/diffview"
 	"github.com/charmbracelet/crush/internal/tui/styles"
 	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/charmbracelet/x/ansi"
 )
 
+type KeyMapHelp interface {
+	Help() help.KeyMap
+}
+
+type simpleHelp struct {
+	shortList []key.Binding
+	fullList  [][]key.Binding
+}
+
+func NewSimpleHelp(shortList []key.Binding, fullList [][]key.Binding) help.KeyMap {
+	return &simpleHelp{
+		shortList: shortList,
+		fullList:  fullList,
+	}
+}
+
+// FullHelp implements help.KeyMap.
+func (s *simpleHelp) FullHelp() [][]key.Binding {
+	return s.fullList
+}
+
+// ShortHelp implements help.KeyMap.
+func (s *simpleHelp) ShortHelp() []key.Binding {
+	return s.shortList
+}
+
 func Section(text string, width int) string {
 	t := styles.CurrentTheme()
 	char := "─"
@@ -23,6 +51,22 @@ func Section(text string, width int) string {
 	return text
 }
 
+func SectionWithInfo(text string, width int, info string) string {
+	t := styles.CurrentTheme()
+	char := "─"
+	length := lipgloss.Width(text) + 1
+	remainingWidth := width - length
+
+	if info != "" {
+		remainingWidth -= lipgloss.Width(info) + 1 // 1 for the space before info
+	}
+	lineStyle := t.S().Base.Foreground(t.Border)
+	if remainingWidth > 0 {
+		text = text + " " + lineStyle.Render(strings.Repeat(char, remainingWidth)) + " " + info
+	}
+	return text
+}
+
 func Title(title string, width int) string {
 	t := styles.CurrentTheme()
 	char := "╱"
@@ -147,6 +191,21 @@ func SelectableButtons(buttons []ButtonOpts, spacing string) string {
 	return lipgloss.JoinHorizontal(lipgloss.Left, parts...)
 }
 
+// SelectableButtonsVertical creates a vertical row of selectable buttons
+func SelectableButtonsVertical(buttons []ButtonOpts, spacing int) string {
+	var parts []string
+	for i, button := range buttons {
+		parts = append(parts, SelectableButton(button))
+		if i < len(buttons)-1 {
+			for j := 0; j < spacing; j++ {
+				parts = append(parts, "")
+			}
+		}
+	}
+
+	return lipgloss.JoinVertical(lipgloss.Center, parts...)
+}
+
 func DiffFormatter() *diffview.DiffView {
 	t := styles.CurrentTheme()
 	formatDiff := diffview.New()

internal/tui/components/core/layout/container.go 🔗

@@ -1,263 +0,0 @@
-package layout
-
-import (
-	"github.com/charmbracelet/bubbles/v2/key"
-	tea "github.com/charmbracelet/bubbletea/v2"
-	"github.com/charmbracelet/crush/internal/tui/styles"
-	"github.com/charmbracelet/crush/internal/tui/util"
-	"github.com/charmbracelet/lipgloss/v2"
-)
-
-type Container interface {
-	util.Model
-	Sizeable
-	Help
-	Positional
-	Focusable
-}
-type container struct {
-	width     int
-	height    int
-	isFocused bool
-
-	x, y int
-
-	content util.Model
-
-	// Style options
-	paddingTop    int
-	paddingRight  int
-	paddingBottom int
-	paddingLeft   int
-
-	borderTop    bool
-	borderRight  bool
-	borderBottom bool
-	borderLeft   bool
-	borderStyle  lipgloss.Border
-}
-
-type ContainerOption func(*container)
-
-func NewContainer(content util.Model, options ...ContainerOption) Container {
-	c := &container{
-		content:     content,
-		borderStyle: lipgloss.NormalBorder(),
-	}
-
-	for _, option := range options {
-		option(c)
-	}
-
-	return c
-}
-
-func (c *container) Init() tea.Cmd {
-	return c.content.Init()
-}
-
-func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
-	switch msg := msg.(type) {
-	case tea.KeyPressMsg:
-		if c.IsFocused() {
-			u, cmd := c.content.Update(msg)
-			c.content = u.(util.Model)
-			return c, cmd
-		}
-		return c, nil
-	default:
-		u, cmd := c.content.Update(msg)
-		c.content = u.(util.Model)
-		return c, cmd
-	}
-}
-
-func (c *container) Cursor() *tea.Cursor {
-	if cursor, ok := c.content.(util.Cursor); ok {
-		return cursor.Cursor()
-	}
-	return nil
-}
-
-func (c *container) View() string {
-	t := styles.CurrentTheme()
-	width := c.width
-	height := c.height
-
-	style := t.S().Base
-
-	// Apply border if any side is enabled
-	if c.borderTop || c.borderRight || c.borderBottom || c.borderLeft {
-		// Adjust width and height for borders
-		if c.borderTop {
-			height--
-		}
-		if c.borderBottom {
-			height--
-		}
-		if c.borderLeft {
-			width--
-		}
-		if c.borderRight {
-			width--
-		}
-		style = style.Border(c.borderStyle, c.borderTop, c.borderRight, c.borderBottom, c.borderLeft)
-		style = style.BorderBackground(t.BgBase).BorderForeground(t.Border)
-	}
-	style = style.
-		Width(width).
-		Height(height).
-		PaddingTop(c.paddingTop).
-		PaddingRight(c.paddingRight).
-		PaddingBottom(c.paddingBottom).
-		PaddingLeft(c.paddingLeft)
-
-	contentView := c.content.View()
-	return style.Render(contentView)
-}
-
-func (c *container) SetSize(width, height int) tea.Cmd {
-	c.width = width
-	c.height = height
-
-	// If the content implements Sizeable, adjust its size to account for padding and borders
-	if sizeable, ok := c.content.(Sizeable); ok {
-		// Calculate horizontal space taken by padding and borders
-		horizontalSpace := c.paddingLeft + c.paddingRight
-		if c.borderLeft {
-			horizontalSpace++
-		}
-		if c.borderRight {
-			horizontalSpace++
-		}
-
-		// Calculate vertical space taken by padding and borders
-		verticalSpace := c.paddingTop + c.paddingBottom
-		if c.borderTop {
-			verticalSpace++
-		}
-		if c.borderBottom {
-			verticalSpace++
-		}
-
-		// Set content size with adjusted dimensions
-		contentWidth := max(0, width-horizontalSpace)
-		contentHeight := max(0, height-verticalSpace)
-		return sizeable.SetSize(contentWidth, contentHeight)
-	}
-	return nil
-}
-
-func (c *container) GetSize() (int, int) {
-	return c.width, c.height
-}
-
-func (c *container) SetPosition(x, y int) tea.Cmd {
-	c.x = x
-	c.y = y
-	if positionable, ok := c.content.(Positional); ok {
-		return positionable.SetPosition(x, y)
-	}
-	return nil
-}
-
-func (c *container) Bindings() []key.Binding {
-	if b, ok := c.content.(Help); ok {
-		return b.Bindings()
-	}
-	return nil
-}
-
-// Blur implements Container.
-func (c *container) Blur() tea.Cmd {
-	c.isFocused = false
-	if focusable, ok := c.content.(Focusable); ok {
-		return focusable.Blur()
-	}
-	return nil
-}
-
-// Focus implements Container.
-func (c *container) Focus() tea.Cmd {
-	c.isFocused = true
-	if focusable, ok := c.content.(Focusable); ok {
-		return focusable.Focus()
-	}
-	return nil
-}
-
-// IsFocused implements Container.
-func (c *container) IsFocused() bool {
-	isFocused := c.isFocused
-	if focusable, ok := c.content.(Focusable); ok {
-		isFocused = isFocused || focusable.IsFocused()
-	}
-	return isFocused
-}
-
-// Padding options
-func WithPadding(top, right, bottom, left int) ContainerOption {
-	return func(c *container) {
-		c.paddingTop = top
-		c.paddingRight = right
-		c.paddingBottom = bottom
-		c.paddingLeft = left
-	}
-}
-
-func WithPaddingAll(padding int) ContainerOption {
-	return WithPadding(padding, padding, padding, padding)
-}
-
-func WithPaddingHorizontal(padding int) ContainerOption {
-	return func(c *container) {
-		c.paddingLeft = padding
-		c.paddingRight = padding
-	}
-}
-
-func WithPaddingVertical(padding int) ContainerOption {
-	return func(c *container) {
-		c.paddingTop = padding
-		c.paddingBottom = padding
-	}
-}
-
-func WithBorder(top, right, bottom, left bool) ContainerOption {
-	return func(c *container) {
-		c.borderTop = top
-		c.borderRight = right
-		c.borderBottom = bottom
-		c.borderLeft = left
-	}
-}
-
-func WithBorderAll() ContainerOption {
-	return WithBorder(true, true, true, true)
-}
-
-func WithBorderHorizontal() ContainerOption {
-	return WithBorder(true, false, true, false)
-}
-
-func WithBorderVertical() ContainerOption {
-	return WithBorder(false, true, false, true)
-}
-
-func WithBorderStyle(style lipgloss.Border) ContainerOption {
-	return func(c *container) {
-		c.borderStyle = style
-	}
-}
-
-func WithRoundedBorder() ContainerOption {
-	return WithBorderStyle(lipgloss.RoundedBorder())
-}
-
-func WithThickBorder() ContainerOption {
-	return WithBorderStyle(lipgloss.ThickBorder())
-}
-
-func WithDoubleBorder() ContainerOption {
-	return WithBorderStyle(lipgloss.DoubleBorder())
-}

internal/tui/components/core/layout/layout.go 🔗

@@ -5,6 +5,8 @@ import (
 	tea "github.com/charmbracelet/bubbletea/v2"
 )
 
+// TODO: move this to core
+
 type Focusable interface {
 	Focus() tea.Cmd
 	Blur() tea.Cmd
@@ -23,8 +25,3 @@ type Help interface {
 type Positional interface {
 	SetPosition(x, y int) tea.Cmd
 }
-
-// KeyMapProvider defines an interface for types that can provide their key bindings as a slice
-type KeyMapProvider interface {
-	KeyBindings() []key.Binding
-}

internal/tui/components/core/layout/split.go 🔗

@@ -1,380 +0,0 @@
-package layout
-
-import (
-	"log/slog"
-
-	"github.com/charmbracelet/bubbles/v2/key"
-	tea "github.com/charmbracelet/bubbletea/v2"
-
-	"github.com/charmbracelet/crush/internal/tui/styles"
-	"github.com/charmbracelet/crush/internal/tui/util"
-	"github.com/charmbracelet/lipgloss/v2"
-)
-
-type LayoutPanel string
-
-const (
-	LeftPanel   LayoutPanel = "left"
-	RightPanel  LayoutPanel = "right"
-	BottomPanel LayoutPanel = "bottom"
-)
-
-type SplitPaneLayout interface {
-	util.Model
-	Sizeable
-	Help
-	SetLeftPanel(panel Container) tea.Cmd
-	SetRightPanel(panel Container) tea.Cmd
-	SetBottomPanel(panel Container) tea.Cmd
-
-	ClearLeftPanel() tea.Cmd
-	ClearRightPanel() tea.Cmd
-	ClearBottomPanel() tea.Cmd
-
-	FocusPanel(panel LayoutPanel) tea.Cmd
-	SetOffset(x, y int)
-}
-
-type splitPaneLayout struct {
-	width   int
-	height  int
-	xOffset int
-	yOffset int
-
-	ratio         float64
-	verticalRatio float64
-
-	rightPanel  Container
-	leftPanel   Container
-	bottomPanel Container
-
-	fixedBottomHeight int // Fixed height for the bottom panel, if any
-	fixedRightWidth   int // Fixed width for the right panel, if any
-}
-
-type SplitPaneOption func(*splitPaneLayout)
-
-func (s *splitPaneLayout) Init() tea.Cmd {
-	var cmds []tea.Cmd
-
-	if s.leftPanel != nil {
-		cmds = append(cmds, s.leftPanel.Init())
-	}
-
-	if s.rightPanel != nil {
-		cmds = append(cmds, s.rightPanel.Init())
-	}
-
-	if s.bottomPanel != nil {
-		cmds = append(cmds, s.bottomPanel.Init())
-	}
-
-	return tea.Batch(cmds...)
-}
-
-func (s *splitPaneLayout) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
-	var cmds []tea.Cmd
-	switch msg := msg.(type) {
-	case tea.WindowSizeMsg:
-		return s, s.SetSize(msg.Width, msg.Height)
-	}
-
-	if s.rightPanel != nil {
-		u, cmd := s.rightPanel.Update(msg)
-		s.rightPanel = u.(Container)
-		if cmd != nil {
-			cmds = append(cmds, cmd)
-		}
-	}
-
-	if s.leftPanel != nil {
-		u, cmd := s.leftPanel.Update(msg)
-		s.leftPanel = u.(Container)
-		if cmd != nil {
-			cmds = append(cmds, cmd)
-		}
-	}
-
-	if s.bottomPanel != nil {
-		u, cmd := s.bottomPanel.Update(msg)
-		s.bottomPanel = u.(Container)
-		if cmd != nil {
-			cmds = append(cmds, cmd)
-		}
-	}
-
-	return s, tea.Batch(cmds...)
-}
-
-func (s *splitPaneLayout) Cursor() *tea.Cursor {
-	if s.bottomPanel != nil {
-		if c, ok := s.bottomPanel.(util.Cursor); ok {
-			return c.Cursor()
-		}
-	} else if s.rightPanel != nil {
-		if c, ok := s.rightPanel.(util.Cursor); ok {
-			return c.Cursor()
-		}
-	} else if s.leftPanel != nil {
-		if c, ok := s.leftPanel.(util.Cursor); ok {
-			return c.Cursor()
-		}
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) View() string {
-	var topSection string
-
-	if s.leftPanel != nil && s.rightPanel != nil {
-		leftView := s.leftPanel.View()
-		rightView := s.rightPanel.View()
-		topSection = lipgloss.JoinHorizontal(lipgloss.Top, leftView, rightView)
-	} else if s.leftPanel != nil {
-		topSection = s.leftPanel.View()
-	} else if s.rightPanel != nil {
-		topSection = s.rightPanel.View()
-	} else {
-		topSection = ""
-	}
-
-	var finalView string
-
-	if s.bottomPanel != nil && topSection != "" {
-		bottomView := s.bottomPanel.View()
-		finalView = lipgloss.JoinVertical(lipgloss.Left, topSection, bottomView)
-	} else if s.bottomPanel != nil {
-		finalView = s.bottomPanel.View()
-	} else {
-		finalView = topSection
-	}
-
-	t := styles.CurrentTheme()
-
-	style := t.S().Base.
-		Width(s.width).
-		Height(s.height)
-
-	return style.Render(finalView)
-}
-
-func (s *splitPaneLayout) SetSize(width, height int) tea.Cmd {
-	s.width = width
-	s.height = height
-	slog.Info("Setting split pane size", "width", width, "height", height)
-
-	var topHeight, bottomHeight int
-	var cmds []tea.Cmd
-	if s.bottomPanel != nil {
-		if s.fixedBottomHeight > 0 {
-			bottomHeight = s.fixedBottomHeight
-			topHeight = height - bottomHeight
-		} else {
-			topHeight = int(float64(height) * s.verticalRatio)
-			bottomHeight = height - topHeight
-			if bottomHeight <= 0 {
-				bottomHeight = 2
-				topHeight = height - bottomHeight
-			}
-		}
-	} else {
-		topHeight = height
-		bottomHeight = 0
-	}
-
-	var leftWidth, rightWidth int
-	if s.leftPanel != nil && s.rightPanel != nil {
-		if s.fixedRightWidth > 0 {
-			rightWidth = s.fixedRightWidth
-			leftWidth = width - rightWidth
-		} else {
-			leftWidth = int(float64(width) * s.ratio)
-			rightWidth = width - leftWidth
-			if rightWidth <= 0 {
-				rightWidth = 2
-				leftWidth = width - rightWidth
-			}
-		}
-	} else if s.leftPanel != nil {
-		leftWidth = width
-		rightWidth = 0
-	} else if s.rightPanel != nil {
-		leftWidth = 0
-		rightWidth = width
-	}
-
-	if s.leftPanel != nil {
-		cmd := s.leftPanel.SetSize(leftWidth, topHeight)
-		cmds = append(cmds, cmd)
-		if positional, ok := s.leftPanel.(Positional); ok {
-			cmds = append(cmds, positional.SetPosition(s.xOffset, s.yOffset))
-		}
-	}
-
-	if s.rightPanel != nil {
-		cmd := s.rightPanel.SetSize(rightWidth, topHeight)
-		cmds = append(cmds, cmd)
-		if positional, ok := s.rightPanel.(Positional); ok {
-			cmds = append(cmds, positional.SetPosition(s.xOffset+leftWidth, s.yOffset))
-		}
-	}
-
-	if s.bottomPanel != nil {
-		cmd := s.bottomPanel.SetSize(width, bottomHeight)
-		cmds = append(cmds, cmd)
-		if positional, ok := s.bottomPanel.(Positional); ok {
-			cmds = append(cmds, positional.SetPosition(s.xOffset, s.yOffset+topHeight))
-		}
-	}
-	return tea.Batch(cmds...)
-}
-
-func (s *splitPaneLayout) GetSize() (int, int) {
-	return s.width, s.height
-}
-
-func (s *splitPaneLayout) SetLeftPanel(panel Container) tea.Cmd {
-	s.leftPanel = panel
-	if s.width > 0 && s.height > 0 {
-		return s.SetSize(s.width, s.height)
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) SetRightPanel(panel Container) tea.Cmd {
-	s.rightPanel = panel
-	if s.width > 0 && s.height > 0 {
-		return s.SetSize(s.width, s.height)
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) SetBottomPanel(panel Container) tea.Cmd {
-	s.bottomPanel = panel
-	if s.width > 0 && s.height > 0 {
-		return s.SetSize(s.width, s.height)
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) ClearLeftPanel() tea.Cmd {
-	s.leftPanel = nil
-	if s.width > 0 && s.height > 0 {
-		return s.SetSize(s.width, s.height)
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) ClearRightPanel() tea.Cmd {
-	s.rightPanel = nil
-	if s.width > 0 && s.height > 0 {
-		return s.SetSize(s.width, s.height)
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) ClearBottomPanel() tea.Cmd {
-	s.bottomPanel = nil
-	if s.width > 0 && s.height > 0 {
-		return s.SetSize(s.width, s.height)
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) Bindings() []key.Binding {
-	if s.leftPanel != nil {
-		if b, ok := s.leftPanel.(Help); ok && s.leftPanel.IsFocused() {
-			return b.Bindings()
-		}
-	}
-	if s.rightPanel != nil {
-		if b, ok := s.rightPanel.(Help); ok && s.rightPanel.IsFocused() {
-			return b.Bindings()
-		}
-	}
-	if s.bottomPanel != nil {
-		if b, ok := s.bottomPanel.(Help); ok && s.bottomPanel.IsFocused() {
-			return b.Bindings()
-		}
-	}
-	return nil
-}
-
-func (s *splitPaneLayout) FocusPanel(panel LayoutPanel) tea.Cmd {
-	panels := map[LayoutPanel]Container{
-		LeftPanel:   s.leftPanel,
-		RightPanel:  s.rightPanel,
-		BottomPanel: s.bottomPanel,
-	}
-	var cmds []tea.Cmd
-	for p, container := range panels {
-		if container == nil {
-			continue
-		}
-		if p == panel {
-			cmds = append(cmds, container.Focus())
-		} else {
-			cmds = append(cmds, container.Blur())
-		}
-	}
-	return tea.Batch(cmds...)
-}
-
-// SetOffset implements SplitPaneLayout.
-func (s *splitPaneLayout) SetOffset(x int, y int) {
-	s.xOffset = x
-	s.yOffset = y
-}
-
-func NewSplitPane(options ...SplitPaneOption) SplitPaneLayout {
-	layout := &splitPaneLayout{
-		ratio:         0.8,
-		verticalRatio: 0.92, // Default 90% for top section, 10% for bottom
-	}
-	for _, option := range options {
-		option(layout)
-	}
-	return layout
-}
-
-func WithLeftPanel(panel Container) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.leftPanel = panel
-	}
-}
-
-func WithRightPanel(panel Container) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.rightPanel = panel
-	}
-}
-
-func WithRatio(ratio float64) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.ratio = ratio
-	}
-}
-
-func WithBottomPanel(panel Container) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.bottomPanel = panel
-	}
-}
-
-func WithVerticalRatio(ratio float64) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.verticalRatio = ratio
-	}
-}
-
-func WithFixedBottomHeight(height int) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.fixedBottomHeight = height
-	}
-}
-
-func WithFixedRightWidth(width int) SplitPaneOption {
-	return func(s *splitPaneLayout) {
-		s.fixedRightWidth = width
-	}
-}

internal/tui/components/core/list/list.go 🔗

@@ -41,6 +41,8 @@ type ListModel interface {
 	SelectedIndex() int             // Get the index of the currently selected item
 	SetSelected(int) tea.Cmd        // Set the selected item by index and scroll to it
 	Filter(string) tea.Cmd          // Filter items based on a search term
+	SetFilterPlaceholder(string)    // Set the placeholder text for the filter input
+	Cursor() *tea.Cursor            // Get the current cursor position in the filter input
 }
 
 // HasAnim interface identifies items that support animation.
@@ -1363,3 +1365,7 @@ func (m *model) Focus() tea.Cmd {
 func (m *model) IsFocused() bool {
 	return m.isFocused
 }
+
+func (m *model) SetFilterPlaceholder(placeholder string) {
+	m.input.Placeholder = placeholder
+}

internal/tui/components/core/status/status.go 🔗

@@ -98,13 +98,12 @@ func (m *statusCmp) SetKeyMap(keyMap help.KeyMap) {
 	m.keyMap = keyMap
 }
 
-func NewStatusCmp(keyMap help.KeyMap) StatusCmp {
+func NewStatusCmp() StatusCmp {
 	t := styles.CurrentTheme()
 	help := help.New()
 	help.Styles = t.S().Help
 	return &statusCmp{
 		messageTTL: 5 * time.Second,
 		help:       help,
-		keyMap:     keyMap,
 	}
 }

internal/tui/components/dialogs/commands/commands.go 🔗

@@ -6,6 +6,7 @@ import (
 	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/charmbracelet/lipgloss/v2"
 
+	"github.com/charmbracelet/crush/internal/llm/prompt"
 	"github.com/charmbracelet/crush/internal/tui/components/chat"
 	"github.com/charmbracelet/crush/internal/tui/components/completions"
 	"github.com/charmbracelet/crush/internal/tui/components/core"
@@ -239,16 +240,8 @@ func (c *commandDialogCmp) defaultCommands() []Command {
 			Title:       "Initialize Project",
 			Description: "Create/Update the CRUSH.md memory file",
 			Handler: func(cmd Command) tea.Cmd {
-				prompt := `Please analyze this codebase and create a CRUSH.md file containing:
-	1. Build/lint/test commands - especially for running a single test
-	2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
-
-	The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20 lines long.
-	If there's already a CRUSH.md, improve it.
-	If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include them.
-	Add the .crush directory to the .gitignore file if it's not already there.`
 				return util.CmdHandler(chat.SendMsg{
-					Text: prompt,
+					Text: prompt.Initialize(),
 				})
 			},
 		},

internal/tui/components/dialogs/commands/item.go 🔗

@@ -14,11 +14,12 @@ type ItemSection interface {
 	util.Model
 	layout.Sizeable
 	list.SectionHeader
+	SetInfo(info string)
 }
 type itemSectionModel struct {
-	width     int
-	title     string
-	noPadding bool // No padding for the section header
+	width int
+	title string
+	info  string
 }
 
 func NewItemSection(title string) ItemSection {
@@ -40,7 +41,14 @@ func (m *itemSectionModel) View() string {
 	title := ansi.Truncate(m.title, m.width-2, "…")
 	style := t.S().Base.Padding(1, 1, 0, 1)
 	title = t.S().Muted.Render(title)
-	return style.Render(core.Section(title, m.width-2))
+	section := ""
+	if m.info != "" {
+		section = core.SectionWithInfo(title, m.width-2, m.info)
+	} else {
+		section = core.Section(title, m.width-2)
+	}
+
+	return style.Render(section)
 }
 
 func (m *itemSectionModel) GetSize() (int, int) {
@@ -55,3 +63,7 @@ func (m *itemSectionModel) SetSize(width int, height int) tea.Cmd {
 func (m *itemSectionModel) IsSectionHeader() bool {
 	return true
 }
+
+func (m *itemSectionModel) SetInfo(info string) {
+	m.info = info
+}

internal/tui/components/dialogs/init/init.go 🔗

@@ -1,214 +0,0 @@
-package init
-
-import (
-	"github.com/charmbracelet/bubbles/v2/key"
-	tea "github.com/charmbracelet/bubbletea/v2"
-	"github.com/charmbracelet/lipgloss/v2"
-
-	"github.com/charmbracelet/crush/internal/config"
-	cmpChat "github.com/charmbracelet/crush/internal/tui/components/chat"
-	"github.com/charmbracelet/crush/internal/tui/components/core"
-	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
-	"github.com/charmbracelet/crush/internal/tui/styles"
-	"github.com/charmbracelet/crush/internal/tui/util"
-)
-
-const InitDialogID dialogs.DialogID = "init"
-
-// InitDialogCmp is a component that asks the user if they want to initialize the project.
-type InitDialogCmp interface {
-	dialogs.DialogModel
-}
-
-type initDialogCmp struct {
-	wWidth, wHeight int
-	width, height   int
-	selected        int
-	keyMap          KeyMap
-}
-
-// NewInitDialogCmp creates a new InitDialogCmp.
-func NewInitDialogCmp() InitDialogCmp {
-	return &initDialogCmp{
-		selected: 0,
-		keyMap:   DefaultKeyMap(),
-	}
-}
-
-// Init implements tea.Model.
-func (m *initDialogCmp) Init() tea.Cmd {
-	return nil
-}
-
-// Update implements tea.Model.
-func (m *initDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
-	switch msg := msg.(type) {
-	case tea.WindowSizeMsg:
-		m.wWidth = msg.Width
-		m.wHeight = msg.Height
-		cmd := m.SetSize()
-		return m, cmd
-	case tea.KeyPressMsg:
-		switch {
-		case key.Matches(msg, m.keyMap.Close):
-			return m, tea.Batch(
-				util.CmdHandler(dialogs.CloseDialogMsg{}),
-				m.handleInitialization(false),
-			)
-		case key.Matches(msg, m.keyMap.ChangeSelection):
-			m.selected = (m.selected + 1) % 2
-			return m, nil
-		case key.Matches(msg, m.keyMap.Select):
-			return m, tea.Batch(
-				util.CmdHandler(dialogs.CloseDialogMsg{}),
-				m.handleInitialization(m.selected == 0),
-			)
-		case key.Matches(msg, m.keyMap.Y):
-			return m, tea.Batch(
-				util.CmdHandler(dialogs.CloseDialogMsg{}),
-				m.handleInitialization(true),
-			)
-		case key.Matches(msg, m.keyMap.N):
-			return m, tea.Batch(
-				util.CmdHandler(dialogs.CloseDialogMsg{}),
-				m.handleInitialization(false),
-			)
-		}
-	}
-	return m, nil
-}
-
-func (m *initDialogCmp) renderButtons() string {
-	t := styles.CurrentTheme()
-	baseStyle := t.S().Base
-
-	buttons := []core.ButtonOpts{
-		{
-			Text:           "Yes",
-			UnderlineIndex: 0, // "Y"
-			Selected:       m.selected == 0,
-		},
-		{
-			Text:           "No",
-			UnderlineIndex: 0, // "N"
-			Selected:       m.selected == 1,
-		},
-	}
-
-	content := core.SelectableButtons(buttons, "  ")
-
-	return baseStyle.AlignHorizontal(lipgloss.Right).Width(m.width - 4).Render(content)
-}
-
-func (m *initDialogCmp) renderContent() string {
-	t := styles.CurrentTheme()
-	baseStyle := t.S().Base
-
-	explanation := t.S().Text.
-		Width(m.width - 4).
-		Render("Initialization generates a new CRUSH.md file that contains information about your codebase, this file serves as memory for each project, you can freely add to it to help the agents be better at their job.")
-
-	question := t.S().Text.
-		Width(m.width - 4).
-		Render("Would you like to initialize this project?")
-
-	return baseStyle.Render(lipgloss.JoinVertical(
-		lipgloss.Left,
-		explanation,
-		"",
-		question,
-	))
-}
-
-func (m *initDialogCmp) render() string {
-	t := styles.CurrentTheme()
-	baseStyle := t.S().Base
-	title := core.Title("Initialize Project", m.width-4)
-
-	content := m.renderContent()
-	buttons := m.renderButtons()
-
-	dialogContent := lipgloss.JoinVertical(
-		lipgloss.Top,
-		title,
-		"",
-		content,
-		"",
-		buttons,
-		"",
-	)
-
-	return baseStyle.
-		Padding(0, 1).
-		Border(lipgloss.RoundedBorder()).
-		BorderForeground(t.BorderFocus).
-		Width(m.width).
-		Render(dialogContent)
-}
-
-// View implements tea.Model.
-func (m *initDialogCmp) View() string {
-	return m.render()
-}
-
-// SetSize sets the size of the component.
-func (m *initDialogCmp) SetSize() tea.Cmd {
-	m.width = min(90, m.wWidth)
-	m.height = min(15, m.wHeight)
-	return nil
-}
-
-// ID implements DialogModel.
-func (m *initDialogCmp) ID() dialogs.DialogID {
-	return InitDialogID
-}
-
-// Position implements DialogModel.
-func (m *initDialogCmp) Position() (int, int) {
-	row := (m.wHeight / 2) - (m.height / 2)
-	col := (m.wWidth / 2) - (m.width / 2)
-	return row, col
-}
-
-// handleInitialization handles the initialization logic when the dialog is closed.
-func (m *initDialogCmp) handleInitialization(initialize bool) tea.Cmd {
-	if initialize {
-		// Run the initialization command
-		prompt := `Please analyze this codebase and create a CRUSH.md file containing:
-1. Build/lint/test commands - especially for running a single test
-2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
-
-The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20 lines long.
-If there's already a CRUSH.md, improve it.
-If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include them.
-Add the .crush directory to the .gitignore file if it's not already there.`
-
-		// Mark the project as initialized
-		if err := config.MarkProjectInitialized(); err != nil {
-			return util.ReportError(err)
-		}
-
-		return tea.Sequence(
-			util.CmdHandler(cmpChat.SessionClearedMsg{}),
-			util.CmdHandler(cmpChat.SendMsg{
-				Text: prompt,
-			}),
-		)
-	} else {
-		// Mark the project as initialized without running the command
-		if err := config.MarkProjectInitialized(); err != nil {
-			return util.ReportError(err)
-		}
-	}
-	return nil
-}
-
-// CloseInitDialogMsg is a message that is sent when the init dialog is closed.
-type CloseInitDialogMsg struct {
-	Initialize bool
-}
-
-// ShowInitDialogMsg is a message that is sent to show the init dialog.
-type ShowInitDialogMsg struct {
-	Show bool
-}

internal/tui/components/dialogs/init/keys.go 🔗

@@ -1,69 +0,0 @@
-package init
-
-import (
-	"github.com/charmbracelet/bubbles/v2/key"
-)
-
-type KeyMap struct {
-	ChangeSelection,
-	Select,
-	Y,
-	N,
-	Close key.Binding
-}
-
-func DefaultKeyMap() KeyMap {
-	return KeyMap{
-		ChangeSelection: key.NewBinding(
-			key.WithKeys("tab", "left", "right", "h", "l"),
-			key.WithHelp("tab/←/→", "toggle selection"),
-		),
-		Select: key.NewBinding(
-			key.WithKeys("enter"),
-			key.WithHelp("enter", "confirm"),
-		),
-		Y: key.NewBinding(
-			key.WithKeys("y"),
-			key.WithHelp("y", "yes"),
-		),
-		N: key.NewBinding(
-			key.WithKeys("n"),
-			key.WithHelp("n", "no"),
-		),
-		Close: key.NewBinding(
-			key.WithKeys("esc"),
-			key.WithHelp("esc", "cancel"),
-		),
-	}
-}
-
-// KeyBindings implements layout.KeyMapProvider
-func (k KeyMap) KeyBindings() []key.Binding {
-	return []key.Binding{
-		k.ChangeSelection,
-		k.Select,
-		k.Y,
-		k.N,
-		k.Close,
-	}
-}
-
-// FullHelp implements help.KeyMap.
-func (k KeyMap) FullHelp() [][]key.Binding {
-	m := [][]key.Binding{}
-	slice := k.KeyBindings()
-	for i := 0; i < len(slice); i += 4 {
-		end := min(i+4, len(slice))
-		m = append(m, slice[i:end])
-	}
-	return m
-}
-
-// ShortHelp implements help.KeyMap.
-func (k KeyMap) ShortHelp() []key.Binding {
-	return []key.Binding{
-		k.ChangeSelection,
-		k.Select,
-		k.Close,
-	}
-}

internal/tui/components/dialogs/models/apikey.go 🔗

@@ -0,0 +1,96 @@
+package models
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/charmbracelet/bubbles/v2/textinput"
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/tui/styles"
+	"github.com/charmbracelet/lipgloss/v2"
+)
+
+type APIKeyInput struct {
+	input        textinput.Model
+	width        int
+	height       int
+	providerName string
+}
+
+func NewAPIKeyInput() *APIKeyInput {
+	t := styles.CurrentTheme()
+
+	ti := textinput.New()
+	ti.Placeholder = "Enter your API key..."
+	ti.SetWidth(50)
+	ti.SetVirtualCursor(false)
+	ti.Prompt = "> "
+	ti.SetStyles(t.S().TextInput)
+	ti.Focus()
+
+	return &APIKeyInput{
+		input:        ti,
+		width:        60,
+		providerName: "Provider",
+	}
+}
+
+func (a *APIKeyInput) SetProviderName(name string) {
+	a.providerName = name
+}
+
+func (a *APIKeyInput) Init() tea.Cmd {
+	return textinput.Blink
+}
+
+func (a *APIKeyInput) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+	switch msg := msg.(type) {
+	case tea.WindowSizeMsg:
+		a.width = msg.Width
+		a.height = msg.Height
+	}
+
+	var cmd tea.Cmd
+	a.input, cmd = a.input.Update(msg)
+	return a, cmd
+}
+
+func (a *APIKeyInput) View() string {
+	t := styles.CurrentTheme()
+
+	title := t.S().Base.
+		Foreground(t.Primary).
+		Bold(true).
+		Render(fmt.Sprintf("Enter your %s API Key", a.providerName))
+
+	inputView := a.input.View()
+
+	dataPath := config.GlobalConfigData()
+	dataPath = strings.Replace(dataPath, config.HomeDir(), "~", 1)
+	helpText := t.S().Muted.
+		Render(fmt.Sprintf("This will be written to the global configuration: %s", dataPath))
+
+	content := lipgloss.JoinVertical(
+		lipgloss.Left,
+		title,
+		"",
+		inputView,
+		"",
+		helpText,
+	)
+
+	return content
+}
+
+func (a *APIKeyInput) Cursor() *tea.Cursor {
+	cursor := a.input.Cursor()
+	if cursor != nil {
+		cursor.Y += 2 // Adjust for title and spacing
+	}
+	return cursor
+}
+
+func (a *APIKeyInput) Value() string {
+	return a.input.Value()
+}

internal/tui/components/dialogs/models/list.go 🔗

@@ -0,0 +1,202 @@
+package models
+
+import (
+	"fmt"
+	"slices"
+
+	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/fur/provider"
+	"github.com/charmbracelet/crush/internal/tui/components/completions"
+	"github.com/charmbracelet/crush/internal/tui/components/core/list"
+	"github.com/charmbracelet/crush/internal/tui/components/dialogs/commands"
+	"github.com/charmbracelet/crush/internal/tui/styles"
+	"github.com/charmbracelet/crush/internal/tui/util"
+	"github.com/charmbracelet/lipgloss/v2"
+)
+
+type ModelListComponent struct {
+	list      list.ListModel
+	modelType int
+	providers []provider.Provider
+}
+
+func NewModelListComponent(keyMap list.KeyMap, inputStyle lipgloss.Style, inputPlaceholder string) *ModelListComponent {
+	modelList := list.New(
+		list.WithFilterable(true),
+		list.WithKeyMap(keyMap),
+		list.WithInputStyle(inputStyle),
+		list.WithFilterPlaceholder(inputPlaceholder),
+		list.WithWrapNavigation(true),
+	)
+
+	return &ModelListComponent{
+		list:      modelList,
+		modelType: LargeModelType,
+	}
+}
+
+func (m *ModelListComponent) Init() tea.Cmd {
+	var cmds []tea.Cmd
+	if len(m.providers) == 0 {
+		providers, err := config.Providers()
+		m.providers = providers
+		if err != nil {
+			cmds = append(cmds, util.ReportError(err))
+		}
+	}
+	cmds = append(cmds, m.list.Init(), m.SetModelType(m.modelType))
+	return tea.Batch(cmds...)
+}
+
+func (m *ModelListComponent) Update(msg tea.Msg) (*ModelListComponent, tea.Cmd) {
+	u, cmd := m.list.Update(msg)
+	m.list = u.(list.ListModel)
+	return m, cmd
+}
+
+func (m *ModelListComponent) View() string {
+	return m.list.View()
+}
+
+func (m *ModelListComponent) Cursor() *tea.Cursor {
+	return m.list.Cursor()
+}
+
+func (m *ModelListComponent) SetSize(width, height int) tea.Cmd {
+	return m.list.SetSize(width, height)
+}
+
+func (m *ModelListComponent) Items() []util.Model {
+	return m.list.Items()
+}
+
+func (m *ModelListComponent) SelectedIndex() int {
+	return m.list.SelectedIndex()
+}
+
+func (m *ModelListComponent) SetModelType(modelType int) tea.Cmd {
+	t := styles.CurrentTheme()
+	m.modelType = modelType
+
+	modelItems := []util.Model{}
+	selectIndex := 0
+
+	cfg := config.Get()
+	var currentModel config.SelectedModel
+	if m.modelType == LargeModelType {
+		currentModel = cfg.Models[config.SelectedModelTypeLarge]
+	} else {
+		currentModel = cfg.Models[config.SelectedModelTypeSmall]
+	}
+
+	configuredIcon := t.S().Base.Foreground(t.Success).Render(styles.CheckIcon)
+	configured := fmt.Sprintf("%s %s", configuredIcon, t.S().Subtle.Render("Configured"))
+
+	// Create a map to track which providers we've already added
+	addedProviders := make(map[string]bool)
+
+	// First, add any configured providers that are not in the known providers list
+	// These should appear at the top of the list
+	knownProviders := provider.KnownProviders()
+	for providerID, providerConfig := range cfg.Providers {
+		if providerConfig.Disable {
+			continue
+		}
+
+		// Check if this provider is not in the known providers list
+		if !slices.Contains(knownProviders, provider.InferenceProvider(providerID)) {
+			// Convert config provider to provider.Provider format
+			configProvider := provider.Provider{
+				Name:   providerConfig.Name,
+				ID:     provider.InferenceProvider(providerID),
+				Models: make([]provider.Model, len(providerConfig.Models)),
+			}
+
+			// Convert models
+			for i, model := range providerConfig.Models {
+				configProvider.Models[i] = provider.Model{
+					ID:                     model.ID,
+					Model:                  model.Model,
+					CostPer1MIn:            model.CostPer1MIn,
+					CostPer1MOut:           model.CostPer1MOut,
+					CostPer1MInCached:      model.CostPer1MInCached,
+					CostPer1MOutCached:     model.CostPer1MOutCached,
+					ContextWindow:          model.ContextWindow,
+					DefaultMaxTokens:       model.DefaultMaxTokens,
+					CanReason:              model.CanReason,
+					HasReasoningEffort:     model.HasReasoningEffort,
+					DefaultReasoningEffort: model.DefaultReasoningEffort,
+					SupportsImages:         model.SupportsImages,
+				}
+			}
+
+			// Add this unknown provider to the list
+			name := configProvider.Name
+			if name == "" {
+				name = string(configProvider.ID)
+			}
+			section := commands.NewItemSection(name)
+			section.SetInfo(configured)
+			modelItems = append(modelItems, section)
+			for _, model := range configProvider.Models {
+				modelItems = append(modelItems, completions.NewCompletionItem(model.Model, ModelOption{
+					Provider: configProvider,
+					Model:    model,
+				}))
+				if model.ID == currentModel.Model && string(configProvider.ID) == currentModel.Provider {
+					selectIndex = len(modelItems) - 1 // Set the selected index to the current model
+				}
+			}
+			addedProviders[providerID] = true
+		}
+	}
+
+	// Then add the known providers from the predefined list
+	for _, provider := range m.providers {
+		// Skip if we already added this provider as an unknown provider
+		if addedProviders[string(provider.ID)] {
+			continue
+		}
+
+		// Check if this provider is configured and not disabled
+		if providerConfig, exists := cfg.Providers[string(provider.ID)]; exists && providerConfig.Disable {
+			continue
+		}
+
+		name := provider.Name
+		if name == "" {
+			name = string(provider.ID)
+		}
+
+		section := commands.NewItemSection(name)
+		if _, ok := cfg.Providers[string(provider.ID)]; ok {
+			section.SetInfo(configured)
+		}
+		modelItems = append(modelItems, section)
+		for _, model := range provider.Models {
+			modelItems = append(modelItems, completions.NewCompletionItem(model.Model, ModelOption{
+				Provider: provider,
+				Model:    model,
+			}))
+			if model.ID == currentModel.Model && string(provider.ID) == currentModel.Provider {
+				selectIndex = len(modelItems) - 1 // Set the selected index to the current model
+			}
+		}
+	}
+
+	return tea.Sequence(m.list.SetItems(modelItems), m.list.SetSelected(selectIndex))
+}
+
+// GetModelType returns the current model type
+func (m *ModelListComponent) GetModelType() int {
+	return m.modelType
+}
+
+func (m *ModelListComponent) SetInputPlaceholder(placeholder string) {
+	m.list.SetFilterPlaceholder(placeholder)
+}
+
+func (m *ModelListComponent) SetProviders(providers []provider.Provider) {
+	m.providers = providers
+}

internal/tui/components/dialogs/models/models.go 🔗

@@ -1,8 +1,6 @@
 package models
 
 import (
-	"slices"
-
 	"github.com/charmbracelet/bubbles/v2/help"
 	"github.com/charmbracelet/bubbles/v2/key"
 	tea "github.com/charmbracelet/bubbletea/v2"
@@ -12,7 +10,6 @@ import (
 	"github.com/charmbracelet/crush/internal/tui/components/core"
 	"github.com/charmbracelet/crush/internal/tui/components/core/list"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
-	"github.com/charmbracelet/crush/internal/tui/components/dialogs/commands"
 	"github.com/charmbracelet/crush/internal/tui/styles"
 	"github.com/charmbracelet/crush/internal/tui/util"
 	"github.com/charmbracelet/lipgloss/v2"
@@ -27,6 +24,9 @@ const (
 const (
 	LargeModelType int = iota
 	SmallModelType
+
+	largeModelInputPlaceholder = "Choose a model for large, complex tasks"
+	smallModelInputPlaceholder = "Choose a model for small, simple tasks"
 )
 
 // ModelSelectedMsg is sent when a model is selected
@@ -53,10 +53,9 @@ type modelDialogCmp struct {
 	wWidth  int
 	wHeight int
 
-	modelList list.ListModel
+	modelList *ModelListComponent
 	keyMap    KeyMap
 	help      help.Model
-	modelType int
 }
 
 func NewModelDialogCmp() ModelDialog {
@@ -75,12 +74,7 @@ func NewModelDialogCmp() ModelDialog {
 
 	t := styles.CurrentTheme()
 	inputStyle := t.S().Base.Padding(0, 1, 0, 1)
-	modelList := list.New(
-		list.WithFilterable(true),
-		list.WithKeyMap(listKeyMap),
-		list.WithInputStyle(inputStyle),
-		list.WithWrapNavigation(true),
-	)
+	modelList := NewModelListComponent(listKeyMap, inputStyle, "Choose a model for large, complex tasks")
 	help := help.New()
 	help.Styles = t.S().Help
 
@@ -89,12 +83,10 @@ func NewModelDialogCmp() ModelDialog {
 		width:     defaultWidth,
 		keyMap:    DefaultKeyMap(),
 		help:      help,
-		modelType: LargeModelType,
 	}
 }
 
 func (m *modelDialogCmp) Init() tea.Cmd {
-	m.SetModelType(m.modelType)
 	return m.modelList.Init()
 }
 
@@ -103,7 +95,6 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	case tea.WindowSizeMsg:
 		m.wWidth = msg.Width
 		m.wHeight = msg.Height
-		m.SetModelType(m.modelType)
 		return m, m.modelList.SetSize(m.listWidth(), m.listHeight())
 	case tea.KeyPressMsg:
 		switch {
@@ -116,7 +107,7 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			selectedItem := items[selectedItemInx].(completions.CompletionItem).Value().(ModelOption)
 
 			var modelType config.SelectedModelType
-			if m.modelType == LargeModelType {
+			if m.modelList.GetModelType() == LargeModelType {
 				modelType = config.SelectedModelTypeLarge
 			} else {
 				modelType = config.SelectedModelTypeSmall
@@ -133,16 +124,18 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 				}),
 			)
 		case key.Matches(msg, m.keyMap.Tab):
-			if m.modelType == LargeModelType {
-				return m, m.SetModelType(SmallModelType)
+			if m.modelList.GetModelType() == LargeModelType {
+				m.modelList.SetInputPlaceholder(smallModelInputPlaceholder)
+				return m, m.modelList.SetModelType(SmallModelType)
 			} else {
-				return m, m.SetModelType(LargeModelType)
+				m.modelList.SetInputPlaceholder(largeModelInputPlaceholder)
+				return m, m.modelList.SetModelType(LargeModelType)
 			}
 		case key.Matches(msg, m.keyMap.Close):
 			return m, util.CmdHandler(dialogs.CloseDialogMsg{})
 		default:
 			u, cmd := m.modelList.Update(msg)
-			m.modelList = u.(list.ListModel)
+			m.modelList = u
 			return m, cmd
 		}
 	}
@@ -164,12 +157,10 @@ func (m *modelDialogCmp) View() string {
 }
 
 func (m *modelDialogCmp) Cursor() *tea.Cursor {
-	if cursor, ok := m.modelList.(util.Cursor); ok {
-		cursor := cursor.Cursor()
-		if cursor != nil {
-			cursor = m.moveCursor(cursor)
-			return cursor
-		}
+	cursor := m.modelList.Cursor()
+	if cursor != nil {
+		cursor = m.moveCursor(cursor)
+		return cursor
 	}
 	return nil
 }
@@ -187,7 +178,8 @@ func (m *modelDialogCmp) listWidth() int {
 }
 
 func (m *modelDialogCmp) listHeight() int {
-	listHeigh := len(m.modelList.Items()) + 2 + 4 // height based on items + 2 for the input + 4 for the sections
+	items := m.modelList.Items()
+	listHeigh := len(items) + 2 + 4
 	return min(listHeigh, m.wHeight/2)
 }
 
@@ -215,115 +207,8 @@ func (m *modelDialogCmp) modelTypeRadio() string {
 	choices := []string{"Large Task", "Small Task"}
 	iconSelected := "◉"
 	iconUnselected := "○"
-	if m.modelType == LargeModelType {
+	if m.modelList.GetModelType() == LargeModelType {
 		return t.S().Base.Foreground(t.FgHalfMuted).Render(iconSelected + " " + choices[0] + "  " + iconUnselected + " " + choices[1])
 	}
 	return t.S().Base.Foreground(t.FgHalfMuted).Render(iconUnselected + " " + choices[0] + "  " + iconSelected + " " + choices[1])
 }
-
-func (m *modelDialogCmp) SetModelType(modelType int) tea.Cmd {
-	m.modelType = modelType
-
-	providers, err := config.Providers()
-	if err != nil {
-		return util.ReportError(err)
-	}
-
-	modelItems := []util.Model{}
-	selectIndex := 0
-
-	cfg := config.Get()
-	var currentModel config.SelectedModel
-	if m.modelType == LargeModelType {
-		currentModel = cfg.Models[config.SelectedModelTypeLarge]
-	} else {
-		currentModel = cfg.Models[config.SelectedModelTypeSmall]
-	}
-
-	// Create a map to track which providers we've already added
-	addedProviders := make(map[string]bool)
-
-	// First, add any configured providers that are not in the known providers list
-	// These should appear at the top of the list
-	knownProviders := provider.KnownProviders()
-	for providerID, providerConfig := range cfg.Providers {
-		if providerConfig.Disable {
-			continue
-		}
-
-		// Check if this provider is not in the known providers list
-		if !slices.Contains(knownProviders, provider.InferenceProvider(providerID)) {
-			// Convert config provider to provider.Provider format
-			configProvider := provider.Provider{
-				Name:   string(providerID), // Use provider ID as name for unknown providers
-				ID:     provider.InferenceProvider(providerID),
-				Models: make([]provider.Model, len(providerConfig.Models)),
-			}
-
-			// Convert models
-			for i, model := range providerConfig.Models {
-				configProvider.Models[i] = provider.Model{
-					ID:                     model.ID,
-					Model:                  model.Model,
-					CostPer1MIn:            model.CostPer1MIn,
-					CostPer1MOut:           model.CostPer1MOut,
-					CostPer1MInCached:      model.CostPer1MInCached,
-					CostPer1MOutCached:     model.CostPer1MOutCached,
-					ContextWindow:          model.ContextWindow,
-					DefaultMaxTokens:       model.DefaultMaxTokens,
-					CanReason:              model.CanReason,
-					HasReasoningEffort:     model.HasReasoningEffort,
-					DefaultReasoningEffort: model.DefaultReasoningEffort,
-					SupportsImages:         model.SupportsImages,
-				}
-			}
-
-			// Add this unknown provider to the list
-			name := configProvider.Name
-			if name == "" {
-				name = string(configProvider.ID)
-			}
-			modelItems = append(modelItems, commands.NewItemSection(name))
-			for _, model := range configProvider.Models {
-				modelItems = append(modelItems, completions.NewCompletionItem(model.Model, ModelOption{
-					Provider: configProvider,
-					Model:    model,
-				}))
-				if model.ID == currentModel.Model && string(configProvider.ID) == currentModel.Provider {
-					selectIndex = len(modelItems) - 1 // Set the selected index to the current model
-				}
-			}
-			addedProviders[providerID] = true
-		}
-	}
-
-	// Then add the known providers from the predefined list
-	for _, provider := range providers {
-		// Skip if we already added this provider as an unknown provider
-		if addedProviders[string(provider.ID)] {
-			continue
-		}
-
-		// Check if this provider is configured and not disabled
-		if providerConfig, exists := cfg.Providers[string(provider.ID)]; exists && providerConfig.Disable {
-			continue
-		}
-
-		name := provider.Name
-		if name == "" {
-			name = string(provider.ID)
-		}
-		modelItems = append(modelItems, commands.NewItemSection(name))
-		for _, model := range provider.Models {
-			modelItems = append(modelItems, completions.NewCompletionItem(model.Model, ModelOption{
-				Provider: provider,
-				Model:    model,
-			}))
-			if model.ID == currentModel.Model && string(provider.ID) == currentModel.Provider {
-				selectIndex = len(modelItems) - 1 // Set the selected index to the current model
-			}
-		}
-	}
-
-	return tea.Sequence(m.modelList.SetItems(modelItems), m.modelList.SetSelected(selectIndex))
-}

internal/tui/components/dialogs/permissions/keys.go 🔗

@@ -109,9 +109,5 @@ func (k KeyMap) ShortHelp() []key.Binding {
 			key.WithKeys("shift+left", "shift+down", "shift+up", "shift+right"),
 			key.WithHelp("shift+←↓↑→", "scroll"),
 		),
-		key.NewBinding(
-			key.WithKeys("shift+h", "shift+j", "shift+k", "shift+l"),
-			key.WithHelp("shift+hjkl", "scroll"),
-		),
 	}
 }

internal/tui/components/dialogs/permissions/permissions.go 🔗

@@ -199,6 +199,13 @@ func (p *permissionDialogCmp) renderButtons() string {
 	}
 
 	content := core.SelectableButtons(buttons, "  ")
+	if lipgloss.Width(content) > p.width-4 {
+		content = core.SelectableButtonsVertical(buttons, 1)
+		return baseStyle.AlignVertical(lipgloss.Center).
+			AlignHorizontal(lipgloss.Center).
+			Width(p.width - 4).
+			Render(content)
+	}
 
 	return baseStyle.AlignHorizontal(lipgloss.Right).Width(p.width - 4).Render(content)
 }
@@ -382,19 +389,10 @@ func (p *permissionDialogCmp) generateFetchContent() string {
 	t := styles.CurrentTheme()
 	baseStyle := t.S().Base.Background(t.BgSubtle)
 	if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
-		content := fmt.Sprintf("```bash\n%s\n```", pr.URL)
-
-		// Use the cache for markdown rendering
-		renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
-			r := styles.GetMarkdownRenderer(p.width - 4)
-			s, err := r.Render(content)
-			return s, err
-		})
-
 		finalContent := baseStyle.
+			Padding(1, 2).
 			Width(p.contentViewPort.Width()).
-			Render(renderedContent)
-
+			Render(pr.URL)
 		return finalContent
 	}
 	return ""
@@ -452,8 +450,8 @@ func (p *permissionDialogCmp) render() string {
 	if p.supportsDiffView() {
 		contentHelp = help.New().View(p.keyMap)
 	}
-	// Calculate content height dynamically based on window size
 
+	// Calculate content height dynamically based on window size
 	strs := []string{
 		title,
 		"",
@@ -491,7 +489,7 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd {
 
 	switch p.permission.ToolName {
 	case tools.BashToolName:
-		p.width = int(float64(p.wWidth) * 0.4)
+		p.width = int(float64(p.wWidth) * 0.8)
 		p.height = int(float64(p.wHeight) * 0.3)
 	case tools.EditToolName:
 		p.width = int(float64(p.wWidth) * 0.8)
@@ -500,7 +498,7 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd {
 		p.width = int(float64(p.wWidth) * 0.8)
 		p.height = int(float64(p.wHeight) * 0.8)
 	case tools.FetchToolName:
-		p.width = int(float64(p.wWidth) * 0.4)
+		p.width = int(float64(p.wWidth) * 0.8)
 		p.height = int(float64(p.wHeight) * 0.3)
 	default:
 		p.width = int(float64(p.wWidth) * 0.7)

internal/tui/components/logo/logo.go 🔗

@@ -85,7 +85,7 @@ func Render(version string, compact bool, o Opts) string {
 	}
 
 	// Right field.
-	rightWidth := max(15, o.Width-crushWidth-leftWidth) // 2 for the gap.
+	rightWidth := max(15, o.Width-crushWidth-leftWidth-2) // 2 for the gap.
 	const stepDownAt = 0
 	rightField := new(strings.Builder)
 	for i := range fieldHeight {
@@ -98,7 +98,16 @@ func Render(version string, compact bool, o Opts) string {
 
 	// Return the wide version.
 	const hGap = " "
-	return lipgloss.JoinHorizontal(lipgloss.Top, leftField.String(), hGap, crush, hGap, rightField.String())
+	logo := lipgloss.JoinHorizontal(lipgloss.Top, leftField.String(), hGap, crush, hGap, rightField.String())
+	if o.Width > 0 {
+		// Truncate the logo to the specified width.
+		lines := strings.Split(logo, "\n")
+		for i, line := range lines {
+			lines[i] = ansi.Truncate(line, o.Width, "")
+		}
+		logo = strings.Join(lines, "\n")
+	}
+	return logo
 }
 
 // renderWord renders letterforms to fork a word.

internal/tui/exp/diffview/diffview.go 🔗

@@ -365,7 +365,8 @@ func (dv *DiffView) renderUnified() string {
 	shouldWrite := func() bool { return printedLines >= 0 }
 
 	getContent := func(in string, ls LineStyle) (content string, leadingEllipsis bool) {
-		content = strings.TrimSuffix(in, "\n")
+		content = strings.ReplaceAll(in, "\r\n", "\n")
+		content = strings.TrimSuffix(content, "\n")
 		content = dv.hightlightCode(content, ls.Code.GetBackground())
 		content = ansi.GraphemeWidth.Cut(content, dv.xOffset, len(content))
 		content = ansi.Truncate(content, dv.codeWidth, "…")
@@ -488,7 +489,8 @@ func (dv *DiffView) renderSplit() string {
 	shouldWrite := func() bool { return printedLines >= 0 }
 
 	getContent := func(in string, ls LineStyle) (content string, leadingEllipsis bool) {
-		content = strings.TrimSuffix(in, "\n")
+		content = strings.ReplaceAll(in, "\r\n", "\n")
+		content = strings.TrimSuffix(content, "\n")
 		content = dv.hightlightCode(content, ls.Code.GetBackground())
 		content = ansi.GraphemeWidth.Cut(content, dv.xOffset, len(content))
 		content = ansi.Truncate(content, dv.codeWidth, "…")

internal/tui/exp/diffview/testdata/TestDiffView/Split/CustomContextLines/DarkMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   @@ -1,13 +1,15 @@                                 …                                                   
-  1   package main                                      1   package main                                    
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  8       fmt.Println(getContent())                     9       fmt.Println(getContent())                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
- 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
-                                                       14 +     return content                              
- 13   }                                                15   }                                               
+  …   @@ -1,13 +1,15 @@                                 …                                                   
+  1   package main                                      1   package main                                    
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  8       fmt.Println(getContent())                     9       fmt.Println(getContent())                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+ 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
+                                                       14 +     return content                              
+ 13   }                                                15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Split/CustomContextLines/LightMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   @@ -1,13 +1,15 @@                                 …                                                   
-  1   package main                                      1   package main                                    
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  8       fmt.Println(getContent())                     9       fmt.Println(getContent())                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffView/Split/Default/DarkMode.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@                    …                                    
-  5   )                                  5   )                                
-  6                                      6                                    
-  7   func main() {                      7   func main() {                    
-  8 -     fmt.Println("Hello, world!")   8 +     content := "Hello, world!"   
-                                         9 +     fmt.Println(content)         
-  9   }                                 10   }                                
+  …   @@ -5,5 +5,6 @@                    …                                    
+  5   )                                  5   )                                
+  6                                      6                                    
+  7   func main() {                      7   func main() {                    
+  8 -     fmt.Println("Hello, world!")   8 +     content := "Hello, world!"   
+                                         9 +     fmt.Println(content)         
+  9   }                                 10   }                                

internal/tui/exp/diffview/testdata/TestDiffView/Split/Default/LightMode.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@                    …                                    
-  5   )                                  5   )                                
-  6                                      6                                    
-  7   func main() {                      7   func main() {                    
-  8 -     fmt.Println("Hello, world!")   8 +     content := "Hello, world!"   
-                                         9 +     fmt.Println(content)         
-  9   }                                 10   }                                
+  …   @@ -5,5 +5,6 @@                    …                                    
+  5   )                                  5   )                                
+  6                                      6                                    
+  7   func main() {                      7   func main() {                    
+  8 -     fmt.Println("Hello, world!")   8 +     content := "Hello, world!"   
+                                         9 +     fmt.Println(content)         
+  9   }                                 10   }                                

internal/tui/exp/diffview/testdata/TestDiffView/Split/LargeWidth/DarkMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                         …                                                         
-  2                                                           2                                                         
-  3   import (                                                3   import (                                              
-  4       "fmt"                                               4       "fmt"                                             
-                                                              5 +     "strings"                                         
-  5   )                                                       6   )                                                     
-  6                                                           7                                                         
-  7   func main() {                                           8   func main() {                                         
-  …   @@ -9,5 +10,6 @@                                        …                                                         
-  9   }                                                      10   }                                                     
- 10                                                          11                                                         
- 11   func getContent() string {                             12   func getContent() string {                            
- 12 -     return "Hello, world!"                             13 +     content := strings.ToUpper("Hello, World!")       
-                                                             14 +     return content                                    
- 13   }                                                      15   }                                                     
+  …   @@ -2,6 +2,7 @@                                         …                                                         
+  2                                                           2                                                         
+  3   import (                                                3   import (                                              
+  4       "fmt"                                               4       "fmt"                                             
+                                                              5 +     "strings"                                         
+  5   )                                                       6   )                                                     
+  6                                                           7                                                         
+  7   func main() {                                           8   func main() {                                         
+  …   @@ -9,5 +10,6 @@                                        …                                                         
+  9   }                                                      10   }                                                     
+ 10                                                          11                                                         
+ 11   func getContent() string {                             12   func getContent() string {                            
+ 12 -     return "Hello, world!"                             13 +     content := strings.ToUpper("Hello, World!")       
+                                                             14 +     return content                                    
+ 13   }                                                      15   }                                                     

internal/tui/exp/diffview/testdata/TestDiffView/Split/LargeWidth/LightMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                         …                                                         
-  2                                                           2                                                         
-  3   import (                                                3   import (                                              
-  4       "fmt"                                               4       "fmt"                                             
-                                                              5 +     "strings"                                         
-  5   )                                                       6   )                                                     
-  6                                                           7                                                         
-  7   func main() {                                           8   func main() {                                         
-  …   @@ -9,5 +10,6 @@                                        …                                                         
-  9   }                                                      10   }                                                     
- 10                                                          11                                                         
- 11   func getContent() string {                             12   func getContent() string {                            

internal/tui/exp/diffview/testdata/TestDiffView/Split/MultipleHunks/DarkMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
- 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
-                                                       14 +     return content                              
- 13   }                                                15   }                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+ 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
+                                                       14 +     return content                              
+ 13   }                                                15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Split/MultipleHunks/LightMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffView/Split/Narrow/DarkMode.golden 🔗

@@ -1,4 +1,4 @@
- …   @@ -1,3 +1,3 @@    …                     
- 1 - a                  1 + d                 
- 2 - b                  2 + e                 
- 3 - c                  3 + f                 
+ …   @@ -1,3 +1,3 @@    …                     
+ 1 - a                  1 + d                 
+ 2 - b                  2 + e                 
+ 3 - c                  3 + f                 

internal/tui/exp/diffview/testdata/TestDiffView/Split/Narrow/LightMode.golden 🔗

@@ -1,4 +1,4 @@
- …   @@ -1,3 +1,3 @@    …                     
- 1 - a                  1 + d                 
- 2 - b                  2 + e                 
- 3 - c                  3 + f                 
+ …   @@ -1,3 +1,3 @@    …                     
+ 1 - a                  1 + d                 
+ 2 - b                  2 + e                 
+ 3 - c                  3 + f                 

internal/tui/exp/diffview/testdata/TestDiffView/Split/NoSyntaxHighlight/DarkMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
- 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
-                                                       14 +     return content                              
- 13   }                                                15   }                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+ 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
+                                                       14 +     return content                              
+ 13   }                                                15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Split/NoSyntaxHighlight/LightMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
- 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
-                                                       14 +     return content                              
- 13   }                                                15   }                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+ 12 -     return "Hello, world!"                       13 +     content := strings.ToUpper("Hello, World!") 
+                                                       14 +     return content                              
+ 13   }                                                15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Split/SmallWidth/DarkMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 …  …                 
-  2                   2                 
-  3   import (        3   import (      
-  4       "fmt"       4       "fmt"     
-                      5 +     "strings" 
-  5   )               6   )             
-  6                   7                 
-  7   func main() {   8   func main() { 
-  …   @@ -9,5 +10,6…  …                 
-  9   }              10   }             
- 10                  11                 
- 11   func getConte… 12   func getConte…
- 12 -     return "H… 13 +     content :…
-                     14 +     return co…
- 13   }              15   }             
+  …   @@ -2,6 +2,7 …  …                 
+  2                   2                 
+  3   import (        3   import (      
+  4       "fmt"       4       "fmt"     
+                      5 +     "strings" 
+  5   )               6   )             
+  6                   7                 
+  7   func main() {   8   func main() { 
+  …   @@ -9,5 +10,6…  …                 
+  9   }              10   }             
+ 10                  11                 
+ 11   func getConte… 12   func getConte…
+ 12 -     return "H… 13 +     content :…
+                     14 +     return co…
+ 13   }              15   }             

internal/tui/exp/diffview/testdata/TestDiffView/Split/SmallWidth/LightMode.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 …  …                 
-  2                   2                 
-  3   import (        3   import (      
-  4       "fmt"       4       "fmt"     
-                      5 +     "strings" 
-  5   )               6   )             
-  6                   7                 
-  7   func main() {   8   func main() { 
-  …   @@ -9,5 +10,6…  …                 
-  9   }              10   }             
- 10                  11                 
- 11   func getConte… 12   func getConte…
- 12 -     return "H… 13 +     content :…
-                     14 +     return co…
- 13   }              15   }             
+  …   @@ -2,6 +2,7 …  …                 
+  2                   2                 
+  3   import (        3   import (      
+  4       "fmt"       4       "fmt"     
+                      5 +     "strings" 
+  5   )               6   )             
+  6                   7                 
+  7   func main() {   8   func main() { 
+  …   @@ -9,5 +10,6…  …                 
+  9   }              10   }             
+ 10                  11                 
+ 11   func getConte… 12   func getConte…
+ 12 -     return "H… 13 +     content :…
+                     14 +     return co…
+ 13   }              15   }             

internal/tui/exp/diffview/testdata/TestDiffView/Unified/CustomContextLines/DarkMode.golden 🔗

@@ -1,17 +1,17 @@
-  …   …   @@ -1,13 +1,15 @@                               
-  1   1   package main                                    
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  8   9       fmt.Println(getContent())                   
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -1,13 +1,15 @@                               
+  1   1   package main                                    
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  8   9       fmt.Println(getContent())                   
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Unified/CustomContextLines/LightMode.golden 🔗

@@ -1,17 +1,17 @@
-  …   …   @@ -1,13 +1,15 @@                               
-  1   1   package main                                    
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  8   9       fmt.Println(getContent())                   
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -1,13 +1,15 @@                               
+  1   1   package main                                    
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  8   9       fmt.Println(getContent())                   
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Unified/Default/DarkMode.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                  
-  5   5   )                                
-  6   6                                    
-  7   7   func main() {                    
-  8     -     fmt.Println("Hello, world!") 
-      8 +     content := "Hello, world!"   
-      9 +     fmt.Println(content)         
-  9  10   }                                
+  …   …   @@ -5,5 +5,6 @@                  
+  5   5   )                                
+  6   6                                    
+  7   7   func main() {                    
+  8     -     fmt.Println("Hello, world!") 
+      8 +     content := "Hello, world!"   
+      9 +     fmt.Println(content)         
+  9  10   }                                

internal/tui/exp/diffview/testdata/TestDiffView/Unified/Default/LightMode.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                  
-  5   5   )                                
-  6   6                                    
-  7   7   func main() {                    
-  8     -     fmt.Println("Hello, world!") 
-      8 +     content := "Hello, world!"   
-      9 +     fmt.Println(content)         
-  9  10   }                                
+  …   …   @@ -5,5 +5,6 @@                  
+  5   5   )                                
+  6   6                                    
+  7   7   func main() {                    
+  8     -     fmt.Println("Hello, world!") 
+      8 +     content := "Hello, world!"   
+      9 +     fmt.Println(content)         
+  9  10   }                                

internal/tui/exp/diffview/testdata/TestDiffView/Unified/LargeWidth/DarkMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                                                                               
-  2   2                                                                                                                 
-  3   3   import (                                                                                                      
-  4   4       "fmt"                                                                                                     
-      5 +     "strings"                                                                                                 
-  5   6   )                                                                                                             
-  6   7                                                                                                                 
-  7   8   func main() {                                                                                                 
-  …   …   @@ -9,5 +10,6 @@                                                                                              
-  9  10   }                                                                                                             
- 10  11                                                                                                                 
- 11  12   func getContent() string {                                                                                    
- 12     -     return "Hello, world!"                                                                                    
-     13 +     content := strings.ToUpper("Hello, World!")                                                               
-     14 +     return content                                                                                            
- 13  15   }                                                                                                             
+  …   …   @@ -2,6 +2,7 @@                                                                                               
+  2   2                                                                                                                 
+  3   3   import (                                                                                                      
+  4   4       "fmt"                                                                                                     
+      5 +     "strings"                                                                                                 
+  5   6   )                                                                                                             
+  6   7                                                                                                                 
+  7   8   func main() {                                                                                                 
+  …   …   @@ -9,5 +10,6 @@                                                                                              
+  9  10   }                                                                                                             
+ 10  11                                                                                                                 
+ 11  12   func getContent() string {                                                                                    
+ 12     -     return "Hello, world!"                                                                                    
+     13 +     content := strings.ToUpper("Hello, World!")                                                               
+     14 +     return content                                                                                            
+ 13  15   }                                                                                                             

internal/tui/exp/diffview/testdata/TestDiffView/Unified/LargeWidth/LightMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                                                                               
-  2   2                                                                                                                 
-  3   3   import (                                                                                                      
-  4   4       "fmt"                                                                                                     
-      5 +     "strings"                                                                                                 
-  5   6   )                                                                                                             
-  6   7                                                                                                                 
-  7   8   func main() {                                                                                                 
-  …   …   @@ -9,5 +10,6 @@                                                                                              
-  9  10   }                                                                                                             
- 10  11                                                                                                                 
- 11  12   func getContent() string {                                                                                    
- 12     -     return "Hello, world!"                                                                                    
-     13 +     content := strings.ToUpper("Hello, World!")                                                               
-     14 +     return content                                                                                            
- 13  15   }                                                                                                             
+  …   …   @@ -2,6 +2,7 @@                                                                                               
+  2   2                                                                                                                 
+  3   3   import (                                                                                                      
+  4   4       "fmt"                                                                                                     
+      5 +     "strings"                                                                                                 
+  5   6   )                                                                                                             
+  6   7                                                                                                                 
+  7   8   func main() {                                                                                                 
+  …   …   @@ -9,5 +10,6 @@                                                                                              
+  9  10   }                                                                                                             
+ 10  11                                                                                                                 
+ 11  12   func getContent() string {                                                                                    
+ 12     -     return "Hello, world!"                                                                                    
+     13 +     content := strings.ToUpper("Hello, World!")                                                               
+     14 +     return content                                                                                            
+ 13  15   }                                                                                                             

internal/tui/exp/diffview/testdata/TestDiffView/Unified/MultipleHunks/DarkMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Unified/MultipleHunks/LightMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Unified/Narrow/DarkMode.golden 🔗

@@ -1,7 +1,7 @@
- …  …   @@ -1,3 +1,3 @@   
- 1    - a                 
- 2    - b                 
- 3    - c                 
-    1 + d                 
-    2 + e                 
-    3 + f                 
+ …  …   @@ -1,3 +1,3 @@   
+ 1    - a                 
+ 2    - b                 
+ 3    - c                 
+    1 + d                 
+    2 + e                 
+    3 + f                 

internal/tui/exp/diffview/testdata/TestDiffView/Unified/Narrow/LightMode.golden 🔗

@@ -1,7 +1,7 @@
- …  …   @@ -1,3 +1,3 @@   
- 1    - a                 
- 2    - b                 
- 3    - c                 
-    1 + d                 
-    2 + e                 
-    3 + f                 
+ …  …   @@ -1,3 +1,3 @@   
+ 1    - a                 
+ 2    - b                 
+ 3    - c                 
+    1 + d                 
+    2 + e                 
+    3 + f                 

internal/tui/exp/diffview/testdata/TestDiffView/Unified/NoSyntaxHighlight/DarkMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Unified/NoSyntaxHighlight/LightMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffView/Unified/SmallWidth/DarkMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@               
-  2   2                                 
-  3   3   import (                      
-  4   4       "fmt"                     
-      5 +     "strings"                 
-  5   6   )                             
-  6   7                                 
-  7   8   func main() {                 
-  …   …   @@ -9,5 +10,6 @@              
-  9  10   }                             
- 10  11                                 
- 11  12   func getContent() string {    
- 12     -     return "Hello, world!"    
-     13 +     content := strings.ToUppe…
-     14 +     return content            
- 13  15   }                             
+  …   …   @@ -2,6 +2,7 @@               
+  2   2                                 
+  3   3   import (                      
+  4   4       "fmt"                     
+      5 +     "strings"                 
+  5   6   )                             
+  6   7                                 
+  7   8   func main() {                 
+  …   …   @@ -9,5 +10,6 @@              
+  9  10   }                             
+ 10  11                                 
+ 11  12   func getContent() string {    
+ 12     -     return "Hello, world!"    
+     13 +     content := strings.ToUppe…
+     14 +     return content            
+ 13  15   }                             

internal/tui/exp/diffview/testdata/TestDiffView/Unified/SmallWidth/LightMode.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@               
-  2   2                                 
-  3   3   import (                      
-  4   4       "fmt"                     
-      5 +     "strings"                 
-  5   6   )                             
-  6   7                                 
-  7   8   func main() {                 
-  …   …   @@ -9,5 +10,6 @@              
-  9  10   }                             
- 10  11                                 
- 11  12   func getContent() string {    
- 12     -     return "Hello, world!"    
-     13 +     content := strings.ToUppe…
-     14 +     return content            
- 13  15   }                             
+  …   …   @@ -2,6 +2,7 @@               
+  2   2                                 
+  3   3   import (                      
+  4   4       "fmt"                     
+      5 +     "strings"                 
+  5   6   )                             
+  6   7                                 
+  7   8   func main() {                 
+  …   …   @@ -9,5 +10,6 @@              
+  9  10   }                             
+ 10  11                                 
+ 11  12   func getContent() string {    
+ 12     -     return "Hello, world!"    
+     13 +     content := strings.ToUppe…
+     14 +     return content            
+ 13  15   }                             

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf001.golden 🔗

@@ -1 +1 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
+  …   @@ -2,6 +2,7 @@                                   …                                                   

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf002.golden 🔗

@@ -1,2 +1,2 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf003.golden 🔗

@@ -1,3 +1,3 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf004.golden 🔗

@@ -1,4 +1,4 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf005.golden 🔗

@@ -1,5 +1,5 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf006.golden 🔗

@@ -1,6 +1,6 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf007.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf008.golden 🔗

@@ -1,8 +1,8 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf009.golden 🔗

@@ -1,9 +1,9 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf010.golden 🔗

@@ -1,10 +1,10 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf011.golden 🔗

@@ -1,11 +1,11 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf012.golden 🔗

@@ -1,12 +1,12 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf013.golden 🔗

@@ -1,13 +1,13 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf014.golden 🔗

@@ -1,14 +1,14 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf015.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf016.golden 🔗

@@ -1,16 +1,16 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf017.golden 🔗

@@ -1,17 +1,17 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf018.golden 🔗

@@ -1,18 +1,18 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf019.golden 🔗

@@ -1,19 +1,19 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Split/HeightOf020.golden 🔗

@@ -1,20 +1,20 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf001.golden 🔗

@@ -1 +1 @@
-  …   …   @@ -2,6 +2,7 @@                                 
+  …   …   @@ -2,6 +2,7 @@                                 

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf002.golden 🔗

@@ -1,2 +1,2 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf003.golden 🔗

@@ -1,3 +1,3 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf004.golden 🔗

@@ -1,4 +1,4 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf005.golden 🔗

@@ -1,5 +1,5 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf006.golden 🔗

@@ -1,6 +1,6 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf007.golden 🔗

@@ -1,7 +1,7 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf008.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf009.golden 🔗

@@ -1,9 +1,9 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf010.golden 🔗

@@ -1,10 +1,10 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf011.golden 🔗

@@ -1,11 +1,11 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf012.golden 🔗

@@ -1,12 +1,12 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf013.golden 🔗

@@ -1,13 +1,13 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf014.golden 🔗

@@ -1,14 +1,14 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf015.golden 🔗

@@ -1,15 +1,15 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf016.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf017.golden 🔗

@@ -1,17 +1,17 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
-                                                          
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf018.golden 🔗

@@ -1,18 +1,18 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
-                                                          
-                                                          
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               
+                                                          
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf019.golden 🔗

@@ -1,19 +1,19 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
-                                                          
-                                                          
-                                                          
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               
+                                                          
+                                                          
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewHeight/Unified/HeightOf020.golden 🔗

@@ -1,20 +1,20 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
-                                                          
-                                                          
-                                                          
-                                                          
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               
+                                                          
+                                                          
+                                                          
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewTabs/Split.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                       …                                                       
-  2                                                         2                                                       
-  3   import (                                              3   import (                                            
-  4           "fmt"                                         4           "fmt"                                       
-                                                            5 +         "strings"                                   
-  5   )                                                     6   )                                                   
-  6                                                         7                                                       
-  7   func main() {                                         8   func main() {                                       
-  …   @@ -9,5 +10,6 @@                                      …                                                       
-  9   }                                                    10   }                                                   
- 10                                                        11                                                       
- 11   func getContent() string {                           12   func getContent() string {                          

internal/tui/exp/diffview/testdata/TestDiffViewTabs/Unified.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                     
-  2   2                                                       
-  3   3   import (                                            
-  4   4           "fmt"                                       
-      5 +         "strings"                                   
-  5   6   )                                                   
-  6   7                                                       
-  7   8   func main() {                                       
-  …   …   @@ -9,5 +10,6 @@                                    
-  9  10   }                                                   
- 10  11                                                       
- 11  12   func getContent() string {                          
- 12     -         return "Hello, world!"                      
-     13 +         content := strings.ToUpper("Hello, World!") 
-     14 +         return content                              
- 13  15   }                                                   
+  …   …   @@ -2,6 +2,7 @@                                     
+  2   2                                                       
+  3   3   import (                                            
+  4   4           "fmt"                                       
+      5 +         "strings"                                   
+  5   6   )                                                   
+  6   7                                                       
+  7   8   func main() {                                       
+  …   …   @@ -9,5 +10,6 @@                                    
+  9  10   }                                                   
+ 10  11                                                       
+ 11  12   func getContent() string {                          
+ 12     -         return "Hello, world!"                      
+     13 +         content := strings.ToUpper("Hello, World!") 
+     14 +         return content                              
+ 13  15   }                                                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf001.golden 🔗

@@ -1,15 +1,15 @@
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf002.golden 🔗

@@ -1,15 +1,15 @@
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
- 1
- 1
- 1
-  
- 1
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+ 1
+ 1
+ 1
+  
+ 1

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf003.golden 🔗

@@ -1,15 +1,15 @@
-  …
-  2
-  3
-  4
-   
-  5
-  6
-  7
-  …
-  9
- 10
- 11
- 12
-   
- 13
+  …
+  2
+  3
+  4
+   
+  5
+  6
+  7
+  …
+  9
+ 10
+ 11
+ 12
+   
+ 13

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf004.golden 🔗

@@ -1,15 +1,15 @@
-  … 
-  2 
-  3 
-  4 
-    
-  5 
-  6 
-  7 
-  … 
-  9 
- 10 
- 11 
- 12 
-    
- 13 
+  … 
+  2 
+  3 
+  4 
+    
+  5 
+  6 
+  7 
+  … 
+  9 
+ 10 
+ 11 
+ 12 
+    
+ 13 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf005.golden 🔗

@@ -1,15 +1,15 @@
-  …  
-  2  
-  3  
-  4  
-     
-  5  
-  6  
-  7  
-  …  
-  9  
- 10  
- 11  
- 12 -
-     
- 13  
+  …  
+  2  
+  3  
+  4  
+     
+  5  
+  6  
+  7  
+  …  
+  9  
+ 10  
+ 11  
+ 12 -
+     
+ 13  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf006.golden 🔗

@@ -1,15 +1,15 @@
-  …   
-  2   
-  3   
-  4   
-      
-  5   
-  6   
-  7   
-  …   
-  9   
- 10   
- 11   
- 12 - 
-      
- 13   
+  …   
+  2   
+  3   
+  4   
+      
+  5   
+  6   
+  7   
+  …   
+  9   
+ 10   
+ 11   
+ 12 - 
+      
+ 13   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf007.golden 🔗

@@ -1,15 +1,15 @@
-  …   …
-  2    
-  3    
-  4    
-       
-  5    
-  6    
-  7    
-  …   …
-  9    
- 10    
- 11    
- 12 -  
-       
- 13    
+  …   …
+  2    
+  3    
+  4    
+       
+  5    
+  6    
+  7    
+  …   …
+  9    
+ 10    
+ 11    
+ 12 -  
+       
+ 13    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf008.golden 🔗

@@ -1,15 +1,15 @@
-  …   … 
-  2     
-  3     
-  4     
-        
-  5     
-  6     
-  7     
-  …   … 
-  9    1
- 10    1
- 11    1
- 12 -  1
-       1
- 13    1
+  …   … 
+  2     
+  3     
+  4     
+        
+  5     
+  6     
+  7     
+  …   … 
+  9    1
+ 10    1
+ 11    1
+ 12 -  1
+       1
+ 13    1

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf009.golden 🔗

@@ -1,15 +1,15 @@
-  … …  … 
-  2    2 
-  3    3 
-  4    4 
-       5 
-  5    6 
-  6    7 
-  7    8 
-  … …  … 
-  9   10 
- 10   11 
- 11   12 
- 12 - 13 
-      14 
- 13   15 
+  … …  … 
+  2    2 
+  3    3 
+  4    4 
+       5 
+  5    6 
+  6    7 
+  7    8 
+  … …  … 
+  9   10 
+ 10   11 
+ 11   12 
+ 12 - 13 
+      14 
+ 13   15 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf010.golden 🔗

@@ -1,15 +1,15 @@
-  … …  …  
-  2    2  
-  3    3  
-  4    4  
-       5 +
-  5    6  
-  6    7  
-  7    8  
-  … …  …  
-  9   10  
- 10   11  
- 11   12  
- 12 - 13 +
-      14 +
- 13   15  
+  … …  …  
+  2    2  
+  3    3  
+  4    4  
+       5 +
+  5    6  
+  6    7  
+  7    8  
+  … …  …  
+  9   10  
+ 10   11  
+ 11   12  
+ 12 - 13 +
+      14 +
+ 13   15  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf011.golden 🔗

@@ -1,15 +1,15 @@
-  …  …  …  
-  2     2  
-  3     3  
-  4     4  
-        5 +
-  5     6  
-  6     7  
-  7     8  
-  …  …  …  
-  9    10  
- 10    11  
- 11    12  
- 12 -  13 +
-       14 +
- 13    15  
+  …  …  …  
+  2     2  
+  3     3  
+  4     4  
+        5 +
+  5     6  
+  6     7  
+  7     8  
+  …  …  …  
+  9    10  
+ 10    11  
+ 11    12  
+ 12 -  13 +
+       14 +
+ 13    15  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf012.golden 🔗

@@ -1,15 +1,15 @@
-  …  …  …   
-  2     2   
-  3     3   
-  4     4   
-        5 + 
-  5     6   
-  6     7   
-  7     8   
-  …  …  …   
-  9    10   
- 10    11   
- 11    12   
- 12 -  13 + 
-       14 + 
- 13    15   
+  …  …  …   
+  2     2   
+  3     3   
+  4     4   
+        5 + 
+  5     6   
+  6     7   
+  7     8   
+  …  …  …   
+  9    10   
+ 10    11   
+ 11    12   
+ 12 -  13 + 
+       14 + 
+ 13    15   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf013.golden 🔗

@@ -1,15 +1,15 @@
-  …  …  …    
-  2     2    
-  3     3    
-  4     4    
-        5 +  
-  5     6    
-  6     7    
-  7     8    
-  …  …  …    
-  9    10    
- 10    11    
- 11    12    
- 12 -  13 +  
-       14 +  
- 13    15    
+  …  …  …    
+  2     2    
+  3     3    
+  4     4    
+        5 +  
+  5     6    
+  6     7    
+  7     8    
+  …  …  …    
+  9    10    
+ 10    11    
+ 11    12    
+ 12 -  13 +  
+       14 +  
+ 13    15    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf014.golden 🔗

@@ -1,15 +1,15 @@
-  …   …  …    
-  2      2    
-  3   …  3   …
-  4   …  4   …
-         5 + …
-  5   )  6   )
-  6      7    
-  7   …  8   …
-  …   …  …    
-  9   } 10   }
- 10     11    
- 11   … 12   …
- 12 - … 13 + …
-        14 + …
- 13   } 15   }
+  …   …  …    
+  2      2    
+  3   …  3   …
+  4   …  4   …
+         5 + …
+  5   )  6   )
+  6      7    
+  7   …  8   …
+  …   …  …    
+  9   } 10   }
+ 10     11    
+ 11   … 12   …
+ 12 - … 13 + …
+        14 + …
+ 13   } 15   }

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf015.golden 🔗

@@ -1,15 +1,15 @@
-  …   …  …     
-  2      2     
-  3   …  3   … 
-  4   …  4   … 
-         5 + … 
-  5   )  6   ) 
-  6      7     
-  7   …  8   … 
-  …   …  …     
-  9   } 10   } 
- 10     11     
- 11   … 12   … 
- 12 - … 13 + … 
-        14 + … 
- 13   } 15   } 
+  …   …  …     
+  2      2     
+  3   …  3   … 
+  4   …  4   … 
+         5 + … 
+  5   )  6   ) 
+  6      7     
+  7   …  8   … 
+  …   …  …     
+  9   } 10   } 
+ 10     11     
+ 11   … 12   … 
+ 12 - … 13 + … 
+        14 + … 
+ 13   } 15   } 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf016.golden 🔗

@@ -1,15 +1,15 @@
-  …   @…  …     
-  2       2     
-  3   i…  3   i…
-  4    …  4    …
-          5 +  …
-  5   )   6   ) 
-  6       7     
-  7   f…  8   f…
-  …   @…  …     
-  9   }  10   } 
- 10      11     
- 11   f… 12   f…
- 12 -  … 13 +  …
-         14 +  …
- 13   }  15   } 
+  …   @…  …     
+  2       2     
+  3   i…  3   i…
+  4    …  4    …
+          5 +  …
+  5   )   6   ) 
+  6       7     
+  7   f…  8   f…
+  …   @…  …     
+  9   }  10   } 
+ 10      11     
+ 11   f… 12   f…
+ 12 -  … 13 +  …
+         14 +  …
+ 13   }  15   } 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf017.golden 🔗

@@ -1,15 +1,15 @@
-  …   @…  …      
-  2       2      
-  3   i…  3   i… 
-  4    …  4    … 
-          5 +  … 
-  5   )   6   )  
-  6       7      
-  7   f…  8   f… 
-  …   @…  …      
-  9   }  10   }  
- 10      11      
- 11   f… 12   f… 
- 12 -  … 13 +  … 
-         14 +  … 
- 13   }  15   }  
+  …   @…  …      
+  2       2      
+  3   i…  3   i… 
+  4    …  4    … 
+          5 +  … 
+  5   )   6   )  
+  6       7      
+  7   f…  8   f… 
+  …   @…  …      
+  9   }  10   }  
+ 10      11      
+ 11   f… 12   f… 
+ 12 -  … 13 +  … 
+         14 +  … 
+ 13   }  15   }  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf018.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@…  …      
-  2        2      
-  3   im…  3   im…
-  4     …  4     …
-           5 +   …
-  5   )    6   )  
-  6        7      
-  7   fu…  8   fu…
-  …   @@…  …      
-  9   }   10   }  
- 10       11      
- 11   fu… 12   fu…
- 12 -   … 13 +   …
-          14 +   …
- 13   }   15   }  
+  …   @@…  …      
+  2        2      
+  3   im…  3   im…
+  4     …  4     …
+           5 +   …
+  5   )    6   )  
+  6        7      
+  7   fu…  8   fu…
+  …   @@…  …      
+  9   }   10   }  
+ 10       11      
+ 11   fu… 12   fu…
+ 12 -   … 13 +   …
+          14 +   …
+ 13   }   15   }  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf019.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@…  …       
-  2        2       
-  3   im…  3   im… 
-  4     …  4     … 
-           5 +   … 
-  5   )    6   )   
-  6        7       
-  7   fu…  8   fu… 
-  …   @@…  …       
-  9   }   10   }   
- 10       11       
- 11   fu… 12   fu… 
- 12 -   … 13 +   … 
-          14 +   … 
- 13   }   15   }   
+  …   @@…  …       
+  2        2       
+  3   im…  3   im… 
+  4     …  4     … 
+           5 +   … 
+  5   )    6   )   
+  6        7       
+  7   fu…  8   fu… 
+  …   @@…  …       
+  9   }   10   }   
+ 10       11       
+ 11   fu… 12   fu… 
+ 12 -   … 13 +   … 
+          14 +   … 
+ 13   }   15   }   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf020.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ …  …       
-  2         2       
-  3   imp…  3   imp…
-  4      …  4      …
-            5 +    …
-  5   )     6   )   
-  6         7       
-  7   fun…  8   fun…
-  …   @@ …  …       
-  9   }    10   }   
- 10        11       
- 11   fun… 12   fun…
- 12 -    … 13 +    …
-           14 +    …
- 13   }    15   }   
+  …   @@ …  …       
+  2         2       
+  3   imp…  3   imp…
+  4      …  4      …
+            5 +    …
+  5   )     6   )   
+  6         7       
+  7   fun…  8   fun…
+  …   @@ …  …       
+  9   }    10   }   
+ 10        11       
+ 11   fun… 12   fun…
+ 12 -    … 13 +    …
+           14 +    …
+ 13   }    15   }   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf021.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ …  …        
-  2         2        
-  3   imp…  3   imp… 
-  4      …  4      … 
-            5 +    … 
-  5   )     6   )    
-  6         7        
-  7   fun…  8   fun… 
-  …   @@ …  …        
-  9   }    10   }    
- 10        11        
- 11   fun… 12   fun… 
- 12 -    … 13 +    … 
-           14 +    … 
- 13   }    15   }    
+  …   @@ …  …        
+  2         2        
+  3   imp…  3   imp… 
+  4      …  4      … 
+            5 +    … 
+  5   )     6   )    
+  6         7        
+  7   fun…  8   fun… 
+  …   @@ …  …        
+  9   }    10   }    
+ 10        11        
+ 11   fun… 12   fun… 
+ 12 -    … 13 +    … 
+           14 +    … 
+ 13   }    15   }    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf022.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -…  …        
-  2          2        
-  3   impo…  3   impo…
-  4       …  4       …
-             5 +     …
-  5   )      6   )    
-  6          7        
-  7   func…  8   func…
-  …   @@ -…  …        
-  9   }     10   }    
- 10         11        
- 11   func… 12   func…
- 12 -     … 13 +     …
-            14 +     …
- 13   }     15   }    
+  …   @@ -…  …        
+  2          2        
+  3   impo…  3   impo…
+  4       …  4       …
+             5 +     …
+  5   )      6   )    
+  6          7        
+  7   func…  8   func…
+  …   @@ -…  …        
+  9   }     10   }    
+ 10         11        
+ 11   func… 12   func…
+ 12 -     … 13 +     …
+            14 +     …
+ 13   }     15   }    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf023.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -…  …         
-  2          2         
-  3   impo…  3   impo… 
-  4       …  4       … 
-             5 +     … 
-  5   )      6   )     
-  6          7         
-  7   func…  8   func… 
-  …   @@ -…  …         
-  9   }     10   }     
- 10         11         
- 11   func… 12   func… 
- 12 -     … 13 +     … 
-            14 +     … 
- 13   }     15   }     
+  …   @@ -…  …         
+  2          2         
+  3   impo…  3   impo… 
+  4       …  4       … 
+             5 +     … 
+  5   )      6   )     
+  6          7         
+  7   func…  8   func… 
+  …   @@ -…  …         
+  9   }     10   }     
+ 10         11         
+ 11   func… 12   func… 
+ 12 -     … 13 +     … 
+            14 +     … 
+ 13   }     15   }     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf024.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2…  …         
-  2           2         
-  3   impor…  3   impor…
-  4       "…  4       "…
-              5 +     "…
-  5   )       6   )     
-  6           7         
-  7   func …  8   func …
-  …   @@ -9…  …         
-  9   }      10   }     
- 10          11         
- 11   func … 12   func …
- 12 -     r… 13 +     c…
-             14 +     r…
- 13   }      15   }     
+  …   @@ -2…  …         
+  2           2         
+  3   impor…  3   impor…
+  4       "…  4       "…
+              5 +     "…
+  5   )       6   )     
+  6           7         
+  7   func …  8   func …
+  …   @@ -9…  …         
+  9   }      10   }     
+ 10          11         
+ 11   func … 12   func …
+ 12 -     r… 13 +     c…
+             14 +     r…
+ 13   }      15   }     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf025.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2…  …          
-  2           2          
-  3   impor…  3   impor… 
-  4       "…  4       "… 
-              5 +     "… 
-  5   )       6   )      
-  6           7          
-  7   func …  8   func … 
-  …   @@ -9…  …          
-  9   }      10   }      
- 10          11          
- 11   func … 12   func … 
- 12 -     r… 13 +     c… 
-             14 +     r… 
- 13   }      15   }      
+  …   @@ -2…  …          
+  2           2          
+  3   impor…  3   impor… 
+  4       "…  4       "… 
+              5 +     "… 
+  5   )       6   )      
+  6           7          
+  7   func …  8   func … 
+  …   @@ -9…  …          
+  9   }      10   }      
+ 10          11          
+ 11   func … 12   func … 
+ 12 -     r… 13 +     c… 
+             14 +     r… 
+ 13   }      15   }      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf026.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,…  …          
-  2            2          
-  3   import…  3   import…
-  4       "f…  4       "f…
-               5 +     "s…
-  5   )        6   )      
-  6            7          
-  7   func m…  8   func m…
-  …   @@ -9,…  …          
-  9   }       10   }      
- 10           11          
- 11   func g… 12   func g…
- 12 -     re… 13 +     co…
-              14 +     re…
- 13   }       15   }      
+  …   @@ -2,…  …          
+  2            2          
+  3   import…  3   import…
+  4       "f…  4       "f…
+               5 +     "s…
+  5   )        6   )      
+  6            7          
+  7   func m…  8   func m…
+  …   @@ -9,…  …          
+  9   }       10   }      
+ 10           11          
+ 11   func g… 12   func g…
+ 12 -     re… 13 +     co…
+              14 +     re…
+ 13   }       15   }      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf027.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,…  …           
-  2            2           
-  3   import…  3   import… 
-  4       "f…  4       "f… 
-               5 +     "s… 
-  5   )        6   )       
-  6            7           
-  7   func m…  8   func m… 
-  …   @@ -9,…  …           
-  9   }       10   }       
- 10           11           
- 11   func g… 12   func g… 
- 12 -     re… 13 +     co… 
-              14 +     re… 
- 13   }       15   }       
+  …   @@ -2,…  …           
+  2            2           
+  3   import…  3   import… 
+  4       "f…  4       "f… 
+               5 +     "s… 
+  5   )        6   )       
+  6            7           
+  7   func m…  8   func m… 
+  …   @@ -9,…  …           
+  9   }       10   }       
+ 10           11           
+ 11   func g… 12   func g… 
+ 12 -     re… 13 +     co… 
+              14 +     re… 
+ 13   }       15   }       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf028.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6…  …           
-  2             2           
-  3   import (  3   import (
-  4       "fm…  4       "fm…
-                5 +     "st…
-  5   )         6   )       
-  6             7           
-  7   func ma…  8   func ma…
-  …   @@ -9,5…  …           
-  9   }        10   }       
- 10            11           
- 11   func ge… 12   func ge…
- 12 -     ret… 13 +     con…
-               14 +     ret…
- 13   }        15   }       
+  …   @@ -2,6…  …           
+  2             2           
+  3   import (  3   import (
+  4       "fm…  4       "fm…
+                5 +     "st…
+  5   )         6   )       
+  6             7           
+  7   func ma…  8   func ma…
+  …   @@ -9,5…  …           
+  9   }        10   }       
+ 10            11           
+ 11   func ge… 12   func ge…
+ 12 -     ret… 13 +     con…
+               14 +     ret…
+ 13   }        15   }       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf029.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6…  …            
-  2             2            
-  3   import (  3   import ( 
-  4       "fm…  4       "fm… 
-                5 +     "st… 
-  5   )         6   )        
-  6             7            
-  7   func ma…  8   func ma… 
-  …   @@ -9,5…  …            
-  9   }        10   }        
- 10            11            
- 11   func ge… 12   func ge… 
- 12 -     ret… 13 +     con… 
-               14 +     ret… 
- 13   }        15   }        
+  …   @@ -2,6…  …            
+  2             2            
+  3   import (  3   import ( 
+  4       "fm…  4       "fm… 
+                5 +     "st… 
+  5   )         6   )        
+  6             7            
+  7   func ma…  8   func ma… 
+  …   @@ -9,5…  …            
+  9   }        10   }        
+ 10            11            
+ 11   func ge… 12   func ge… 
+ 12 -     ret… 13 +     con… 
+               14 +     ret… 
+ 13   }        15   }        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf030.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 …  …            
-  2              2            
-  3   import (   3   import ( 
-  4       "fmt"  4       "fmt"
-                 5 +     "str…
-  5   )          6   )        
-  6              7            
-  7   func mai…  8   func mai…
-  …   @@ -9,5 …  …            
-  9   }         10   }        
- 10             11            
- 11   func get… 12   func get…
- 12 -     retu… 13 +     cont…
-                14 +     retu…
- 13   }         15   }        
+  …   @@ -2,6 …  …            
+  2              2            
+  3   import (   3   import ( 
+  4       "fmt"  4       "fmt"
+                 5 +     "str…
+  5   )          6   )        
+  6              7            
+  7   func mai…  8   func mai…
+  …   @@ -9,5 …  …            
+  9   }         10   }        
+ 10             11            
+ 11   func get… 12   func get…
+ 12 -     retu… 13 +     cont…
+                14 +     retu…
+ 13   }         15   }        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf031.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 …  …             
-  2              2             
-  3   import (   3   import (  
-  4       "fmt"  4       "fmt" 
-                 5 +     "str… 
-  5   )          6   )         
-  6              7             
-  7   func mai…  8   func mai… 
-  …   @@ -9,5 …  …             
-  9   }         10   }         
- 10             11             
- 11   func get… 12   func get… 
- 12 -     retu… 13 +     cont… 
-                14 +     retu… 
- 13   }         15   }         
+  …   @@ -2,6 …  …             
+  2              2             
+  3   import (   3   import (  
+  4       "fmt"  4       "fmt" 
+                 5 +     "str… 
+  5   )          6   )         
+  6              7             
+  7   func mai…  8   func mai… 
+  …   @@ -9,5 …  …             
+  9   }         10   }         
+ 10             11             
+ 11   func get… 12   func get… 
+ 12 -     retu… 13 +     cont… 
+                14 +     retu… 
+ 13   }         15   }         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf032.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +…  …             
-  2               2             
-  3   import (    3   import (  
-  4       "fmt"   4       "fmt" 
-                  5 +     "stri…
-  5   )           6   )         
-  6               7             
-  7   func main…  8   func main…
-  …   @@ -9,5 +…  …             
-  9   }          10   }         
- 10              11             
- 11   func getC… 12   func getC…
- 12 -     retur… 13 +     conte…
-                 14 +     retur…
- 13   }          15   }         
+  …   @@ -2,6 +…  …             
+  2               2             
+  3   import (    3   import (  
+  4       "fmt"   4       "fmt" 
+                  5 +     "stri…
+  5   )           6   )         
+  6               7             
+  7   func main…  8   func main…
+  …   @@ -9,5 +…  …             
+  9   }          10   }         
+ 10              11             
+ 11   func getC… 12   func getC…
+ 12 -     retur… 13 +     conte…
+                 14 +     retur…
+ 13   }          15   }         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf033.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +…  …              
-  2               2              
-  3   import (    3   import (   
-  4       "fmt"   4       "fmt"  
-                  5 +     "stri… 
-  5   )           6   )          
-  6               7              
-  7   func main…  8   func main… 
-  …   @@ -9,5 +…  …              
-  9   }          10   }          
- 10              11              
- 11   func getC… 12   func getC… 
- 12 -     retur… 13 +     conte… 
-                 14 +     retur… 
- 13   }          15   }          
+  …   @@ -2,6 +…  …              
+  2               2              
+  3   import (    3   import (   
+  4       "fmt"   4       "fmt"  
+                  5 +     "stri… 
+  5   )           6   )          
+  6               7              
+  7   func main…  8   func main… 
+  …   @@ -9,5 +…  …              
+  9   }          10   }          
+ 10              11              
+ 11   func getC… 12   func getC… 
+ 12 -     retur… 13 +     conte… 
+                 14 +     retur… 
+ 13   }          15   }          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf034.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2…  …              
-  2                2              
-  3   import (     3   import (   
-  4       "fmt"    4       "fmt"  
-                   5 +     "strin…
-  5   )            6   )          
-  6                7              
-  7   func main(…  8   func main(…
-  …   @@ -9,5 +1…  …              
-  9   }           10   }          
- 10               11              
- 11   func getCo… 12   func getCo…
- 12 -     return… 13 +     conten…
-                  14 +     return…
- 13   }           15   }          
+  …   @@ -2,6 +2…  …              
+  2                2              
+  3   import (     3   import (   
+  4       "fmt"    4       "fmt"  
+                   5 +     "strin…
+  5   )            6   )          
+  6                7              
+  7   func main(…  8   func main(…
+  …   @@ -9,5 +1…  …              
+  9   }           10   }          
+ 10               11              
+ 11   func getCo… 12   func getCo…
+ 12 -     return… 13 +     conten…
+                  14 +     return…
+ 13   }           15   }          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf035.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2…  …               
-  2                2               
-  3   import (     3   import (    
-  4       "fmt"    4       "fmt"   
-                   5 +     "strin… 
-  5   )            6   )           
-  6                7               
-  7   func main(…  8   func main(… 
-  …   @@ -9,5 +1…  …               
-  9   }           10   }           
- 10               11               
- 11   func getCo… 12   func getCo… 
- 12 -     return… 13 +     conten… 
-                  14 +     return… 
- 13   }           15   }           
+  …   @@ -2,6 +2…  …               
+  2                2               
+  3   import (     3   import (    
+  4       "fmt"    4       "fmt"   
+                   5 +     "strin… 
+  5   )            6   )           
+  6                7               
+  7   func main(…  8   func main(… 
+  …   @@ -9,5 +1…  …               
+  9   }           10   }           
+ 10               11               
+ 11   func getCo… 12   func getCo… 
+ 12 -     return… 13 +     conten… 
+                  14 +     return… 
+ 13   }           15   }           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf036.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,…  …               
-  2                 2               
-  3   import (      3   import (    
-  4       "fmt"     4       "fmt"   
-                    5 +     "string…
-  5   )             6   )           
-  6                 7               
-  7   func main()…  8   func main()…
-  …   @@ -9,5 +10…  …               
-  9   }            10   }           
- 10                11               
- 11   func getCon… 12   func getCon…
- 12 -     return … 13 +     content…
-                   14 +     return …
- 13   }            15   }           
+  …   @@ -2,6 +2,…  …               
+  2                 2               
+  3   import (      3   import (    
+  4       "fmt"     4       "fmt"   
+                    5 +     "string…
+  5   )             6   )           
+  6                 7               
+  7   func main()…  8   func main()…
+  …   @@ -9,5 +10…  …               
+  9   }            10   }           
+ 10                11               
+ 11   func getCon… 12   func getCon…
+ 12 -     return … 13 +     content…
+                   14 +     return …
+ 13   }            15   }           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf037.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,…  …                
-  2                 2                
-  3   import (      3   import (     
-  4       "fmt"     4       "fmt"    
-                    5 +     "string… 
-  5   )             6   )            
-  6                 7                
-  7   func main()…  8   func main()… 
-  …   @@ -9,5 +10…  …                
-  9   }            10   }            
- 10                11                
- 11   func getCon… 12   func getCon… 
- 12 -     return … 13 +     content… 
-                   14 +     return … 
- 13   }            15   }            
+  …   @@ -2,6 +2,…  …                
+  2                 2                
+  3   import (      3   import (     
+  4       "fmt"     4       "fmt"    
+                    5 +     "string… 
+  5   )             6   )            
+  6                 7                
+  7   func main()…  8   func main()… 
+  …   @@ -9,5 +10…  …                
+  9   }            10   }            
+ 10                11                
+ 11   func getCon… 12   func getCon… 
+ 12 -     return … 13 +     content… 
+                   14 +     return … 
+ 13   }            15   }            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf038.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7…  …                
-  2                  2                
-  3   import (       3   import (     
-  4       "fmt"      4       "fmt"    
-                     5 +     "strings"
-  5   )              6   )            
-  6                  7                
-  7   func main() {  8   func main() {
-  …   @@ -9,5 +10,…  …                
-  9   }             10   }            
- 10                 11                
- 11   func getCont… 12   func getCont…
- 12 -     return "… 13 +     content …
-                    14 +     return c…
- 13   }             15   }            
+  …   @@ -2,6 +2,7…  …                
+  2                  2                
+  3   import (       3   import (     
+  4       "fmt"      4       "fmt"    
+                     5 +     "strings"
+  5   )              6   )            
+  6                  7                
+  7   func main() {  8   func main() {
+  …   @@ -9,5 +10,…  …                
+  9   }             10   }            
+ 10                 11                
+ 11   func getCont… 12   func getCont…
+ 12 -     return "… 13 +     content …
+                    14 +     return c…
+ 13   }             15   }            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf039.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7…  …                 
-  2                  2                 
-  3   import (       3   import (      
-  4       "fmt"      4       "fmt"     
-                     5 +     "strings" 
-  5   )              6   )             
-  6                  7                 
-  7   func main() {  8   func main() { 
-  …   @@ -9,5 +10,…  …                 
-  9   }             10   }             
- 10                 11                 
- 11   func getCont… 12   func getCont… 
- 12 -     return "… 13 +     content … 
-                    14 +     return c… 
- 13   }             15   }             
+  …   @@ -2,6 +2,7…  …                 
+  2                  2                 
+  3   import (       3   import (      
+  4       "fmt"      4       "fmt"     
+                     5 +     "strings" 
+  5   )              6   )             
+  6                  7                 
+  7   func main() {  8   func main() { 
+  …   @@ -9,5 +10,…  …                 
+  9   }             10   }             
+ 10                 11                 
+ 11   func getCont… 12   func getCont… 
+ 12 -     return "… 13 +     content … 
+                    14 +     return c… 
+ 13   }             15   }             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf040.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 …  …                 
-  2                   2                 
-  3   import (        3   import (      
-  4       "fmt"       4       "fmt"     
-                      5 +     "strings" 
-  5   )               6   )             
-  6                   7                 
-  7   func main() {   8   func main() { 
-  …   @@ -9,5 +10,6…  …                 
-  9   }              10   }             
- 10                  11                 
- 11   func getConte… 12   func getConte…
- 12 -     return "H… 13 +     content :…
-                     14 +     return co…
- 13   }              15   }             
+  …   @@ -2,6 +2,7 …  …                 
+  2                   2                 
+  3   import (        3   import (      
+  4       "fmt"       4       "fmt"     
+                      5 +     "strings" 
+  5   )               6   )             
+  6                   7                 
+  7   func main() {   8   func main() { 
+  …   @@ -9,5 +10,6…  …                 
+  9   }              10   }             
+ 10                  11                 
+ 11   func getConte… 12   func getConte…
+ 12 -     return "H… 13 +     content :…
+                     14 +     return co…
+ 13   }              15   }             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf041.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 …  …                  
-  2                   2                  
-  3   import (        3   import (       
-  4       "fmt"       4       "fmt"      
-                      5 +     "strings"  
-  5   )               6   )              
-  6                   7                  
-  7   func main() {   8   func main() {  
-  …   @@ -9,5 +10,6…  …                  
-  9   }              10   }              
- 10                  11                  
- 11   func getConte… 12   func getConte… 
- 12 -     return "H… 13 +     content :… 
-                     14 +     return co… 
- 13   }              15   }              
+  …   @@ -2,6 +2,7 …  …                  
+  2                   2                  
+  3   import (        3   import (       
+  4       "fmt"       4       "fmt"      
+                      5 +     "strings"  
+  5   )               6   )              
+  6                   7                  
+  7   func main() {   8   func main() {  
+  …   @@ -9,5 +10,6…  …                  
+  9   }              10   }              
+ 10                  11                  
+ 11   func getConte… 12   func getConte… 
+ 12 -     return "H… 13 +     content :… 
+                     14 +     return co… 
+ 13   }              15   }              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf042.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @…  …                  
-  2                    2                  
-  3   import (         3   import (       
-  4       "fmt"        4       "fmt"      
-                       5 +     "strings"  
-  5   )                6   )              
-  6                    7                  
-  7   func main() {    8   func main() {  
-  …   @@ -9,5 +10,6 …  …                  
-  9   }               10   }              
- 10                   11                  
- 11   func getConten… 12   func getConten…
- 12 -     return "He… 13 +     content :=…
-                      14 +     return con…
- 13   }               15   }              
+  …   @@ -2,6 +2,7 @…  …                  
+  2                    2                  
+  3   import (         3   import (       
+  4       "fmt"        4       "fmt"      
+                       5 +     "strings"  
+  5   )                6   )              
+  6                    7                  
+  7   func main() {    8   func main() {  
+  …   @@ -9,5 +10,6 …  …                  
+  9   }               10   }              
+ 10                   11                  
+ 11   func getConten… 12   func getConten…
+ 12 -     return "He… 13 +     content :=…
+                      14 +     return con…
+ 13   }               15   }              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf043.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @…  …                   
-  2                    2                   
-  3   import (         3   import (        
-  4       "fmt"        4       "fmt"       
-                       5 +     "strings"   
-  5   )                6   )               
-  6                    7                   
-  7   func main() {    8   func main() {   
-  …   @@ -9,5 +10,6 …  …                   
-  9   }               10   }               
- 10                   11                   
- 11   func getConten… 12   func getConten… 
- 12 -     return "He… 13 +     content :=… 
-                      14 +     return con… 
- 13   }               15   }               
+  …   @@ -2,6 +2,7 @…  …                   
+  2                    2                   
+  3   import (         3   import (        
+  4       "fmt"        4       "fmt"       
+                       5 +     "strings"   
+  5   )                6   )               
+  6                    7                   
+  7   func main() {    8   func main() {   
+  …   @@ -9,5 +10,6 …  …                   
+  9   }               10   }               
+ 10                   11                   
+ 11   func getConten… 12   func getConten… 
+ 12 -     return "He… 13 +     content :=… 
+                      14 +     return con… 
+ 13   }               15   }               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf044.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@   …                   
-  2                     2                   
-  3   import (          3   import (        
-  4       "fmt"         4       "fmt"       
-                        5 +     "strings"   
-  5   )                 6   )               
-  6                     7                   
-  7   func main() {     8   func main() {   
-  …   @@ -9,5 +10,6 @…  …                   
-  9   }                10   }               
- 10                    11                   
- 11   func getContent… 12   func getContent…
- 12 -     return "Hel… 13 +     content := …
-                       14 +     return cont…
- 13   }                15   }               
+  …   @@ -2,6 +2,7 @@   …                   
+  2                     2                   
+  3   import (          3   import (        
+  4       "fmt"         4       "fmt"       
+                        5 +     "strings"   
+  5   )                 6   )               
+  6                     7                   
+  7   func main() {     8   func main() {   
+  …   @@ -9,5 +10,6 @…  …                   
+  9   }                10   }               
+ 10                    11                   
+ 11   func getContent… 12   func getContent…
+ 12 -     return "Hel… 13 +     content := …
+                       14 +     return cont…
+ 13   }                15   }               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf045.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@   …                    
-  2                     2                    
-  3   import (          3   import (         
-  4       "fmt"         4       "fmt"        
-                        5 +     "strings"    
-  5   )                 6   )                
-  6                     7                    
-  7   func main() {     8   func main() {    
-  …   @@ -9,5 +10,6 @…  …                    
-  9   }                10   }                
- 10                    11                    
- 11   func getContent… 12   func getContent… 
- 12 -     return "Hel… 13 +     content := … 
-                       14 +     return cont… 
- 13   }                15   }                
+  …   @@ -2,6 +2,7 @@   …                    
+  2                     2                    
+  3   import (          3   import (         
+  4       "fmt"         4       "fmt"        
+                        5 +     "strings"    
+  5   )                 6   )                
+  6                     7                    
+  7   func main() {     8   func main() {    
+  …   @@ -9,5 +10,6 @…  …                    
+  9   }                10   }                
+ 10                    11                    
+ 11   func getContent… 12   func getContent… 
+ 12 -     return "Hel… 13 +     content := … 
+                       14 +     return cont… 
+ 13   }                15   }                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf046.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@    …                    
-  2                      2                    
-  3   import (           3   import (         
-  4       "fmt"          4       "fmt"        
-                         5 +     "strings"    
-  5   )                  6   )                
-  6                      7                    
-  7   func main() {      8   func main() {    
-  …   @@ -9,5 +10,6 @@   …                    
-  9   }                 10   }                
- 10                     11                    
- 11   func getContent(… 12   func getContent(…
- 12 -     return "Hell… 13 +     content := s…
-                        14 +     return conte…
- 13   }                 15   }                
+  …   @@ -2,6 +2,7 @@    …                    
+  2                      2                    
+  3   import (           3   import (         
+  4       "fmt"          4       "fmt"        
+                         5 +     "strings"    
+  5   )                  6   )                
+  6                      7                    
+  7   func main() {      8   func main() {    
+  …   @@ -9,5 +10,6 @@   …                    
+  9   }                 10   }                
+ 10                     11                    
+ 11   func getContent(… 12   func getContent(…
+ 12 -     return "Hell… 13 +     content := s…
+                        14 +     return conte…
+ 13   }                 15   }                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf047.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@    …                     
-  2                      2                     
-  3   import (           3   import (          
-  4       "fmt"          4       "fmt"         
-                         5 +     "strings"     
-  5   )                  6   )                 
-  6                      7                     
-  7   func main() {      8   func main() {     
-  …   @@ -9,5 +10,6 @@   …                     
-  9   }                 10   }                 
- 10                     11                     
- 11   func getContent(… 12   func getContent(… 
- 12 -     return "Hell… 13 +     content := s… 
-                        14 +     return conte… 
- 13   }                 15   }                 
+  …   @@ -2,6 +2,7 @@    …                     
+  2                      2                     
+  3   import (           3   import (          
+  4       "fmt"          4       "fmt"         
+                         5 +     "strings"     
+  5   )                  6   )                 
+  6                      7                     
+  7   func main() {      8   func main() {     
+  …   @@ -9,5 +10,6 @@   …                     
+  9   }                 10   }                 
+ 10                     11                     
+ 11   func getContent(… 12   func getContent(… 
+ 12 -     return "Hell… 13 +     content := s… 
+                        14 +     return conte… 
+ 13   }                 15   }                 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf048.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@     …                     
-  2                       2                     
-  3   import (            3   import (          
-  4       "fmt"           4       "fmt"         
-                          5 +     "strings"     
-  5   )                   6   )                 
-  6                       7                     
-  7   func main() {       8   func main() {     
-  …   @@ -9,5 +10,6 @@    …                     
-  9   }                  10   }                 
- 10                      11                     
- 11   func getContent()… 12   func getContent()…
- 12 -     return "Hello… 13 +     content := st…
-                         14 +     return content
- 13   }                  15   }                 
+  …   @@ -2,6 +2,7 @@     …                     
+  2                       2                     
+  3   import (            3   import (          
+  4       "fmt"           4       "fmt"         
+                          5 +     "strings"     
+  5   )                   6   )                 
+  6                       7                     
+  7   func main() {       8   func main() {     
+  …   @@ -9,5 +10,6 @@    …                     
+  9   }                  10   }                 
+ 10                      11                     
+ 11   func getContent()… 12   func getContent()…
+ 12 -     return "Hello… 13 +     content := st…
+                         14 +     return content
+ 13   }                  15   }                 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf049.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@     …                      
-  2                       2                      
-  3   import (            3   import (           
-  4       "fmt"           4       "fmt"          
-                          5 +     "strings"      
-  5   )                   6   )                  
-  6                       7                      
-  7   func main() {       8   func main() {      
-  …   @@ -9,5 +10,6 @@    …                      
-  9   }                  10   }                  
- 10                      11                      
- 11   func getContent()… 12   func getContent()… 
- 12 -     return "Hello… 13 +     content := st… 
-                         14 +     return content 
- 13   }                  15   }                  
+  …   @@ -2,6 +2,7 @@     …                      
+  2                       2                      
+  3   import (            3   import (           
+  4       "fmt"           4       "fmt"          
+                          5 +     "strings"      
+  5   )                   6   )                  
+  6                       7                      
+  7   func main() {       8   func main() {      
+  …   @@ -9,5 +10,6 @@    …                      
+  9   }                  10   }                  
+ 10                      11                      
+ 11   func getContent()… 12   func getContent()… 
+ 12 -     return "Hello… 13 +     content := st… 
+                         14 +     return content 
+ 13   }                  15   }                  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf050.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@      …                      
-  2                        2                      
-  3   import (             3   import (           
-  4       "fmt"            4       "fmt"          
-                           5 +     "strings"      
-  5   )                    6   )                  
-  6                        7                      
-  7   func main() {        8   func main() {      
-  …   @@ -9,5 +10,6 @@     …                      
-  9   }                   10   }                  
- 10                       11                      
- 11   func getContent() … 12   func getContent() …
- 12 -     return "Hello,… 13 +     content := str…
-                          14 +     return content 
- 13   }                   15   }                  
+  …   @@ -2,6 +2,7 @@      …                      
+  2                        2                      
+  3   import (             3   import (           
+  4       "fmt"            4       "fmt"          
+                           5 +     "strings"      
+  5   )                    6   )                  
+  6                        7                      
+  7   func main() {        8   func main() {      
+  …   @@ -9,5 +10,6 @@     …                      
+  9   }                   10   }                  
+ 10                       11                      
+ 11   func getContent() … 12   func getContent() …
+ 12 -     return "Hello,… 13 +     content := str…
+                          14 +     return content 
+ 13   }                   15   }                  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf051.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@      …                       
-  2                        2                       
-  3   import (             3   import (            
-  4       "fmt"            4       "fmt"           
-                           5 +     "strings"       
-  5   )                    6   )                   
-  6                        7                       
-  7   func main() {        8   func main() {       
-  …   @@ -9,5 +10,6 @@     …                       
-  9   }                   10   }                   
- 10                       11                       
- 11   func getContent() … 12   func getContent() … 
- 12 -     return "Hello,… 13 +     content := str… 
-                          14 +     return content  
- 13   }                   15   }                   
+  …   @@ -2,6 +2,7 @@      …                       
+  2                        2                       
+  3   import (             3   import (            
+  4       "fmt"            4       "fmt"           
+                           5 +     "strings"       
+  5   )                    6   )                   
+  6                        7                       
+  7   func main() {        8   func main() {       
+  …   @@ -9,5 +10,6 @@     …                       
+  9   }                   10   }                   
+ 10                       11                       
+ 11   func getContent() … 12   func getContent() … 
+ 12 -     return "Hello,… 13 +     content := str… 
+                          14 +     return content  
+ 13   }                   15   }                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf052.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@       …                       
-  2                         2                       
-  3   import (              3   import (            
-  4       "fmt"             4       "fmt"           
-                            5 +     "strings"       
-  5   )                     6   )                   
-  6                         7                       
-  7   func main() {         8   func main() {       
-  …   @@ -9,5 +10,6 @@      …                       
-  9   }                    10   }                   
- 10                        11                       
- 11   func getContent() s… 12   func getContent() s…
- 12 -     return "Hello, … 13 +     content := stri…
-                           14 +     return content  
- 13   }                    15   }                   
+  …   @@ -2,6 +2,7 @@       …                       
+  2                         2                       
+  3   import (              3   import (            
+  4       "fmt"             4       "fmt"           
+                            5 +     "strings"       
+  5   )                     6   )                   
+  6                         7                       
+  7   func main() {         8   func main() {       
+  …   @@ -9,5 +10,6 @@      …                       
+  9   }                    10   }                   
+ 10                        11                       
+ 11   func getContent() s… 12   func getContent() s…
+ 12 -     return "Hello, … 13 +     content := stri…
+                           14 +     return content  
+ 13   }                    15   }                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf053.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@       …                        
-  2                         2                        
-  3   import (              3   import (             
-  4       "fmt"             4       "fmt"            
-                            5 +     "strings"        
-  5   )                     6   )                    
-  6                         7                        
-  7   func main() {         8   func main() {        
-  …   @@ -9,5 +10,6 @@      …                        
-  9   }                    10   }                    
- 10                        11                        
- 11   func getContent() s… 12   func getContent() s… 
- 12 -     return "Hello, … 13 +     content := stri… 
-                           14 +     return content   
- 13   }                    15   }                    
+  …   @@ -2,6 +2,7 @@       …                        
+  2                         2                        
+  3   import (              3   import (             
+  4       "fmt"             4       "fmt"            
+                            5 +     "strings"        
+  5   )                     6   )                    
+  6                         7                        
+  7   func main() {         8   func main() {        
+  …   @@ -9,5 +10,6 @@      …                        
+  9   }                    10   }                    
+ 10                        11                        
+ 11   func getContent() s… 12   func getContent() s… 
+ 12 -     return "Hello, … 13 +     content := stri… 
+                           14 +     return content   
+ 13   }                    15   }                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf054.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@        …                        
-  2                          2                        
-  3   import (               3   import (             
-  4       "fmt"              4       "fmt"            
-                             5 +     "strings"        
-  5   )                      6   )                    
-  6                          7                        
-  7   func main() {          8   func main() {        
-  …   @@ -9,5 +10,6 @@       …                        
-  9   }                     10   }                    
- 10                         11                        
- 11   func getContent() st… 12   func getContent() st…
- 12 -     return "Hello, w… 13 +     content := strin…
-                            14 +     return content   
- 13   }                     15   }                    
+  …   @@ -2,6 +2,7 @@        …                        
+  2                          2                        
+  3   import (               3   import (             
+  4       "fmt"              4       "fmt"            
+                             5 +     "strings"        
+  5   )                      6   )                    
+  6                          7                        
+  7   func main() {          8   func main() {        
+  …   @@ -9,5 +10,6 @@       …                        
+  9   }                     10   }                    
+ 10                         11                        
+ 11   func getContent() st… 12   func getContent() st…
+ 12 -     return "Hello, w… 13 +     content := strin…
+                            14 +     return content   
+ 13   }                     15   }                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf055.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@        …                         
-  2                          2                         
-  3   import (               3   import (              
-  4       "fmt"              4       "fmt"             
-                             5 +     "strings"         
-  5   )                      6   )                     
-  6                          7                         
-  7   func main() {          8   func main() {         
-  …   @@ -9,5 +10,6 @@       …                         
-  9   }                     10   }                     
- 10                         11                         
- 11   func getContent() st… 12   func getContent() st… 
- 12 -     return "Hello, w… 13 +     content := strin… 
-                            14 +     return content    
- 13   }                     15   }                     
+  …   @@ -2,6 +2,7 @@        …                         
+  2                          2                         
+  3   import (               3   import (              
+  4       "fmt"              4       "fmt"             
+                             5 +     "strings"         
+  5   )                      6   )                     
+  6                          7                         
+  7   func main() {          8   func main() {         
+  …   @@ -9,5 +10,6 @@       …                         
+  9   }                     10   }                     
+ 10                         11                         
+ 11   func getContent() st… 12   func getContent() st… 
+ 12 -     return "Hello, w… 13 +     content := strin… 
+                            14 +     return content    
+ 13   }                     15   }                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf056.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@         …                         
-  2                           2                         
-  3   import (                3   import (              
-  4       "fmt"               4       "fmt"             
-                              5 +     "strings"         
-  5   )                       6   )                     
-  6                           7                         
-  7   func main() {           8   func main() {         
-  …   @@ -9,5 +10,6 @@        …                         
-  9   }                      10   }                     
- 10                          11                         
- 11   func getContent() str… 12   func getContent() str…
- 12 -     return "Hello, wo… 13 +     content := string…
-                             14 +     return content    
- 13   }                      15   }                     
+  …   @@ -2,6 +2,7 @@         …                         
+  2                           2                         
+  3   import (                3   import (              
+  4       "fmt"               4       "fmt"             
+                              5 +     "strings"         
+  5   )                       6   )                     
+  6                           7                         
+  7   func main() {           8   func main() {         
+  …   @@ -9,5 +10,6 @@        …                         
+  9   }                      10   }                     
+ 10                          11                         
+ 11   func getContent() str… 12   func getContent() str…
+ 12 -     return "Hello, wo… 13 +     content := string…
+                             14 +     return content    
+ 13   }                      15   }                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf057.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@         …                          
-  2                           2                          
-  3   import (                3   import (               
-  4       "fmt"               4       "fmt"              
-                              5 +     "strings"          
-  5   )                       6   )                      
-  6                           7                          
-  7   func main() {           8   func main() {          
-  …   @@ -9,5 +10,6 @@        …                          
-  9   }                      10   }                      
- 10                          11                          
- 11   func getContent() str… 12   func getContent() str… 
- 12 -     return "Hello, wo… 13 +     content := string… 
-                             14 +     return content     
- 13   }                      15   }                      
+  …   @@ -2,6 +2,7 @@         …                          
+  2                           2                          
+  3   import (                3   import (               
+  4       "fmt"               4       "fmt"              
+                              5 +     "strings"          
+  5   )                       6   )                      
+  6                           7                          
+  7   func main() {           8   func main() {          
+  …   @@ -9,5 +10,6 @@        …                          
+  9   }                      10   }                      
+ 10                          11                          
+ 11   func getContent() str… 12   func getContent() str… 
+ 12 -     return "Hello, wo… 13 +     content := string… 
+                             14 +     return content     
+ 13   }                      15   }                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf058.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@          …                          
-  2                            2                          
-  3   import (                 3   import (               
-  4       "fmt"                4       "fmt"              
-                               5 +     "strings"          
-  5   )                        6   )                      
-  6                            7                          
-  7   func main() {            8   func main() {          
-  …   @@ -9,5 +10,6 @@         …                          
-  9   }                       10   }                      
- 10                           11                          
- 11   func getContent() stri… 12   func getContent() stri…
- 12 -     return "Hello, wor… 13 +     content := strings…
-                              14 +     return content     
- 13   }                       15   }                      
+  …   @@ -2,6 +2,7 @@          …                          
+  2                            2                          
+  3   import (                 3   import (               
+  4       "fmt"                4       "fmt"              
+                               5 +     "strings"          
+  5   )                        6   )                      
+  6                            7                          
+  7   func main() {            8   func main() {          
+  …   @@ -9,5 +10,6 @@         …                          
+  9   }                       10   }                      
+ 10                           11                          
+ 11   func getContent() stri… 12   func getContent() stri…
+ 12 -     return "Hello, wor… 13 +     content := strings…
+                              14 +     return content     
+ 13   }                       15   }                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf059.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@          …                           
-  2                            2                           
-  3   import (                 3   import (                
-  4       "fmt"                4       "fmt"               
-                               5 +     "strings"           
-  5   )                        6   )                       
-  6                            7                           
-  7   func main() {            8   func main() {           
-  …   @@ -9,5 +10,6 @@         …                           
-  9   }                       10   }                       
- 10                           11                           
- 11   func getContent() stri… 12   func getContent() stri… 
- 12 -     return "Hello, wor… 13 +     content := strings… 
-                              14 +     return content      
- 13   }                       15   }                       
+  …   @@ -2,6 +2,7 @@          …                           
+  2                            2                           
+  3   import (                 3   import (                
+  4       "fmt"                4       "fmt"               
+                               5 +     "strings"           
+  5   )                        6   )                       
+  6                            7                           
+  7   func main() {            8   func main() {           
+  …   @@ -9,5 +10,6 @@         …                           
+  9   }                       10   }                       
+ 10                           11                           
+ 11   func getContent() stri… 12   func getContent() stri… 
+ 12 -     return "Hello, wor… 13 +     content := strings… 
+                              14 +     return content      
+ 13   }                       15   }                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf060.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@           …                           
-  2                             2                           
-  3   import (                  3   import (                
-  4       "fmt"                 4       "fmt"               
-                                5 +     "strings"           
-  5   )                         6   )                       
-  6                             7                           
-  7   func main() {             8   func main() {           
-  …   @@ -9,5 +10,6 @@          …                           
-  9   }                        10   }                       
- 10                            11                           
- 11   func getContent() strin… 12   func getContent() strin…
- 12 -     return "Hello, worl… 13 +     content := strings.…
-                               14 +     return content      
- 13   }                        15   }                       
+  …   @@ -2,6 +2,7 @@           …                           
+  2                             2                           
+  3   import (                  3   import (                
+  4       "fmt"                 4       "fmt"               
+                                5 +     "strings"           
+  5   )                         6   )                       
+  6                             7                           
+  7   func main() {             8   func main() {           
+  …   @@ -9,5 +10,6 @@          …                           
+  9   }                        10   }                       
+ 10                            11                           
+ 11   func getContent() strin… 12   func getContent() strin…
+ 12 -     return "Hello, worl… 13 +     content := strings.…
+                               14 +     return content      
+ 13   }                        15   }                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf061.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@           …                            
-  2                             2                            
-  3   import (                  3   import (                 
-  4       "fmt"                 4       "fmt"                
-                                5 +     "strings"            
-  5   )                         6   )                        
-  6                             7                            
-  7   func main() {             8   func main() {            
-  …   @@ -9,5 +10,6 @@          …                            
-  9   }                        10   }                        
- 10                            11                            
- 11   func getContent() strin… 12   func getContent() strin… 
- 12 -     return "Hello, worl… 13 +     content := strings.… 
-                               14 +     return content       
- 13   }                        15   }                        
+  …   @@ -2,6 +2,7 @@           …                            
+  2                             2                            
+  3   import (                  3   import (                 
+  4       "fmt"                 4       "fmt"                
+                                5 +     "strings"            
+  5   )                         6   )                        
+  6                             7                            
+  7   func main() {             8   func main() {            
+  …   @@ -9,5 +10,6 @@          …                            
+  9   }                        10   }                        
+ 10                            11                            
+ 11   func getContent() strin… 12   func getContent() strin… 
+ 12 -     return "Hello, worl… 13 +     content := strings.… 
+                               14 +     return content       
+ 13   }                        15   }                        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf062.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@            …                            
-  2                              2                            
-  3   import (                   3   import (                 
-  4       "fmt"                  4       "fmt"                
-                                 5 +     "strings"            
-  5   )                          6   )                        
-  6                              7                            
-  7   func main() {              8   func main() {            
-  …   @@ -9,5 +10,6 @@           …                            
-  9   }                         10   }                        
- 10                             11                            
- 11   func getContent() string… 12   func getContent() string…
- 12 -     return "Hello, world… 13 +     content := strings.T…
-                                14 +     return content       
- 13   }                         15   }                        
+  …   @@ -2,6 +2,7 @@            …                            
+  2                              2                            
+  3   import (                   3   import (                 
+  4       "fmt"                  4       "fmt"                
+                                 5 +     "strings"            
+  5   )                          6   )                        
+  6                              7                            
+  7   func main() {              8   func main() {            
+  …   @@ -9,5 +10,6 @@           …                            
+  9   }                         10   }                        
+ 10                             11                            
+ 11   func getContent() string… 12   func getContent() string…
+ 12 -     return "Hello, world… 13 +     content := strings.T…
+                                14 +     return content       
+ 13   }                         15   }                        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf063.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@            …                             
-  2                              2                             
-  3   import (                   3   import (                  
-  4       "fmt"                  4       "fmt"                 
-                                 5 +     "strings"             
-  5   )                          6   )                         
-  6                              7                             
-  7   func main() {              8   func main() {             
-  …   @@ -9,5 +10,6 @@           …                             
-  9   }                         10   }                         
- 10                             11                             
- 11   func getContent() string… 12   func getContent() string… 
- 12 -     return "Hello, world… 13 +     content := strings.T… 
-                                14 +     return content        
- 13   }                         15   }                         
+  …   @@ -2,6 +2,7 @@            …                             
+  2                              2                             
+  3   import (                   3   import (                  
+  4       "fmt"                  4       "fmt"                 
+                                 5 +     "strings"             
+  5   )                          6   )                         
+  6                              7                             
+  7   func main() {              8   func main() {             
+  …   @@ -9,5 +10,6 @@           …                             
+  9   }                         10   }                         
+ 10                             11                             
+ 11   func getContent() string… 12   func getContent() string… 
+ 12 -     return "Hello, world… 13 +     content := strings.T… 
+                                14 +     return content        
+ 13   }                         15   }                         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf064.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@             …                             
-  2                               2                             
-  3   import (                    3   import (                  
-  4       "fmt"                   4       "fmt"                 
-                                  5 +     "strings"             
-  5   )                           6   )                         
-  6                               7                             
-  7   func main() {               8   func main() {             
-  …   @@ -9,5 +10,6 @@            …                             
-  9   }                          10   }                         
- 10                              11                             
- 11   func getContent() string { 12   func getContent() string {
- 12 -     return "Hello, world!" 13 +     content := strings.To…
-                                 14 +     return content        
- 13   }                          15   }                         
+  …   @@ -2,6 +2,7 @@             …                             
+  2                               2                             
+  3   import (                    3   import (                  
+  4       "fmt"                   4       "fmt"                 
+                                  5 +     "strings"             
+  5   )                           6   )                         
+  6                               7                             
+  7   func main() {               8   func main() {             
+  …   @@ -9,5 +10,6 @@            …                             
+  9   }                          10   }                         
+ 10                              11                             
+ 11   func getContent() string { 12   func getContent() string {
+ 12 -     return "Hello, world!" 13 +     content := strings.To…
+                                 14 +     return content        
+ 13   }                          15   }                         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf065.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@             …                              
-  2                               2                              
-  3   import (                    3   import (                   
-  4       "fmt"                   4       "fmt"                  
-                                  5 +     "strings"              
-  5   )                           6   )                          
-  6                               7                              
-  7   func main() {               8   func main() {              
-  …   @@ -9,5 +10,6 @@            …                              
-  9   }                          10   }                          
- 10                              11                              
- 11   func getContent() string { 12   func getContent() string { 
- 12 -     return "Hello, world!" 13 +     content := strings.To… 
-                                 14 +     return content         
- 13   }                          15   }                          
+  …   @@ -2,6 +2,7 @@             …                              
+  2                               2                              
+  3   import (                    3   import (                   
+  4       "fmt"                   4       "fmt"                  
+                                  5 +     "strings"              
+  5   )                           6   )                          
+  6                               7                              
+  7   func main() {               8   func main() {              
+  …   @@ -9,5 +10,6 @@            …                              
+  9   }                          10   }                          
+ 10                              11                              
+ 11   func getContent() string { 12   func getContent() string { 
+ 12 -     return "Hello, world!" 13 +     content := strings.To… 
+                                 14 +     return content         
+ 13   }                          15   }                          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf066.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@              …                              
-  2                                2                              
-  3   import (                     3   import (                   
-  4       "fmt"                    4       "fmt"                  
-                                   5 +     "strings"              
-  5   )                            6   )                          
-  6                                7                              
-  7   func main() {                8   func main() {              
-  …   @@ -9,5 +10,6 @@             …                              
-  9   }                           10   }                          
- 10                               11                              
- 11   func getContent() string {  12   func getContent() string { 
- 12 -     return "Hello, world!"  13 +     content := strings.ToU…
-                                  14 +     return content         
- 13   }                           15   }                          
+  …   @@ -2,6 +2,7 @@              …                              
+  2                                2                              
+  3   import (                     3   import (                   
+  4       "fmt"                    4       "fmt"                  
+                                   5 +     "strings"              
+  5   )                            6   )                          
+  6                                7                              
+  7   func main() {                8   func main() {              
+  …   @@ -9,5 +10,6 @@             …                              
+  9   }                           10   }                          
+ 10                               11                              
+ 11   func getContent() string {  12   func getContent() string { 
+ 12 -     return "Hello, world!"  13 +     content := strings.ToU…
+                                  14 +     return content         
+ 13   }                           15   }                          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf067.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@              …                               
-  2                                2                               
-  3   import (                     3   import (                    
-  4       "fmt"                    4       "fmt"                   
-                                   5 +     "strings"               
-  5   )                            6   )                           
-  6                                7                               
-  7   func main() {                8   func main() {               
-  …   @@ -9,5 +10,6 @@             …                               
-  9   }                           10   }                           
- 10                               11                               
- 11   func getContent() string {  12   func getContent() string {  
- 12 -     return "Hello, world!"  13 +     content := strings.ToU… 
-                                  14 +     return content          
- 13   }                           15   }                           
+  …   @@ -2,6 +2,7 @@              …                               
+  2                                2                               
+  3   import (                     3   import (                    
+  4       "fmt"                    4       "fmt"                   
+                                   5 +     "strings"               
+  5   )                            6   )                           
+  6                                7                               
+  7   func main() {                8   func main() {               
+  …   @@ -9,5 +10,6 @@             …                               
+  9   }                           10   }                           
+ 10                               11                               
+ 11   func getContent() string {  12   func getContent() string {  
+ 12 -     return "Hello, world!"  13 +     content := strings.ToU… 
+                                  14 +     return content          
+ 13   }                           15   }                           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf068.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@               …                               
-  2                                 2                               
-  3   import (                      3   import (                    
-  4       "fmt"                     4       "fmt"                   
-                                    5 +     "strings"               
-  5   )                             6   )                           
-  6                                 7                               
-  7   func main() {                 8   func main() {               
-  …   @@ -9,5 +10,6 @@              …                               
-  9   }                            10   }                           
- 10                                11                               
- 11   func getContent() string {   12   func getContent() string {  
- 12 -     return "Hello, world!"   13 +     content := strings.ToUp…
-                                   14 +     return content          
- 13   }                            15   }                           
+  …   @@ -2,6 +2,7 @@               …                               
+  2                                 2                               
+  3   import (                      3   import (                    
+  4       "fmt"                     4       "fmt"                   
+                                    5 +     "strings"               
+  5   )                             6   )                           
+  6                                 7                               
+  7   func main() {                 8   func main() {               
+  …   @@ -9,5 +10,6 @@              …                               
+  9   }                            10   }                           
+ 10                                11                               
+ 11   func getContent() string {   12   func getContent() string {  
+ 12 -     return "Hello, world!"   13 +     content := strings.ToUp…
+                                   14 +     return content          
+ 13   }                            15   }                           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf069.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@               …                                
-  2                                 2                                
-  3   import (                      3   import (                     
-  4       "fmt"                     4       "fmt"                    
-                                    5 +     "strings"                
-  5   )                             6   )                            
-  6                                 7                                
-  7   func main() {                 8   func main() {                
-  …   @@ -9,5 +10,6 @@              …                                
-  9   }                            10   }                            
- 10                                11                                
- 11   func getContent() string {   12   func getContent() string {   
- 12 -     return "Hello, world!"   13 +     content := strings.ToUp… 
-                                   14 +     return content           
- 13   }                            15   }                            
+  …   @@ -2,6 +2,7 @@               …                                
+  2                                 2                                
+  3   import (                      3   import (                     
+  4       "fmt"                     4       "fmt"                    
+                                    5 +     "strings"                
+  5   )                             6   )                            
+  6                                 7                                
+  7   func main() {                 8   func main() {                
+  …   @@ -9,5 +10,6 @@              …                                
+  9   }                            10   }                            
+ 10                                11                                
+ 11   func getContent() string {   12   func getContent() string {   
+ 12 -     return "Hello, world!"   13 +     content := strings.ToUp… 
+                                   14 +     return content           
+ 13   }                            15   }                            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf070.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                …                                
-  2                                  2                                
-  3   import (                       3   import (                     
-  4       "fmt"                      4       "fmt"                    
-                                     5 +     "strings"                
-  5   )                              6   )                            
-  6                                  7                                
-  7   func main() {                  8   func main() {                
-  …   @@ -9,5 +10,6 @@               …                                
-  9   }                             10   }                            
- 10                                 11                                
- 11   func getContent() string {    12   func getContent() string {   
- 12 -     return "Hello, world!"    13 +     content := strings.ToUpp…
-                                    14 +     return content           
- 13   }                             15   }                            
+  …   @@ -2,6 +2,7 @@                …                                
+  2                                  2                                
+  3   import (                       3   import (                     
+  4       "fmt"                      4       "fmt"                    
+                                     5 +     "strings"                
+  5   )                              6   )                            
+  6                                  7                                
+  7   func main() {                  8   func main() {                
+  …   @@ -9,5 +10,6 @@               …                                
+  9   }                             10   }                            
+ 10                                 11                                
+ 11   func getContent() string {    12   func getContent() string {   
+ 12 -     return "Hello, world!"    13 +     content := strings.ToUpp…
+                                    14 +     return content           
+ 13   }                             15   }                            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf071.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                …                                 
-  2                                  2                                 
-  3   import (                       3   import (                      
-  4       "fmt"                      4       "fmt"                     
-                                     5 +     "strings"                 
-  5   )                              6   )                             
-  6                                  7                                 
-  7   func main() {                  8   func main() {                 
-  …   @@ -9,5 +10,6 @@               …                                 
-  9   }                             10   }                             
- 10                                 11                                 
- 11   func getContent() string {    12   func getContent() string {    
- 12 -     return "Hello, world!"    13 +     content := strings.ToUpp… 
-                                    14 +     return content            
- 13   }                             15   }                             
+  …   @@ -2,6 +2,7 @@                …                                 
+  2                                  2                                 
+  3   import (                       3   import (                      
+  4       "fmt"                      4       "fmt"                     
+                                     5 +     "strings"                 
+  5   )                              6   )                             
+  6                                  7                                 
+  7   func main() {                  8   func main() {                 
+  …   @@ -9,5 +10,6 @@               …                                 
+  9   }                             10   }                             
+ 10                                 11                                 
+ 11   func getContent() string {    12   func getContent() string {    
+ 12 -     return "Hello, world!"    13 +     content := strings.ToUpp… 
+                                    14 +     return content            
+ 13   }                             15   }                             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf072.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                 …                                 
-  2                                   2                                 
-  3   import (                        3   import (                      
-  4       "fmt"                       4       "fmt"                     
-                                      5 +     "strings"                 
-  5   )                               6   )                             
-  6                                   7                                 
-  7   func main() {                   8   func main() {                 
-  …   @@ -9,5 +10,6 @@                …                                 
-  9   }                              10   }                             
- 10                                  11                                 
- 11   func getContent() string {     12   func getContent() string {    
- 12 -     return "Hello, world!"     13 +     content := strings.ToUppe…
-                                     14 +     return content            
- 13   }                              15   }                             
+  …   @@ -2,6 +2,7 @@                 …                                 
+  2                                   2                                 
+  3   import (                        3   import (                      
+  4       "fmt"                       4       "fmt"                     
+                                      5 +     "strings"                 
+  5   )                               6   )                             
+  6                                   7                                 
+  7   func main() {                   8   func main() {                 
+  …   @@ -9,5 +10,6 @@                …                                 
+  9   }                              10   }                             
+ 10                                  11                                 
+ 11   func getContent() string {     12   func getContent() string {    
+ 12 -     return "Hello, world!"     13 +     content := strings.ToUppe…
+                                     14 +     return content            
+ 13   }                              15   }                             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf073.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                 …                                  
-  2                                   2                                  
-  3   import (                        3   import (                       
-  4       "fmt"                       4       "fmt"                      
-                                      5 +     "strings"                  
-  5   )                               6   )                              
-  6                                   7                                  
-  7   func main() {                   8   func main() {                  
-  …   @@ -9,5 +10,6 @@                …                                  
-  9   }                              10   }                              
- 10                                  11                                  
- 11   func getContent() string {     12   func getContent() string {     
- 12 -     return "Hello, world!"     13 +     content := strings.ToUppe… 
-                                     14 +     return content             
- 13   }                              15   }                              
+  …   @@ -2,6 +2,7 @@                 …                                  
+  2                                   2                                  
+  3   import (                        3   import (                       
+  4       "fmt"                       4       "fmt"                      
+                                      5 +     "strings"                  
+  5   )                               6   )                              
+  6                                   7                                  
+  7   func main() {                   8   func main() {                  
+  …   @@ -9,5 +10,6 @@                …                                  
+  9   }                              10   }                              
+ 10                                  11                                  
+ 11   func getContent() string {     12   func getContent() string {     
+ 12 -     return "Hello, world!"     13 +     content := strings.ToUppe… 
+                                     14 +     return content             
+ 13   }                              15   }                              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf074.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                  …                                  
-  2                                    2                                  
-  3   import (                         3   import (                       
-  4       "fmt"                        4       "fmt"                      
-                                       5 +     "strings"                  
-  5   )                                6   )                              
-  6                                    7                                  
-  7   func main() {                    8   func main() {                  
-  …   @@ -9,5 +10,6 @@                 …                                  
-  9   }                               10   }                              
- 10                                   11                                  
- 11   func getContent() string {      12   func getContent() string {     
- 12 -     return "Hello, world!"      13 +     content := strings.ToUpper…
-                                      14 +     return content             
- 13   }                               15   }                              
+  …   @@ -2,6 +2,7 @@                  …                                  
+  2                                    2                                  
+  3   import (                         3   import (                       
+  4       "fmt"                        4       "fmt"                      
+                                       5 +     "strings"                  
+  5   )                                6   )                              
+  6                                    7                                  
+  7   func main() {                    8   func main() {                  
+  …   @@ -9,5 +10,6 @@                 …                                  
+  9   }                               10   }                              
+ 10                                   11                                  
+ 11   func getContent() string {      12   func getContent() string {     
+ 12 -     return "Hello, world!"      13 +     content := strings.ToUpper…
+                                      14 +     return content             
+ 13   }                               15   }                              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf075.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                  …                                   
-  2                                    2                                   
-  3   import (                         3   import (                        
-  4       "fmt"                        4       "fmt"                       
-                                       5 +     "strings"                   
-  5   )                                6   )                               
-  6                                    7                                   
-  7   func main() {                    8   func main() {                   
-  …   @@ -9,5 +10,6 @@                 …                                   
-  9   }                               10   }                               
- 10                                   11                                   
- 11   func getContent() string {      12   func getContent() string {      
- 12 -     return "Hello, world!"      13 +     content := strings.ToUpper… 
-                                      14 +     return content              
- 13   }                               15   }                               
+  …   @@ -2,6 +2,7 @@                  …                                   
+  2                                    2                                   
+  3   import (                         3   import (                        
+  4       "fmt"                        4       "fmt"                       
+                                       5 +     "strings"                   
+  5   )                                6   )                               
+  6                                    7                                   
+  7   func main() {                    8   func main() {                   
+  …   @@ -9,5 +10,6 @@                 …                                   
+  9   }                               10   }                               
+ 10                                   11                                   
+ 11   func getContent() string {      12   func getContent() string {      
+ 12 -     return "Hello, world!"      13 +     content := strings.ToUpper… 
+                                      14 +     return content              
+ 13   }                               15   }                               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf076.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                   …                                   
-  2                                     2                                   
-  3   import (                          3   import (                        
-  4       "fmt"                         4       "fmt"                       
-                                        5 +     "strings"                   
-  5   )                                 6   )                               
-  6                                     7                                   
-  7   func main() {                     8   func main() {                   
-  …   @@ -9,5 +10,6 @@                  …                                   
-  9   }                                10   }                               
- 10                                    11                                   
- 11   func getContent() string {       12   func getContent() string {      
- 12 -     return "Hello, world!"       13 +     content := strings.ToUpper(…
-                                       14 +     return content              
- 13   }                                15   }                               
+  …   @@ -2,6 +2,7 @@                   …                                   
+  2                                     2                                   
+  3   import (                          3   import (                        
+  4       "fmt"                         4       "fmt"                       
+                                        5 +     "strings"                   
+  5   )                                 6   )                               
+  6                                     7                                   
+  7   func main() {                     8   func main() {                   
+  …   @@ -9,5 +10,6 @@                  …                                   
+  9   }                                10   }                               
+ 10                                    11                                   
+ 11   func getContent() string {       12   func getContent() string {      
+ 12 -     return "Hello, world!"       13 +     content := strings.ToUpper(…
+                                       14 +     return content              
+ 13   }                                15   }                               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf077.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                   …                                    
-  2                                     2                                    
-  3   import (                          3   import (                         
-  4       "fmt"                         4       "fmt"                        
-                                        5 +     "strings"                    
-  5   )                                 6   )                                
-  6                                     7                                    
-  7   func main() {                     8   func main() {                    
-  …   @@ -9,5 +10,6 @@                  …                                    
-  9   }                                10   }                                
- 10                                    11                                    
- 11   func getContent() string {       12   func getContent() string {       
- 12 -     return "Hello, world!"       13 +     content := strings.ToUpper(… 
-                                       14 +     return content               
- 13   }                                15   }                                
+  …   @@ -2,6 +2,7 @@                   …                                    
+  2                                     2                                    
+  3   import (                          3   import (                         
+  4       "fmt"                         4       "fmt"                        
+                                        5 +     "strings"                    
+  5   )                                 6   )                                
+  6                                     7                                    
+  7   func main() {                     8   func main() {                    
+  …   @@ -9,5 +10,6 @@                  …                                    
+  9   }                                10   }                                
+ 10                                    11                                    
+ 11   func getContent() string {       12   func getContent() string {       
+ 12 -     return "Hello, world!"       13 +     content := strings.ToUpper(… 
+                                       14 +     return content               
+ 13   }                                15   }                                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf078.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                    …                                    
-  2                                      2                                    
-  3   import (                           3   import (                         
-  4       "fmt"                          4       "fmt"                        
-                                         5 +     "strings"                    
-  5   )                                  6   )                                
-  6                                      7                                    
-  7   func main() {                      8   func main() {                    
-  …   @@ -9,5 +10,6 @@                   …                                    
-  9   }                                 10   }                                
- 10                                     11                                    
- 11   func getContent() string {        12   func getContent() string {       
- 12 -     return "Hello, world!"        13 +     content := strings.ToUpper("…
-                                        14 +     return content               
- 13   }                                 15   }                                
+  …   @@ -2,6 +2,7 @@                    …                                    
+  2                                      2                                    
+  3   import (                           3   import (                         
+  4       "fmt"                          4       "fmt"                        
+                                         5 +     "strings"                    
+  5   )                                  6   )                                
+  6                                      7                                    
+  7   func main() {                      8   func main() {                    
+  …   @@ -9,5 +10,6 @@                   …                                    
+  9   }                                 10   }                                
+ 10                                     11                                    
+ 11   func getContent() string {        12   func getContent() string {       
+ 12 -     return "Hello, world!"        13 +     content := strings.ToUpper("…
+                                        14 +     return content               
+ 13   }                                 15   }                                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf079.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                    …                                     
-  2                                      2                                     
-  3   import (                           3   import (                          
-  4       "fmt"                          4       "fmt"                         
-                                         5 +     "strings"                     
-  5   )                                  6   )                                 
-  6                                      7                                     
-  7   func main() {                      8   func main() {                     
-  …   @@ -9,5 +10,6 @@                   …                                     
-  9   }                                 10   }                                 
- 10                                     11                                     
- 11   func getContent() string {        12   func getContent() string {        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf080.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                     …                                     
-  2                                       2                                     
-  3   import (                            3   import (                          
-  4       "fmt"                           4       "fmt"                         
-                                          5 +     "strings"                     
-  5   )                                   6   )                                 
-  6                                       7                                     
-  7   func main() {                       8   func main() {                     
-  …   @@ -9,5 +10,6 @@                    …                                     
-  9   }                                  10   }                                 
- 10                                      11                                     
- 11   func getContent() string {         12   func getContent() string {        
- 12 -     return "Hello, world!"         13 +     content := strings.ToUpper("H…
-                                         14 +     return content                
- 13   }                                  15   }                                 
+  …   @@ -2,6 +2,7 @@                     …                                     
+  2                                       2                                     
+  3   import (                            3   import (                          
+  4       "fmt"                           4       "fmt"                         
+                                          5 +     "strings"                     
+  5   )                                   6   )                                 
+  6                                       7                                     
+  7   func main() {                       8   func main() {                     
+  …   @@ -9,5 +10,6 @@                    …                                     
+  9   }                                  10   }                                 
+ 10                                      11                                     
+ 11   func getContent() string {         12   func getContent() string {        
+ 12 -     return "Hello, world!"         13 +     content := strings.ToUpper("H…
+                                         14 +     return content                
+ 13   }                                  15   }                                 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf081.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                     …                                      
-  2                                       2                                      
-  3   import (                            3   import (                           
-  4       "fmt"                           4       "fmt"                          
-                                          5 +     "strings"                      
-  5   )                                   6   )                                  
-  6                                       7                                      
-  7   func main() {                       8   func main() {                      
-  …   @@ -9,5 +10,6 @@                    …                                      
-  9   }                                  10   }                                  
- 10                                      11                                      
- 11   func getContent() string {         12   func getContent() string {         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf082.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                      …                                      
-  2                                        2                                      
-  3   import (                             3   import (                           
-  4       "fmt"                            4       "fmt"                          
-                                           5 +     "strings"                      
-  5   )                                    6   )                                  
-  6                                        7                                      
-  7   func main() {                        8   func main() {                      
-  …   @@ -9,5 +10,6 @@                     …                                      
-  9   }                                   10   }                                  
- 10                                       11                                      
- 11   func getContent() string {          12   func getContent() string {         
- 12 -     return "Hello, world!"          13 +     content := strings.ToUpper("He…
-                                          14 +     return content                 
- 13   }                                   15   }                                  
+  …   @@ -2,6 +2,7 @@                      …                                      
+  2                                        2                                      
+  3   import (                             3   import (                           
+  4       "fmt"                            4       "fmt"                          
+                                           5 +     "strings"                      
+  5   )                                    6   )                                  
+  6                                        7                                      
+  7   func main() {                        8   func main() {                      
+  …   @@ -9,5 +10,6 @@                     …                                      
+  9   }                                   10   }                                  
+ 10                                       11                                      
+ 11   func getContent() string {          12   func getContent() string {         
+ 12 -     return "Hello, world!"          13 +     content := strings.ToUpper("He…
+                                          14 +     return content                 
+ 13   }                                   15   }                                  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf083.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                      …                                       
-  2                                        2                                       
-  3   import (                             3   import (                            
-  4       "fmt"                            4       "fmt"                           
-                                           5 +     "strings"                       
-  5   )                                    6   )                                   
-  6                                        7                                       
-  7   func main() {                        8   func main() {                       
-  …   @@ -9,5 +10,6 @@                     …                                       
-  9   }                                   10   }                                   
- 10                                       11                                       
- 11   func getContent() string {          12   func getContent() string {          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf084.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                       …                                       
-  2                                         2                                       
-  3   import (                              3   import (                            
-  4       "fmt"                             4       "fmt"                           
-                                            5 +     "strings"                       
-  5   )                                     6   )                                   
-  6                                         7                                       
-  7   func main() {                         8   func main() {                       
-  …   @@ -9,5 +10,6 @@                      …                                       
-  9   }                                    10   }                                   
- 10                                        11                                       
- 11   func getContent() string {           12   func getContent() string {          
- 12 -     return "Hello, world!"           13 +     content := strings.ToUpper("Hel…
-                                           14 +     return content                  
- 13   }                                    15   }                                   
+  …   @@ -2,6 +2,7 @@                       …                                       
+  2                                         2                                       
+  3   import (                              3   import (                            
+  4       "fmt"                             4       "fmt"                           
+                                            5 +     "strings"                       
+  5   )                                     6   )                                   
+  6                                         7                                       
+  7   func main() {                         8   func main() {                       
+  …   @@ -9,5 +10,6 @@                      …                                       
+  9   }                                    10   }                                   
+ 10                                        11                                       
+ 11   func getContent() string {           12   func getContent() string {          
+ 12 -     return "Hello, world!"           13 +     content := strings.ToUpper("Hel…
+                                           14 +     return content                  
+ 13   }                                    15   }                                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf085.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                       …                                        
-  2                                         2                                        
-  3   import (                              3   import (                             
-  4       "fmt"                             4       "fmt"                            
-                                            5 +     "strings"                        
-  5   )                                     6   )                                    
-  6                                         7                                        
-  7   func main() {                         8   func main() {                        
-  …   @@ -9,5 +10,6 @@                      …                                        
-  9   }                                    10   }                                    
- 10                                        11                                        
- 11   func getContent() string {           12   func getContent() string {           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf086.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                        …                                        
-  2                                          2                                        
-  3   import (                               3   import (                             
-  4       "fmt"                              4       "fmt"                            
-                                             5 +     "strings"                        
-  5   )                                      6   )                                    
-  6                                          7                                        
-  7   func main() {                          8   func main() {                        
-  …   @@ -9,5 +10,6 @@                       …                                        
-  9   }                                     10   }                                    
- 10                                         11                                        
- 11   func getContent() string {            12   func getContent() string {           
- 12 -     return "Hello, world!"            13 +     content := strings.ToUpper("Hell…
-                                            14 +     return content                   
- 13   }                                     15   }                                    
+  …   @@ -2,6 +2,7 @@                        …                                        
+  2                                          2                                        
+  3   import (                               3   import (                             
+  4       "fmt"                              4       "fmt"                            
+                                             5 +     "strings"                        
+  5   )                                      6   )                                    
+  6                                          7                                        
+  7   func main() {                          8   func main() {                        
+  …   @@ -9,5 +10,6 @@                       …                                        
+  9   }                                     10   }                                    
+ 10                                         11                                        
+ 11   func getContent() string {            12   func getContent() string {           
+ 12 -     return "Hello, world!"            13 +     content := strings.ToUpper("Hell…
+                                            14 +     return content                   
+ 13   }                                     15   }                                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf087.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                        …                                         
-  2                                          2                                         
-  3   import (                               3   import (                              
-  4       "fmt"                              4       "fmt"                             
-                                             5 +     "strings"                         
-  5   )                                      6   )                                     
-  6                                          7                                         
-  7   func main() {                          8   func main() {                         
-  …   @@ -9,5 +10,6 @@                       …                                         
-  9   }                                     10   }                                     
- 10                                         11                                         
- 11   func getContent() string {            12   func getContent() string {            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf088.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                         …                                         
-  2                                           2                                         
-  3   import (                                3   import (                              
-  4       "fmt"                               4       "fmt"                             
-                                              5 +     "strings"                         
-  5   )                                       6   )                                     
-  6                                           7                                         
-  7   func main() {                           8   func main() {                         
-  …   @@ -9,5 +10,6 @@                        …                                         
-  9   }                                      10   }                                     
- 10                                          11                                         
- 11   func getContent() string {             12   func getContent() string {            
- 12 -     return "Hello, world!"             13 +     content := strings.ToUpper("Hello…
-                                             14 +     return content                    
- 13   }                                      15   }                                     
+  …   @@ -2,6 +2,7 @@                         …                                         
+  2                                           2                                         
+  3   import (                                3   import (                              
+  4       "fmt"                               4       "fmt"                             
+                                              5 +     "strings"                         
+  5   )                                       6   )                                     
+  6                                           7                                         
+  7   func main() {                           8   func main() {                         
+  …   @@ -9,5 +10,6 @@                        …                                         
+  9   }                                      10   }                                     
+ 10                                          11                                         
+ 11   func getContent() string {             12   func getContent() string {            
+ 12 -     return "Hello, world!"             13 +     content := strings.ToUpper("Hello…
+                                             14 +     return content                    
+ 13   }                                      15   }                                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf089.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                         …                                          
-  2                                           2                                          
-  3   import (                                3   import (                               
-  4       "fmt"                               4       "fmt"                              
-                                              5 +     "strings"                          
-  5   )                                       6   )                                      
-  6                                           7                                          
-  7   func main() {                           8   func main() {                          
-  …   @@ -9,5 +10,6 @@                        …                                          
-  9   }                                      10   }                                      
- 10                                          11                                          
- 11   func getContent() string {             12   func getContent() string {             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf090.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                          …                                          
-  2                                            2                                          
-  3   import (                                 3   import (                               
-  4       "fmt"                                4       "fmt"                              
-                                               5 +     "strings"                          
-  5   )                                        6   )                                      
-  6                                            7                                          
-  7   func main() {                            8   func main() {                          
-  …   @@ -9,5 +10,6 @@                         …                                          
-  9   }                                       10   }                                      
- 10                                           11                                          
- 11   func getContent() string {              12   func getContent() string {             
- 12 -     return "Hello, world!"              13 +     content := strings.ToUpper("Hello,…
-                                              14 +     return content                     
- 13   }                                       15   }                                      
+  …   @@ -2,6 +2,7 @@                          …                                          
+  2                                            2                                          
+  3   import (                                 3   import (                               
+  4       "fmt"                                4       "fmt"                              
+                                               5 +     "strings"                          
+  5   )                                        6   )                                      
+  6                                            7                                          
+  7   func main() {                            8   func main() {                          
+  …   @@ -9,5 +10,6 @@                         …                                          
+  9   }                                       10   }                                      
+ 10                                           11                                          
+ 11   func getContent() string {              12   func getContent() string {             
+ 12 -     return "Hello, world!"              13 +     content := strings.ToUpper("Hello,…
+                                              14 +     return content                     
+ 13   }                                       15   }                                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf091.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                          …                                           
-  2                                            2                                           
-  3   import (                                 3   import (                                
-  4       "fmt"                                4       "fmt"                               
-                                               5 +     "strings"                           
-  5   )                                        6   )                                       
-  6                                            7                                           
-  7   func main() {                            8   func main() {                           
-  …   @@ -9,5 +10,6 @@                         …                                           
-  9   }                                       10   }                                       
- 10                                           11                                           
- 11   func getContent() string {              12   func getContent() string {              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf092.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                           …                                           
-  2                                             2                                           
-  3   import (                                  3   import (                                
-  4       "fmt"                                 4       "fmt"                               
-                                                5 +     "strings"                           
-  5   )                                         6   )                                       
-  6                                             7                                           
-  7   func main() {                             8   func main() {                           
-  …   @@ -9,5 +10,6 @@                          …                                           
-  9   }                                        10   }                                       
- 10                                            11                                           
- 11   func getContent() string {               12   func getContent() string {              
- 12 -     return "Hello, world!"               13 +     content := strings.ToUpper("Hello, …
-                                               14 +     return content                      
- 13   }                                        15   }                                       
+  …   @@ -2,6 +2,7 @@                           …                                           
+  2                                             2                                           
+  3   import (                                  3   import (                                
+  4       "fmt"                                 4       "fmt"                               
+                                                5 +     "strings"                           
+  5   )                                         6   )                                       
+  6                                             7                                           
+  7   func main() {                             8   func main() {                           
+  …   @@ -9,5 +10,6 @@                          …                                           
+  9   }                                        10   }                                       
+ 10                                            11                                           
+ 11   func getContent() string {               12   func getContent() string {              
+ 12 -     return "Hello, world!"               13 +     content := strings.ToUpper("Hello, …
+                                               14 +     return content                      
+ 13   }                                        15   }                                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf093.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                           …                                            
-  2                                             2                                            
-  3   import (                                  3   import (                                 
-  4       "fmt"                                 4       "fmt"                                
-                                                5 +     "strings"                            
-  5   )                                         6   )                                        
-  6                                             7                                            
-  7   func main() {                             8   func main() {                            
-  …   @@ -9,5 +10,6 @@                          …                                            
-  9   }                                        10   }                                        
- 10                                            11                                            
- 11   func getContent() string {               12   func getContent() string {               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf094.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                            …                                            
-  2                                              2                                            
-  3   import (                                   3   import (                                 
-  4       "fmt"                                  4       "fmt"                                
-                                                 5 +     "strings"                            
-  5   )                                          6   )                                        
-  6                                              7                                            
-  7   func main() {                              8   func main() {                            
-  …   @@ -9,5 +10,6 @@                           …                                            
-  9   }                                         10   }                                        
- 10                                             11                                            
- 11   func getContent() string {                12   func getContent() string {               
- 12 -     return "Hello, world!"                13 +     content := strings.ToUpper("Hello, W…
-                                                14 +     return content                       
- 13   }                                         15   }                                        
+  …   @@ -2,6 +2,7 @@                            …                                            
+  2                                              2                                            
+  3   import (                                   3   import (                                 
+  4       "fmt"                                  4       "fmt"                                
+                                                 5 +     "strings"                            
+  5   )                                          6   )                                        
+  6                                              7                                            
+  7   func main() {                              8   func main() {                            
+  …   @@ -9,5 +10,6 @@                           …                                            
+  9   }                                         10   }                                        
+ 10                                             11                                            
+ 11   func getContent() string {                12   func getContent() string {               
+ 12 -     return "Hello, world!"                13 +     content := strings.ToUpper("Hello, W…
+                                                14 +     return content                       
+ 13   }                                         15   }                                        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf095.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                            …                                             
-  2                                              2                                             
-  3   import (                                   3   import (                                  
-  4       "fmt"                                  4       "fmt"                                 
-                                                 5 +     "strings"                             
-  5   )                                          6   )                                         
-  6                                              7                                             
-  7   func main() {                              8   func main() {                             
-  …   @@ -9,5 +10,6 @@                           …                                             
-  9   }                                         10   }                                         
- 10                                             11                                             
- 11   func getContent() string {                12   func getContent() string {                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf096.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                             …                                             
-  2                                               2                                             
-  3   import (                                    3   import (                                  
-  4       "fmt"                                   4       "fmt"                                 
-                                                  5 +     "strings"                             
-  5   )                                           6   )                                         
-  6                                               7                                             
-  7   func main() {                               8   func main() {                             
-  …   @@ -9,5 +10,6 @@                            …                                             
-  9   }                                          10   }                                         
- 10                                              11                                             
- 11   func getContent() string {                 12   func getContent() string {                
- 12 -     return "Hello, world!"                 13 +     content := strings.ToUpper("Hello, Wo…
-                                                 14 +     return content                        
- 13   }                                          15   }                                         
+  …   @@ -2,6 +2,7 @@                             …                                             
+  2                                               2                                             
+  3   import (                                    3   import (                                  
+  4       "fmt"                                   4       "fmt"                                 
+                                                  5 +     "strings"                             
+  5   )                                           6   )                                         
+  6                                               7                                             
+  7   func main() {                               8   func main() {                             
+  …   @@ -9,5 +10,6 @@                            …                                             
+  9   }                                          10   }                                         
+ 10                                              11                                             
+ 11   func getContent() string {                 12   func getContent() string {                
+ 12 -     return "Hello, world!"                 13 +     content := strings.ToUpper("Hello, Wo…
+                                                 14 +     return content                        
+ 13   }                                          15   }                                         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf097.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                             …                                              
-  2                                               2                                              
-  3   import (                                    3   import (                                   
-  4       "fmt"                                   4       "fmt"                                  
-                                                  5 +     "strings"                              
-  5   )                                           6   )                                          
-  6                                               7                                              
-  7   func main() {                               8   func main() {                              
-  …   @@ -9,5 +10,6 @@                            …                                              
-  9   }                                          10   }                                          
- 10                                              11                                              
- 11   func getContent() string {                 12   func getContent() string {                 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf098.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                              …                                              
-  2                                                2                                              
-  3   import (                                     3   import (                                   
-  4       "fmt"                                    4       "fmt"                                  
-                                                   5 +     "strings"                              
-  5   )                                            6   )                                          
-  6                                                7                                              
-  7   func main() {                                8   func main() {                              
-  …   @@ -9,5 +10,6 @@                             …                                              
-  9   }                                           10   }                                          
- 10                                               11                                              
- 11   func getContent() string {                  12   func getContent() string {                 
- 12 -     return "Hello, world!"                  13 +     content := strings.ToUpper("Hello, Wor…
-                                                  14 +     return content                         
- 13   }                                           15   }                                          
+  …   @@ -2,6 +2,7 @@                              …                                              
+  2                                                2                                              
+  3   import (                                     3   import (                                   
+  4       "fmt"                                    4       "fmt"                                  
+                                                   5 +     "strings"                              
+  5   )                                            6   )                                          
+  6                                                7                                              
+  7   func main() {                                8   func main() {                              
+  …   @@ -9,5 +10,6 @@                             …                                              
+  9   }                                           10   }                                          
+ 10                                               11                                              
+ 11   func getContent() string {                  12   func getContent() string {                 
+ 12 -     return "Hello, world!"                  13 +     content := strings.ToUpper("Hello, Wor…
+                                                  14 +     return content                         
+ 13   }                                           15   }                                          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf099.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                              …                                               
-  2                                                2                                               
-  3   import (                                     3   import (                                    
-  4       "fmt"                                    4       "fmt"                                   
-                                                   5 +     "strings"                               
-  5   )                                            6   )                                           
-  6                                                7                                               
-  7   func main() {                                8   func main() {                               
-  …   @@ -9,5 +10,6 @@                             …                                               
-  9   }                                           10   }                                           
- 10                                               11                                               
- 11   func getContent() string {                  12   func getContent() string {                  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf100.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                               …                                               
-  2                                                 2                                               
-  3   import (                                      3   import (                                    
-  4       "fmt"                                     4       "fmt"                                   
-                                                    5 +     "strings"                               
-  5   )                                             6   )                                           
-  6                                                 7                                               
-  7   func main() {                                 8   func main() {                               
-  …   @@ -9,5 +10,6 @@                              …                                               
-  9   }                                            10   }                                           
- 10                                                11                                               
- 11   func getContent() string {                   12   func getContent() string {                  
- 12 -     return "Hello, world!"                   13 +     content := strings.ToUpper("Hello, Worl…
-                                                   14 +     return content                          
- 13   }                                            15   }                                           
+  …   @@ -2,6 +2,7 @@                               …                                               
+  2                                                 2                                               
+  3   import (                                      3   import (                                    
+  4       "fmt"                                     4       "fmt"                                   
+                                                    5 +     "strings"                               
+  5   )                                             6   )                                           
+  6                                                 7                                               
+  7   func main() {                                 8   func main() {                               
+  …   @@ -9,5 +10,6 @@                              …                                               
+  9   }                                            10   }                                           
+ 10                                                11                                               
+ 11   func getContent() string {                   12   func getContent() string {                  
+ 12 -     return "Hello, world!"                   13 +     content := strings.ToUpper("Hello, Worl…
+                                                   14 +     return content                          
+ 13   }                                            15   }                                           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf101.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                               …                                                
-  2                                                 2                                                
-  3   import (                                      3   import (                                     
-  4       "fmt"                                     4       "fmt"                                    
-                                                    5 +     "strings"                                
-  5   )                                             6   )                                            
-  6                                                 7                                                
-  7   func main() {                                 8   func main() {                                
-  …   @@ -9,5 +10,6 @@                              …                                                
-  9   }                                            10   }                                            
- 10                                                11                                                
- 11   func getContent() string {                   12   func getContent() string {                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf102.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                …                                                
-  2                                                  2                                                
-  3   import (                                       3   import (                                     
-  4       "fmt"                                      4       "fmt"                                    
-                                                     5 +     "strings"                                
-  5   )                                              6   )                                            
-  6                                                  7                                                
-  7   func main() {                                  8   func main() {                                
-  …   @@ -9,5 +10,6 @@                               …                                                
-  9   }                                             10   }                                            
- 10                                                 11                                                
- 11   func getContent() string {                    12   func getContent() string {                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf103.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                …                                                 
-  2                                                  2                                                 
-  3   import (                                       3   import (                                      
-  4       "fmt"                                      4       "fmt"                                     
-                                                     5 +     "strings"                                 
-  5   )                                              6   )                                             
-  6                                                  7                                                 
-  7   func main() {                                  8   func main() {                                 
-  …   @@ -9,5 +10,6 @@                               …                                                 
-  9   }                                             10   }                                             
- 10                                                 11                                                 
- 11   func getContent() string {                    12   func getContent() string {                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf104.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                 …                                                 
-  2                                                   2                                                 
-  3   import (                                        3   import (                                      
-  4       "fmt"                                       4       "fmt"                                     
-                                                      5 +     "strings"                                 
-  5   )                                               6   )                                             
-  6                                                   7                                                 
-  7   func main() {                                   8   func main() {                                 
-  …   @@ -9,5 +10,6 @@                                …                                                 
-  9   }                                              10   }                                             
- 10                                                  11                                                 
- 11   func getContent() string {                     12   func getContent() string {                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf105.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                 …                                                  
-  2                                                   2                                                  
-  3   import (                                        3   import (                                       
-  4       "fmt"                                       4       "fmt"                                      
-                                                      5 +     "strings"                                  
-  5   )                                               6   )                                              
-  6                                                   7                                                  
-  7   func main() {                                   8   func main() {                                  
-  …   @@ -9,5 +10,6 @@                                …                                                  
-  9   }                                              10   }                                              
- 10                                                  11                                                  
- 11   func getContent() string {                     12   func getContent() string {                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf106.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                  …                                                  
-  2                                                    2                                                  
-  3   import (                                         3   import (                                       
-  4       "fmt"                                        4       "fmt"                                      
-                                                       5 +     "strings"                                  
-  5   )                                                6   )                                              
-  6                                                    7                                                  
-  7   func main() {                                    8   func main() {                                  
-  …   @@ -9,5 +10,6 @@                                 …                                                  
-  9   }                                               10   }                                              
- 10                                                   11                                                  
- 11   func getContent() string {                      12   func getContent() string {                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf107.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                  …                                                   
-  2                                                    2                                                   
-  3   import (                                         3   import (                                        
-  4       "fmt"                                        4       "fmt"                                       
-                                                       5 +     "strings"                                   
-  5   )                                                6   )                                               
-  6                                                    7                                                   
-  7   func main() {                                    8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                 …                                                   
-  9   }                                               10   }                                               
- 10                                                   11                                                   
- 11   func getContent() string {                      12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf108.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf109.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                    
-  2                                                     2                                                    
-  3   import (                                          3   import (                                         
-  4       "fmt"                                         4       "fmt"                                        
-                                                        5 +     "strings"                                    
-  5   )                                                 6   )                                                
-  6                                                     7                                                    
-  7   func main() {                                     8   func main() {                                    
-  …   @@ -9,5 +10,6 @@                                  …                                                    
-  9   }                                                10   }                                                
- 10                                                    11                                                    
- 11   func getContent() string {                       12   func getContent() string {                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Split/WidthOf110.golden 🔗

@@ -1,15 +1,15 @@
-  …   @@ -2,6 +2,7 @@                                    …                                                    
-  2                                                      2                                                    
-  3   import (                                           3   import (                                         
-  4       "fmt"                                          4       "fmt"                                        
-                                                         5 +     "strings"                                    
-  5   )                                                  6   )                                                
-  6                                                      7                                                    
-  7   func main() {                                      8   func main() {                                    
-  …   @@ -9,5 +10,6 @@                                   …                                                    
-  9   }                                                 10   }                                                
- 10                                                     11                                                    
- 11   func getContent() string {                        12   func getContent() string {                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf001.golden 🔗

@@ -1,16 +1,16 @@
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf002.golden 🔗

@@ -1,16 +1,16 @@
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
- 1
- 1
- 1
-  
-  
- 1
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+ 1
+ 1
+ 1
+  
+  
+ 1

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf003.golden 🔗

@@ -1,16 +1,16 @@
-  …
-  2
-  3
-  4
-   
-  5
-  6
-  7
-  …
-  9
- 10
- 11
- 12
-   
-   
- 13
+  …
+  2
+  3
+  4
+   
+  5
+  6
+  7
+  …
+  9
+ 10
+ 11
+ 12
+   
+   
+ 13

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf004.golden 🔗

@@ -1,16 +1,16 @@
-  … 
-  2 
-  3 
-  4 
-    
-  5 
-  6 
-  7 
-  … 
-  9 
- 10 
- 11 
- 12 
-    
-    
- 13 
+  … 
+  2 
+  3 
+  4 
+    
+  5 
+  6 
+  7 
+  … 
+  9 
+ 10 
+ 11 
+ 12 
+    
+    
+ 13 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf005.golden 🔗

@@ -1,16 +1,16 @@
-  …  
-  2  
-  3  
-  4  
-     
-  5  
-  6  
-  7  
-  …  
-  9  
- 10  
- 11  
- 12  
-     
-     
- 13  
+  …  
+  2  
+  3  
+  4  
+     
+  5  
+  6  
+  7  
+  …  
+  9  
+ 10  
+ 11  
+ 12  
+     
+     
+ 13  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf006.golden 🔗

@@ -1,16 +1,16 @@
-  …   
-  2   
-  3   
-  4   
-      
-  5   
-  6   
-  7   
-  …   
-  9  1
- 10  1
- 11  1
- 12   
-     1
-     1
- 13  1
+  …   
+  2   
+  3   
+  4   
+      
+  5   
+  6   
+  7   
+  …   
+  9  1
+ 10  1
+ 11  1
+ 12   
+     1
+     1
+ 13  1

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf007.golden 🔗

@@ -1,16 +1,16 @@
-  …   …
-  2   2
-  3   3
-  4   4
-      5
-  5   6
-  6   7
-  7   8
-  …   …
-  9  10
- 10  11
- 11  12
- 12    
-     13
-     14
- 13  15
+  …   …
+  2   2
+  3   3
+  4   4
+      5
+  5   6
+  6   7
+  7   8
+  …   …
+  9  10
+ 10  11
+ 11  12
+ 12    
+     13
+     14
+ 13  15

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf008.golden 🔗

@@ -1,16 +1,16 @@
-  …   … 
-  2   2 
-  3   3 
-  4   4 
-      5 
-  5   6 
-  6   7 
-  7   8 
-  …   … 
-  9  10 
- 10  11 
- 11  12 
- 12     
-     13 
-     14 
- 13  15 
+  …   … 
+  2   2 
+  3   3 
+  4   4 
+      5 
+  5   6 
+  6   7 
+  7   8 
+  …   … 
+  9  10 
+ 10  11 
+ 11  12 
+ 12     
+     13 
+     14 
+ 13  15 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf009.golden 🔗

@@ -1,16 +1,16 @@
-  …   … …
-  2   2  
-  3   3  
-  4   4  
-      5 +
-  5   6  
-  6   7  
-  7   8  
-  …   … …
-  9  10  
- 10  11  
- 11  12  
- 12     -
-     13 +
-     14 +
- 13  15  
+  …   … …
+  2   2  
+  3   3  
+  4   4  
+      5 +
+  5   6  
+  6   7  
+  7   8  
+  …   … …
+  9  10  
+ 10  11  
+ 11  12  
+ 12     -
+     13 +
+     14 +
+ 13  15  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf010.golden 🔗

@@ -1,16 +1,16 @@
-  …   …  …
-  2   2   
-  3   3   
-  4   4   
-      5 + 
-  5   6   
-  6   7   
-  7   8   
-  …   …  …
-  9  10   
- 10  11   
- 11  12   
- 12     - 
-     13 + 
-     14 + 
- 13  15   
+  …   …  …
+  2   2   
+  3   3   
+  4   4   
+      5 + 
+  5   6   
+  6   7   
+  7   8   
+  …   …  …
+  9  10   
+ 10  11   
+ 11  12   
+ 12     - 
+     13 + 
+     14 + 
+ 13  15   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf011.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   …
-  2   2    
-  3   3   …
-  4   4   …
-      5 + …
-  5   6   )
-  6   7    
-  7   8   …
-  …   …   …
-  9  10   }
- 10  11    
- 11  12   …
- 12     - …
-     13 + …
-     14 + …
- 13  15   }
+  …   …   …
+  2   2    
+  3   3   …
+  4   4   …
+      5 + …
+  5   6   )
+  6   7    
+  7   8   …
+  …   …   …
+  9  10   }
+ 10  11    
+ 11  12   …
+ 12     - …
+     13 + …
+     14 + …
+ 13  15   }

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf012.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @…
-  2   2     
-  3   3   i…
-  4   4    …
-      5 +  …
-  5   6   ) 
-  6   7     
-  7   8   f…
-  …   …   @…
-  9  10   } 
- 10  11     
- 11  12   f…
- 12     -  …
-     13 +  …
-     14 +  …
- 13  15   } 
+  …   …   @…
+  2   2     
+  3   3   i…
+  4   4    …
+      5 +  …
+  5   6   ) 
+  6   7     
+  7   8   f…
+  …   …   @…
+  9  10   } 
+ 10  11     
+ 11  12   f…
+ 12     -  …
+     13 +  …
+     14 +  …
+ 13  15   } 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf013.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@…
-  2   2      
-  3   3   im…
-  4   4     …
-      5 +   …
-  5   6   )  
-  6   7      
-  7   8   fu…
-  …   …   @@…
-  9  10   }  
- 10  11      
- 11  12   fu…
- 12     -   …
-     13 +   …
-     14 +   …
- 13  15   }  
+  …   …   @@…
+  2   2      
+  3   3   im…
+  4   4     …
+      5 +   …
+  5   6   )  
+  6   7      
+  7   8   fu…
+  …   …   @@…
+  9  10   }  
+ 10  11      
+ 11  12   fu…
+ 12     -   …
+     13 +   …
+     14 +   …
+ 13  15   }  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf014.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ …
-  2   2       
-  3   3   imp…
-  4   4      …
-      5 +    …
-  5   6   )   
-  6   7       
-  7   8   fun…
-  …   …   @@ …
-  9  10   }   
- 10  11       
- 11  12   fun…
- 12     -    …
-     13 +    …
-     14 +    …
- 13  15   }   
+  …   …   @@ …
+  2   2       
+  3   3   imp…
+  4   4      …
+      5 +    …
+  5   6   )   
+  6   7       
+  7   8   fun…
+  …   …   @@ …
+  9  10   }   
+ 10  11       
+ 11  12   fun…
+ 12     -    …
+     13 +    …
+     14 +    …
+ 13  15   }   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf015.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -…
-  2   2        
-  3   3   impo…
-  4   4       …
-      5 +     …
-  5   6   )    
-  6   7        
-  7   8   func…
-  …   …   @@ -…
-  9  10   }    
- 10  11        
- 11  12   func…
- 12     -     …
-     13 +     …
-     14 +     …
- 13  15   }    
+  …   …   @@ -…
+  2   2        
+  3   3   impo…
+  4   4       …
+      5 +     …
+  5   6   )    
+  6   7        
+  7   8   func…
+  …   …   @@ -…
+  9  10   }    
+ 10  11        
+ 11  12   func…
+ 12     -     …
+     13 +     …
+     14 +     …
+ 13  15   }    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf016.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2…
-  2   2         
-  3   3   impor…
-  4   4       "…
-      5 +     "…
-  5   6   )     
-  6   7         
-  7   8   func …
-  …   …   @@ -9…
-  9  10   }     
- 10  11         
- 11  12   func …
- 12     -     r…
-     13 +     c…
-     14 +     r…
- 13  15   }     
+  …   …   @@ -2…
+  2   2         
+  3   3   impor…
+  4   4       "…
+      5 +     "…
+  5   6   )     
+  6   7         
+  7   8   func …
+  …   …   @@ -9…
+  9  10   }     
+ 10  11         
+ 11  12   func …
+ 12     -     r…
+     13 +     c…
+     14 +     r…
+ 13  15   }     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf017.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,…
-  2   2          
-  3   3   import…
-  4   4       "f…
-      5 +     "s…
-  5   6   )      
-  6   7          
-  7   8   func m…
-  …   …   @@ -9,…
-  9  10   }      
- 10  11          
- 11  12   func g…
- 12     -     re…
-     13 +     co…
-     14 +     re…
- 13  15   }      
+  …   …   @@ -2,…
+  2   2          
+  3   3   import…
+  4   4       "f…
+      5 +     "s…
+  5   6   )      
+  6   7          
+  7   8   func m…
+  …   …   @@ -9,…
+  9  10   }      
+ 10  11          
+ 11  12   func g…
+ 12     -     re…
+     13 +     co…
+     14 +     re…
+ 13  15   }      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf018.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6…
-  2   2           
-  3   3   import (
-  4   4       "fm…
-      5 +     "st…
-  5   6   )       
-  6   7           
-  7   8   func ma…
-  …   …   @@ -9,5…
-  9  10   }       
- 10  11           
- 11  12   func ge…
- 12     -     ret…
-     13 +     con…
-     14 +     ret…
- 13  15   }       
+  …   …   @@ -2,6…
+  2   2           
+  3   3   import (
+  4   4       "fm…
+      5 +     "st…
+  5   6   )       
+  6   7           
+  7   8   func ma…
+  …   …   @@ -9,5…
+  9  10   }       
+ 10  11           
+ 11  12   func ge…
+ 12     -     ret…
+     13 +     con…
+     14 +     ret…
+ 13  15   }       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf019.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 …
-  2   2            
-  3   3   import ( 
-  4   4       "fmt"
-      5 +     "str…
-  5   6   )        
-  6   7            
-  7   8   func mai…
-  …   …   @@ -9,5 …
-  9  10   }        
- 10  11            
- 11  12   func get…
- 12     -     retu…
-     13 +     cont…
-     14 +     retu…
- 13  15   }        
+  …   …   @@ -2,6 …
+  2   2            
+  3   3   import ( 
+  4   4       "fmt"
+      5 +     "str…
+  5   6   )        
+  6   7            
+  7   8   func mai…
+  …   …   @@ -9,5 …
+  9  10   }        
+ 10  11            
+ 11  12   func get…
+ 12     -     retu…
+     13 +     cont…
+     14 +     retu…
+ 13  15   }        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf020.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +…
-  2   2             
-  3   3   import (  
-  4   4       "fmt" 
-      5 +     "stri…
-  5   6   )         
-  6   7             
-  7   8   func main…
-  …   …   @@ -9,5 +…
-  9  10   }         
- 10  11             
- 11  12   func getC…
- 12     -     retur…
-     13 +     conte…
-     14 +     retur…
- 13  15   }         
+  …   …   @@ -2,6 +…
+  2   2             
+  3   3   import (  
+  4   4       "fmt" 
+      5 +     "stri…
+  5   6   )         
+  6   7             
+  7   8   func main…
+  …   …   @@ -9,5 +…
+  9  10   }         
+ 10  11             
+ 11  12   func getC…
+ 12     -     retur…
+     13 +     conte…
+     14 +     retur…
+ 13  15   }         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf021.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2…
-  2   2              
-  3   3   import (   
-  4   4       "fmt"  
-      5 +     "strin…
-  5   6   )          
-  6   7              
-  7   8   func main(…
-  …   …   @@ -9,5 +1…
-  9  10   }          
- 10  11              
- 11  12   func getCo…
- 12     -     return…
-     13 +     conten…
-     14 +     return…
- 13  15   }          
+  …   …   @@ -2,6 +2…
+  2   2              
+  3   3   import (   
+  4   4       "fmt"  
+      5 +     "strin…
+  5   6   )          
+  6   7              
+  7   8   func main(…
+  …   …   @@ -9,5 +1…
+  9  10   }          
+ 10  11              
+ 11  12   func getCo…
+ 12     -     return…
+     13 +     conten…
+     14 +     return…
+ 13  15   }          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf022.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,…
-  2   2               
-  3   3   import (    
-  4   4       "fmt"   
-      5 +     "string…
-  5   6   )           
-  6   7               
-  7   8   func main()…
-  …   …   @@ -9,5 +10…
-  9  10   }           
- 10  11               
- 11  12   func getCon…
- 12     -     return …
-     13 +     content…
-     14 +     return …
- 13  15   }           
+  …   …   @@ -2,6 +2,…
+  2   2               
+  3   3   import (    
+  4   4       "fmt"   
+      5 +     "string…
+  5   6   )           
+  6   7               
+  7   8   func main()…
+  …   …   @@ -9,5 +10…
+  9  10   }           
+ 10  11               
+ 11  12   func getCon…
+ 12     -     return …
+     13 +     content…
+     14 +     return …
+ 13  15   }           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf023.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7…
-  2   2                
-  3   3   import (     
-  4   4       "fmt"    
-      5 +     "strings"
-  5   6   )            
-  6   7                
-  7   8   func main() {
-  …   …   @@ -9,5 +10,…
-  9  10   }            
- 10  11                
- 11  12   func getCont…
- 12     -     return "…
-     13 +     content …
-     14 +     return c…
- 13  15   }            
+  …   …   @@ -2,6 +2,7…
+  2   2                
+  3   3   import (     
+  4   4       "fmt"    
+      5 +     "strings"
+  5   6   )            
+  6   7                
+  7   8   func main() {
+  …   …   @@ -9,5 +10,…
+  9  10   }            
+ 10  11                
+ 11  12   func getCont…
+ 12     -     return "…
+     13 +     content …
+     14 +     return c…
+ 13  15   }            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf024.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 …
-  2   2                 
-  3   3   import (      
-  4   4       "fmt"     
-      5 +     "strings" 
-  5   6   )             
-  6   7                 
-  7   8   func main() { 
-  …   …   @@ -9,5 +10,6…
-  9  10   }             
- 10  11                 
- 11  12   func getConte…
- 12     -     return "H…
-     13 +     content :…
-     14 +     return co…
- 13  15   }             
+  …   …   @@ -2,6 +2,7 …
+  2   2                 
+  3   3   import (      
+  4   4       "fmt"     
+      5 +     "strings" 
+  5   6   )             
+  6   7                 
+  7   8   func main() { 
+  …   …   @@ -9,5 +10,6…
+  9  10   }             
+ 10  11                 
+ 11  12   func getConte…
+ 12     -     return "H…
+     13 +     content :…
+     14 +     return co…
+ 13  15   }             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf025.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @…
-  2   2                  
-  3   3   import (       
-  4   4       "fmt"      
-      5 +     "strings"  
-  5   6   )              
-  6   7                  
-  7   8   func main() {  
-  …   …   @@ -9,5 +10,6 …
-  9  10   }              
- 10  11                  
- 11  12   func getConten…
- 12     -     return "He…
-     13 +     content :=…
-     14 +     return con…
- 13  15   }              
+  …   …   @@ -2,6 +2,7 @…
+  2   2                  
+  3   3   import (       
+  4   4       "fmt"      
+      5 +     "strings"  
+  5   6   )              
+  6   7                  
+  7   8   func main() {  
+  …   …   @@ -9,5 +10,6 …
+  9  10   }              
+ 10  11                  
+ 11  12   func getConten…
+ 12     -     return "He…
+     13 +     content :=…
+     14 +     return con…
+ 13  15   }              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf026.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@ 
-  2   2                   
-  3   3   import (        
-  4   4       "fmt"       
-      5 +     "strings"   
-  5   6   )               
-  6   7                   
-  7   8   func main() {   
-  …   …   @@ -9,5 +10,6 @…
-  9  10   }               
- 10  11                   
- 11  12   func getContent…
- 12     -     return "Hel…
-     13 +     content := …
-     14 +     return cont…
- 13  15   }               
+  …   …   @@ -2,6 +2,7 @@ 
+  2   2                   
+  3   3   import (        
+  4   4       "fmt"       
+      5 +     "strings"   
+  5   6   )               
+  6   7                   
+  7   8   func main() {   
+  …   …   @@ -9,5 +10,6 @…
+  9  10   }               
+ 10  11                   
+ 11  12   func getContent…
+ 12     -     return "Hel…
+     13 +     content := …
+     14 +     return cont…
+ 13  15   }               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf027.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@  
-  2   2                    
-  3   3   import (         
-  4   4       "fmt"        
-      5 +     "strings"    
-  5   6   )                
-  6   7                    
-  7   8   func main() {    
-  …   …   @@ -9,5 +10,6 @@ 
-  9  10   }                
- 10  11                    
- 11  12   func getContent(…
- 12     -     return "Hell…
-     13 +     content := s…
-     14 +     return conte…
- 13  15   }                
+  …   …   @@ -2,6 +2,7 @@  
+  2   2                    
+  3   3   import (         
+  4   4       "fmt"        
+      5 +     "strings"    
+  5   6   )                
+  6   7                    
+  7   8   func main() {    
+  …   …   @@ -9,5 +10,6 @@ 
+  9  10   }                
+ 10  11                    
+ 11  12   func getContent(…
+ 12     -     return "Hell…
+     13 +     content := s…
+     14 +     return conte…
+ 13  15   }                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf028.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@   
-  2   2                     
-  3   3   import (          
-  4   4       "fmt"         
-      5 +     "strings"     
-  5   6   )                 
-  6   7                     
-  7   8   func main() {     
-  …   …   @@ -9,5 +10,6 @@  
-  9  10   }                 
- 10  11                     
- 11  12   func getContent()…
- 12     -     return "Hello…
-     13 +     content := st…
-     14 +     return content
- 13  15   }                 
+  …   …   @@ -2,6 +2,7 @@   
+  2   2                     
+  3   3   import (          
+  4   4       "fmt"         
+      5 +     "strings"     
+  5   6   )                 
+  6   7                     
+  7   8   func main() {     
+  …   …   @@ -9,5 +10,6 @@  
+  9  10   }                 
+ 10  11                     
+ 11  12   func getContent()…
+ 12     -     return "Hello…
+     13 +     content := st…
+     14 +     return content
+ 13  15   }                 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf029.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@    
-  2   2                      
-  3   3   import (           
-  4   4       "fmt"          
-      5 +     "strings"      
-  5   6   )                  
-  6   7                      
-  7   8   func main() {      
-  …   …   @@ -9,5 +10,6 @@   
-  9  10   }                  
- 10  11                      
- 11  12   func getContent() …
- 12     -     return "Hello,…
-     13 +     content := str…
-     14 +     return content 
- 13  15   }                  
+  …   …   @@ -2,6 +2,7 @@    
+  2   2                      
+  3   3   import (           
+  4   4       "fmt"          
+      5 +     "strings"      
+  5   6   )                  
+  6   7                      
+  7   8   func main() {      
+  …   …   @@ -9,5 +10,6 @@   
+  9  10   }                  
+ 10  11                      
+ 11  12   func getContent() …
+ 12     -     return "Hello,…
+     13 +     content := str…
+     14 +     return content 
+ 13  15   }                  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf030.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@     
-  2   2                       
-  3   3   import (            
-  4   4       "fmt"           
-      5 +     "strings"       
-  5   6   )                   
-  6   7                       
-  7   8   func main() {       
-  …   …   @@ -9,5 +10,6 @@    
-  9  10   }                   
- 10  11                       
- 11  12   func getContent() s…
- 12     -     return "Hello, …
-     13 +     content := stri…
-     14 +     return content  
- 13  15   }                   
+  …   …   @@ -2,6 +2,7 @@     
+  2   2                       
+  3   3   import (            
+  4   4       "fmt"           
+      5 +     "strings"       
+  5   6   )                   
+  6   7                       
+  7   8   func main() {       
+  …   …   @@ -9,5 +10,6 @@    
+  9  10   }                   
+ 10  11                       
+ 11  12   func getContent() s…
+ 12     -     return "Hello, …
+     13 +     content := stri…
+     14 +     return content  
+ 13  15   }                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf031.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@      
-  2   2                        
-  3   3   import (             
-  4   4       "fmt"            
-      5 +     "strings"        
-  5   6   )                    
-  6   7                        
-  7   8   func main() {        
-  …   …   @@ -9,5 +10,6 @@     
-  9  10   }                    
- 10  11                        
- 11  12   func getContent() st…
- 12     -     return "Hello, w…
-     13 +     content := strin…
-     14 +     return content   
- 13  15   }                    
+  …   …   @@ -2,6 +2,7 @@      
+  2   2                        
+  3   3   import (             
+  4   4       "fmt"            
+      5 +     "strings"        
+  5   6   )                    
+  6   7                        
+  7   8   func main() {        
+  …   …   @@ -9,5 +10,6 @@     
+  9  10   }                    
+ 10  11                        
+ 11  12   func getContent() st…
+ 12     -     return "Hello, w…
+     13 +     content := strin…
+     14 +     return content   
+ 13  15   }                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf032.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@       
-  2   2                         
-  3   3   import (              
-  4   4       "fmt"             
-      5 +     "strings"         
-  5   6   )                     
-  6   7                         
-  7   8   func main() {         
-  …   …   @@ -9,5 +10,6 @@      
-  9  10   }                     
- 10  11                         
- 11  12   func getContent() str…
- 12     -     return "Hello, wo…
-     13 +     content := string…
-     14 +     return content    
- 13  15   }                     
+  …   …   @@ -2,6 +2,7 @@       
+  2   2                         
+  3   3   import (              
+  4   4       "fmt"             
+      5 +     "strings"         
+  5   6   )                     
+  6   7                         
+  7   8   func main() {         
+  …   …   @@ -9,5 +10,6 @@      
+  9  10   }                     
+ 10  11                         
+ 11  12   func getContent() str…
+ 12     -     return "Hello, wo…
+     13 +     content := string…
+     14 +     return content    
+ 13  15   }                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf033.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@        
-  2   2                          
-  3   3   import (               
-  4   4       "fmt"              
-      5 +     "strings"          
-  5   6   )                      
-  6   7                          
-  7   8   func main() {          
-  …   …   @@ -9,5 +10,6 @@       
-  9  10   }                      
- 10  11                          
- 11  12   func getContent() stri…
- 12     -     return "Hello, wor…
-     13 +     content := strings…
-     14 +     return content     
- 13  15   }                      
+  …   …   @@ -2,6 +2,7 @@        
+  2   2                          
+  3   3   import (               
+  4   4       "fmt"              
+      5 +     "strings"          
+  5   6   )                      
+  6   7                          
+  7   8   func main() {          
+  …   …   @@ -9,5 +10,6 @@       
+  9  10   }                      
+ 10  11                          
+ 11  12   func getContent() stri…
+ 12     -     return "Hello, wor…
+     13 +     content := strings…
+     14 +     return content     
+ 13  15   }                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf034.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@         
-  2   2                           
-  3   3   import (                
-  4   4       "fmt"               
-      5 +     "strings"           
-  5   6   )                       
-  6   7                           
-  7   8   func main() {           
-  …   …   @@ -9,5 +10,6 @@        
-  9  10   }                       
- 10  11                           
- 11  12   func getContent() strin…
- 12     -     return "Hello, worl…
-     13 +     content := strings.…
-     14 +     return content      
- 13  15   }                       
+  …   …   @@ -2,6 +2,7 @@         
+  2   2                           
+  3   3   import (                
+  4   4       "fmt"               
+      5 +     "strings"           
+  5   6   )                       
+  6   7                           
+  7   8   func main() {           
+  …   …   @@ -9,5 +10,6 @@        
+  9  10   }                       
+ 10  11                           
+ 11  12   func getContent() strin…
+ 12     -     return "Hello, worl…
+     13 +     content := strings.…
+     14 +     return content      
+ 13  15   }                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf035.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@          
-  2   2                            
-  3   3   import (                 
-  4   4       "fmt"                
-      5 +     "strings"            
-  5   6   )                        
-  6   7                            
-  7   8   func main() {            
-  …   …   @@ -9,5 +10,6 @@         
-  9  10   }                        
- 10  11                            
- 11  12   func getContent() string…
- 12     -     return "Hello, world…
-     13 +     content := strings.T…
-     14 +     return content       
- 13  15   }                        
+  …   …   @@ -2,6 +2,7 @@          
+  2   2                            
+  3   3   import (                 
+  4   4       "fmt"                
+      5 +     "strings"            
+  5   6   )                        
+  6   7                            
+  7   8   func main() {            
+  …   …   @@ -9,5 +10,6 @@         
+  9  10   }                        
+ 10  11                            
+ 11  12   func getContent() string…
+ 12     -     return "Hello, world…
+     13 +     content := strings.T…
+     14 +     return content       
+ 13  15   }                        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf036.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@           
-  2   2                             
-  3   3   import (                  
-  4   4       "fmt"                 
-      5 +     "strings"             
-  5   6   )                         
-  6   7                             
-  7   8   func main() {             
-  …   …   @@ -9,5 +10,6 @@          
-  9  10   }                         
- 10  11                             
- 11  12   func getContent() string {
- 12     -     return "Hello, world!"
-     13 +     content := strings.To…
-     14 +     return content        
- 13  15   }                         
+  …   …   @@ -2,6 +2,7 @@           
+  2   2                             
+  3   3   import (                  
+  4   4       "fmt"                 
+      5 +     "strings"             
+  5   6   )                         
+  6   7                             
+  7   8   func main() {             
+  …   …   @@ -9,5 +10,6 @@          
+  9  10   }                         
+ 10  11                             
+ 11  12   func getContent() string {
+ 12     -     return "Hello, world!"
+     13 +     content := strings.To…
+     14 +     return content        
+ 13  15   }                         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf037.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@            
-  2   2                              
-  3   3   import (                   
-  4   4       "fmt"                  
-      5 +     "strings"              
-  5   6   )                          
-  6   7                              
-  7   8   func main() {              
-  …   …   @@ -9,5 +10,6 @@           
-  9  10   }                          
- 10  11                              
- 11  12   func getContent() string { 
- 12     -     return "Hello, world!" 
-     13 +     content := strings.ToU…
-     14 +     return content         
- 13  15   }                          
+  …   …   @@ -2,6 +2,7 @@            
+  2   2                              
+  3   3   import (                   
+  4   4       "fmt"                  
+      5 +     "strings"              
+  5   6   )                          
+  6   7                              
+  7   8   func main() {              
+  …   …   @@ -9,5 +10,6 @@           
+  9  10   }                          
+ 10  11                              
+ 11  12   func getContent() string { 
+ 12     -     return "Hello, world!" 
+     13 +     content := strings.ToU…
+     14 +     return content         
+ 13  15   }                          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf038.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@             
-  2   2                               
-  3   3   import (                    
-  4   4       "fmt"                   
-      5 +     "strings"               
-  5   6   )                           
-  6   7                               
-  7   8   func main() {               
-  …   …   @@ -9,5 +10,6 @@            
-  9  10   }                           
- 10  11                               
- 11  12   func getContent() string {  
- 12     -     return "Hello, world!"  
-     13 +     content := strings.ToUp…
-     14 +     return content          
- 13  15   }                           
+  …   …   @@ -2,6 +2,7 @@             
+  2   2                               
+  3   3   import (                    
+  4   4       "fmt"                   
+      5 +     "strings"               
+  5   6   )                           
+  6   7                               
+  7   8   func main() {               
+  …   …   @@ -9,5 +10,6 @@            
+  9  10   }                           
+ 10  11                               
+ 11  12   func getContent() string {  
+ 12     -     return "Hello, world!"  
+     13 +     content := strings.ToUp…
+     14 +     return content          
+ 13  15   }                           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf039.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@              
-  2   2                                
-  3   3   import (                     
-  4   4       "fmt"                    
-      5 +     "strings"                
-  5   6   )                            
-  6   7                                
-  7   8   func main() {                
-  …   …   @@ -9,5 +10,6 @@             
-  9  10   }                            
- 10  11                                
- 11  12   func getContent() string {   
- 12     -     return "Hello, world!"   
-     13 +     content := strings.ToUpp…
-     14 +     return content           
- 13  15   }                            
+  …   …   @@ -2,6 +2,7 @@              
+  2   2                                
+  3   3   import (                     
+  4   4       "fmt"                    
+      5 +     "strings"                
+  5   6   )                            
+  6   7                                
+  7   8   func main() {                
+  …   …   @@ -9,5 +10,6 @@             
+  9  10   }                            
+ 10  11                                
+ 11  12   func getContent() string {   
+ 12     -     return "Hello, world!"   
+     13 +     content := strings.ToUpp…
+     14 +     return content           
+ 13  15   }                            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf040.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@               
-  2   2                                 
-  3   3   import (                      
-  4   4       "fmt"                     
-      5 +     "strings"                 
-  5   6   )                             
-  6   7                                 
-  7   8   func main() {                 
-  …   …   @@ -9,5 +10,6 @@              
-  9  10   }                             
- 10  11                                 
- 11  12   func getContent() string {    
- 12     -     return "Hello, world!"    
-     13 +     content := strings.ToUppe…
-     14 +     return content            
- 13  15   }                             
+  …   …   @@ -2,6 +2,7 @@               
+  2   2                                 
+  3   3   import (                      
+  4   4       "fmt"                     
+      5 +     "strings"                 
+  5   6   )                             
+  6   7                                 
+  7   8   func main() {                 
+  …   …   @@ -9,5 +10,6 @@              
+  9  10   }                             
+ 10  11                                 
+ 11  12   func getContent() string {    
+ 12     -     return "Hello, world!"    
+     13 +     content := strings.ToUppe…
+     14 +     return content            
+ 13  15   }                             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf041.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                
-  2   2                                  
-  3   3   import (                       
-  4   4       "fmt"                      
-      5 +     "strings"                  
-  5   6   )                              
-  6   7                                  
-  7   8   func main() {                  
-  …   …   @@ -9,5 +10,6 @@               
-  9  10   }                              
- 10  11                                  
- 11  12   func getContent() string {     
- 12     -     return "Hello, world!"     
-     13 +     content := strings.ToUpper…
-     14 +     return content             
- 13  15   }                              
+  …   …   @@ -2,6 +2,7 @@                
+  2   2                                  
+  3   3   import (                       
+  4   4       "fmt"                      
+      5 +     "strings"                  
+  5   6   )                              
+  6   7                                  
+  7   8   func main() {                  
+  …   …   @@ -9,5 +10,6 @@               
+  9  10   }                              
+ 10  11                                  
+ 11  12   func getContent() string {     
+ 12     -     return "Hello, world!"     
+     13 +     content := strings.ToUpper…
+     14 +     return content             
+ 13  15   }                              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf042.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                 
-  2   2                                   
-  3   3   import (                        
-  4   4       "fmt"                       
-      5 +     "strings"                   
-  5   6   )                               
-  6   7                                   
-  7   8   func main() {                   
-  …   …   @@ -9,5 +10,6 @@                
-  9  10   }                               
- 10  11                                   
- 11  12   func getContent() string {      
- 12     -     return "Hello, world!"      
-     13 +     content := strings.ToUpper(…
-     14 +     return content              
- 13  15   }                               
+  …   …   @@ -2,6 +2,7 @@                 
+  2   2                                   
+  3   3   import (                        
+  4   4       "fmt"                       
+      5 +     "strings"                   
+  5   6   )                               
+  6   7                                   
+  7   8   func main() {                   
+  …   …   @@ -9,5 +10,6 @@                
+  9  10   }                               
+ 10  11                                   
+ 11  12   func getContent() string {      
+ 12     -     return "Hello, world!"      
+     13 +     content := strings.ToUpper(…
+     14 +     return content              
+ 13  15   }                               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf043.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                  
-  2   2                                    
-  3   3   import (                         
-  4   4       "fmt"                        
-      5 +     "strings"                    
-  5   6   )                                
-  6   7                                    
-  7   8   func main() {                    
-  …   …   @@ -9,5 +10,6 @@                 
-  9  10   }                                
- 10  11                                    
- 11  12   func getContent() string {       
- 12     -     return "Hello, world!"       
-     13 +     content := strings.ToUpper("…
-     14 +     return content               
- 13  15   }                                
+  …   …   @@ -2,6 +2,7 @@                  
+  2   2                                    
+  3   3   import (                         
+  4   4       "fmt"                        
+      5 +     "strings"                    
+  5   6   )                                
+  6   7                                    
+  7   8   func main() {                    
+  …   …   @@ -9,5 +10,6 @@                 
+  9  10   }                                
+ 10  11                                    
+ 11  12   func getContent() string {       
+ 12     -     return "Hello, world!"       
+     13 +     content := strings.ToUpper("…
+     14 +     return content               
+ 13  15   }                                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf044.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                   
-  2   2                                     
-  3   3   import (                          
-  4   4       "fmt"                         
-      5 +     "strings"                     
-  5   6   )                                 
-  6   7                                     
-  7   8   func main() {                     
-  …   …   @@ -9,5 +10,6 @@                  
-  9  10   }                                 
- 10  11                                     
- 11  12   func getContent() string {        
- 12     -     return "Hello, world!"        
-     13 +     content := strings.ToUpper("H…
-     14 +     return content                
- 13  15   }                                 
+  …   …   @@ -2,6 +2,7 @@                   
+  2   2                                     
+  3   3   import (                          
+  4   4       "fmt"                         
+      5 +     "strings"                     
+  5   6   )                                 
+  6   7                                     
+  7   8   func main() {                     
+  …   …   @@ -9,5 +10,6 @@                  
+  9  10   }                                 
+ 10  11                                     
+ 11  12   func getContent() string {        
+ 12     -     return "Hello, world!"        
+     13 +     content := strings.ToUpper("H…
+     14 +     return content                
+ 13  15   }                                 

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf045.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                    
-  2   2                                      
-  3   3   import (                           
-  4   4       "fmt"                          
-      5 +     "strings"                      
-  5   6   )                                  
-  6   7                                      
-  7   8   func main() {                      
-  …   …   @@ -9,5 +10,6 @@                   
-  9  10   }                                  
- 10  11                                      
- 11  12   func getContent() string {         
- 12     -     return "Hello, world!"         
-     13 +     content := strings.ToUpper("He…
-     14 +     return content                 
- 13  15   }                                  
+  …   …   @@ -2,6 +2,7 @@                    
+  2   2                                      
+  3   3   import (                           
+  4   4       "fmt"                          
+      5 +     "strings"                      
+  5   6   )                                  
+  6   7                                      
+  7   8   func main() {                      
+  …   …   @@ -9,5 +10,6 @@                   
+  9  10   }                                  
+ 10  11                                      
+ 11  12   func getContent() string {         
+ 12     -     return "Hello, world!"         
+     13 +     content := strings.ToUpper("He…
+     14 +     return content                 
+ 13  15   }                                  

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf046.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                     
-  2   2                                       
-  3   3   import (                            
-  4   4       "fmt"                           
-      5 +     "strings"                       
-  5   6   )                                   
-  6   7                                       
-  7   8   func main() {                       
-  …   …   @@ -9,5 +10,6 @@                    
-  9  10   }                                   
- 10  11                                       
- 11  12   func getContent() string {          
- 12     -     return "Hello, world!"          
-     13 +     content := strings.ToUpper("Hel…
-     14 +     return content                  
- 13  15   }                                   
+  …   …   @@ -2,6 +2,7 @@                     
+  2   2                                       
+  3   3   import (                            
+  4   4       "fmt"                           
+      5 +     "strings"                       
+  5   6   )                                   
+  6   7                                       
+  7   8   func main() {                       
+  …   …   @@ -9,5 +10,6 @@                    
+  9  10   }                                   
+ 10  11                                       
+ 11  12   func getContent() string {          
+ 12     -     return "Hello, world!"          
+     13 +     content := strings.ToUpper("Hel…
+     14 +     return content                  
+ 13  15   }                                   

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf047.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                      
-  2   2                                        
-  3   3   import (                             
-  4   4       "fmt"                            
-      5 +     "strings"                        
-  5   6   )                                    
-  6   7                                        
-  7   8   func main() {                        
-  …   …   @@ -9,5 +10,6 @@                     
-  9  10   }                                    
- 10  11                                        
- 11  12   func getContent() string {           
- 12     -     return "Hello, world!"           
-     13 +     content := strings.ToUpper("Hell…
-     14 +     return content                   
- 13  15   }                                    
+  …   …   @@ -2,6 +2,7 @@                      
+  2   2                                        
+  3   3   import (                             
+  4   4       "fmt"                            
+      5 +     "strings"                        
+  5   6   )                                    
+  6   7                                        
+  7   8   func main() {                        
+  …   …   @@ -9,5 +10,6 @@                     
+  9  10   }                                    
+ 10  11                                        
+ 11  12   func getContent() string {           
+ 12     -     return "Hello, world!"           
+     13 +     content := strings.ToUpper("Hell…
+     14 +     return content                   
+ 13  15   }                                    

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf048.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                       
-  2   2                                         
-  3   3   import (                              
-  4   4       "fmt"                             
-      5 +     "strings"                         
-  5   6   )                                     
-  6   7                                         
-  7   8   func main() {                         
-  …   …   @@ -9,5 +10,6 @@                      
-  9  10   }                                     
- 10  11                                         
- 11  12   func getContent() string {            
- 12     -     return "Hello, world!"            
-     13 +     content := strings.ToUpper("Hello…
-     14 +     return content                    
- 13  15   }                                     
+  …   …   @@ -2,6 +2,7 @@                       
+  2   2                                         
+  3   3   import (                              
+  4   4       "fmt"                             
+      5 +     "strings"                         
+  5   6   )                                     
+  6   7                                         
+  7   8   func main() {                         
+  …   …   @@ -9,5 +10,6 @@                      
+  9  10   }                                     
+ 10  11                                         
+ 11  12   func getContent() string {            
+ 12     -     return "Hello, world!"            
+     13 +     content := strings.ToUpper("Hello…
+     14 +     return content                    
+ 13  15   }                                     

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf049.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                        
-  2   2                                          
-  3   3   import (                               
-  4   4       "fmt"                              
-      5 +     "strings"                          
-  5   6   )                                      
-  6   7                                          
-  7   8   func main() {                          
-  …   …   @@ -9,5 +10,6 @@                       
-  9  10   }                                      
- 10  11                                          
- 11  12   func getContent() string {             
- 12     -     return "Hello, world!"             
-     13 +     content := strings.ToUpper("Hello,…
-     14 +     return content                     
- 13  15   }                                      
+  …   …   @@ -2,6 +2,7 @@                        
+  2   2                                          
+  3   3   import (                               
+  4   4       "fmt"                              
+      5 +     "strings"                          
+  5   6   )                                      
+  6   7                                          
+  7   8   func main() {                          
+  …   …   @@ -9,5 +10,6 @@                       
+  9  10   }                                      
+ 10  11                                          
+ 11  12   func getContent() string {             
+ 12     -     return "Hello, world!"             
+     13 +     content := strings.ToUpper("Hello,…
+     14 +     return content                     
+ 13  15   }                                      

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf050.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                         
-  2   2                                           
-  3   3   import (                                
-  4   4       "fmt"                               
-      5 +     "strings"                           
-  5   6   )                                       
-  6   7                                           
-  7   8   func main() {                           
-  …   …   @@ -9,5 +10,6 @@                        
-  9  10   }                                       
- 10  11                                           
- 11  12   func getContent() string {              
- 12     -     return "Hello, world!"              
-     13 +     content := strings.ToUpper("Hello, …
-     14 +     return content                      
- 13  15   }                                       
+  …   …   @@ -2,6 +2,7 @@                         
+  2   2                                           
+  3   3   import (                                
+  4   4       "fmt"                               
+      5 +     "strings"                           
+  5   6   )                                       
+  6   7                                           
+  7   8   func main() {                           
+  …   …   @@ -9,5 +10,6 @@                        
+  9  10   }                                       
+ 10  11                                           
+ 11  12   func getContent() string {              
+ 12     -     return "Hello, world!"              
+     13 +     content := strings.ToUpper("Hello, …
+     14 +     return content                      
+ 13  15   }                                       

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf051.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                          
-  2   2                                            
-  3   3   import (                                 
-  4   4       "fmt"                                
-      5 +     "strings"                            
-  5   6   )                                        
-  6   7                                            
-  7   8   func main() {                            
-  …   …   @@ -9,5 +10,6 @@                         
-  9  10   }                                        
- 10  11                                            
- 11  12   func getContent() string {               
- 12     -     return "Hello, world!"               
-     13 +     content := strings.ToUpper("Hello, W…
-     14 +     return content                       
- 13  15   }                                        
+  …   …   @@ -2,6 +2,7 @@                          
+  2   2                                            
+  3   3   import (                                 
+  4   4       "fmt"                                
+      5 +     "strings"                            
+  5   6   )                                        
+  6   7                                            
+  7   8   func main() {                            
+  …   …   @@ -9,5 +10,6 @@                         
+  9  10   }                                        
+ 10  11                                            
+ 11  12   func getContent() string {               
+ 12     -     return "Hello, world!"               
+     13 +     content := strings.ToUpper("Hello, W…
+     14 +     return content                       
+ 13  15   }                                        

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf052.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                           
-  2   2                                             
-  3   3   import (                                  
-  4   4       "fmt"                                 
-      5 +     "strings"                             
-  5   6   )                                         
-  6   7                                             
-  7   8   func main() {                             
-  …   …   @@ -9,5 +10,6 @@                          
-  9  10   }                                         
- 10  11                                             
- 11  12   func getContent() string {                
- 12     -     return "Hello, world!"                
-     13 +     content := strings.ToUpper("Hello, Wo…
-     14 +     return content                        
- 13  15   }                                         
+  …   …   @@ -2,6 +2,7 @@                           
+  2   2                                             
+  3   3   import (                                  
+  4   4       "fmt"                                 
+      5 +     "strings"                             
+  5   6   )                                         
+  6   7                                             
+  7   8   func main() {                             
+  …   …   @@ -9,5 +10,6 @@                          
+  9  10   }                                         
+ 10  11                                             
+ 11  12   func getContent() string {                
+ 12     -     return "Hello, world!"                
+     13 +     content := strings.ToUpper("Hello, Wo…
+     14 +     return content                        
+ 13  15   }                                         

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf053.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                            
-  2   2                                              
-  3   3   import (                                   
-  4   4       "fmt"                                  
-      5 +     "strings"                              
-  5   6   )                                          
-  6   7                                              
-  7   8   func main() {                              
-  …   …   @@ -9,5 +10,6 @@                           
-  9  10   }                                          
- 10  11                                              
- 11  12   func getContent() string {                 
- 12     -     return "Hello, world!"                 
-     13 +     content := strings.ToUpper("Hello, Wor…
-     14 +     return content                         
- 13  15   }                                          
+  …   …   @@ -2,6 +2,7 @@                            
+  2   2                                              
+  3   3   import (                                   
+  4   4       "fmt"                                  
+      5 +     "strings"                              
+  5   6   )                                          
+  6   7                                              
+  7   8   func main() {                              
+  …   …   @@ -9,5 +10,6 @@                           
+  9  10   }                                          
+ 10  11                                              
+ 11  12   func getContent() string {                 
+ 12     -     return "Hello, world!"                 
+     13 +     content := strings.ToUpper("Hello, Wor…
+     14 +     return content                         
+ 13  15   }                                          

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf054.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                             
-  2   2                                               
-  3   3   import (                                    
-  4   4       "fmt"                                   
-      5 +     "strings"                               
-  5   6   )                                           
-  6   7                                               
-  7   8   func main() {                               
-  …   …   @@ -9,5 +10,6 @@                            
-  9  10   }                                           
- 10  11                                               
- 11  12   func getContent() string {                  
- 12     -     return "Hello, world!"                  
-     13 +     content := strings.ToUpper("Hello, Worl…
-     14 +     return content                          
- 13  15   }                                           
+  …   …   @@ -2,6 +2,7 @@                             
+  2   2                                               
+  3   3   import (                                    
+  4   4       "fmt"                                   
+      5 +     "strings"                               
+  5   6   )                                           
+  6   7                                               
+  7   8   func main() {                               
+  …   …   @@ -9,5 +10,6 @@                            
+  9  10   }                                           
+ 10  11                                               
+ 11  12   func getContent() string {                  
+ 12     -     return "Hello, world!"                  
+     13 +     content := strings.ToUpper("Hello, Worl…
+     14 +     return content                          
+ 13  15   }                                           

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf055.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                              
-  2   2                                                
-  3   3   import (                                     
-  4   4       "fmt"                                    
-      5 +     "strings"                                
-  5   6   )                                            
-  6   7                                                
-  7   8   func main() {                                
-  …   …   @@ -9,5 +10,6 @@                             
-  9  10   }                                            
- 10  11                                                
- 11  12   func getContent() string {                   
- 12     -     return "Hello, world!"                   
-     13 +     content := strings.ToUpper("Hello, World…
-     14 +     return content                           
- 13  15   }                                            
+  …   …   @@ -2,6 +2,7 @@                              
+  2   2                                                
+  3   3   import (                                     
+  4   4       "fmt"                                    
+      5 +     "strings"                                
+  5   6   )                                            
+  6   7                                                
+  7   8   func main() {                                
+  …   …   @@ -9,5 +10,6 @@                             
+  9  10   }                                            
+ 10  11                                                
+ 11  12   func getContent() string {                   
+ 12     -     return "Hello, world!"                   
+     13 +     content := strings.ToUpper("Hello, World…
+     14 +     return content                           
+ 13  15   }                                            

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf056.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                               
-  2   2                                                 
-  3   3   import (                                      
-  4   4       "fmt"                                     
-      5 +     "strings"                                 
-  5   6   )                                             
-  6   7                                                 
-  7   8   func main() {                                 
-  …   …   @@ -9,5 +10,6 @@                              
-  9  10   }                                             
- 10  11                                                 
- 11  12   func getContent() string {                    
- 12     -     return "Hello, world!"                    
-     13 +     content := strings.ToUpper("Hello, World!…
-     14 +     return content                            
- 13  15   }                                             
+  …   …   @@ -2,6 +2,7 @@                               
+  2   2                                                 
+  3   3   import (                                      
+  4   4       "fmt"                                     
+      5 +     "strings"                                 
+  5   6   )                                             
+  6   7                                                 
+  7   8   func main() {                                 
+  …   …   @@ -9,5 +10,6 @@                              
+  9  10   }                                             
+ 10  11                                                 
+ 11  12   func getContent() string {                    
+ 12     -     return "Hello, world!"                    
+     13 +     content := strings.ToUpper("Hello, World!…
+     14 +     return content                            
+ 13  15   }                                             

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf057.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                
-  2   2                                                  
-  3   3   import (                                       
-  4   4       "fmt"                                      
-      5 +     "strings"                                  
-  5   6   )                                              
-  6   7                                                  
-  7   8   func main() {                                  
-  …   …   @@ -9,5 +10,6 @@                               
-  9  10   }                                              
- 10  11                                                  
- 11  12   func getContent() string {                     
- 12     -     return "Hello, world!"                     
-     13 +     content := strings.ToUpper("Hello, World!")
-     14 +     return content                             
- 13  15   }                                              
+  …   …   @@ -2,6 +2,7 @@                                
+  2   2                                                  
+  3   3   import (                                       
+  4   4       "fmt"                                      
+      5 +     "strings"                                  
+  5   6   )                                              
+  6   7                                                  
+  7   8   func main() {                                  
+  …   …   @@ -9,5 +10,6 @@                               
+  9  10   }                                              
+ 10  11                                                  
+ 11  12   func getContent() string {                     
+ 12     -     return "Hello, world!"                     
+     13 +     content := strings.ToUpper("Hello, World!")
+     14 +     return content                             
+ 13  15   }                                              

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf058.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf059.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                  
-  2   2                                                    
-  3   3   import (                                         
-  4   4       "fmt"                                        
-      5 +     "strings"                                    
-  5   6   )                                                
-  6   7                                                    
-  7   8   func main() {                                    
-  …   …   @@ -9,5 +10,6 @@                                 
-  9  10   }                                                
- 10  11                                                    
- 11  12   func getContent() string {                       
- 12     -     return "Hello, world!"                       
-     13 +     content := strings.ToUpper("Hello, World!")  
-     14 +     return content                               
- 13  15   }                                                
+  …   …   @@ -2,6 +2,7 @@                                  
+  2   2                                                    
+  3   3   import (                                         
+  4   4       "fmt"                                        
+      5 +     "strings"                                    
+  5   6   )                                                
+  6   7                                                    
+  7   8   func main() {                                    
+  …   …   @@ -9,5 +10,6 @@                                 
+  9  10   }                                                
+ 10  11                                                    
+ 11  12   func getContent() string {                       
+ 12     -     return "Hello, world!"                       
+     13 +     content := strings.ToUpper("Hello, World!")  
+     14 +     return content                               
+ 13  15   }                                                

internal/tui/exp/diffview/testdata/TestDiffViewWidth/Unified/WidthOf060.golden 🔗

@@ -1,16 +1,16 @@
-  …   …   @@ -2,6 +2,7 @@                                   
-  2   2                                                     
-  3   3   import (                                          
-  4   4       "fmt"                                         
-      5 +     "strings"                                     
-  5   6   )                                                 
-  6   7                                                     
-  7   8   func main() {                                     
-  …   …   @@ -9,5 +10,6 @@                                  
-  9  10   }                                                 
- 10  11                                                     
- 11  12   func getContent() string {                        
- 12     -     return "Hello, world!"                        
-     13 +     content := strings.ToUpper("Hello, World!")   
-     14 +     return content                                
- 13  15   }                                                 
+  …   …   @@ -2,6 +2,7 @@                                   
+  2   2                                                     
+  3   3   import (                                          
+  4   4       "fmt"                                         
+      5 +     "strings"                                     
+  5   6   )                                                 
+  6   7                                                     
+  7   8   func main() {                                     
+  …   …   @@ -9,5 +10,6 @@                                  
+  9  10   }                                                 
+ 10  11                                                     
+ 11  12   func getContent() string {                        
+ 12     -     return "Hello, world!"                        
+     13 +     content := strings.ToUpper("Hello, World!")   
+     14 +     return content                                
+ 13  15   }                                                 

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf00.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5   )                         5   )                       
-  6                             6                           
-  7   func main() {             7   func main() {           
-  8 -     fmt.Println("Hello,…  8 +     content := "Hello, …
-                                9 +     fmt.Println(content)
-  9   }                        10   }                       
+  …   @@ -5,5 +5,6 @@           …                           
+  5   )                         5   )                       
+  6                             6                           
+  7   func main() {             7   func main() {           
+  8 -     fmt.Println("Hello,…  8 +     content := "Hello, …
+                                9 +     fmt.Println(content)
+  9   }                        10   }                       

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf01.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …unc main() {              7  …unc main() {            
-  8 -…   fmt.Println("Hello, …  8 +…   content := "Hello, w…
-                                9 +…   fmt.Println(content) 
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …unc main() {              7  …unc main() {            
+  8 -…   fmt.Println("Hello, …  8 +…   content := "Hello, w…
+                                9 +…   fmt.Println(content) 
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf02.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …nc main() {               7  …nc main() {             
-  8 -…  fmt.Println("Hello, w…  8 +…  content := "Hello, wo…
-                                9 +…  fmt.Println(content)  
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …nc main() {               7  …nc main() {             
+  8 -…  fmt.Println("Hello, w…  8 +…  content := "Hello, wo…
+                                9 +…  fmt.Println(content)  
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf03.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …c main() {                7  …c main() {              
-  8 -… fmt.Println("Hello, wo…  8 +… content := "Hello, wor…
-                                9 +… fmt.Println(content)   
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …c main() {                7  …c main() {              
+  8 -… fmt.Println("Hello, wo…  8 +… content := "Hello, wor…
+                                9 +… fmt.Println(content)   
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf04.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  … main() {                 7  … main() {               
-  8 -…fmt.Println("Hello, wor…  8 +…content := "Hello, worl…
-                                9 +…fmt.Println(content)    
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  … main() {                 7  … main() {               
+  8 -…fmt.Println("Hello, wor…  8 +…content := "Hello, worl…
+                                9 +…fmt.Println(content)    
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf05.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …main() {                  7  …main() {                
-  8 -…mt.Println("Hello, worl…  8 +…ontent := "Hello, world…
-                                9 +…mt.Println(content)     
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …main() {                  7  …main() {                
+  8 -…mt.Println("Hello, worl…  8 +…ontent := "Hello, world…
+                                9 +…mt.Println(content)     
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf06.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …ain() {                   7  …ain() {                 
-  8 -…t.Println("Hello, world…  8 +…ntent := "Hello, world!"
-                                9 +…t.Println(content)      
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …ain() {                   7  …ain() {                 
+  8 -…t.Println("Hello, world…  8 +…ntent := "Hello, world!"
+                                9 +…t.Println(content)      
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf07.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …in() {                    7  …in() {                  
-  8 -….Println("Hello, world!…  8 +…tent := "Hello, world!" 
-                                9 +….Println(content)       
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …in() {                    7  …in() {                  
+  8 -….Println("Hello, world!…  8 +…tent := "Hello, world!" 
+                                9 +….Println(content)       
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf08.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …n() {                     7  …n() {                   
-  8 -…Println("Hello, world!")  8 +…ent := "Hello, world!"  
-                                9 +…Println(content)        
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …n() {                     7  …n() {                   
+  8 -…Println("Hello, world!")  8 +…ent := "Hello, world!"  
+                                9 +…Println(content)        
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf09.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …() {                      7  …() {                    
-  8 -…rintln("Hello, world!")   8 +…nt := "Hello, world!"   
-                                9 +…rintln(content)         
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …() {                      7  …() {                    
+  8 -…rintln("Hello, world!")   8 +…nt := "Hello, world!"   
+                                9 +…rintln(content)         
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf10.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …) {                       7  …) {                     
-  8 -…intln("Hello, world!")    8 +…t := "Hello, world!"    
-                                9 +…intln(content)          
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …) {                       7  …) {                     
+  8 -…intln("Hello, world!")    8 +…t := "Hello, world!"    
+                                9 +…intln(content)          
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf11.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  … {                        7  … {                      
-  8 -…ntln("Hello, world!")     8 +… := "Hello, world!"     
-                                9 +…ntln(content)           
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  … {                        7  … {                      
+  8 -…ntln("Hello, world!")     8 +… := "Hello, world!"     
+                                9 +…ntln(content)           
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf12.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …{                         7  …{                       
-  8 -…tln("Hello, world!")      8 +…:= "Hello, world!"      
-                                9 +…tln(content)            
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …{                         7  …{                       
+  8 -…tln("Hello, world!")      8 +…:= "Hello, world!"      
+                                9 +…tln(content)            
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf13.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…ln("Hello, world!")       8 +…= "Hello, world!"       
-                                9 +…ln(content)             
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…ln("Hello, world!")       8 +…= "Hello, world!"       
+                                9 +…ln(content)             
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf14.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…n("Hello, world!")        8 +… "Hello, world!"        
-                                9 +…n(content)              
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…n("Hello, world!")        8 +… "Hello, world!"        
+                                9 +…n(content)              
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf15.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…("Hello, world!")         8 +…"Hello, world!"         
-                                9 +…(content)               
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…("Hello, world!")         8 +…"Hello, world!"         
+                                9 +…(content)               
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf16.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…"Hello, world!")          8 +…Hello, world!"          
-                                9 +…content)                
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…"Hello, world!")          8 +…Hello, world!"          
+                                9 +…content)                
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf17.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…Hello, world!")           8 +…ello, world!"           
-                                9 +…ontent)                 
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…Hello, world!")           8 +…ello, world!"           
+                                9 +…ontent)                 
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf18.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…ello, world!")            8 +…llo, world!"            
-                                9 +…ntent)                  
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…ello, world!")            8 +…llo, world!"            
+                                9 +…ntent)                  
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf19.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…llo, world!")             8 +…lo, world!"             
-                                9 +…tent)                   
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…llo, world!")             8 +…lo, world!"             
+                                9 +…tent)                   
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Split/XOffsetOf20.golden 🔗

@@ -1,7 +1,7 @@
-  …   @@ -5,5 +5,6 @@           …                           
-  5  …                          5  …                        
-  6                             6                           
-  7  …                          7  …                        
-  8 -…lo, world!")              8 +…o, world!"              
-                                9 +…ent)                    
-  9  …                         10  …                        
+  …   @@ -5,5 +5,6 @@           …                           
+  5  …                          5  …                        
+  6                             6                           
+  7  …                          7  …                        
+  8 -…lo, world!")              8 +…o, world!"              
+                                9 +…ent)                    
+  9  …                         10  …                        

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf00.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5   )                                                 
-  6   6                                                     
-  7   7   func main() {                                     
-  8     -     fmt.Println("Hello, world!")                  
-      8 +     content := "Hello, world!"                    
-      9 +     fmt.Println(content)                          
-  9  10   }                                                 
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5   )                                                 
+  6   6                                                     
+  7   7   func main() {                                     
+  8     -     fmt.Println("Hello, world!")                  
+      8 +     content := "Hello, world!"                    
+      9 +     fmt.Println(content)                          
+  9  10   }                                                 

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf01.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …unc main() {                                      
-  8     -…   fmt.Println("Hello, world!")                   
-      8 +…   content := "Hello, world!"                     
-      9 +…   fmt.Println(content)                           
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …unc main() {                                      
+  8     -…   fmt.Println("Hello, world!")                   
+      8 +…   content := "Hello, world!"                     
+      9 +…   fmt.Println(content)                           
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf02.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …nc main() {                                       
-  8     -…  fmt.Println("Hello, world!")                    
-      8 +…  content := "Hello, world!"                      
-      9 +…  fmt.Println(content)                            
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …nc main() {                                       
+  8     -…  fmt.Println("Hello, world!")                    
+      8 +…  content := "Hello, world!"                      
+      9 +…  fmt.Println(content)                            
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf03.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …c main() {                                        
-  8     -… fmt.Println("Hello, world!")                     
-      8 +… content := "Hello, world!"                       
-      9 +… fmt.Println(content)                             
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …c main() {                                        
+  8     -… fmt.Println("Hello, world!")                     
+      8 +… content := "Hello, world!"                       
+      9 +… fmt.Println(content)                             
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf04.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  … main() {                                         
-  8     -…fmt.Println("Hello, world!")                      
-      8 +…content := "Hello, world!"                        
-      9 +…fmt.Println(content)                              
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  … main() {                                         
+  8     -…fmt.Println("Hello, world!")                      
+      8 +…content := "Hello, world!"                        
+      9 +…fmt.Println(content)                              
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf05.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …main() {                                          
-  8     -…mt.Println("Hello, world!")                       
-      8 +…ontent := "Hello, world!"                         
-      9 +…mt.Println(content)                               
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …main() {                                          
+  8     -…mt.Println("Hello, world!")                       
+      8 +…ontent := "Hello, world!"                         
+      9 +…mt.Println(content)                               
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf06.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …ain() {                                           
-  8     -…t.Println("Hello, world!")                        
-      8 +…ntent := "Hello, world!"                          
-      9 +…t.Println(content)                                
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …ain() {                                           
+  8     -…t.Println("Hello, world!")                        
+      8 +…ntent := "Hello, world!"                          
+      9 +…t.Println(content)                                
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf07.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …in() {                                            
-  8     -….Println("Hello, world!")                         
-      8 +…tent := "Hello, world!"                           
-      9 +….Println(content)                                 
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …in() {                                            
+  8     -….Println("Hello, world!")                         
+      8 +…tent := "Hello, world!"                           
+      9 +….Println(content)                                 
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf08.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …n() {                                             
-  8     -…Println("Hello, world!")                          
-      8 +…ent := "Hello, world!"                            
-      9 +…Println(content)                                  
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …n() {                                             
+  8     -…Println("Hello, world!")                          
+      8 +…ent := "Hello, world!"                            
+      9 +…Println(content)                                  
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf09.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …() {                                              
-  8     -…rintln("Hello, world!")                           
-      8 +…nt := "Hello, world!"                             
-      9 +…rintln(content)                                   
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …() {                                              
+  8     -…rintln("Hello, world!")                           
+      8 +…nt := "Hello, world!"                             
+      9 +…rintln(content)                                   
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf10.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …) {                                               
-  8     -…intln("Hello, world!")                            
-      8 +…t := "Hello, world!"                              
-      9 +…intln(content)                                    
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …) {                                               
+  8     -…intln("Hello, world!")                            
+      8 +…t := "Hello, world!"                              
+      9 +…intln(content)                                    
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf11.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  … {                                                
-  8     -…ntln("Hello, world!")                             
-      8 +… := "Hello, world!"                               
-      9 +…ntln(content)                                     
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  … {                                                
+  8     -…ntln("Hello, world!")                             
+      8 +… := "Hello, world!"                               
+      9 +…ntln(content)                                     
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf12.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …{                                                 
-  8     -…tln("Hello, world!")                              
-      8 +…:= "Hello, world!"                                
-      9 +…tln(content)                                      
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …{                                                 
+  8     -…tln("Hello, world!")                              
+      8 +…:= "Hello, world!"                                
+      9 +…tln(content)                                      
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf13.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…ln("Hello, world!")                               
-      8 +…= "Hello, world!"                                 
-      9 +…ln(content)                                       
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…ln("Hello, world!")                               
+      8 +…= "Hello, world!"                                 
+      9 +…ln(content)                                       
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf14.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…n("Hello, world!")                                
-      8 +… "Hello, world!"                                  
-      9 +…n(content)                                        
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…n("Hello, world!")                                
+      8 +… "Hello, world!"                                  
+      9 +…n(content)                                        
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf15.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…("Hello, world!")                                 
-      8 +…"Hello, world!"                                   
-      9 +…(content)                                         
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…("Hello, world!")                                 
+      8 +…"Hello, world!"                                   
+      9 +…(content)                                         
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf16.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…"Hello, world!")                                  
-      8 +…Hello, world!"                                    
-      9 +…content)                                          
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…"Hello, world!")                                  
+      8 +…Hello, world!"                                    
+      9 +…content)                                          
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf17.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…Hello, world!")                                   
-      8 +…ello, world!"                                     
-      9 +…ontent)                                           
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…Hello, world!")                                   
+      8 +…ello, world!"                                     
+      9 +…ontent)                                           
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf18.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…ello, world!")                                    
-      8 +…llo, world!"                                      
-      9 +…ntent)                                            
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…ello, world!")                                    
+      8 +…llo, world!"                                      
+      9 +…ntent)                                            
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf19.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…llo, world!")                                     
-      8 +…lo, world!"                                       
-      9 +…tent)                                             
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…llo, world!")                                     
+      8 +…lo, world!"                                       
+      9 +…tent)                                             
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewXOffset/Unified/XOffsetOf20.golden 🔗

@@ -1,8 +1,8 @@
-  …   …   @@ -5,5 +5,6 @@                                   
-  5   5  …                                                  
-  6   6                                                     
-  7   7  …                                                  
-  8     -…lo, world!")                                      
-      8 +…o, world!"                                        
-      9 +…ent)                                              
-  9  10  …                                                  
+  …   …   @@ -5,5 +5,6 @@                                   
+  5   5  …                                                  
+  6   6                                                     
+  7   7  …                                                  
+  8     -…lo, world!")                                      
+      8 +…o, world!"                                        
+      9 +…ent)                                              
+  9  10  …                                                  

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf00.golden 🔗

@@ -1,5 +1,5 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf01.golden 🔗

@@ -1,5 +1,5 @@
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  …   …                                                 …   …                                               
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf02.golden 🔗

@@ -1,5 +1,5 @@
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  …   …                                                 …   …                                               
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf03.golden 🔗

@@ -1,5 +1,5 @@
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  …   …                                                 …   …                                               
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf04.golden 🔗

@@ -1,5 +1,5 @@
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf05.golden 🔗

@@ -1,5 +1,5 @@
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  …   …                                                 …   …                                               
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf06.golden 🔗

@@ -1,5 +1,5 @@
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
-  …   …                                                 …   …                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf07.golden 🔗

@@ -1,5 +1,5 @@
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
-  …   …                                                 …   …                                               
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf08.golden 🔗

@@ -1,5 +1,5 @@
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
-  …   …                                                 …   …                                               
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf09.golden 🔗

@@ -1,5 +1,5 @@
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf10.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf11.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf12.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf13.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf14.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf15.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Split/YOffsetOf16.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf00.golden 🔗

@@ -1,5 +1,5 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf01.golden 🔗

@@ -1,5 +1,5 @@
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  …   …   …                                               
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf02.golden 🔗

@@ -1,5 +1,5 @@
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  …   …   …                                               
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf03.golden 🔗

@@ -1,5 +1,5 @@
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  …   …   …                                               
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf04.golden 🔗

@@ -1,5 +1,5 @@
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf05.golden 🔗

@@ -1,5 +1,5 @@
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  …   …   …                                               
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf06.golden 🔗

@@ -1,5 +1,5 @@
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
-  …   …   …                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf07.golden 🔗

@@ -1,5 +1,5 @@
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
-  …   …   …                                               
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf08.golden 🔗

@@ -1,5 +1,5 @@
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
-  …   …   …                                               
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf09.golden 🔗

@@ -1,5 +1,5 @@
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-  …   …   …                                               
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf10.golden 🔗

@@ -1,5 +1,5 @@
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-  …   …   …                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf11.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf12.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf13.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf14.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf15.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffset/Unified/YOffsetOf16.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf00.golden 🔗

@@ -1,5 +1,5 @@
-  …   @@ -2,6 +2,7 @@                                   …                                                   
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-  …   …                                                 …   …                                               
+  …   @@ -2,6 +2,7 @@                                   …                                                   
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf01.golden 🔗

@@ -1,5 +1,5 @@
-  2                                                     2                                                   
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  …   …                                                 …   …                                               
+  2                                                     2                                                   
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf02.golden 🔗

@@ -1,5 +1,5 @@
-  3   import (                                          3   import (                                        
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  …   …                                                 …   …                                               
+  3   import (                                          3   import (                                        
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf03.golden 🔗

@@ -1,5 +1,5 @@
-  4       "fmt"                                         4       "fmt"                                       
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  …   …                                                 …   …                                               
+  4       "fmt"                                         4       "fmt"                                       
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf04.golden 🔗

@@ -1,5 +1,5 @@
-                                                        5 +     "strings"                                   
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
+                                                        5 +     "strings"                                   
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf05.golden 🔗

@@ -1,5 +1,5 @@
-  5   )                                                 6   )                                               
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  …   …                                                 …   …                                               
+  5   )                                                 6   )                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf06.golden 🔗

@@ -1,5 +1,5 @@
-  6                                                     7                                                   
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
-  …   …                                                 …   …                                               
+  6                                                     7                                                   
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf07.golden 🔗

@@ -1,5 +1,5 @@
-  7   func main() {                                     8   func main() {                                   
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
-  …   …                                                 …   …                                               
+  7   func main() {                                     8   func main() {                                   
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf08.golden 🔗

@@ -1,5 +1,5 @@
-  …   @@ -9,5 +10,6 @@                                  …                                                   
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      
-  …   …                                                 …   …                                               
+  …   @@ -9,5 +10,6 @@                                  …                                                   
+  9   }                                                10   }                                               
+ 10                                                    11                                                   
+ 11   func getContent() string {                       12   func getContent() string {                      
+  …   …                                                 …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf09.golden 🔗

@@ -1,5 +1,5 @@
-  9   }                                                10   }                                               
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf10.golden 🔗

@@ -1,5 +1,5 @@
- 10                                                    11                                                   
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf11.golden 🔗

@@ -1,5 +1,5 @@
- 11   func getContent() string {                       12   func getContent() string {                      

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf13.golden 🔗

@@ -1,5 +1,5 @@
-                                                       14 +     return content                              
- 13   }                                                15   }                                               
-                                                                                                            
-                                                                                                            
-                                                                                                            
+                                                       14 +     return content                              
+ 13   }                                                15   }                                               
+                                                                                                            
+                                                                                                            
+                                                                                                            

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf14.golden 🔗

@@ -1,5 +1,5 @@
- 13   }                                                15   }                                               
-                                                                                                            
-                                                                                                            
-                                                                                                            
-                                                                                                            
+ 13   }                                                15   }                                               
+                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf15.golden 🔗

@@ -1,5 +1,5 @@
-                                                                                                            
-                                                                                                            
-                                                                                                            
-                                                                                                            
-                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Split/YOffsetOf16.golden 🔗

@@ -1,5 +1,5 @@
-                                                                                                            
-                                                                                                            
-                                                                                                            
-                                                                                                            
-                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            
+                                                                                                            

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf00.golden 🔗

@@ -1,5 +1,5 @@
-  …   …   @@ -2,6 +2,7 @@                                 
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-  …   …   …                                               
+  …   …   @@ -2,6 +2,7 @@                                 
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf01.golden 🔗

@@ -1,5 +1,5 @@
-  2   2                                                   
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  …   …   …                                               
+  2   2                                                   
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf02.golden 🔗

@@ -1,5 +1,5 @@
-  3   3   import (                                        
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  …   …   …                                               
+  3   3   import (                                        
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf03.golden 🔗

@@ -1,5 +1,5 @@
-  4   4       "fmt"                                       
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  …   …   …                                               
+  4   4       "fmt"                                       
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf04.golden 🔗

@@ -1,5 +1,5 @@
-      5 +     "strings"                                   
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
+      5 +     "strings"                                   
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf05.golden 🔗

@@ -1,5 +1,5 @@
-  5   6   )                                               
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  …   …   …                                               
+  5   6   )                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf06.golden 🔗

@@ -1,5 +1,5 @@
-  6   7                                                   
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
-  …   …   …                                               
+  6   7                                                   
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf07.golden 🔗

@@ -1,5 +1,5 @@
-  7   8   func main() {                                   
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
-  …   …   …                                               
+  7   8   func main() {                                   
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf08.golden 🔗

@@ -1,5 +1,5 @@
-  …   …   @@ -9,5 +10,6 @@                                
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
-  …   …   …                                               
+  …   …   @@ -9,5 +10,6 @@                                
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf09.golden 🔗

@@ -1,5 +1,5 @@
-  9  10   }                                               
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-  …   …   …                                               
+  9  10   }                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf10.golden 🔗

@@ -1,5 +1,5 @@
- 10  11                                                   
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-  …   …   …                                               
+ 10  11                                                   
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+  …   …   …                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf11.golden 🔗

@@ -1,5 +1,5 @@
- 11  12   func getContent() string {                      
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
+ 11  12   func getContent() string {                      
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf12.golden 🔗

@@ -1,5 +1,5 @@
- 12     -     return "Hello, world!"                      
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
-                                                          
+ 12     -     return "Hello, world!"                      
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf13.golden 🔗

@@ -1,5 +1,5 @@
-     13 +     content := strings.ToUpper("Hello, World!") 
-     14 +     return content                              
- 13  15   }                                               
-                                                          
-                                                          
+     13 +     content := strings.ToUpper("Hello, World!") 
+     14 +     return content                              
+ 13  15   }                                               
+                                                          
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf14.golden 🔗

@@ -1,5 +1,5 @@
-     14 +     return content                              
- 13  15   }                                               
-                                                          
-                                                          
-                                                          
+     14 +     return content                              
+ 13  15   }                                               
+                                                          
+                                                          
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf15.golden 🔗

@@ -1,5 +1,5 @@
- 13  15   }                                               
-                                                          
-                                                          
-                                                          
-                                                          
+ 13  15   }                                               
+                                                          
+                                                          
+                                                          
+                                                          

internal/tui/exp/diffview/testdata/TestDiffViewYOffsetInfinite/Unified/YOffsetOf16.golden 🔗

@@ -1,5 +1,5 @@
-                                                          
-                                                          
-                                                          
-                                                          
-                                                          
+                                                          
+                                                          
+                                                          
+                                                          
+                                                          

internal/tui/keys.go 🔗

@@ -20,8 +20,8 @@ func DefaultKeyMap() KeyMap {
 			key.WithHelp("ctrl+c", "quit"),
 		),
 		Help: key.NewBinding(
-			key.WithKeys("ctrl+?", "ctrl+_", "ctrl+/"),
-			key.WithHelp("ctrl+?", "more"),
+			key.WithKeys("ctrl+g"),
+			key.WithHelp("ctrl+g", "more"),
 		),
 		Commands: key.NewBinding(
 			key.WithKeys("ctrl+p"),
@@ -33,62 +33,3 @@ func DefaultKeyMap() KeyMap {
 		),
 	}
 }
-
-// FullHelp implements help.KeyMap.
-func (k KeyMap) FullHelp() [][]key.Binding {
-	m := [][]key.Binding{}
-	slice := []key.Binding{
-		k.Commands,
-		k.Sessions,
-		k.Quit,
-		k.Help,
-	}
-	slice = k.prependEscAndTab(slice)
-	slice = append(slice, k.pageBindings...)
-	// remove duplicates
-	seen := make(map[string]bool)
-	cleaned := []key.Binding{}
-	for _, b := range slice {
-		if !seen[b.Help().Key] {
-			seen[b.Help().Key] = true
-			cleaned = append(cleaned, b)
-		}
-	}
-
-	for i := 0; i < len(cleaned); i += 3 {
-		end := min(i+3, len(cleaned))
-		m = append(m, cleaned[i:end])
-	}
-	return m
-}
-
-func (k KeyMap) prependEscAndTab(bindings []key.Binding) []key.Binding {
-	var cancel key.Binding
-	var tab key.Binding
-	for _, b := range k.pageBindings {
-		if b.Help().Key == "esc" {
-			cancel = b
-		}
-		if b.Help().Key == "tab" {
-			tab = b
-		}
-	}
-	if tab.Help().Key != "" {
-		bindings = append([]key.Binding{tab}, bindings...)
-	}
-	if cancel.Help().Key != "" {
-		bindings = append([]key.Binding{cancel}, bindings...)
-	}
-	return bindings
-}
-
-// ShortHelp implements help.KeyMap.
-func (k KeyMap) ShortHelp() []key.Binding {
-	bindings := []key.Binding{
-		k.Commands,
-		k.Sessions,
-		k.Quit,
-		k.Help,
-	}
-	return k.prependEscAndTab(bindings)
-}

internal/tui/page/chat/chat.go 🔗

@@ -2,21 +2,29 @@ package chat
 
 import (
 	"context"
-	"strings"
 	"time"
 
+	"github.com/charmbracelet/bubbles/v2/help"
 	"github.com/charmbracelet/bubbles/v2/key"
+	"github.com/charmbracelet/bubbles/v2/spinner"
 	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/charmbracelet/crush/internal/app"
 	"github.com/charmbracelet/crush/internal/config"
+	"github.com/charmbracelet/crush/internal/history"
 	"github.com/charmbracelet/crush/internal/message"
+	"github.com/charmbracelet/crush/internal/pubsub"
 	"github.com/charmbracelet/crush/internal/session"
+	"github.com/charmbracelet/crush/internal/tui/components/anim"
 	"github.com/charmbracelet/crush/internal/tui/components/chat"
 	"github.com/charmbracelet/crush/internal/tui/components/chat/editor"
 	"github.com/charmbracelet/crush/internal/tui/components/chat/header"
 	"github.com/charmbracelet/crush/internal/tui/components/chat/sidebar"
+	"github.com/charmbracelet/crush/internal/tui/components/chat/splash"
+	"github.com/charmbracelet/crush/internal/tui/components/completions"
+	"github.com/charmbracelet/crush/internal/tui/components/core"
 	"github.com/charmbracelet/crush/internal/tui/components/core/layout"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/commands"
+	"github.com/charmbracelet/crush/internal/tui/components/dialogs/filepicker"
 	"github.com/charmbracelet/crush/internal/tui/page"
 	"github.com/charmbracelet/crush/internal/tui/styles"
 	"github.com/charmbracelet/crush/internal/tui/util"
@@ -26,150 +34,223 @@ import (
 
 var ChatPageID page.PageID = "chat"
 
-const CompactModeBreakpoint = 120 // Width at which the chat page switches to compact mode
-
 type (
 	OpenFilePickerMsg struct{}
 	ChatFocusedMsg    struct {
-		Focused bool // True if the chat input is focused, false otherwise
+		Focused bool
 	}
 	CancelTimerExpiredMsg struct{}
 )
 
+type PanelType string
+
+const (
+	PanelTypeChat   PanelType = "chat"
+	PanelTypeEditor PanelType = "editor"
+	PanelTypeSplash PanelType = "splash"
+)
+
+const (
+	CompactModeBreakpoint = 120 // Width at which the chat page switches to compact mode
+	EditorHeight          = 5   // Height of the editor input area including padding
+	SideBarWidth          = 31  // Width of the sidebar
+	SideBarDetailsPadding = 1   // Padding for the sidebar details section
+	HeaderHeight          = 1   // Height of the header
+
+	// Layout constants for borders and padding
+	BorderWidth        = 1 // Width of component borders
+	LeftRightBorders   = 2 // Left + right border width (1 + 1)
+	TopBottomBorders   = 2 // Top + bottom border width (1 + 1)
+	DetailsPositioning = 2 // Positioning adjustment for details panel
+
+	// Timing constants
+	CancelTimerDuration = 2 * time.Second // Duration before cancel timer expires
+)
+
 type ChatPage interface {
 	util.Model
 	layout.Help
 	IsChatFocused() bool
 }
 
+// cancelTimerCmd creates a command that expires the cancel timer
+func cancelTimerCmd() tea.Cmd {
+	return tea.Tick(CancelTimerDuration, func(time.Time) tea.Msg {
+		return CancelTimerExpiredMsg{}
+	})
+}
+
 type chatPage struct {
-	wWidth, wHeight int // Window dimensions
-	app             *app.App
+	width, height               int
+	detailsWidth, detailsHeight int
+	app                         *app.App
+	keyboardEnhancements        tea.KeyboardEnhancementsMsg
 
-	layout layout.SplitPaneLayout
+	// Layout state
+	compact      bool
+	forceCompact bool
+	focusedPane  PanelType
 
+	// Session
 	session session.Session
+	keyMap  KeyMap
+
+	// Components
+	header  header.Header
+	sidebar sidebar.Sidebar
+	chat    chat.MessageListCmp
+	editor  editor.Editor
+	splash  splash.Splash
+
+	// Simple state flags
+	showingDetails   bool
+	isCanceling      bool
+	splashFullScreen bool
+	isOnboarding     bool
+	isProjectInit    bool
+}
 
-	keyMap KeyMap
-
-	chatFocused bool
-
-	compactMode      bool
-	forceCompactMode bool // Force compact mode regardless of window size
-	showDetails      bool // Show details in the header
-	header           header.Header
-	compactSidebar   layout.Container
-
-	cancelPending bool // True if ESC was pressed once and waiting for second press
+func New(app *app.App) ChatPage {
+	return &chatPage{
+		app:         app,
+		keyMap:      DefaultKeyMap(),
+		header:      header.New(app.LSPClients),
+		sidebar:     sidebar.New(app.History, app.LSPClients, false),
+		chat:        chat.New(app),
+		editor:      editor.New(app),
+		splash:      splash.New(),
+		focusedPane: PanelTypeSplash,
+	}
 }
 
 func (p *chatPage) Init() tea.Cmd {
+	cfg := config.Get()
+	compact := cfg.Options.TUI.CompactMode
+	p.compact = compact
+	p.forceCompact = compact
+	p.sidebar.SetCompactMode(p.compact)
+
+	// Set splash state based on config
+	if !config.HasInitialDataConfig() {
+		// First-time setup: show model selection
+		p.splash.SetOnboarding(true)
+		p.isOnboarding = true
+		p.splashFullScreen = true
+	} else if b, _ := config.ProjectNeedsInitialization(); b {
+		// Project needs CRUSH.md initialization
+		p.splash.SetProjectInit(true)
+		p.isProjectInit = true
+		p.splashFullScreen = true
+	} else {
+		// Ready to chat: focus editor, splash in background
+		p.focusedPane = PanelTypeEditor
+		p.splashFullScreen = false
+	}
+
 	return tea.Batch(
-		p.layout.Init(),
-		p.compactSidebar.Init(),
-		p.layout.FocusPanel(layout.BottomPanel), // Focus on the bottom panel (editor),
+		p.header.Init(),
+		p.sidebar.Init(),
+		p.chat.Init(),
+		p.editor.Init(),
+		p.splash.Init(),
 	)
 }
 
-// cancelTimerCmd creates a command that expires the cancel timer after 2 seconds
-func (p *chatPage) cancelTimerCmd() tea.Cmd {
-	return tea.Tick(2*time.Second, func(time.Time) tea.Msg {
-		return CancelTimerExpiredMsg{}
-	})
-}
-
 func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 	var cmds []tea.Cmd
 	switch msg := msg.(type) {
-	case CancelTimerExpiredMsg:
-		p.cancelPending = false
+	case tea.KeyboardEnhancementsMsg:
+		p.keyboardEnhancements = msg
 		return p, nil
 	case tea.WindowSizeMsg:
-		h, cmd := p.header.Update(msg)
-		cmds = append(cmds, cmd)
-		p.header = h.(header.Header)
-		cmds = append(cmds, p.compactSidebar.SetSize(msg.Width-4, 0))
-		// the mode is only relevant when there is a  session
-		if p.session.ID != "" {
-			// Only auto-switch to compact mode if not forced
-			if !p.forceCompactMode {
-				if msg.Width <= CompactModeBreakpoint && p.wWidth > CompactModeBreakpoint {
-					p.wWidth = msg.Width
-					p.wHeight = msg.Height
-					cmds = append(cmds, p.setCompactMode(true))
-					return p, tea.Batch(cmds...)
-				} else if msg.Width > CompactModeBreakpoint && p.wWidth <= CompactModeBreakpoint {
-					p.wWidth = msg.Width
-					p.wHeight = msg.Height
-					return p, p.setCompactMode(false)
-				}
-			}
-		}
-		p.wWidth = msg.Width
-		p.wHeight = msg.Height
-		layoutHeight := msg.Height
-		if p.compactMode {
-			// make space for the header
-			layoutHeight -= 1
+		return p, p.SetSize(msg.Width, msg.Height)
+	case CancelTimerExpiredMsg:
+		p.isCanceling = false
+		return p, nil
+	case chat.SendMsg:
+		return p, p.sendMessage(msg.Text, msg.Attachments)
+	case chat.SessionSelectedMsg:
+		return p, p.setSession(msg)
+	case commands.ToggleCompactModeMsg:
+		p.forceCompact = !p.forceCompact
+		var cmd tea.Cmd
+		if p.forceCompact {
+			p.setCompactMode(true)
+			cmd = p.updateCompactConfig(true)
+		} else if p.width >= CompactModeBreakpoint {
+			p.setCompactMode(false)
+			cmd = p.updateCompactConfig(false)
 		}
-		cmd = p.layout.SetSize(msg.Width, layoutHeight)
+		return p, tea.Batch(p.SetSize(p.width, p.height), cmd)
+	case pubsub.Event[session.Session]:
+		u, cmd := p.header.Update(msg)
+		p.header = u.(header.Header)
+		cmds = append(cmds, cmd)
+		u, cmd = p.sidebar.Update(msg)
+		p.sidebar = u.(sidebar.Sidebar)
+		cmds = append(cmds, cmd)
+		return p, tea.Batch(cmds...)
+	case chat.SessionClearedMsg:
+		u, cmd := p.header.Update(msg)
+		p.header = u.(header.Header)
+		cmds = append(cmds, cmd)
+		u, cmd = p.sidebar.Update(msg)
+		p.sidebar = u.(sidebar.Sidebar)
+		cmds = append(cmds, cmd)
+		u, cmd = p.chat.Update(msg)
+		p.chat = u.(chat.MessageListCmp)
+		cmds = append(cmds, cmd)
+		return p, tea.Batch(cmds...)
+	case filepicker.FilePickedMsg,
+		completions.CompletionsClosedMsg,
+		completions.SelectCompletionMsg:
+		u, cmd := p.editor.Update(msg)
+		p.editor = u.(editor.Editor)
+		cmds = append(cmds, cmd)
+		return p, tea.Batch(cmds...)
+
+	case pubsub.Event[message.Message],
+		anim.StepMsg,
+		spinner.TickMsg:
+		u, cmd := p.chat.Update(msg)
+		p.chat = u.(chat.MessageListCmp)
+		cmds = append(cmds, cmd)
+		return p, tea.Batch(cmds...)
+
+	case pubsub.Event[history.File], sidebar.SessionFilesMsg:
+		u, cmd := p.sidebar.Update(msg)
+		p.sidebar = u.(sidebar.Sidebar)
 		cmds = append(cmds, cmd)
 		return p, tea.Batch(cmds...)
 
-	case chat.SendMsg:
-		cmd := p.sendMessage(msg.Text, msg.Attachments)
-		if cmd != nil {
-			return p, cmd
-		}
-	case commands.ToggleCompactModeMsg:
-		// Only allow toggling if window width is larger than compact breakpoint
-		if p.wWidth > CompactModeBreakpoint {
-			p.forceCompactMode = !p.forceCompactMode
-			// If force compact mode is enabled, switch to compact mode
-			// If force compact mode is disabled, switch based on window size
-			if p.forceCompactMode {
-				return p, p.setCompactMode(true)
-			} else {
-				// Return to auto mode based on window size
-				shouldBeCompact := p.wWidth <= CompactModeBreakpoint
-				return p, p.setCompactMode(shouldBeCompact)
-			}
-		}
 	case commands.CommandRunCustomMsg:
-		// Check if the agent is busy before executing custom commands
 		if p.app.CoderAgent.IsBusy() {
 			return p, util.ReportWarn("Agent is busy, please wait before executing a command...")
 		}
 
-		// Handle custom command execution
 		cmd := p.sendMessage(msg.Content, nil)
 		if cmd != nil {
 			return p, cmd
 		}
-	case chat.SessionSelectedMsg:
-		if p.session.ID == "" {
-			cmd := p.setMessages()
-			if cmd != nil {
-				cmds = append(cmds, cmd)
-			}
+	case splash.OnboardingCompleteMsg:
+		p.splashFullScreen = false
+		if b, _ := config.ProjectNeedsInitialization(); b {
+			p.splash.SetProjectInit(true)
+			p.splashFullScreen = true
+			return p, p.SetSize(p.width, p.height)
 		}
-		needsModeChange := p.session.ID == ""
-		p.session = msg
-		p.header.SetSession(msg)
-		if needsModeChange && (p.wWidth <= CompactModeBreakpoint || p.forceCompactMode) {
-			cmds = append(cmds, p.setCompactMode(true))
+		err := p.app.InitCoderAgent()
+		if err != nil {
+			return p, util.ReportError(err)
 		}
+		p.isOnboarding = false
+		p.isProjectInit = false
+		p.focusedPane = PanelTypeEditor
+		return p, p.SetSize(p.width, p.height)
 	case tea.KeyPressMsg:
 		switch {
 		case key.Matches(msg, p.keyMap.NewSession):
-			p.session = session.Session{}
-			return p, tea.Batch(
-				p.clearMessages(),
-				util.CmdHandler(chat.SessionClearedMsg{}),
-				p.setCompactMode(false),
-				p.layout.FocusPanel(layout.BottomPanel),
-				util.CmdHandler(ChatFocusedMsg{Focused: false}),
-			)
+			return p, p.newSession()
 		case key.Matches(msg, p.keyMap.AddAttachment):
 			agentCfg := config.Get().Agents["coder"]
 			model := config.Get().GetModelByType(agentCfg.Model)
@@ -180,171 +261,290 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			}
 		case key.Matches(msg, p.keyMap.Tab):
 			if p.session.ID == "" {
-				return p, nil
-			}
-			p.chatFocused = !p.chatFocused
-			if p.chatFocused {
-				cmds = append(cmds, p.layout.FocusPanel(layout.LeftPanel))
-				cmds = append(cmds, util.CmdHandler(ChatFocusedMsg{Focused: true}))
-			} else {
-				cmds = append(cmds, p.layout.FocusPanel(layout.BottomPanel))
-				cmds = append(cmds, util.CmdHandler(ChatFocusedMsg{Focused: false}))
+				u, cmd := p.splash.Update(msg)
+				p.splash = u.(splash.Splash)
+				return p, cmd
 			}
-			return p, tea.Batch(cmds...)
+			p.changeFocus()
+			return p, nil
 		case key.Matches(msg, p.keyMap.Cancel):
-			if p.session.ID != "" {
-				if p.cancelPending {
-					// Second ESC press - actually cancel the session
-					p.cancelPending = false
-					p.app.CoderAgent.Cancel(p.session.ID)
-					return p, nil
-				} else {
-					// First ESC press - start the timer
-					p.cancelPending = true
-					return p, p.cancelTimerCmd()
-				}
+			if p.session.ID != "" && p.app.CoderAgent.IsBusy() {
+				return p, p.cancel()
 			}
 		case key.Matches(msg, p.keyMap.Details):
-			if p.session.ID == "" || !p.compactMode {
-				return p, nil // No session to show details for
-			}
-			p.showDetails = !p.showDetails
-			p.header.SetDetailsOpen(p.showDetails)
-			if p.showDetails {
-				return p, tea.Batch()
-			}
-
+			p.showDetails()
 			return p, nil
 		}
+
+		switch p.focusedPane {
+		case PanelTypeChat:
+			u, cmd := p.chat.Update(msg)
+			p.chat = u.(chat.MessageListCmp)
+			cmds = append(cmds, cmd)
+		case PanelTypeEditor:
+			u, cmd := p.editor.Update(msg)
+			p.editor = u.(editor.Editor)
+			cmds = append(cmds, cmd)
+		case PanelTypeSplash:
+			u, cmd := p.splash.Update(msg)
+			p.splash = u.(splash.Splash)
+			cmds = append(cmds, cmd)
+		}
+	case tea.PasteMsg:
+		switch p.focusedPane {
+		case PanelTypeEditor:
+			u, cmd := p.editor.Update(msg)
+			p.editor = u.(editor.Editor)
+			cmds = append(cmds, cmd)
+			return p, tea.Batch(cmds...)
+		case PanelTypeChat:
+			u, cmd := p.chat.Update(msg)
+			p.chat = u.(chat.MessageListCmp)
+			cmds = append(cmds, cmd)
+			return p, tea.Batch(cmds...)
+		case PanelTypeSplash:
+			u, cmd := p.splash.Update(msg)
+			p.splash = u.(splash.Splash)
+			cmds = append(cmds, cmd)
+			return p, tea.Batch(cmds...)
+		}
 	}
-	u, cmd := p.layout.Update(msg)
-	cmds = append(cmds, cmd)
-	p.layout = u.(layout.SplitPaneLayout)
-	h, cmd := p.header.Update(msg)
-	p.header = h.(header.Header)
-	cmds = append(cmds, cmd)
-	s, cmd := p.compactSidebar.Update(msg)
-	p.compactSidebar = s.(layout.Container)
-	cmds = append(cmds, cmd)
 	return p, tea.Batch(cmds...)
 }
 
-func (p *chatPage) setMessages() tea.Cmd {
-	messagesContainer := layout.NewContainer(
-		chat.NewMessagesListCmp(p.app),
-		layout.WithPadding(1, 1, 0, 1),
-	)
-	return tea.Batch(p.layout.SetLeftPanel(messagesContainer), messagesContainer.Init())
+func (p *chatPage) Cursor() *tea.Cursor {
+	switch p.focusedPane {
+	case PanelTypeEditor:
+		return p.editor.Cursor()
+	case PanelTypeSplash:
+		return p.splash.Cursor()
+	default:
+		return nil
+	}
 }
 
-func (p *chatPage) setSidebar() tea.Cmd {
-	sidebarContainer := sidebarCmp(p.app, false, p.session)
-	sidebarContainer.Init()
-	return p.layout.SetRightPanel(sidebarContainer)
+func (p *chatPage) View() string {
+	var chatView string
+	t := styles.CurrentTheme()
+
+	if p.session.ID == "" {
+		splashView := p.splash.View()
+		// Full screen during onboarding or project initialization
+		if p.splashFullScreen {
+			chatView = splashView
+		} else {
+			// Show splash + editor for new message state
+			editorView := p.editor.View()
+			chatView = lipgloss.JoinVertical(
+				lipgloss.Left,
+				t.S().Base.Render(splashView),
+				editorView,
+			)
+		}
+	} else {
+		messagesView := p.chat.View()
+		editorView := p.editor.View()
+		if p.compact {
+			headerView := p.header.View()
+			chatView = lipgloss.JoinVertical(
+				lipgloss.Left,
+				headerView,
+				messagesView,
+				editorView,
+			)
+		} else {
+			sidebarView := p.sidebar.View()
+			messages := lipgloss.JoinHorizontal(
+				lipgloss.Left,
+				messagesView,
+				sidebarView,
+			)
+			chatView = lipgloss.JoinVertical(
+				lipgloss.Left,
+				messages,
+				p.editor.View(),
+			)
+		}
+	}
+
+	layers := []*lipgloss.Layer{
+		lipgloss.NewLayer(chatView).X(0).Y(0),
+	}
+
+	if p.showingDetails {
+		style := t.S().Base.
+			Width(p.detailsWidth).
+			Border(lipgloss.RoundedBorder()).
+			BorderForeground(t.BorderFocus)
+		version := t.S().Subtle.Width(p.detailsWidth - 2).AlignHorizontal(lipgloss.Right).Render(version.Version)
+		details := style.Render(
+			lipgloss.JoinVertical(
+				lipgloss.Left,
+				p.sidebar.View(),
+				version,
+			),
+		)
+		layers = append(layers, lipgloss.NewLayer(details).X(1).Y(1))
+	}
+	canvas := lipgloss.NewCanvas(
+		layers...,
+	)
+	return canvas.Render()
 }
 
-func (p *chatPage) clearMessages() tea.Cmd {
-	return p.layout.ClearLeftPanel()
+func (p *chatPage) updateCompactConfig(compact bool) tea.Cmd {
+	return func() tea.Msg {
+		err := config.Get().SetCompactMode(compact)
+		if err != nil {
+			return util.InfoMsg{
+				Type: util.InfoTypeError,
+				Msg:  "Failed to update compact mode configuration: " + err.Error(),
+			}
+		}
+		return nil
+	}
 }
 
-func (p *chatPage) setCompactMode(compact bool) tea.Cmd {
-	p.compactMode = compact
-	var cmds []tea.Cmd
+func (p *chatPage) setCompactMode(compact bool) {
+	if p.compact == compact {
+		return
+	}
+	p.compact = compact
 	if compact {
-		// add offset for the header
-		p.layout.SetOffset(0, 1)
-		// make space for the header
-		cmds = append(cmds, p.layout.SetSize(p.wWidth, p.wHeight-1))
-		// remove the sidebar
-		cmds = append(cmds, p.layout.ClearRightPanel())
-		return tea.Batch(cmds...)
+		p.compact = true
+		p.sidebar.SetCompactMode(true)
 	} else {
-		// remove the offset for the header
-		p.layout.SetOffset(0, 0)
-		// restore the original size
-		cmds = append(cmds, p.layout.SetSize(p.wWidth, p.wHeight))
-		// set the sidebar
-		cmds = append(cmds, p.setSidebar())
-		l, cmd := p.layout.Update(chat.SessionSelectedMsg(p.session))
-		p.layout = l.(layout.SplitPaneLayout)
-		cmds = append(cmds, cmd)
+		p.compact = false
+		p.showingDetails = false
+		p.sidebar.SetCompactMode(false)
+	}
+}
 
-		return tea.Batch(cmds...)
+func (p *chatPage) handleCompactMode(newWidth int) {
+	if p.forceCompact {
+		return
+	}
+	if newWidth < CompactModeBreakpoint && !p.compact {
+		p.setCompactMode(true)
+	}
+	if newWidth >= CompactModeBreakpoint && p.compact {
+		p.setCompactMode(false)
 	}
 }
 
-func (p *chatPage) sendMessage(text string, attachments []message.Attachment) tea.Cmd {
+func (p *chatPage) SetSize(width, height int) tea.Cmd {
+	p.handleCompactMode(width)
+	p.width = width
+	p.height = height
 	var cmds []tea.Cmd
+
 	if p.session.ID == "" {
-		session, err := p.app.Sessions.Create(context.Background(), "New Session")
-		if err != nil {
-			return util.ReportError(err)
+		if p.splashFullScreen {
+			cmds = append(cmds, p.splash.SetSize(width, height))
+		} else {
+			cmds = append(cmds, p.splash.SetSize(width, height-EditorHeight))
+			cmds = append(cmds, p.editor.SetSize(width, EditorHeight))
+			cmds = append(cmds, p.editor.SetPosition(0, height-EditorHeight))
 		}
-
-		p.session = session
-		cmd := p.setMessages()
-		if cmd != nil {
-			cmds = append(cmds, cmd)
+	} else {
+		if p.compact {
+			cmds = append(cmds, p.chat.SetSize(width, height-EditorHeight-HeaderHeight))
+			p.detailsWidth = width - DetailsPositioning
+			cmds = append(cmds, p.sidebar.SetSize(p.detailsWidth-LeftRightBorders, p.detailsHeight-TopBottomBorders))
+			cmds = append(cmds, p.editor.SetSize(width, EditorHeight))
+			cmds = append(cmds, p.header.SetWidth(width-BorderWidth))
+		} else {
+			cmds = append(cmds, p.chat.SetSize(width-SideBarWidth, height-EditorHeight))
+			cmds = append(cmds, p.editor.SetSize(width, EditorHeight))
+			cmds = append(cmds, p.sidebar.SetSize(SideBarWidth, height-EditorHeight))
 		}
-		cmds = append(cmds, util.CmdHandler(chat.SessionSelectedMsg(session)))
-	}
-
-	_, err := p.app.CoderAgent.Run(context.Background(), p.session.ID, text, attachments...)
-	if err != nil {
-		return util.ReportError(err)
+		cmds = append(cmds, p.editor.SetPosition(0, height-EditorHeight))
 	}
 	return tea.Batch(cmds...)
 }
 
-func (p *chatPage) SetSize(width, height int) tea.Cmd {
-	return p.layout.SetSize(width, height)
+func (p *chatPage) newSession() tea.Cmd {
+	if p.session.ID == "" {
+		return nil
+	}
+
+	p.session = session.Session{}
+	p.focusedPane = PanelTypeEditor
+	p.isCanceling = false
+	return tea.Batch(
+		util.CmdHandler(chat.SessionClearedMsg{}),
+		p.SetSize(p.width, p.height),
+	)
 }
 
-func (p *chatPage) GetSize() (int, int) {
-	return p.layout.GetSize()
+func (p *chatPage) setSession(session session.Session) tea.Cmd {
+	if p.session.ID == session.ID {
+		return nil
+	}
+
+	var cmds []tea.Cmd
+	p.session = session
+
+	cmds = append(cmds, p.SetSize(p.width, p.height))
+	cmds = append(cmds, p.chat.SetSession(session))
+	cmds = append(cmds, p.sidebar.SetSession(session))
+	cmds = append(cmds, p.header.SetSession(session))
+	cmds = append(cmds, p.editor.SetSession(session))
+
+	return tea.Sequence(cmds...)
 }
 
-func (p *chatPage) View() string {
-	if !p.compactMode || p.session.ID == "" {
-		// If not in compact mode or there is no session, we don't show the header
-		return p.layout.View()
+func (p *chatPage) changeFocus() {
+	if p.session.ID == "" {
+		return
 	}
-	layoutView := p.layout.View()
-	chatView := strings.Join(
-		[]string{
-			p.header.View(),
-			layoutView,
-		}, "\n",
-	)
-	layers := []*lipgloss.Layer{
-		lipgloss.NewLayer(chatView).X(0).Y(0),
+	switch p.focusedPane {
+	case PanelTypeChat:
+		p.focusedPane = PanelTypeEditor
+		p.editor.Focus()
+		p.chat.Blur()
+	case PanelTypeEditor:
+		p.focusedPane = PanelTypeChat
+		p.chat.Focus()
+		p.editor.Blur()
 	}
-	if p.showDetails {
-		t := styles.CurrentTheme()
-		style := t.S().Base.
-			Border(lipgloss.RoundedBorder()).
-			BorderForeground(t.BorderFocus)
-		version := t.S().Subtle.Padding(0, 1).AlignHorizontal(lipgloss.Right).Width(p.wWidth - 4).Render(version.Version)
-		details := style.Render(
-			lipgloss.JoinVertical(
-				lipgloss.Left,
-				p.compactSidebar.View(),
-				version,
-			),
-		)
-		layers = append(layers, lipgloss.NewLayer(details).X(1).Y(1))
+}
+
+func (p *chatPage) cancel() tea.Cmd {
+	if p.isCanceling {
+		p.isCanceling = false
+		p.app.CoderAgent.Cancel(p.session.ID)
+		return nil
 	}
-	canvas := lipgloss.NewCanvas(
-		layers...,
-	)
-	return canvas.Render()
+
+	p.isCanceling = true
+	return cancelTimerCmd()
 }
 
-func (p *chatPage) Cursor() *tea.Cursor {
-	if v, ok := p.layout.(util.Cursor); ok {
-		return v.Cursor()
+func (p *chatPage) showDetails() {
+	if p.session.ID == "" || !p.compact {
+		return
+	}
+	p.showingDetails = !p.showingDetails
+	p.header.SetDetailsOpen(p.showingDetails)
+}
+
+func (p *chatPage) sendMessage(text string, attachments []message.Attachment) tea.Cmd {
+	session := p.session
+	var cmds []tea.Cmd
+	if p.session.ID == "" {
+		newSession, err := p.app.Sessions.Create(context.Background(), "New Session")
+		if err != nil {
+			return util.ReportError(err)
+		}
+		session = newSession
+		cmds = append(cmds, util.CmdHandler(chat.SessionSelectedMsg(session)))
+	}
+	_, err := p.app.CoderAgent.Run(context.Background(), session.ID, text, attachments...)
+	if err != nil {
+		return util.ReportError(err)
 	}
-	return nil
+	return tea.Batch(cmds...)
 }
 
 func (p *chatPage) Bindings() []key.Binding {
@@ -352,9 +552,9 @@ func (p *chatPage) Bindings() []key.Binding {
 		p.keyMap.NewSession,
 		p.keyMap.AddAttachment,
 	}
-	if p.app.CoderAgent.IsBusy() {
+	if p.app.CoderAgent != nil && p.app.CoderAgent.IsBusy() {
 		cancelBinding := p.keyMap.Cancel
-		if p.cancelPending {
+		if p.isCanceling {
 			cancelBinding = key.NewBinding(
 				key.WithKeys("esc"),
 				key.WithHelp("esc", "press again to cancel"),
@@ -363,61 +563,261 @@ func (p *chatPage) Bindings() []key.Binding {
 		bindings = append([]key.Binding{cancelBinding}, bindings...)
 	}
 
-	if p.chatFocused {
+	switch p.focusedPane {
+	case PanelTypeChat:
 		bindings = append([]key.Binding{
 			key.NewBinding(
 				key.WithKeys("tab"),
 				key.WithHelp("tab", "focus editor"),
 			),
 		}, bindings...)
-	} else {
+		bindings = append(bindings, p.chat.Bindings()...)
+	case PanelTypeEditor:
 		bindings = append([]key.Binding{
 			key.NewBinding(
 				key.WithKeys("tab"),
 				key.WithHelp("tab", "focus chat"),
 			),
 		}, bindings...)
+		bindings = append(bindings, p.editor.Bindings()...)
+	case PanelTypeSplash:
+		bindings = append(bindings, p.splash.Bindings()...)
 	}
 
-	bindings = append(bindings, p.layout.Bindings()...)
 	return bindings
 }
 
-func sidebarCmp(app *app.App, compact bool, session session.Session) layout.Container {
-	padding := layout.WithPadding(1, 1, 1, 1)
-	if compact {
-		padding = layout.WithPadding(0, 1, 1, 1)
-	}
-	sidebar := sidebar.NewSidebarCmp(app.History, app.LSPClients, compact)
-	if session.ID != "" {
-		sidebar.SetSession(session)
+func (a *chatPage) Help() help.KeyMap {
+	var shortList []key.Binding
+	var fullList [][]key.Binding
+	switch {
+	case a.isOnboarding && !a.splash.IsShowingAPIKey():
+		shortList = append(shortList,
+			// Choose model
+			key.NewBinding(
+				key.WithKeys("up", "down"),
+				key.WithHelp("↑/↓", "choose"),
+			),
+			// Accept selection
+			key.NewBinding(
+				key.WithKeys("enter", "ctrl+y"),
+				key.WithHelp("enter", "accept"),
+			),
+			// Quit
+			key.NewBinding(
+				key.WithKeys("ctrl+c"),
+				key.WithHelp("ctrl+c", "quit"),
+			),
+		)
+		// keep them the same
+		for _, v := range shortList {
+			fullList = append(fullList, []key.Binding{v})
+		}
+	case a.isOnboarding && a.splash.IsShowingAPIKey():
+		shortList = append(shortList,
+			// Go back
+			key.NewBinding(
+				key.WithKeys("esc"),
+				key.WithHelp("esc", "back"),
+			),
+			// Quit
+			key.NewBinding(
+				key.WithKeys("ctrl+c"),
+				key.WithHelp("ctrl+c", "quit"),
+			),
+		)
+		// keep them the same
+		for _, v := range shortList {
+			fullList = append(fullList, []key.Binding{v})
+		}
+	case a.isProjectInit:
+		shortList = append(shortList,
+			key.NewBinding(
+				key.WithKeys("ctrl+c"),
+				key.WithHelp("ctrl+c", "quit"),
+			),
+		)
+		// keep them the same
+		for _, v := range shortList {
+			fullList = append(fullList, []key.Binding{v})
+		}
+	default:
+		if a.editor.IsCompletionsOpen() {
+			shortList = append(shortList,
+				key.NewBinding(
+					key.WithKeys("tab", "enter"),
+					key.WithHelp("tab/enter", "complete"),
+				),
+				key.NewBinding(
+					key.WithKeys("esc"),
+					key.WithHelp("esc", "cancel"),
+				),
+				key.NewBinding(
+					key.WithKeys("up", "down"),
+					key.WithHelp("↑/↓", "choose"),
+				),
+			)
+			for _, v := range shortList {
+				fullList = append(fullList, []key.Binding{v})
+			}
+			return core.NewSimpleHelp(shortList, fullList)
+		}
+		if a.app.CoderAgent != nil && a.app.CoderAgent.IsBusy() {
+			cancelBinding := key.NewBinding(
+				key.WithKeys("esc"),
+				key.WithHelp("esc", "cancel"),
+			)
+			if a.isCanceling {
+				cancelBinding = key.NewBinding(
+					key.WithKeys("esc"),
+					key.WithHelp("esc", "press again to cancel"),
+				)
+			}
+			shortList = append(shortList, cancelBinding)
+			fullList = append(fullList,
+				[]key.Binding{
+					cancelBinding,
+				},
+			)
+		}
+		globalBindings := []key.Binding{}
+		// we are in a session
+		if a.session.ID != "" {
+			tabKey := key.NewBinding(
+				key.WithKeys("tab"),
+				key.WithHelp("tab", "focus chat"),
+			)
+			if a.focusedPane == PanelTypeChat {
+				tabKey = key.NewBinding(
+					key.WithKeys("tab"),
+					key.WithHelp("tab", "focus editor"),
+				)
+			}
+			shortList = append(shortList, tabKey)
+			globalBindings = append(globalBindings, tabKey)
+		}
+		commandsBinding := key.NewBinding(
+			key.WithKeys("ctrl+p"),
+			key.WithHelp("ctrl+p", "commands"),
+		)
+		helpBinding := key.NewBinding(
+			key.WithKeys("ctrl+g"),
+			key.WithHelp("ctrl+g", "more"),
+		)
+		globalBindings = append(globalBindings, commandsBinding)
+		globalBindings = append(globalBindings,
+			key.NewBinding(
+				key.WithKeys("ctrl+s"),
+				key.WithHelp("ctrl+s", "sessions"),
+			),
+		)
+		if a.session.ID != "" {
+			globalBindings = append(globalBindings,
+				key.NewBinding(
+					key.WithKeys("ctrl+n"),
+					key.WithHelp("ctrl+n", "new sessions"),
+				))
+		}
+		shortList = append(shortList,
+			// Commands
+			commandsBinding,
+		)
+		fullList = append(fullList, globalBindings)
+
+		if a.focusedPane == PanelTypeChat {
+			shortList = append(shortList,
+				key.NewBinding(
+					key.WithKeys("up", "down"),
+					key.WithHelp("↑↓", "scroll"),
+				),
+			)
+			fullList = append(fullList,
+				[]key.Binding{
+					key.NewBinding(
+						key.WithKeys("up", "down"),
+						key.WithHelp("↑↓", "scroll"),
+					),
+					key.NewBinding(
+						key.WithKeys("shift+up", "shift+down"),
+						key.WithHelp("shift+↑↓", "next/prev item"),
+					),
+					key.NewBinding(
+						key.WithKeys("pgup", "b"),
+						key.WithHelp("b/pgup", "page up"),
+					),
+					key.NewBinding(
+						key.WithKeys("pgdown", " ", "f"),
+						key.WithHelp("f/pgdn", "page down"),
+					),
+				},
+				[]key.Binding{
+					key.NewBinding(
+						key.WithKeys("u"),
+						key.WithHelp("u", "half page up"),
+					),
+					key.NewBinding(
+						key.WithKeys("d"),
+						key.WithHelp("d", "half page down"),
+					),
+					key.NewBinding(
+						key.WithKeys("g", "home"),
+						key.WithHelp("g", "hone"),
+					),
+					key.NewBinding(
+						key.WithKeys("G", "end"),
+						key.WithHelp("G", "end"),
+					),
+				},
+			)
+		} else if a.focusedPane == PanelTypeEditor {
+			newLineBinding := key.NewBinding(
+				key.WithKeys("shift+enter", "ctrl+j"),
+				// "ctrl+j" is a common keybinding for newline in many editors. If
+				// the terminal supports "shift+enter", we substitute the help text
+				// to reflect that.
+				key.WithHelp("ctrl+j", "newline"),
+			)
+			if a.keyboardEnhancements.SupportsKeyDisambiguation() {
+				newLineBinding.SetHelp("shift+enter", newLineBinding.Help().Desc)
+			}
+			shortList = append(shortList, newLineBinding)
+			fullList = append(fullList,
+				[]key.Binding{
+					newLineBinding,
+					key.NewBinding(
+						key.WithKeys("ctrl+f"),
+						key.WithHelp("ctrl+f", "add image"),
+					),
+					key.NewBinding(
+						key.WithKeys("/"),
+						key.WithHelp("/", "add file"),
+					),
+					key.NewBinding(
+						key.WithKeys("ctrl+v"),
+						key.WithHelp("ctrl+v", "open editor"),
+					),
+				})
+		}
+		shortList = append(shortList,
+			// Quit
+			key.NewBinding(
+				key.WithKeys("ctrl+c"),
+				key.WithHelp("ctrl+c", "quit"),
+			),
+			// Help
+			helpBinding,
+		)
+		fullList = append(fullList, []key.Binding{
+			key.NewBinding(
+				key.WithKeys("ctrl+g"),
+				key.WithHelp("ctrl+g", "less"),
+			),
+		})
 	}
 
-	return layout.NewContainer(
-		sidebar,
-		padding,
-	)
-}
-
-func NewChatPage(app *app.App) ChatPage {
-	editorContainer := layout.NewContainer(
-		editor.NewEditorCmp(app),
-	)
-	return &chatPage{
-		app: app,
-		layout: layout.NewSplitPane(
-			layout.WithRightPanel(sidebarCmp(app, false, session.Session{})),
-			layout.WithBottomPanel(editorContainer),
-			layout.WithFixedBottomHeight(5),
-			layout.WithFixedRightWidth(31),
-		),
-		compactSidebar: sidebarCmp(app, true, session.Session{}),
-		keyMap:         DefaultKeyMap(),
-		header:         header.New(app.LSPClients),
-	}
+	return core.NewSimpleHelp(shortList, fullList)
 }
 
-// IsChatFocused returns whether the chat messages are focused (true) or editor is focused (false)
 func (p *chatPage) IsChatFocused() bool {
-	return p.chatFocused
+	return p.focusedPane == PanelTypeChat
 }

internal/tui/styles/crush.go 🔗

@@ -16,7 +16,7 @@ func NewCrushTheme() *Theme {
 
 		// Backgrounds
 		BgBase:        charmtone.Pepper,
-		BgBaseLighter: Lighten(charmtone.Pepper, 2),
+		BgBaseLighter: charmtone.BBQ,
 		BgSubtle:      charmtone.Charcoal,
 		BgOverlay:     charmtone.Iron,
 

internal/tui/tui.go 🔗

@@ -13,13 +13,13 @@ import (
 	"github.com/charmbracelet/crush/internal/pubsub"
 	cmpChat "github.com/charmbracelet/crush/internal/tui/components/chat"
 	"github.com/charmbracelet/crush/internal/tui/components/completions"
+	"github.com/charmbracelet/crush/internal/tui/components/core"
 	"github.com/charmbracelet/crush/internal/tui/components/core/layout"
 	"github.com/charmbracelet/crush/internal/tui/components/core/status"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/commands"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/compact"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/filepicker"
-	initDialog "github.com/charmbracelet/crush/internal/tui/components/dialogs/init"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/models"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/permissions"
 	"github.com/charmbracelet/crush/internal/tui/components/dialogs/quit"
@@ -88,22 +88,7 @@ func (a appModel) Init() tea.Cmd {
 	cmd = a.status.Init()
 	cmds = append(cmds, cmd)
 
-	// Check if we should show the init dialog
-	cmds = append(cmds, func() tea.Msg {
-		shouldShow, err := config.ProjectNeedsInitialization()
-		if err != nil {
-			return util.InfoMsg{
-				Type: util.InfoTypeError,
-				Msg:  "Failed to check init status: " + err.Error(),
-			}
-		}
-		if shouldShow {
-			return dialogs.OpenDialogMsg{
-				Model: initDialog.NewInitDialogCmp(),
-			}
-		}
-		return nil
-	})
+	cmds = append(cmds, tea.EnableMouseAllMotion)
 
 	return tea.Batch(cmds...)
 }
@@ -115,8 +100,16 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 	switch msg := msg.(type) {
 	case tea.KeyboardEnhancementsMsg:
-		return a, nil
+		for id, page := range a.pages {
+			m, pageCmd := page.Update(msg)
+			a.pages[id] = m.(util.Model)
+			if pageCmd != nil {
+				cmds = append(cmds, pageCmd)
+			}
+		}
+		return a, tea.Batch(cmds...)
 	case tea.WindowSizeMsg:
+		a.completions.Update(msg)
 		return a, a.handleWindowResize(msg.Width, msg.Height)
 
 	// Completions messages
@@ -127,9 +120,11 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 	// Dialog messages
 	case dialogs.OpenDialogMsg, dialogs.CloseDialogMsg:
+		u, completionCmd := a.completions.Update(completions.CloseCompletionsMsg{})
+		a.completions = u.(completions.Completions)
 		u, dialogCmd := a.dialog.Update(msg)
 		a.dialog = u.(dialogs.DialogCmp)
-		return a, dialogCmd
+		return a, tea.Batch(completionCmd, dialogCmd)
 	case commands.ShowArgumentsDialogMsg:
 		return a, util.CmdHandler(
 			dialogs.OpenDialogMsg{
@@ -179,7 +174,7 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 
 	// Model Switch
 	case models.ModelSelectedMsg:
-		config.UpdatePreferredModel(msg.ModelType, msg.Model)
+		config.Get().UpdatePreferredModel(msg.ModelType, msg.Model)
 
 		// Update the agent with the new model/provider configuration
 		if err := a.app.UpdateAgentModel(); err != nil {
@@ -266,7 +261,7 @@ func (a *appModel) handleWindowResize(width, height int) tea.Cmd {
 	var cmds []tea.Cmd
 	a.wWidth, a.wHeight = width, height
 	if a.showingFullHelp {
-		height -= 4
+		height -= 5
 	} else {
 		height -= 2
 	}
@@ -332,6 +327,9 @@ func (a *appModel) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
 			// If the commands dialog is already open, close it
 			return util.CmdHandler(dialogs.CloseDialogMsg{})
 		}
+		if a.dialog.HasDialogs() {
+			return nil // Don't open commands dialog if another dialog is active
+		}
 		return util.CmdHandler(dialogs.OpenDialogMsg{
 			Model: commands.NewCommandDialog(a.selectedSessionID),
 		})
@@ -393,10 +391,9 @@ func (a *appModel) moveToPage(pageID page.PageID) tea.Cmd {
 // View renders the complete application interface including pages, dialogs, and overlays.
 func (a *appModel) View() tea.View {
 	page := a.pages[a.currentPage]
-	if withHelp, ok := page.(layout.Help); ok {
-		a.keyMap.pageBindings = withHelp.Bindings()
+	if withHelp, ok := page.(core.KeyMapHelp); ok {
+		a.status.SetKeyMap(withHelp.Help())
 	}
-	a.status.SetKeyMap(a.keyMap)
 	pageView := page.View()
 	components := []string{
 		pageView,
@@ -449,14 +446,14 @@ func (a *appModel) View() tea.View {
 
 // New creates and initializes a new TUI application model.
 func New(app *app.App) tea.Model {
-	chatPage := chat.NewChatPage(app)
+	chatPage := chat.New(app)
 	keyMap := DefaultKeyMap()
 	keyMap.pageBindings = chatPage.Bindings()
 
 	model := &appModel{
 		currentPage: chat.ChatPageID,
 		app:         app,
-		status:      status.NewStatusCmp(keyMap),
+		status:      status.NewStatusCmp(),
 		loadedPages: make(map[page.PageID]bool),
 		keyMap:      keyMap,
 

internal/tui/util/util.go 🔗

@@ -1,6 +1,7 @@
 package util
 
 import (
+	"log/slog"
 	"time"
 
 	tea "github.com/charmbracelet/bubbletea/v2"
@@ -22,6 +23,7 @@ func CmdHandler(msg tea.Msg) tea.Cmd {
 }
 
 func ReportError(err error) tea.Cmd {
+	slog.Error("Error reported", "error", err)
 	return CmdHandler(InfoMsg{
 		Type: InfoTypeError,
 		Msg:  err.Error(),

vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work.sum 🔗

@@ -1,60 +0,0 @@
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0-beta.1 h1:ODs3brnqQM99Tq1PffODpAViYv3Bf8zOg464MU7p5ew=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0-beta.1/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
-github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/keybase/dbus v0.0.0-20220506165403-5aa21ea2c23a/go.mod h1:YPNKjjE7Ubp9dTbnWvsP3HT+hYnY6TfXzubYTBeUxc8=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
-github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
-golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
-golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
-golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
-golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
-golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
-golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
-golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
-golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

vendor/github.com/charmbracelet/bubbles/v2/textarea/textarea.go 🔗

@@ -133,6 +133,13 @@ type LineInfo struct {
 	CharOffset int
 }
 
+// PromptInfo is a struct that can be used to store information about the
+// prompt.
+type PromptInfo struct {
+	LineNumber int
+	Focused    bool
+}
+
 // CursorStyle is the style for real and virtual cursors.
 type CursorStyle struct {
 	// Style styles the cursor block.
@@ -287,7 +294,7 @@ type Model struct {
 
 	// If promptFunc is set, it replaces Prompt as a generator for
 	// prompt strings at the beginning of each line.
-	promptFunc func(line int, focused bool) string
+	promptFunc func(PromptInfo) string
 
 	// promptWidth is the width of the prompt.
 	promptWidth int
@@ -983,14 +990,14 @@ func (m Model) Width() int {
 	return m.width
 }
 
-// moveToBegin moves the cursor to the beginning of the input.
-func (m *Model) moveToBegin() {
+// MoveToBegin moves the cursor to the beginning of the input.
+func (m *Model) MoveToBegin() {
 	m.row = 0
 	m.SetCursorColumn(0)
 }
 
-// moveToEnd moves the cursor to the end of the input.
-func (m *Model) moveToEnd() {
+// MoveToEnd moves the cursor to the end of the input.
+func (m *Model) MoveToEnd() {
 	m.row = len(m.value) - 1
 	m.SetCursorColumn(len(m.value[m.row]))
 }
@@ -1052,7 +1059,7 @@ func (m *Model) SetWidth(w int) {
 // promptWidth, it will be padded to the left. If it returns a prompt that is
 // longer, display artifacts may occur; the caller is responsible for computing
 // an adequate promptWidth.
-func (m *Model) SetPromptFunc(promptWidth int, fn func(lineIndex int, focused bool) string) {
+func (m *Model) SetPromptFunc(promptWidth int, fn func(PromptInfo) string) {
 	m.promptFunc = fn
 	m.promptWidth = promptWidth
 }
@@ -1170,9 +1177,9 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
 		case key.Matches(msg, m.KeyMap.WordBackward):
 			m.wordLeft()
 		case key.Matches(msg, m.KeyMap.InputBegin):
-			m.moveToBegin()
+			m.MoveToBegin()
 		case key.Matches(msg, m.KeyMap.InputEnd):
-			m.moveToEnd()
+			m.MoveToEnd()
 		case key.Matches(msg, m.KeyMap.LowercaseWordForward):
 			m.lowercaseRight()
 		case key.Matches(msg, m.KeyMap.UppercaseWordForward):
@@ -1320,7 +1327,10 @@ func (m Model) promptView(displayLine int) (prompt string) {
 	if m.promptFunc == nil {
 		return prompt
 	}
-	prompt = m.promptFunc(displayLine, m.focus)
+	prompt = m.promptFunc(PromptInfo{
+		LineNumber: displayLine,
+		Focused:    m.focus,
+	})
 	width := lipgloss.Width(prompt)
 	if width < m.promptWidth {
 		prompt = fmt.Sprintf("%*s%s", m.promptWidth-width, "", prompt)

vendor/github.com/charmbracelet/bubbletea/v2/tea.go 🔗

@@ -624,6 +624,10 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
 				switch msg.Mode {
 				case ansi.AltScreenSaveCursorMode:
 					p.renderer.enterAltScreen()
+					// Main and alternate screen have their own Kitty keyboard
+					// stack. We need to request keyboard enhancements again
+					// when entering/exiting the alternate screen.
+					p.requestKeyboardEnhancements()
 				case ansi.TextCursorEnableMode:
 					p.renderer.showCursor()
 				case ansi.GraphemeClusteringMode:
@@ -645,6 +649,10 @@ func (p *Program) eventLoop(model Model, cmds chan Cmd) (Model, error) {
 				switch msg.Mode {
 				case ansi.AltScreenSaveCursorMode:
 					p.renderer.exitAltScreen()
+					// Main and alternate screen have their own Kitty keyboard
+					// stack. We need to request keyboard enhancements again
+					// when entering/exiting the alternate screen.
+					p.requestKeyboardEnhancements()
 				case ansi.TextCursorEnableMode:
 					p.renderer.hideCursor()
 				default:
@@ -1410,13 +1418,16 @@ func (p *Program) stopRenderer(kill bool) {
 // requestKeyboardEnhancements tries to enable keyboard enhancements and read
 // the active keyboard enhancements from the terminal.
 func (p *Program) requestKeyboardEnhancements() {
+	// XXX: We write to the renderer directly so that we synchronize with the
+	// alt-screen state of the renderer. This is because the main screen and
+	// alternate screen have their own Kitty keyboard state stack.
 	if p.requestedEnhancements.modifyOtherKeys > 0 {
-		p.execute(ansi.KeyModifierOptions(4, p.requestedEnhancements.modifyOtherKeys)) //nolint:mnd
-		p.execute(ansi.QueryModifyOtherKeys)
+		_, _ = p.renderer.writeString(ansi.KeyModifierOptions(4, p.requestedEnhancements.modifyOtherKeys)) //nolint:mnd
+		_, _ = p.renderer.writeString(ansi.QueryModifyOtherKeys)
 	}
 	if p.requestedEnhancements.kittyFlags > 0 {
-		p.execute(ansi.PushKittyKeyboard(p.requestedEnhancements.kittyFlags))
-		p.execute(ansi.RequestKittyKeyboard)
+		_, _ = p.renderer.writeString(ansi.PushKittyKeyboard(p.requestedEnhancements.kittyFlags))
+		_, _ = p.renderer.writeString(ansi.RequestKittyKeyboard)
 	}
 }
 

vendor/github.com/charmbracelet/fang/README.md 🔗

@@ -1,7 +1,7 @@
 # Fang
 
 <p>
-    <img width="485" alt="Charm Fang" src="https://github.com/user-attachments/assets/3f34ea01-3750-4760-beb2-a1b700e110f5">   
+    <img width="485" alt="Charm Fang" src="https://github.com/user-attachments/assets/3f34ea01-3750-4760-beb2-a1b700e110f5">
 </p>
 <p>
     <a href="https://github.com/charmbracelet/fang/releases"><img src="https://img.shields.io/github/release/charmbracelet/fang.svg" alt="Latest Release"></a>
@@ -12,7 +12,7 @@
 The CLI starter kit. A small, experimental library for batteries-included [Cobra][cobra] applications.
 
 <p>
-    <img width="865" alt="fang-02" src="https://github.com/user-attachments/assets/7f68ec3f-2b42-4188-a750-7e2808696132" />
+    <img width="859" alt="The Charm Fang mascot and title treatment" src="https://github.com/user-attachments/assets/5c35e1fa-9577-4f81-a879-3ddb4d4a43f0" />
 </p>
 
 ## Features
@@ -45,6 +45,7 @@ To use it, invoke `fang.Execute` passing your root `*cobra.Command`:
 package main
 
 import (
+	"context"
 	"os"
 
 	"github.com/charmbracelet/fang"
@@ -56,7 +57,7 @@ func main() {
 		Use:   "example",
 		Short: "A simple example program!",
 	}
-	if err := fang.Execute(context.TODO(), cmd); err != nil {
+	if err := fang.Execute(context.Background(), cmd); err != nil {
 		os.Exit(1)
 	}
 }

vendor/github.com/charmbracelet/fang/fang.go 🔗

@@ -4,11 +4,14 @@ package fang
 import (
 	"context"
 	"fmt"
+	"io"
 	"os"
+	"os/signal"
 	"runtime/debug"
 
 	"github.com/charmbracelet/colorprofile"
 	"github.com/charmbracelet/lipgloss/v2"
+	"github.com/charmbracelet/x/term"
 	mango "github.com/muesli/mango-cobra"
 	"github.com/muesli/roff"
 	"github.com/spf13/cobra"
@@ -16,12 +19,24 @@ import (
 
 const shaLen = 7
 
+// ErrorHandler handles an error, printing them to the given [io.Writer].
+//
+// Note that this will only be used if the STDERR is a terminal, and should
+// be used for styling only.
+type ErrorHandler = func(w io.Writer, styles Styles, err error)
+
+// ColorSchemeFunc gets a [lipgloss.LightDarkFunc] and returns a [ColorScheme].
+type ColorSchemeFunc = func(lipgloss.LightDarkFunc) ColorScheme
+
 type settings struct {
 	completions bool
 	manpages    bool
+	skipVersion bool
 	version     string
 	commit      string
-	theme       *ColorScheme
+	colorscheme ColorSchemeFunc
+	errHandler  ErrorHandler
+	signals     []os.Signal
 }
 
 // Option changes fang settings.
@@ -41,10 +56,21 @@ func WithoutManpage() Option {
 	}
 }
 
+// WithColorSchemeFunc sets a function that return colorscheme.
+func WithColorSchemeFunc(cs ColorSchemeFunc) Option {
+	return func(s *settings) {
+		s.colorscheme = cs
+	}
+}
+
 // WithTheme sets the colorscheme.
+//
+// Deprecated: use [WithColorSchemeFunc] instead.
 func WithTheme(theme ColorScheme) Option {
 	return func(s *settings) {
-		s.theme = &theme
+		s.colorscheme = func(lipgloss.LightDarkFunc) ColorScheme {
+			return theme
+		}
 	}
 }
 
@@ -55,6 +81,13 @@ func WithVersion(version string) Option {
 	}
 }
 
+// WithoutVersion skips the `-v`/`--version` functionality.
+func WithoutVersion() Option {
+	return func(s *settings) {
+		s.skipVersion = true
+	}
+}
+
 // WithCommit sets the commit SHA.
 func WithCommit(commit string) Option {
 	return func(s *settings) {
@@ -62,30 +95,45 @@ func WithCommit(commit string) Option {
 	}
 }
 
+// WithErrorHandler sets the error handler.
+func WithErrorHandler(handler ErrorHandler) Option {
+	return func(s *settings) {
+		s.errHandler = handler
+	}
+}
+
+// WithNotifySignal sets the signals that should interrupt the execution of the
+// program.
+func WithNotifySignal(signals ...os.Signal) Option {
+	return func(s *settings) {
+		s.signals = signals
+	}
+}
+
 // Execute applies fang to the command and executes it.
 func Execute(ctx context.Context, root *cobra.Command, options ...Option) error {
 	opts := settings{
 		manpages:    true,
 		completions: true,
+		colorscheme: DefaultColorScheme,
+		errHandler:  DefaultErrorHandler,
 	}
+
 	for _, option := range options {
 		option(&opts)
 	}
 
-	if opts.theme == nil {
-		isDark := lipgloss.HasDarkBackground(os.Stdin, os.Stderr)
-		t := DefaultTheme(isDark)
-		opts.theme = &t
+	helpFunc := func(c *cobra.Command, _ []string) {
+		w := colorprofile.NewWriter(c.OutOrStdout(), os.Environ())
+		helpFn(c, w, makeStyles(mustColorscheme(opts.colorscheme)))
 	}
 
-	styles := makeStyles(*opts.theme)
-
-	root.SetHelpFunc(func(c *cobra.Command, _ []string) {
-		w := colorprofile.NewWriter(c.OutOrStdout(), os.Environ())
-		helpFn(c, w, styles)
-	})
 	root.SilenceUsage = true
 	root.SilenceErrors = true
+	if !opts.skipVersion {
+		root.Version = buildVersion(opts)
+	}
+	root.SetHelpFunc(helpFunc)
 
 	if opts.manpages {
 		root.AddCommand(&cobra.Command{
@@ -108,34 +156,49 @@ func Execute(ctx context.Context, root *cobra.Command, options ...Option) error
 		})
 	}
 
-	if opts.completions {
-		root.InitDefaultCompletionCmd()
-	} else {
+	if !opts.completions {
 		root.CompletionOptions.DisableDefaultCmd = true
 	}
 
-	if opts.version == "" {
-		if info, ok := debug.ReadBuildInfo(); ok && info.Main.Sum != "" {
-			opts.version = info.Main.Version
-			opts.commit = getKey(info, "vcs.revision")
-		} else {
-			opts.version = "unknown (built from source)"
-		}
-	}
-	if len(opts.commit) >= shaLen {
-		opts.version += " (" + opts.commit[:shaLen] + ")"
+	if len(opts.signals) > 0 {
+		var cancel context.CancelFunc
+		ctx, cancel = signal.NotifyContext(ctx, opts.signals...)
+		defer cancel()
 	}
 
-	root.Version = opts.version
-
 	if err := root.ExecuteContext(ctx); err != nil {
+		if w, ok := root.ErrOrStderr().(term.File); ok {
+			// if stderr is not a tty, simply print the error without any
+			// styling or going through an [ErrorHandler]:
+			if !term.IsTerminal(w.Fd()) {
+				_, _ = fmt.Fprintln(w, err.Error())
+				return err //nolint:wrapcheck
+			}
+		}
 		w := colorprofile.NewWriter(root.ErrOrStderr(), os.Environ())
-		writeError(w, styles, err)
+		opts.errHandler(w, makeStyles(mustColorscheme(opts.colorscheme)), err)
 		return err //nolint:wrapcheck
 	}
 	return nil
 }
 
+func buildVersion(opts settings) string {
+	commit := opts.commit
+	version := opts.version
+	if version == "" {
+		if info, ok := debug.ReadBuildInfo(); ok && info.Main.Sum != "" {
+			version = info.Main.Version
+			commit = getKey(info, "vcs.revision")
+		} else {
+			version = "unknown (built from source)"
+		}
+	}
+	if len(commit) >= shaLen {
+		version += " (" + commit[:shaLen] + ")"
+	}
+	return version
+}
+
 func getKey(info *debug.BuildInfo, key string) string {
 	if info == nil {
 		return ""

vendor/github.com/charmbracelet/fang/help.go 🔗

@@ -3,7 +3,10 @@ package fang
 import (
 	"cmp"
 	"fmt"
+	"io"
+	"iter"
 	"os"
+	"reflect"
 	"regexp"
 	"strconv"
 	"strings"
@@ -20,6 +23,7 @@ import (
 const (
 	minSpace = 10
 	shortPad = 2
+	longPad  = 4
 )
 
 var width = sync.OnceValue(func() int {
@@ -45,65 +49,95 @@ func helpFn(c *cobra.Command, w *colorprofile.Writer, styles Styles) {
 		blockWidth = max(blockWidth, lipgloss.Width(ex))
 	}
 	blockWidth = min(width()-padding, blockWidth+padding)
+	blockStyle := styles.Codeblock.Base.Width(blockWidth)
 
-	styles.Codeblock.Base = styles.Codeblock.Base.Width(blockWidth)
+	// if the color profile is ascii or notty, or if the block has no
+	// background color set, remove the vertical padding.
+	if w.Profile <= colorprofile.Ascii || reflect.DeepEqual(blockStyle.GetBackground(), lipgloss.NoColor{}) {
+		blockStyle = blockStyle.PaddingTop(0).PaddingBottom(0)
+	}
 
 	_, _ = fmt.Fprintln(w, styles.Title.Render("usage"))
-	_, _ = fmt.Fprintln(w, styles.Codeblock.Base.Render(usage))
+	_, _ = fmt.Fprintln(w, blockStyle.Render(usage))
 	if len(examples) > 0 {
-		cw := styles.Codeblock.Base.GetWidth() - styles.Codeblock.Base.GetHorizontalPadding()
+		cw := blockStyle.GetWidth() - blockStyle.GetHorizontalPadding()
 		_, _ = fmt.Fprintln(w, styles.Title.Render("examples"))
 		for i, example := range examples {
 			if lipgloss.Width(example) > cw {
 				examples[i] = ansi.Truncate(example, cw, "…")
 			}
 		}
-		_, _ = fmt.Fprintln(w, styles.Codeblock.Base.Render(strings.Join(examples, "\n")))
+		_, _ = fmt.Fprintln(w, blockStyle.Render(strings.Join(examples, "\n")))
 	}
 
+	groups, groupKeys := evalGroups(c)
 	cmds, cmdKeys := evalCmds(c, styles)
 	flags, flagKeys := evalFlags(c, styles)
 	space := calculateSpace(cmdKeys, flagKeys)
 
-	leftPadding := 4
-	if len(cmds) > 0 {
-		_, _ = fmt.Fprintln(w, styles.Title.Render("commands"))
-		for _, k := range cmdKeys {
-			_, _ = fmt.Fprintln(w, lipgloss.JoinHorizontal(
-				lipgloss.Left,
-				lipgloss.NewStyle().PaddingLeft(leftPadding).Render(k),
-				strings.Repeat(" ", space-lipgloss.Width(k)),
-				cmds[k],
-			))
+	for _, groupID := range groupKeys {
+		group := cmds[groupID]
+		if len(group) == 0 {
+			continue
 		}
+		renderGroup(w, styles, space, groups[groupID], func(yield func(string, string) bool) {
+			for _, k := range cmdKeys {
+				cmds, ok := group[k]
+				if !ok {
+					continue
+				}
+				if !yield(k, cmds) {
+					return
+				}
+			}
+		})
 	}
 
 	if len(flags) > 0 {
-		_, _ = fmt.Fprintln(w, styles.Title.Render("flags"))
-		for _, k := range flagKeys {
-			_, _ = fmt.Fprintln(w, lipgloss.JoinHorizontal(
-				lipgloss.Left,
-				lipgloss.NewStyle().PaddingLeft(leftPadding).Render(k),
-				strings.Repeat(" ", space-lipgloss.Width(k)),
-				flags[k],
-			))
-		}
+		renderGroup(w, styles, space, "flags", func(yield func(string, string) bool) {
+			for _, k := range flagKeys {
+				if !yield(k, flags[k]) {
+					return
+				}
+			}
+		})
 	}
 
 	_, _ = fmt.Fprintln(w)
 }
 
-func writeError(w *colorprofile.Writer, styles Styles, err error) {
+// DefaultErrorHandler is the default [ErrorHandler] implementation.
+func DefaultErrorHandler(w io.Writer, styles Styles, err error) {
 	_, _ = fmt.Fprintln(w, styles.ErrorHeader.String())
 	_, _ = fmt.Fprintln(w, styles.ErrorText.Render(err.Error()+"."))
 	_, _ = fmt.Fprintln(w)
-	_, _ = fmt.Fprintln(w, lipgloss.JoinHorizontal(
-		lipgloss.Left,
-		styles.ErrorText.UnsetWidth().Render("Try"),
-		styles.Program.Flag.Render("--help"),
-		styles.ErrorText.UnsetWidth().UnsetMargins().UnsetTransform().PaddingLeft(1).Render("for usage."),
-	))
-	_, _ = fmt.Fprintln(w)
+	if isUsageError(err) {
+		_, _ = fmt.Fprintln(w, lipgloss.JoinHorizontal(
+			lipgloss.Left,
+			styles.ErrorText.UnsetWidth().Render("Try"),
+			styles.Program.Flag.Render(" --help "),
+			styles.ErrorText.UnsetWidth().UnsetMargins().UnsetTransform().Render("for usage."),
+		))
+		_, _ = fmt.Fprintln(w)
+	}
+}
+
+// XXX: this is a hack to detect usage errors.
+// See: https://github.com/spf13/cobra/pull/2266
+func isUsageError(err error) bool {
+	s := err.Error()
+	for _, prefix := range []string{
+		"flag needs an argument:",
+		"unknown flag:",
+		"unknown shorthand flag:",
+		"unknown command",
+		"invalid argument",
+	} {
+		if strings.HasPrefix(s, prefix) {
+			return true
+		}
+	}
+	return false
 }
 
 func writeLongShort(w *colorprofile.Writer, styles Styles, longShort string) {
@@ -118,8 +152,10 @@ var otherArgsRe = regexp.MustCompile(`(\[.*\])`)
 
 // styleUsage stylized styleUsage line for a given command.
 func styleUsage(c *cobra.Command, styles Program, complete bool) string {
-	// XXX: maybe use c.UseLine() here?
 	u := c.Use
+	if complete {
+		u = c.UseLine()
+	}
 	hasArgs := strings.Contains(u, "[args]")
 	hasFlags := strings.Contains(u, "[flags]") || strings.Contains(u, "[--flags]") || c.HasFlags() || c.HasPersistentFlags() || c.HasAvailableFlags()
 	hasCommands := strings.Contains(u, "[command]") || c.HasAvailableSubCommands()
@@ -139,34 +175,38 @@ func styleUsage(c *cobra.Command, styles Program, complete bool) string {
 
 	u = strings.TrimSpace(u)
 
-	useLine := []string{
-		styles.Name.Render(u),
-	}
-	if !complete {
-		useLine[0] = styles.Command.Render(u)
+	useLine := []string{}
+	if complete {
+		parts := strings.Fields(u)
+		useLine = append(useLine, styles.Name.Render(parts[0]))
+		if len(parts) > 1 {
+			useLine = append(useLine, styles.Command.Render(" "+strings.Join(parts[1:], " ")))
+		}
+	} else {
+		useLine = append(useLine, styles.Command.Render(u))
 	}
 	if hasCommands {
 		useLine = append(
 			useLine,
-			styles.DimmedArgument.Render("[command]"),
+			styles.DimmedArgument.Render(" [command]"),
 		)
 	}
 	if hasArgs {
 		useLine = append(
 			useLine,
-			styles.DimmedArgument.Render("[args]"),
+			styles.DimmedArgument.Render(" [args]"),
 		)
 	}
 	for _, arg := range otherArgs {
 		useLine = append(
 			useLine,
-			styles.DimmedArgument.Render(arg),
+			styles.DimmedArgument.Render(" "+arg),
 		)
 	}
 	if hasFlags {
 		useLine = append(
 			useLine,
-			styles.DimmedArgument.Render("[--flags]"),
+			styles.DimmedArgument.Render(" [--flags]"),
 		)
 	}
 	return lipgloss.JoinHorizontal(lipgloss.Left, useLine...)
@@ -180,19 +220,21 @@ func styleExamples(c *cobra.Command, styles Styles) []string {
 	}
 	usage := []string{}
 	examples := strings.Split(c.Example, "\n")
+	var indent bool
 	for i, line := range examples {
 		line = strings.TrimSpace(line)
 		if (i == 0 || i == len(examples)-1) && line == "" {
 			continue
 		}
-		s := styleExample(c, line, styles.Codeblock)
+		s := styleExample(c, line, indent, styles.Codeblock)
 		usage = append(usage, s)
+		indent = len(line) > 1 && (line[len(line)-1] == '\\' || line[len(line)-1] == '|')
 	}
 
 	return usage
 }
 
-func styleExample(c *cobra.Command, line string, styles Codeblock) string {
+func styleExample(c *cobra.Command, line string, indent bool, styles Codeblock) string {
 	if strings.HasPrefix(line, "# ") {
 		return lipgloss.JoinHorizontal(
 			lipgloss.Left,
@@ -200,66 +242,110 @@ func styleExample(c *cobra.Command, line string, styles Codeblock) string {
 		)
 	}
 
-	args := strings.Fields(line)
-	var nextIsFlag bool
 	var isQuotedString bool
+	var foundProgramName bool
+	var isRedirecting bool
+	programName := c.Root().Name()
+	args := strings.Fields(line)
+	var cleanArgs []string
 	for i, arg := range args {
-		if i == 0 {
-			args[i] = styles.Program.Name.Render(arg)
-			continue
+		isQuoteStart := arg[0] == '"' || arg[0] == '\''
+		isQuoteEnd := arg[len(arg)-1] == '"' || arg[len(arg)-1] == '\''
+		isFlag := arg[0] == '-'
+
+		switch i {
+		case 0:
+			args[i] = ""
+			if indent {
+				args[i] = styles.Program.DimmedArgument.Render("  ")
+				indent = false
+			}
+		default:
+			args[i] = styles.Program.DimmedArgument.Render(" ")
 		}
 
-		quoteStart := arg[0] == '"'
-		quoteEnd := arg[len(arg)-1] == '"'
-		flagStart := arg[0] == '-'
-		if i == 1 && !quoteStart && !flagStart {
-			args[i] = styles.Program.Command.Render(arg)
+		if isRedirecting {
+			args[i] += styles.Program.DimmedArgument.Render(arg)
+			isRedirecting = false
 			continue
 		}
-		if quoteStart {
-			isQuotedString = true
-		}
-		if isQuotedString {
-			args[i] = styles.Program.QuotedString.Render(arg)
-			if quoteEnd {
-				isQuotedString = false
+
+		switch arg {
+		case "\\":
+			if i == len(args)-1 {
+				args[i] += styles.Program.DimmedArgument.Render(arg)
+				continue
 			}
+		case "|", "||", "-", "&", "&&":
+			args[i] += styles.Program.DimmedArgument.Render(arg)
 			continue
 		}
-		if nextIsFlag {
-			args[i] = styles.Program.Flag.Render(arg)
+
+		if isRedirect(arg) {
+			args[i] += styles.Program.DimmedArgument.Render(arg)
+			isRedirecting = true
 			continue
 		}
-		var dashes string
-		if strings.HasPrefix(arg, "-") {
-			dashes = "-"
+
+		if !foundProgramName { //nolint:nestif
+			if isQuotedString {
+				args[i] += styles.Program.QuotedString.Render(arg)
+				isQuotedString = !isQuoteEnd
+				continue
+			}
+			if left, right, ok := strings.Cut(arg, "="); ok {
+				args[i] += styles.Program.Flag.Render(left + "=")
+				if right[0] == '"' {
+					isQuotedString = true
+					args[i] += styles.Program.QuotedString.Render(right)
+					continue
+				}
+				args[i] += styles.Program.Argument.Render(right)
+				continue
+			}
+
+			if arg == programName {
+				args[i] += styles.Program.Name.Render(arg)
+				foundProgramName = true
+				continue
+			}
 		}
-		if strings.HasPrefix(arg, "--") {
-			dashes = "--"
+
+		if !isQuoteStart && !isQuotedString && !isFlag {
+			cleanArgs = append(cleanArgs, arg)
+		}
+
+		if !isQuoteStart && !isFlag && isSubCommand(c, cleanArgs, arg) {
+			args[i] += styles.Program.Command.Render(arg)
+			continue
+		}
+		isQuotedString = isQuotedString || isQuoteStart
+		if isQuotedString {
+			args[i] += styles.Program.QuotedString.Render(arg)
+			isQuotedString = !isQuoteEnd
+			continue
 		}
 		// handle a flag
-		if dashes != "" {
+		if isFlag {
 			name, value, ok := strings.Cut(arg, "=")
-			name = strings.TrimPrefix(name, dashes)
 			// it is --flag=value
 			if ok {
-				args[i] = lipgloss.JoinHorizontal(
+				args[i] += lipgloss.JoinHorizontal(
 					lipgloss.Left,
-					styles.Program.Flag.Render(dashes+name+"="),
-					styles.Program.Argument.UnsetPadding().Render(value),
+					styles.Program.Flag.Render(name+"="),
+					styles.Program.Argument.Render(value),
 				)
 				continue
 			}
 			// it is either --bool-flag or --flag value
-			args[i] = lipgloss.JoinHorizontal(
+			args[i] += lipgloss.JoinHorizontal(
 				lipgloss.Left,
-				styles.Program.Flag.Render(dashes+name),
+				styles.Program.Flag.Render(name),
 			)
-			// if the flag is not a bool flag, next arg continues current flag
-			nextIsFlag = !isFlagBool(c, name)
 			continue
 		}
-		args[i] = styles.Program.Argument.Render(arg)
+
+		args[i] += styles.Program.Argument.Render(arg)
 	}
 
 	return lipgloss.JoinHorizontal(
@@ -284,8 +370,7 @@ func evalFlags(c *cobra.Command, styles Styles) (map[string]string, []string) {
 		} else {
 			parts = append(
 				parts,
-				styles.Program.Flag.Render("-"+f.Shorthand),
-				styles.Program.Flag.Render("--"+f.Name),
+				styles.Program.Flag.Render("-"+f.Shorthand+" --"+f.Name),
 			)
 		}
 		key := lipgloss.JoinHorizontal(lipgloss.Left, parts...)
@@ -303,22 +388,50 @@ func evalFlags(c *cobra.Command, styles Styles) (map[string]string, []string) {
 	return flags, keys
 }
 
-func evalCmds(c *cobra.Command, styles Styles) (map[string]string, []string) {
+// result is map[groupID]map[styled cmd name]styled cmd help, and the keys in
+// the order they are defined.
+func evalCmds(c *cobra.Command, styles Styles) (map[string](map[string]string), []string) {
 	padStyle := lipgloss.NewStyle().PaddingLeft(0) //nolint:mnd
 	keys := []string{}
-	cmds := map[string]string{}
+	cmds := map[string]map[string]string{}
 	for _, sc := range c.Commands() {
 		if sc.Hidden {
 			continue
 		}
+		if _, ok := cmds[sc.GroupID]; !ok {
+			cmds[sc.GroupID] = map[string]string{}
+		}
 		key := padStyle.Render(styleUsage(sc, styles.Program, false))
 		help := styles.FlagDescription.Render(sc.Short)
-		cmds[key] = help
+		cmds[sc.GroupID][key] = help
 		keys = append(keys, key)
 	}
 	return cmds, keys
 }
 
+func evalGroups(c *cobra.Command) (map[string]string, []string) {
+	// make sure the default group is the first
+	ids := []string{""}
+	groups := map[string]string{"": "commands"}
+	for _, g := range c.Groups() {
+		groups[g.ID] = g.Title
+		ids = append(ids, g.ID)
+	}
+	return groups, ids
+}
+
+func renderGroup(w io.Writer, styles Styles, space int, name string, items iter.Seq2[string, string]) {
+	_, _ = fmt.Fprintln(w, styles.Title.Render(name))
+	for key, help := range items {
+		_, _ = fmt.Fprintln(w, lipgloss.JoinHorizontal(
+			lipgloss.Left,
+			lipgloss.NewStyle().PaddingLeft(longPad).Render(key),
+			strings.Repeat(" ", space-lipgloss.Width(key)),
+			help,
+		))
+	}
+}
+
 func calculateSpace(k1, k2 []string) int {
 	const spaceBetween = 2
 	space := minSpace
@@ -328,13 +441,18 @@ func calculateSpace(k1, k2 []string) int {
 	return space
 }
 
-func isFlagBool(c *cobra.Command, name string) bool {
-	flag := c.Flags().Lookup(name)
-	if flag == nil && len(name) == 1 {
-		flag = c.Flags().ShorthandLookup(name)
-	}
-	if flag == nil {
-		return false
+func isSubCommand(c *cobra.Command, args []string, word string) bool {
+	cmd, _, _ := c.Root().Traverse(args)
+	return cmd != nil && cmd.Name() == word
+}
+
+var redirectPrefixes = []string{">", "<", "&>", "2>", "1>", ">>", "2>>"}
+
+func isRedirect(s string) bool {
+	for _, p := range redirectPrefixes {
+		if strings.HasPrefix(s, p) {
+			return true
+		}
 	}
-	return flag.Value.Type() == "bool"
+	return false
 }

vendor/github.com/charmbracelet/fang/theme.go 🔗

@@ -2,10 +2,12 @@ package fang
 
 import (
 	"image/color"
+	"os"
 	"strings"
 
 	"github.com/charmbracelet/lipgloss/v2"
 	"github.com/charmbracelet/x/exp/charmtone"
+	"github.com/charmbracelet/x/term"
 	"golang.org/x/text/cases"
 	"golang.org/x/text/language"
 )
@@ -31,8 +33,14 @@ type ColorScheme struct {
 }
 
 // DefaultTheme is the default colorscheme.
+//
+// Deprecated: use [DefaultColorScheme] instead.
 func DefaultTheme(isDark bool) ColorScheme {
-	c := lipgloss.LightDark(isDark)
+	return DefaultColorScheme(lipgloss.LightDark(isDark))
+}
+
+// DefaultColorScheme is the default colorscheme.
+func DefaultColorScheme(c lipgloss.LightDarkFunc) ColorScheme {
 	return ColorScheme{
 		Base:           c(charmtone.Charcoal, charmtone.Ash),
 		Title:          charmtone.Charple,
@@ -45,7 +53,7 @@ func DefaultTheme(isDark bool) ColorScheme {
 		Argument:       c(charmtone.Charcoal, charmtone.Ash),
 		Description:    c(charmtone.Charcoal, charmtone.Ash), // flag and command descriptions
 		FlagDefault:    c(charmtone.Smoke, charmtone.Squid),  // flag default values in descriptions
-		QuotedString:   c(charmtone.Charcoal, charmtone.Ash),
+		QuotedString:   c(charmtone.Coral, charmtone.Salmon),
 		ErrorHeader: [2]color.Color{
 			charmtone.Butter,
 			charmtone.Cherry,
@@ -53,6 +61,26 @@ func DefaultTheme(isDark bool) ColorScheme {
 	}
 }
 
+// AnsiColorScheme is a ANSI colorscheme.
+func AnsiColorScheme(c lipgloss.LightDarkFunc) ColorScheme {
+	base := c(lipgloss.Black, lipgloss.White)
+	return ColorScheme{
+		Base:         base,
+		Title:        lipgloss.Blue,
+		Description:  base,
+		Comment:      c(lipgloss.BrightWhite, lipgloss.BrightBlack),
+		Flag:         lipgloss.Magenta,
+		FlagDefault:  lipgloss.BrightMagenta,
+		Command:      lipgloss.Cyan,
+		QuotedString: lipgloss.Green,
+		Argument:     base,
+		Help:         base,
+		Dash:         base,
+		ErrorHeader:  [2]color.Color{lipgloss.Black, lipgloss.Red},
+		ErrorDetails: lipgloss.Red,
+	}
+}
+
 // Styles represents all the styles used.
 type Styles struct {
 	Text            lipgloss.Style
@@ -84,6 +112,14 @@ type Program struct {
 	QuotedString   lipgloss.Style
 }
 
+func mustColorscheme(cs func(lipgloss.LightDarkFunc) ColorScheme) ColorScheme {
+	var isDark bool
+	if term.IsTerminal(os.Stdout.Fd()) {
+		isDark = lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+	}
+	return cs(lipgloss.LightDark(isDark))
+}
+
 func makeStyles(cs ColorScheme) Styles {
 	//nolint:mnd
 	return Styles{
@@ -98,8 +134,7 @@ func makeStyles(cs ColorScheme) Styles {
 			Foreground(cs.Description).
 			Transform(titleFirstWord),
 		FlagDefault: lipgloss.NewStyle().
-			Foreground(cs.FlagDefault).
-			PaddingLeft(1),
+			Foreground(cs.FlagDefault),
 		Codeblock: Codeblock{
 			Base: lipgloss.NewStyle().
 				Background(cs.Codeblock).
@@ -116,23 +151,18 @@ func makeStyles(cs ColorScheme) Styles {
 					Background(cs.Codeblock).
 					Foreground(cs.Program),
 				Flag: lipgloss.NewStyle().
-					PaddingLeft(1).
 					Background(cs.Codeblock).
 					Foreground(cs.Flag),
 				Argument: lipgloss.NewStyle().
-					PaddingLeft(1).
 					Background(cs.Codeblock).
 					Foreground(cs.Argument),
 				DimmedArgument: lipgloss.NewStyle().
-					PaddingLeft(1).
 					Background(cs.Codeblock).
 					Foreground(cs.DimmedArgument),
 				Command: lipgloss.NewStyle().
-					PaddingLeft(1).
 					Background(cs.Codeblock).
 					Foreground(cs.Command),
 				QuotedString: lipgloss.NewStyle().
-					PaddingLeft(1).
 					Background(cs.Codeblock).
 					Foreground(cs.QuotedString),
 			},
@@ -141,18 +171,14 @@ func makeStyles(cs ColorScheme) Styles {
 			Name: lipgloss.NewStyle().
 				Foreground(cs.Program),
 			Argument: lipgloss.NewStyle().
-				PaddingLeft(1).
 				Foreground(cs.Argument),
 			DimmedArgument: lipgloss.NewStyle().
-				PaddingLeft(1).
 				Foreground(cs.DimmedArgument),
 			Flag: lipgloss.NewStyle().
-				PaddingLeft(1).
 				Foreground(cs.Flag),
 			Command: lipgloss.NewStyle().
 				Foreground(cs.Command),
 			QuotedString: lipgloss.NewStyle().
-				PaddingLeft(1).
 				Foreground(cs.QuotedString),
 		},
 		Span: lipgloss.NewStyle().

vendor/github.com/charmbracelet/lipgloss/v2/get.go 🔗

@@ -135,6 +135,16 @@ func (s Style) GetPaddingLeft() int {
 	return s.getAsInt(paddingLeftKey)
 }
 
+// GetPaddingChar returns the style's padding character. If no value is set a
+// space (`\u0020`) is returned.
+func (s Style) GetPaddingChar() rune {
+	char := s.getAsRune(paddingCharKey)
+	if char == 0 {
+		return ' '
+	}
+	return char
+}
+
 // GetHorizontalPadding returns the style's left and right padding. Unset
 // values are measured as 0.
 func (s Style) GetHorizontalPadding() int {
@@ -186,6 +196,16 @@ func (s Style) GetMarginLeft() int {
 	return s.getAsInt(marginLeftKey)
 }
 
+// GetMarginChar returns the style's padding character. If no value is set a
+// space (`\u0020`) is returned.
+func (s Style) GetMarginChar() rune {
+	char := s.getAsRune(marginCharKey)
+	if char == 0 {
+		return ' '
+	}
+	return char
+}
+
 // GetHorizontalMargins returns the style's left and right margins. Unset
 // values are measured as 0.
 func (s Style) GetHorizontalMargins() int {
@@ -432,6 +452,19 @@ func (s Style) isSet(k propKey) bool {
 	return s.props.has(k)
 }
 
+func (s Style) getAsRune(k propKey) rune {
+	if !s.isSet(k) {
+		return 0
+	}
+	switch k { //nolint:exhaustive
+	case paddingCharKey:
+		return s.paddingChar
+	case marginCharKey:
+		return s.marginChar
+	}
+	return 0
+}
+
 func (s Style) getAsBool(k propKey, defaultVal bool) bool {
 	if !s.isSet(k) {
 		return defaultVal

vendor/github.com/charmbracelet/lipgloss/v2/set.go 🔗

@@ -29,6 +29,8 @@ func (s *Style) set(key propKey, value any) {
 		s.paddingBottom = max(0, value.(int))
 	case paddingLeftKey:
 		s.paddingLeft = max(0, value.(int))
+	case paddingCharKey:
+		s.paddingChar = value.(rune)
 	case marginTopKey:
 		s.marginTop = max(0, value.(int))
 	case marginRightKey:
@@ -39,6 +41,8 @@ func (s *Style) set(key propKey, value any) {
 		s.marginLeft = max(0, value.(int))
 	case marginBackgroundKey:
 		s.marginBgColor = colorOrNil(value)
+	case marginCharKey:
+		s.marginChar = value.(rune)
 	case borderStyleKey:
 		s.borderStyle = value.(Border)
 	case borderTopForegroundKey:
@@ -111,6 +115,8 @@ func (s *Style) setFrom(key propKey, i Style) {
 		s.set(paddingBottomKey, i.paddingBottom)
 	case paddingLeftKey:
 		s.set(paddingLeftKey, i.paddingLeft)
+	case paddingCharKey:
+		s.set(paddingCharKey, i.paddingChar)
 	case marginTopKey:
 		s.set(marginTopKey, i.marginTop)
 	case marginRightKey:
@@ -121,6 +127,8 @@ func (s *Style) setFrom(key propKey, i Style) {
 		s.set(marginLeftKey, i.marginLeft)
 	case marginBackgroundKey:
 		s.set(marginBackgroundKey, i.marginBgColor)
+	case marginCharKey:
+		s.set(marginCharKey, i.marginChar)
 	case borderStyleKey:
 		s.set(borderStyleKey, i.borderStyle)
 	case borderTopForegroundKey:
@@ -320,6 +328,18 @@ func (s Style) PaddingBottom(i int) Style {
 	return s
 }
 
+// PaddingChar sets the character used for padding. This is useful for
+// rendering blocks with a specific character, such as a space or a dot.
+// Example of using [NBSP] as padding to prevent line breaks:
+//
+//	```go
+//	s := lipgloss.NewStyle().PaddingChar(lipgloss.NBSP)
+//	```
+func (s Style) PaddingChar(r rune) Style {
+	s.set(paddingCharKey, r)
+	return s
+}
+
 // ColorWhitespace determines whether or not the background color should be
 // applied to the padding. This is true by default as it's more than likely the
 // desired and expected behavior, but it can be disabled for certain graphic
@@ -390,6 +410,13 @@ func (s Style) MarginBackground(c color.Color) Style {
 	return s
 }
 
+// MarginChar sets the character used for the margin. This is useful for
+// rendering blocks with a specific character, such as a space or a dot.
+func (s Style) MarginChar(r rune) Style {
+	s.set(marginCharKey, r)
+	return s
+}
+
 // Border is shorthand for setting the border style and which sides should
 // have a border at once. The variadic argument sides works as follows:
 //

vendor/github.com/charmbracelet/lipgloss/v2/style.go 🔗

@@ -10,7 +10,8 @@ import (
 )
 
 const (
-	nbsp            = '\u00A0'
+	// NBSP is the non-breaking space rune.
+	NBSP            = '\u00A0'
 	tabWidthDefault = 4
 )
 
@@ -44,6 +45,7 @@ const (
 	paddingRightKey
 	paddingBottomKey
 	paddingLeftKey
+	paddingCharKey
 
 	// Margins.
 	marginTopKey
@@ -51,6 +53,7 @@ const (
 	marginBottomKey
 	marginLeftKey
 	marginBackgroundKey
+	marginCharKey
 
 	// Border runes.
 	borderStyleKey
@@ -128,12 +131,14 @@ type Style struct {
 	paddingRight  int
 	paddingBottom int
 	paddingLeft   int
+	paddingChar   rune
 
 	marginTop     int
 	marginRight   int
 	marginBottom  int
 	marginLeft    int
 	marginBgColor color.Color
+	marginChar    rune
 
 	borderStyle         Border
 	borderTopFgColor    color.Color
@@ -387,23 +392,24 @@ func (s Style) Render(strs ...string) string {
 
 	// Padding
 	if !inline { //nolint:nestif
+		padChar := s.paddingChar
+		if padChar == 0 {
+			padChar = ' '
+		}
 		if leftPadding > 0 {
 			var st *ansi.Style
 			if colorWhitespace || styleWhitespace {
 				st = &teWhitespace
 			}
-			str = padLeft(str, leftPadding, st, nbsp)
+			str = padLeft(str, leftPadding, st, padChar)
 		}
 
-		// XXX: We use a non-breaking space to pad so that the padding is
-		// preserved when the string is copied and pasted.
-
 		if rightPadding > 0 {
 			var st *ansi.Style
 			if colorWhitespace || styleWhitespace {
 				st = &teWhitespace
 			}
-			str = padRight(str, rightPadding, st, nbsp)
+			str = padRight(str, rightPadding, st, padChar)
 		}
 
 		if topPadding > 0 {
@@ -494,8 +500,12 @@ func (s Style) applyMargins(str string, inline bool) string {
 	}
 
 	// Add left and right margin
-	str = padLeft(str, leftMargin, &style, ' ')
-	str = padRight(str, rightMargin, &style, ' ')
+	marginChar := s.marginChar
+	if marginChar == 0 {
+		marginChar = ' '
+	}
+	str = padLeft(str, leftMargin, &style, marginChar)
+	str = padRight(str, rightMargin, &style, marginChar)
 
 	// Top/bottom margin
 	if !inline {

vendor/github.com/charmbracelet/lipgloss/v2/unset.go 🔗

@@ -96,6 +96,13 @@ func (s Style) UnsetPadding() Style {
 	s.unset(paddingRightKey)
 	s.unset(paddingTopKey)
 	s.unset(paddingBottomKey)
+	s.unset(paddingCharKey)
+	return s
+}
+
+// UnsetPaddingChar removes the padding character style rule, if set.
+func (s Style) UnsetPaddingChar() Style {
+	s.unset(paddingCharKey)
 	return s
 }
 

vendor/github.com/charmbracelet/x/exp/charmtone/charmtone.go 🔗

@@ -65,7 +65,7 @@ const (
 	Citron
 	Zest
 	Pepper
-	Barbeque
+	BBQ
 	Charcoal
 	Iron
 	Oyster
@@ -74,6 +74,22 @@ const (
 	Ash
 	Salt
 	Butter
+
+	// Diffs: additions. The brightest color in this set is Julep, defined
+	// above.
+	Pickle
+	Gator
+	Spinach
+
+	// Diffs: deletions. The brightest color in this set is Cherry, defined
+	// above.
+	Pom
+	Steak
+	Toast
+
+	// Provisional.
+	NeueGuac
+	NeueZinc
 )
 
 // RGBA returns the red, green, blue, and alpha values of the color. It
@@ -139,7 +155,7 @@ func (k Key) String() string {
 		Citron:   "Citron",
 		Zest:     "Zest",
 		Pepper:   "Pepper",
-		Barbeque: "Barbeque",
+		BBQ:      "BBQ",
 		Charcoal: "Charcoal",
 		Iron:     "Iron",
 		Oyster:   "Oyster",
@@ -148,6 +164,20 @@ func (k Key) String() string {
 		Salt:     "Salt",
 		Ash:      "Ash",
 		Butter:   "Butter",
+
+		// Diffs: additions.
+		Pickle:  "Pickle",
+		Gator:   "Gator",
+		Spinach: "Spinach",
+
+		// Diffs: deletions.
+		Pom:   "Pom",
+		Steak: "Steak",
+		Toast: "Toast",
+
+		// Provisional.
+		NeueGuac: "Neue Guac",
+		NeueZinc: "Neue Zinc",
 	}[k]
 }
 
@@ -193,17 +223,17 @@ func (k Key) Hex() string {
 		Damson:   "#007AB8",
 		Malibu:   "#00A4FF",
 		Sardine:  "#4FBEFE",
-		Zinc:     "#0e9996",
+		Zinc:     "#10B1AE",
 		Turtle:   "#0ADCD9",
 		Lichen:   "#5CDFEA",
-		Guac:     "#00b875",
+		Guac:     "#12C78F",
 		Julep:    "#00FFB2",
 		Bok:      "#68FFD6",
 		Mustard:  "#F5EF34",
 		Citron:   "#E8FF27",
 		Zest:     "#E8FE96",
 		Pepper:   "#201F26",
-		Barbeque: "#2d2c35",
+		BBQ:      "#2d2c35",
 		Charcoal: "#3A3943",
 		Iron:     "#4D4C57",
 		Oyster:   "#605F6B",
@@ -212,6 +242,20 @@ func (k Key) Hex() string {
 		Ash:      "#DFDBDD",
 		Salt:     "#F1EFEF",
 		Butter:   "#FFFAF1",
+
+		// Diffs: additions.
+		Pickle:  "#00A475",
+		Gator:   "#18463D",
+		Spinach: "#1C3634",
+
+		// Diffs: deletions.
+		Pom:   "#AB2454",
+		Steak: "#582238",
+		Toast: "#412130",
+
+		// Provisional.
+		NeueGuac: "#00b875",
+		NeueZinc: "#0e9996",
 	}[k]
 }
 
@@ -267,7 +311,7 @@ func Keys() []Key {
 		Citron,
 		Zest,
 		Pepper,
-		Barbeque,
+		BBQ,
 		Charcoal,
 		Iron,
 		Oyster,
@@ -276,6 +320,8 @@ func Keys() []Key {
 		Ash,
 		Salt,
 		Butter,
+
+		// XXX: additions and deletions are not included, yet.
 	}
 }
 

vendor/github.com/mark3labs/mcp-go/client/client.go 🔗

@@ -22,6 +22,7 @@ type Client struct {
 	requestID          atomic.Int64
 	clientCapabilities mcp.ClientCapabilities
 	serverCapabilities mcp.ServerCapabilities
+	samplingHandler    SamplingHandler
 }
 
 type ClientOption func(*Client)
@@ -33,6 +34,21 @@ func WithClientCapabilities(capabilities mcp.ClientCapabilities) ClientOption {
 	}
 }
 
+// WithSamplingHandler sets the sampling handler for the client.
+// When set, the client will declare sampling capability during initialization.
+func WithSamplingHandler(handler SamplingHandler) ClientOption {
+	return func(c *Client) {
+		c.samplingHandler = handler
+  }
+}
+
+// WithSession assumes a MCP Session has already been initialized
+func WithSession() ClientOption {
+	return func(c *Client) {
+		c.initialized = true
+	}
+}
+
 // NewClient creates a new MCP client with the given transport.
 // Usage:
 //
@@ -71,6 +87,12 @@ func (c *Client) Start(ctx context.Context) error {
 			handler(notification)
 		}
 	})
+
+	// Set up request handler for bidirectional communication (e.g., sampling)
+	if bidirectional, ok := c.transport.(transport.BidirectionalInterface); ok {
+		bidirectional.SetRequestHandler(c.handleIncomingRequest)
+	}
+
 	return nil
 }
 
@@ -127,6 +149,12 @@ func (c *Client) Initialize(
 	ctx context.Context,
 	request mcp.InitializeRequest,
 ) (*mcp.InitializeResult, error) {
+	// Merge client capabilities with sampling capability if handler is configured
+	capabilities := request.Params.Capabilities
+	if c.samplingHandler != nil {
+		capabilities.Sampling = &struct{}{}
+	}
+
 	// Ensure we send a params object with all required fields
 	params := struct {
 		ProtocolVersion string                 `json:"protocolVersion"`
@@ -135,7 +163,7 @@ func (c *Client) Initialize(
 	}{
 		ProtocolVersion: request.Params.ProtocolVersion,
 		ClientInfo:      request.Params.ClientInfo,
-		Capabilities:    request.Params.Capabilities, // Will be empty struct if not set
+		Capabilities:    capabilities,
 	}
 
 	response, err := c.sendRequest(ctx, "initialize", params)
@@ -398,6 +426,64 @@ func (c *Client) Complete(
 	return &result, nil
 }
 
+// handleIncomingRequest processes incoming requests from the server.
+// This is the main entry point for server-to-client requests like sampling.
+func (c *Client) handleIncomingRequest(ctx context.Context, request transport.JSONRPCRequest) (*transport.JSONRPCResponse, error) {
+	switch request.Method {
+	case string(mcp.MethodSamplingCreateMessage):
+		return c.handleSamplingRequestTransport(ctx, request)
+	default:
+		return nil, fmt.Errorf("unsupported request method: %s", request.Method)
+	}
+}
+
+// handleSamplingRequestTransport handles sampling requests at the transport level.
+func (c *Client) handleSamplingRequestTransport(ctx context.Context, request transport.JSONRPCRequest) (*transport.JSONRPCResponse, error) {
+	if c.samplingHandler == nil {
+		return nil, fmt.Errorf("no sampling handler configured")
+	}
+
+	// Parse the request parameters
+	var params mcp.CreateMessageParams
+	if request.Params != nil {
+		paramsBytes, err := json.Marshal(request.Params)
+		if err != nil {
+			return nil, fmt.Errorf("failed to marshal params: %w", err)
+		}
+		if err := json.Unmarshal(paramsBytes, &params); err != nil {
+			return nil, fmt.Errorf("failed to unmarshal params: %w", err)
+		}
+	}
+
+	// Create the MCP request
+	mcpRequest := mcp.CreateMessageRequest{
+		Request: mcp.Request{
+			Method: string(mcp.MethodSamplingCreateMessage),
+		},
+		CreateMessageParams: params,
+	}
+
+	// Call the sampling handler
+	result, err := c.samplingHandler.CreateMessage(ctx, mcpRequest)
+	if err != nil {
+		return nil, err
+	}
+
+	// Marshal the result
+	resultBytes, err := json.Marshal(result)
+	if err != nil {
+		return nil, fmt.Errorf("failed to marshal result: %w", err)
+	}
+
+	// Create the transport response
+	response := &transport.JSONRPCResponse{
+		JSONRPC: mcp.JSONRPC_VERSION,
+		ID:      request.ID,
+		Result:  json.RawMessage(resultBytes),
+	}
+
+	return response, nil
+}
 func listByPage[T any](
 	ctx context.Context,
 	client *Client,
@@ -432,3 +518,17 @@ func (c *Client) GetServerCapabilities() mcp.ServerCapabilities {
 func (c *Client) GetClientCapabilities() mcp.ClientCapabilities {
 	return c.clientCapabilities
 }
+
+// GetSessionId returns the session ID of the transport.
+// If the transport does not support sessions, it returns an empty string.
+func (c *Client) GetSessionId() string {
+	if c.transport == nil {
+		return ""
+	}
+	return c.transport.GetSessionId()
+}
+
+// IsInitialized returns true if the client has been initialized.
+func (c *Client) IsInitialized() bool {
+	return c.initialized
+}

vendor/github.com/mark3labs/mcp-go/client/http.go 🔗

@@ -13,5 +13,10 @@ func NewStreamableHttpClient(baseURL string, options ...transport.StreamableHTTP
 	if err != nil {
 		return nil, fmt.Errorf("failed to create SSE transport: %w", err)
 	}
-	return NewClient(trans), nil
+	clientOptions := make([]ClientOption, 0)
+	sessionID := trans.GetSessionId()
+	if sessionID != "" {
+		clientOptions = append(clientOptions, WithSession())
+	}
+	return NewClient(trans, clientOptions...), nil
 }

vendor/github.com/mark3labs/mcp-go/client/sampling.go 🔗

@@ -0,0 +1,20 @@
+package client
+
+import (
+	"context"
+
+	"github.com/mark3labs/mcp-go/mcp"
+)
+
+// SamplingHandler defines the interface for handling sampling requests from servers.
+// Clients can implement this interface to provide LLM sampling capabilities to servers.
+type SamplingHandler interface {
+	// CreateMessage handles a sampling request from the server and returns the generated message.
+	// The implementation should:
+	// 1. Validate the request parameters
+	// 2. Optionally prompt the user for approval (human-in-the-loop)
+	// 3. Select an appropriate model based on preferences
+	// 4. Generate the response using the selected model
+	// 5. Return the result with model information and stop reason
+	CreateMessage(ctx context.Context, request mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error)
+}

vendor/github.com/mark3labs/mcp-go/client/stdio.go 🔗

@@ -19,10 +19,26 @@ func NewStdioMCPClient(
 	env []string,
 	args ...string,
 ) (*Client, error) {
+	return NewStdioMCPClientWithOptions(command, env, args)
+}
+
+// NewStdioMCPClientWithOptions creates a new stdio-based MCP client that communicates with a subprocess.
+// It launches the specified command with given arguments and sets up stdin/stdout pipes for communication.
+// Optional configuration functions can be provided to customize the transport before it starts,
+// such as setting a custom command function.
+//
+// NOTICE: NewStdioMCPClientWithOptions automatically starts the underlying transport.
+// Don't call the Start method manually.
+// This is for backward compatibility.
+func NewStdioMCPClientWithOptions(
+	command string,
+	env []string,
+	args []string,
+	opts ...transport.StdioOption,
+) (*Client, error) {
+	stdioTransport := transport.NewStdioWithOptions(command, env, args, opts...)
 
-	stdioTransport := transport.NewStdio(command, env, args...)
-	err := stdioTransport.Start(context.Background())
-	if err != nil {
+	if err := stdioTransport.Start(context.Background()); err != nil {
 		return nil, fmt.Errorf("failed to start stdio transport: %w", err)
 	}
 

vendor/github.com/mark3labs/mcp-go/client/transport/interface.go 🔗

@@ -29,6 +29,22 @@ type Interface interface {
 
 	// Close the connection.
 	Close() error
+
+	// GetSessionId returns the session ID of the transport.
+	GetSessionId() string
+}
+
+// RequestHandler defines a function that handles incoming requests from the server.
+type RequestHandler func(ctx context.Context, request JSONRPCRequest) (*JSONRPCResponse, error)
+
+// BidirectionalInterface extends Interface to support incoming requests from the server.
+// This is used for features like sampling where the server can send requests to the client.
+type BidirectionalInterface interface {
+	Interface
+
+	// SetRequestHandler sets the handler for incoming requests from the server.
+	// The handler should process the request and return a response.
+	SetRequestHandler(handler RequestHandler)
 }
 
 type JSONRPCRequest struct {
@@ -41,10 +57,10 @@ type JSONRPCRequest struct {
 type JSONRPCResponse struct {
 	JSONRPC string          `json:"jsonrpc"`
 	ID      mcp.RequestId   `json:"id"`
-	Result  json.RawMessage `json:"result"`
+	Result  json.RawMessage `json:"result,omitempty"`
 	Error   *struct {
 		Code    int             `json:"code"`
 		Message string          `json:"message"`
 		Data    json.RawMessage `json:"data"`
-	} `json:"error"`
+	} `json:"error,omitempty"`
 }

vendor/github.com/mark3labs/mcp-go/client/transport/sse.go 🔗

@@ -428,6 +428,12 @@ func (c *SSE) Close() error {
 	return nil
 }
 
+// GetSessionId returns the session ID of the transport.
+// Since SSE does not maintain a session ID, it returns an empty string.
+func (c *SSE) GetSessionId() string {
+	return ""
+}
+
 // SendNotification sends a JSON-RPC notification to the server without expecting a response.
 func (c *SSE) SendNotification(ctx context.Context, notification mcp.JSONRPCNotification) error {
 	if c.endpoint == nil {

vendor/github.com/mark3labs/mcp-go/client/transport/stdio.go 🔗

@@ -23,6 +23,7 @@ type Stdio struct {
 	env     []string
 
 	cmd            *exec.Cmd
+	cmdFunc        CommandFunc
 	stdin          io.WriteCloser
 	stdout         *bufio.Reader
 	stderr         io.ReadCloser
@@ -31,6 +32,28 @@ type Stdio struct {
 	done           chan struct{}
 	onNotification func(mcp.JSONRPCNotification)
 	notifyMu       sync.RWMutex
+	onRequest      RequestHandler
+	requestMu      sync.RWMutex
+	ctx            context.Context
+	ctxMu          sync.RWMutex
+}
+
+// StdioOption defines a function that configures a Stdio transport instance.
+// Options can be used to customize the behavior of the transport before it starts,
+// such as setting a custom command function.
+type StdioOption func(*Stdio)
+
+// CommandFunc is a factory function that returns a custom exec.Cmd used to launch the MCP subprocess.
+// It can be used to apply sandboxing, custom environment control, working directories, etc.
+type CommandFunc func(ctx context.Context, command string, env []string, args []string) (*exec.Cmd, error)
+
+// WithCommandFunc sets a custom command factory function for the stdio transport.
+// The CommandFunc is responsible for constructing the exec.Cmd used to launch the subprocess,
+// allowing control over attributes like environment, working directory, and system-level sandboxing.
+func WithCommandFunc(f CommandFunc) StdioOption {
+	return func(s *Stdio) {
+		s.cmdFunc = f
+	}
 }
 
 // NewIO returns a new stdio-based transport using existing input, output, and
@@ -44,6 +67,7 @@ func NewIO(input io.Reader, output io.WriteCloser, logging io.ReadCloser) *Stdio
 
 		responses: make(map[string]chan *JSONRPCResponse),
 		done:      make(chan struct{}),
+		ctx:       context.Background(),
 	}
 }
 
@@ -55,20 +79,43 @@ func NewStdio(
 	env []string,
 	args ...string,
 ) *Stdio {
+	return NewStdioWithOptions(command, env, args)
+}
 
-	client := &Stdio{
+// NewStdioWithOptions creates a new stdio transport to communicate with a subprocess.
+// It launches the specified command with given arguments and sets up stdin/stdout pipes for communication.
+// Returns an error if the subprocess cannot be started or the pipes cannot be created.
+// Optional configuration functions can be provided to customize the transport before it starts,
+// such as setting a custom command factory.
+func NewStdioWithOptions(
+	command string,
+	env []string,
+	args []string,
+	opts ...StdioOption,
+) *Stdio {
+	s := &Stdio{
 		command: command,
 		args:    args,
 		env:     env,
 
 		responses: make(map[string]chan *JSONRPCResponse),
 		done:      make(chan struct{}),
+		ctx:       context.Background(),
+	}
+
+	for _, opt := range opts {
+		opt(s)
 	}
 
-	return client
+	return s
 }
 
 func (c *Stdio) Start(ctx context.Context) error {
+	// Store the context for use in request handling
+	c.ctxMu.Lock()
+	c.ctx = ctx
+	c.ctxMu.Unlock()
+
 	if err := c.spawnCommand(ctx); err != nil {
 		return err
 	}
@@ -83,18 +130,25 @@ func (c *Stdio) Start(ctx context.Context) error {
 	return nil
 }
 
-// spawnCommand spawns a new process running c.command.
+// spawnCommand spawns a new process running the configured command, args, and env.
+// If an (optional) cmdFunc custom command factory function was configured, it will be used to construct the subprocess;
+// otherwise, the default behavior uses exec.CommandContext with the merged environment.
+// Initializes stdin, stdout, and stderr pipes for JSON-RPC communication.
 func (c *Stdio) spawnCommand(ctx context.Context) error {
 	if c.command == "" {
 		return nil
 	}
 
-	cmd := exec.CommandContext(ctx, c.command, c.args...)
-
-	mergedEnv := os.Environ()
-	mergedEnv = append(mergedEnv, c.env...)
+	var cmd *exec.Cmd
+	var err error
 
-	cmd.Env = mergedEnv
+	// Standard behavior if no command func present.
+	if c.cmdFunc == nil {
+		cmd = exec.CommandContext(ctx, c.command, c.args...)
+		cmd.Env = append(os.Environ(), c.env...)
+	} else if cmd, err = c.cmdFunc(ctx, c.command, c.env, c.args); err != nil {
+		return err
+	}
 
 	stdin, err := cmd.StdinPipe()
 	if err != nil {
@@ -148,6 +202,12 @@ func (c *Stdio) Close() error {
 	return nil
 }
 
+// GetSessionId returns the session ID of the transport.
+// Since stdio does not maintain a session ID, it returns an empty string.
+func (c *Stdio) GetSessionId() string {
+	return ""
+}
+
 // SetNotificationHandler sets the handler function to be called when a notification is received.
 // Only one handler can be set at a time; setting a new one replaces the previous handler.
 func (c *Stdio) SetNotificationHandler(
@@ -158,6 +218,14 @@ func (c *Stdio) SetNotificationHandler(
 	c.onNotification = handler
 }
 
+// SetRequestHandler sets the handler function to be called when a request is received from the server.
+// This enables bidirectional communication for features like sampling.
+func (c *Stdio) SetRequestHandler(handler RequestHandler) {
+	c.requestMu.Lock()
+	defer c.requestMu.Unlock()
+	c.onRequest = handler
+}
+
 // readResponses continuously reads and processes responses from the server's stdout.
 // It handles both responses to requests and notifications, routing them appropriately.
 // Runs until the done channel is closed or an error occurs reading from stdout.
@@ -175,13 +243,18 @@ func (c *Stdio) readResponses() {
 				return
 			}
 
-			var baseMessage JSONRPCResponse
+			// First try to parse as a generic message to check for ID field
+			var baseMessage struct {
+				JSONRPC string         `json:"jsonrpc"`
+				ID      *mcp.RequestId `json:"id,omitempty"`
+				Method  string         `json:"method,omitempty"`
+			}
 			if err := json.Unmarshal([]byte(line), &baseMessage); err != nil {
 				continue
 			}
 
-			// Handle notification
-			if baseMessage.ID.IsNil() {
+			// If it has a method but no ID, it's a notification
+			if baseMessage.Method != "" && baseMessage.ID == nil {
 				var notification mcp.JSONRPCNotification
 				if err := json.Unmarshal([]byte(line), &notification); err != nil {
 					continue
@@ -194,15 +267,30 @@ func (c *Stdio) readResponses() {
 				continue
 			}
 
+			// If it has a method and an ID, it's an incoming request
+			if baseMessage.Method != "" && baseMessage.ID != nil {
+				var request JSONRPCRequest
+				if err := json.Unmarshal([]byte(line), &request); err == nil {
+					c.handleIncomingRequest(request)
+					continue
+				}
+			}
+
+			// Otherwise, it's a response to our request
+			var response JSONRPCResponse
+			if err := json.Unmarshal([]byte(line), &response); err != nil {
+				continue
+			}
+
 			// Create string key for map lookup
-			idKey := baseMessage.ID.String()
+			idKey := response.ID.String()
 
 			c.mu.RLock()
 			ch, exists := c.responses[idKey]
 			c.mu.RUnlock()
 
 			if exists {
-				ch <- &baseMessage
+				ch <- &response
 				c.mu.Lock()
 				delete(c.responses, idKey)
 				c.mu.Unlock()
@@ -281,6 +369,96 @@ func (c *Stdio) SendNotification(
 	return nil
 }
 
+// handleIncomingRequest processes incoming requests from the server.
+// It calls the registered request handler and sends the response back to the server.
+func (c *Stdio) handleIncomingRequest(request JSONRPCRequest) {
+	c.requestMu.RLock()
+	handler := c.onRequest
+	c.requestMu.RUnlock()
+
+	if handler == nil {
+		// Send error response if no handler is configured
+		errorResponse := JSONRPCResponse{
+			JSONRPC: mcp.JSONRPC_VERSION,
+			ID:      request.ID,
+			Error: &struct {
+				Code    int             `json:"code"`
+				Message string          `json:"message"`
+				Data    json.RawMessage `json:"data"`
+			}{
+				Code:    mcp.METHOD_NOT_FOUND,
+				Message: "No request handler configured",
+			},
+		}
+		c.sendResponse(errorResponse)
+		return
+	}
+
+	// Handle the request in a goroutine to avoid blocking
+	go func() {
+		c.ctxMu.RLock()
+		ctx := c.ctx
+		c.ctxMu.RUnlock()
+
+		// Check if context is already cancelled before processing
+		select {
+		case <-ctx.Done():
+			errorResponse := JSONRPCResponse{
+				JSONRPC: mcp.JSONRPC_VERSION,
+				ID:      request.ID,
+				Error: &struct {
+					Code    int             `json:"code"`
+					Message string          `json:"message"`
+					Data    json.RawMessage `json:"data"`
+				}{
+					Code:    mcp.INTERNAL_ERROR,
+					Message: ctx.Err().Error(),
+				},
+			}
+			c.sendResponse(errorResponse)
+			return
+		default:
+		}
+
+		response, err := handler(ctx, request)
+
+		if err != nil {
+			errorResponse := JSONRPCResponse{
+				JSONRPC: mcp.JSONRPC_VERSION,
+				ID:      request.ID,
+				Error: &struct {
+					Code    int             `json:"code"`
+					Message string          `json:"message"`
+					Data    json.RawMessage `json:"data"`
+				}{
+					Code:    mcp.INTERNAL_ERROR,
+					Message: err.Error(),
+				},
+			}
+			c.sendResponse(errorResponse)
+			return
+		}
+
+		if response != nil {
+			c.sendResponse(*response)
+		}
+	}()
+}
+
+// sendResponse sends a response back to the server.
+func (c *Stdio) sendResponse(response JSONRPCResponse) {
+	responseBytes, err := json.Marshal(response)
+	if err != nil {
+		fmt.Printf("Error marshaling response: %v\n", err)
+		return
+	}
+	responseBytes = append(responseBytes, '\n')
+
+	if _, err := c.stdin.Write(responseBytes); err != nil {
+		fmt.Printf("Error writing response: %v\n", err)
+	}
+}
+
 // Stderr returns a reader for the stderr output of the subprocess.
 // This can be used to capture error messages or logs from the subprocess.
 func (c *Stdio) Stderr() io.Reader {

vendor/github.com/mark3labs/mcp-go/client/transport/streamable_http.go 🔗

@@ -17,10 +17,24 @@ import (
 	"time"
 
 	"github.com/mark3labs/mcp-go/mcp"
+	"github.com/mark3labs/mcp-go/util"
 )
 
 type StreamableHTTPCOption func(*StreamableHTTP)
 
+// WithContinuousListening enables receiving server-to-client notifications when no request is in flight.
+// In particular, if you want to receive global notifications from the server (like ToolListChangedNotification),
+// you should enable this option.
+//
+// It will establish a standalone long-live GET HTTP connection to the server.
+// https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#listening-for-messages-from-the-server
+// NOTICE: Even enabled, the server may not support this feature.
+func WithContinuousListening() StreamableHTTPCOption {
+	return func(sc *StreamableHTTP) {
+		sc.getListeningEnabled = true
+	}
+}
+
 // WithHTTPClient sets a custom HTTP client on the StreamableHTTP transport.
 func WithHTTPBasicClient(client *http.Client) StreamableHTTPCOption {
 	return func(sc *StreamableHTTP) {
@@ -54,6 +68,19 @@ func WithHTTPOAuth(config OAuthConfig) StreamableHTTPCOption {
 	}
 }
 
+func WithLogger(logger util.Logger) StreamableHTTPCOption {
+	return func(sc *StreamableHTTP) {
+		sc.logger = logger
+	}
+}
+
+// WithSession creates a client with a pre-configured session
+func WithSession(sessionID string) StreamableHTTPCOption {
+	return func(sc *StreamableHTTP) {
+		sc.sessionID.Store(sessionID)
+	}
+}
+
 // StreamableHTTP implements Streamable HTTP transport.
 //
 // It transmits JSON-RPC messages over individual HTTP requests. One message per request.
@@ -64,19 +91,22 @@ func WithHTTPOAuth(config OAuthConfig) StreamableHTTPCOption {
 //
 // The current implementation does not support the following features:
 //   - batching
-//   - continuously listening for server notifications when no request is in flight
-//     (https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#listening-for-messages-from-the-server)
 //   - resuming stream
 //     (https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#resumability-and-redelivery)
 //   - server -> client request
 type StreamableHTTP struct {
-	serverURL  *url.URL
-	httpClient *http.Client
-	headers    map[string]string
-	headerFunc HTTPHeaderFunc
+	serverURL           *url.URL
+	httpClient          *http.Client
+	headers             map[string]string
+	headerFunc          HTTPHeaderFunc
+	logger              util.Logger
+	getListeningEnabled bool
 
 	sessionID atomic.Value // string
 
+	initialized     chan struct{}
+	initializedOnce sync.Once
+
 	notificationHandler func(mcp.JSONRPCNotification)
 	notifyMu            sync.RWMutex
 
@@ -95,15 +125,19 @@ func NewStreamableHTTP(serverURL string, options ...StreamableHTTPCOption) (*Str
 	}
 
 	smc := &StreamableHTTP{
-		serverURL:  parsedURL,
-		httpClient: &http.Client{},
-		headers:    make(map[string]string),
-		closed:     make(chan struct{}),
+		serverURL:   parsedURL,
+		httpClient:  &http.Client{},
+		headers:     make(map[string]string),
+		closed:      make(chan struct{}),
+		logger:      util.DefaultLogger(),
+		initialized: make(chan struct{}),
 	}
 	smc.sessionID.Store("") // set initial value to simplify later usage
 
 	for _, opt := range options {
-		opt(smc)
+		if opt != nil {
+			opt(smc)
+		}
 	}
 
 	// If OAuth is configured, set the base URL for metadata discovery
@@ -118,7 +152,20 @@ func NewStreamableHTTP(serverURL string, options ...StreamableHTTPCOption) (*Str
 
 // Start initiates the HTTP connection to the server.
 func (c *StreamableHTTP) Start(ctx context.Context) error {
-	// For Streamable HTTP, we don't need to establish a persistent connection
+	// For Streamable HTTP, we don't need to establish a persistent connection by default
+	if c.getListeningEnabled {
+		go func() {
+			select {
+			case <-c.initialized:
+				ctx, cancel := c.contextAwareOfClientClose(ctx)
+				defer cancel()
+				c.listenForever(ctx)
+			case <-c.closed:
+				return
+			}
+		}()
+	}
+
 	return nil
 }
 
@@ -142,13 +189,13 @@ func (c *StreamableHTTP) Close() error {
 			defer cancel()
 			req, err := http.NewRequestWithContext(ctx, http.MethodDelete, c.serverURL.String(), nil)
 			if err != nil {
-				fmt.Printf("failed to create close request\n: %v", err)
+				c.logger.Errorf("failed to create close request: %v", err)
 				return
 			}
 			req.Header.Set(headerKeySessionID, sessionId)
 			res, err := c.httpClient.Do(req)
 			if err != nil {
-				fmt.Printf("failed to send close request\n: %v", err)
+				c.logger.Errorf("failed to send close request: %v", err)
 				return
 			}
 			res.Body.Close()
@@ -185,77 +232,29 @@ func (c *StreamableHTTP) SendRequest(
 	request JSONRPCRequest,
 ) (*JSONRPCResponse, error) {
 
-	// Create a combined context that could be canceled when the client is closed
-	newCtx, cancel := context.WithCancel(ctx)
-	defer cancel()
-	go func() {
-		select {
-		case <-c.closed:
-			cancel()
-		case <-newCtx.Done():
-			// The original context was canceled, no need to do anything
-		}
-	}()
-	ctx = newCtx
-
 	// Marshal request
 	requestBody, err := json.Marshal(request)
 	if err != nil {
 		return nil, fmt.Errorf("failed to marshal request: %w", err)
 	}
 
-	// Create HTTP request
-	req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.serverURL.String(), bytes.NewReader(requestBody))
-	if err != nil {
-		return nil, fmt.Errorf("failed to create request: %w", err)
-	}
-
-	// Set headers
-	req.Header.Set("Content-Type", "application/json")
-	req.Header.Set("Accept", "application/json, text/event-stream")
-	sessionID := c.sessionID.Load()
-	if sessionID != "" {
-		req.Header.Set(headerKeySessionID, sessionID.(string))
-	}
-	for k, v := range c.headers {
-		req.Header.Set(k, v)
-	}
-
-	// Add OAuth authorization if configured
-	if c.oauthHandler != nil {
-		authHeader, err := c.oauthHandler.GetAuthorizationHeader(ctx)
-		if err != nil {
-			// If we get an authorization error, return a specific error that can be handled by the client
-			if err.Error() == "no valid token available, authorization required" {
-				return nil, &OAuthAuthorizationRequiredError{
-					Handler: c.oauthHandler,
-				}
-			}
-			return nil, fmt.Errorf("failed to get authorization header: %w", err)
-		}
-		req.Header.Set("Authorization", authHeader)
-	}
-
-	if c.headerFunc != nil {
-		for k, v := range c.headerFunc(ctx) {
-			req.Header.Set(k, v)
-		}
-	}
+	ctx, cancel := c.contextAwareOfClientClose(ctx)
+	defer cancel()
 
-	// Send request
-	resp, err := c.httpClient.Do(req)
+	resp, err := c.sendHTTP(ctx, http.MethodPost, bytes.NewReader(requestBody), "application/json, text/event-stream")
 	if err != nil {
-		return nil, fmt.Errorf("failed to send request: %w", err)
+		if errors.Is(err, ErrSessionTerminated) && request.Method == string(mcp.MethodInitialize) {
+			// If the request is initialize, should not return a SessionTerminated error
+			// It should be a genuine endpoint-routing issue.
+			// ( Fall through to return StatusCode checking. )
+		} else {
+			return nil, fmt.Errorf("failed to send request: %w", err)
+		}
 	}
 	defer resp.Body.Close()
 
 	// Check if we got an error response
 	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted {
-		// handle session closed
-		if resp.StatusCode == http.StatusNotFound {
-			c.sessionID.CompareAndSwap(sessionID, "")
-			return nil, fmt.Errorf("session terminated (404). need to re-initialize")
-		}
 
 		// Handle OAuth unauthorized error
 		if resp.StatusCode == http.StatusUnauthorized && c.oauthHandler != nil {
@@ -279,6 +278,10 @@ func (c *StreamableHTTP) SendRequest(
 		if sessionID := resp.Header.Get(headerKeySessionID); sessionID != "" {
 			c.sessionID.Store(sessionID)
 		}
+
+		c.initializedOnce.Do(func() {
+			close(c.initialized)
+		})
 	}
 
 	// Handle different response types
@@ -300,16 +303,77 @@ func (c *StreamableHTTP) SendRequest(
 
 	case "text/event-stream":
 		// Server is using SSE for streaming responses
-		return c.handleSSEResponse(ctx, resp.Body)
+		return c.handleSSEResponse(ctx, resp.Body, false)
 
 	default:
 		return nil, fmt.Errorf("unexpected content type: %s", resp.Header.Get("Content-Type"))
 	}
 }
 
+func (c *StreamableHTTP) sendHTTP(
+	ctx context.Context,
+	method string,
+	body io.Reader,
+	acceptType string,
+) (resp *http.Response, err error) {
+
+	// Create HTTP request
+	req, err := http.NewRequestWithContext(ctx, method, c.serverURL.String(), body)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create request: %w", err)
+	}
+
+	// Set headers
+	req.Header.Set("Content-Type", "application/json")
+	req.Header.Set("Accept", acceptType)
+	sessionID := c.sessionID.Load().(string)
+	if sessionID != "" {
+		req.Header.Set(headerKeySessionID, sessionID)
+	}
+	for k, v := range c.headers {
+		req.Header.Set(k, v)
+	}
+
+	// Add OAuth authorization if configured
+	if c.oauthHandler != nil {
+		authHeader, err := c.oauthHandler.GetAuthorizationHeader(ctx)
+		if err != nil {
+			// If we get an authorization error, return a specific error that can be handled by the client
+			if err.Error() == "no valid token available, authorization required" {
+				return nil, &OAuthAuthorizationRequiredError{
+					Handler: c.oauthHandler,
+				}
+			}
+			return nil, fmt.Errorf("failed to get authorization header: %w", err)
+		}
+		req.Header.Set("Authorization", authHeader)
+	}
+
+	if c.headerFunc != nil {
+		for k, v := range c.headerFunc(ctx) {
+			req.Header.Set(k, v)
+		}
+	}
+
+	// Send request
+	resp, err = c.httpClient.Do(req)
+	if err != nil {
+		return nil, fmt.Errorf("failed to send request: %w", err)
+	}
+
+	// universal handling for session terminated
+	if resp.StatusCode == http.StatusNotFound {
+		c.sessionID.CompareAndSwap(sessionID, "")
+		return nil, ErrSessionTerminated
+	}
+
+	return resp, nil
+}
+
 // handleSSEResponse processes an SSE stream for a specific request.
 // It returns the final result for the request once received, or an error.
-func (c *StreamableHTTP) handleSSEResponse(ctx context.Context, reader io.ReadCloser) (*JSONRPCResponse, error) {
+// If ignoreResponse is true, it won't return when a response messge is received. This is for continuous listening.
+func (c *StreamableHTTP) handleSSEResponse(ctx context.Context, reader io.ReadCloser, ignoreResponse bool) (*JSONRPCResponse, error) {
 
 	// Create a channel for this specific request
 	responseChan := make(chan *JSONRPCResponse, 1)
@@ -328,7 +392,7 @@ func (c *StreamableHTTP) handleSSEResponse(ctx context.Context, reader io.ReadCl
 
 			var message JSONRPCResponse
 			if err := json.Unmarshal([]byte(data), &message); err != nil {
-				fmt.Printf("failed to unmarshal message: %v\n", err)
+				c.logger.Errorf("failed to unmarshal message: %v", err)
 				return
 			}
 
@@ -336,7 +400,7 @@ func (c *StreamableHTTP) handleSSEResponse(ctx context.Context, reader io.ReadCl
 			if message.ID.IsNil() {
 				var notification mcp.JSONRPCNotification
 				if err := json.Unmarshal([]byte(data), &notification); err != nil {
-					fmt.Printf("failed to unmarshal notification: %v\n", err)
+					c.logger.Errorf("failed to unmarshal notification: %v", err)
 					return
 				}
 				c.notifyMu.RLock()
@@ -347,7 +411,9 @@ func (c *StreamableHTTP) handleSSEResponse(ctx context.Context, reader io.ReadCl
 				return
 			}
 
-			responseChan <- &message
+			if !ignoreResponse {
+				responseChan <- &message
+			}
 		})
 	}()
 
@@ -393,7 +459,7 @@ func (c *StreamableHTTP) readSSE(ctx context.Context, reader io.ReadCloser, hand
 				case <-ctx.Done():
 					return
 				default:
-					fmt.Printf("SSE stream error: %v\n", err)
+					c.logger.Errorf("SSE stream error: %v", err)
 					return
 				}
 			}
@@ -432,44 +498,10 @@ func (c *StreamableHTTP) SendNotification(ctx context.Context, notification mcp.
 	}
 
 	// Create HTTP request
-	req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.serverURL.String(), bytes.NewReader(requestBody))
-	if err != nil {
-		return fmt.Errorf("failed to create request: %w", err)
-	}
-
-	// Set headers
-	req.Header.Set("Content-Type", "application/json")
-	req.Header.Set("Accept", "application/json, text/event-stream")
-	if sessionID := c.sessionID.Load(); sessionID != "" {
-		req.Header.Set(headerKeySessionID, sessionID.(string))
-	}
-	for k, v := range c.headers {
-		req.Header.Set(k, v)
-	}
-
-	// Add OAuth authorization if configured
-	if c.oauthHandler != nil {
-		authHeader, err := c.oauthHandler.GetAuthorizationHeader(ctx)
-		if err != nil {
-			// If we get an authorization error, return a specific error that can be handled by the client
-			if errors.Is(err, ErrOAuthAuthorizationRequired) {
-				return &OAuthAuthorizationRequiredError{
-					Handler: c.oauthHandler,
-				}
-			}
-			return fmt.Errorf("failed to get authorization header: %w", err)
-		}
-		req.Header.Set("Authorization", authHeader)
-	}
-
-	if c.headerFunc != nil {
-		for k, v := range c.headerFunc(ctx) {
-			req.Header.Set(k, v)
-		}
-	}
+	ctx, cancel := c.contextAwareOfClientClose(ctx)
+	defer cancel()
 
-	// Send request
-	resp, err := c.httpClient.Do(req)
+	resp, err := c.sendHTTP(ctx, http.MethodPost, bytes.NewReader(requestBody), "application/json, text/event-stream")
 	if err != nil {
 		return fmt.Errorf("failed to send request: %w", err)
 	}
@@ -513,3 +545,84 @@ func (c *StreamableHTTP) GetOAuthHandler() *OAuthHandler {
 func (c *StreamableHTTP) IsOAuthEnabled() bool {
 	return c.oauthHandler != nil
 }
+
+func (c *StreamableHTTP) listenForever(ctx context.Context) {
+	c.logger.Infof("listening to server forever")
+	for {
+		err := c.createGETConnectionToServer(ctx)
+		if errors.Is(err, ErrGetMethodNotAllowed) {
+			// server does not support listening
+			c.logger.Errorf("server does not support listening")
+			return
+		}
+
+		select {
+		case <-ctx.Done():
+			return
+		default:
+		}
+
+		if err != nil {
+			c.logger.Errorf("failed to listen to server. retry in 1 second: %v", err)
+		}
+		time.Sleep(retryInterval)
+	}
+}
+
+var (
+	ErrSessionTerminated   = fmt.Errorf("session terminated (404). need to re-initialize")
+	ErrGetMethodNotAllowed = fmt.Errorf("GET method not allowed")
+
+	retryInterval = 1 * time.Second // a variable is convenient for testing
+)
+
+func (c *StreamableHTTP) createGETConnectionToServer(ctx context.Context) error {
+
+	resp, err := c.sendHTTP(ctx, http.MethodGet, nil, "text/event-stream")
+	if err != nil {
+		return fmt.Errorf("failed to send request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	// Check if we got an error response
+	if resp.StatusCode == http.StatusMethodNotAllowed {
+		return ErrGetMethodNotAllowed
+	}
+
+	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted {
+		body, _ := io.ReadAll(resp.Body)
+		return fmt.Errorf("request failed with status %d: %s", resp.StatusCode, body)
+	}
+
+	// handle SSE response
+	contentType := resp.Header.Get("Content-Type")
+	if contentType != "text/event-stream" {
+		return fmt.Errorf("unexpected content type: %s", contentType)
+	}
+
+	// When ignoreResponse is true, the function will never return expect context is done.
+	// NOTICE: Due to the ambiguity of the specification, other SDKs may use the GET connection to transfer the response
+	// messages. To be more compatible, we should handle this response, however, as the transport layer is message-based,
+	// currently, there is no convenient way to handle this response.
+	// So we ignore the response here. It's not a bug, but may be not compatible with other SDKs.
+	_, err = c.handleSSEResponse(ctx, resp.Body, true)
+	if err != nil {
+		return fmt.Errorf("failed to handle SSE response: %w", err)
+	}
+
+	return nil
+}
+
+func (c *StreamableHTTP) contextAwareOfClientClose(ctx context.Context) (context.Context, context.CancelFunc) {
+	newCtx, cancel := context.WithCancel(ctx)
+	go func() {
+		select {
+		case <-c.closed:
+			cancel()
+		case <-newCtx.Done():
+			// The original context was canceled
+			cancel()
+		}
+	}()
+	return newCtx, cancel
+}

vendor/github.com/mark3labs/mcp-go/mcp/tools.go 🔗

@@ -945,7 +945,20 @@ func PropertyNames(schema map[string]any) PropertyOption {
 	}
 }
 
-// Items defines the schema for array items
+// Items defines the schema for array items.
+// Accepts any schema definition for maximum flexibility.
+//
+// Example:
+//
+//	Items(map[string]any{
+//	    "type": "object",
+//	    "properties": map[string]any{
+//	        "name": map[string]any{"type": "string"},
+//	        "age": map[string]any{"type": "number"},
+//	    },
+//	})
+//
+// For simple types, use ItemsString(), ItemsNumber(), ItemsBoolean() instead.
 func Items(schema any) PropertyOption {
 	return func(schemaMap map[string]any) {
 		schemaMap["items"] = schema
@@ -972,3 +985,94 @@ func UniqueItems(unique bool) PropertyOption {
 		schema["uniqueItems"] = unique
 	}
 }
+
+// WithStringItems configures an array's items to be of type string.
+//
+// Supported options: Description(), DefaultString(), Enum(), MaxLength(), MinLength(), Pattern()
+// Note: Options like Required() are not valid for item schemas and will be ignored.
+//
+// Examples:
+//
+//	mcp.WithArray("tags", mcp.WithStringItems())
+//	mcp.WithArray("colors", mcp.WithStringItems(mcp.Enum("red", "green", "blue")))
+//	mcp.WithArray("names", mcp.WithStringItems(mcp.MinLength(1), mcp.MaxLength(50)))
+//
+// Limitations: Only supports simple string arrays. Use Items() for complex objects.
+func WithStringItems(opts ...PropertyOption) PropertyOption {
+	return func(schema map[string]any) {
+		itemSchema := map[string]any{
+			"type": "string",
+		}
+
+		for _, opt := range opts {
+			opt(itemSchema)
+		}
+
+		schema["items"] = itemSchema
+	}
+}
+
+// WithStringEnumItems configures an array's items to be of type string with a specified enum.
+// Example:
+//
+//	mcp.WithArray("priority", mcp.WithStringEnumItems([]string{"low", "medium", "high"}))
+//
+// Limitations: Only supports string enums. Use WithStringItems(Enum(...)) for more flexibility.
+func WithStringEnumItems(values []string) PropertyOption {
+	return func(schema map[string]any) {
+		schema["items"] = map[string]any{
+			"type": "string",
+			"enum": values,
+		}
+	}
+}
+
+// WithNumberItems configures an array's items to be of type number.
+//
+// Supported options: Description(), DefaultNumber(), Min(), Max(), MultipleOf()
+// Note: Options like Required() are not valid for item schemas and will be ignored.
+//
+// Examples:
+//
+//	mcp.WithArray("scores", mcp.WithNumberItems(mcp.Min(0), mcp.Max(100)))
+//	mcp.WithArray("prices", mcp.WithNumberItems(mcp.Min(0)))
+//
+// Limitations: Only supports simple number arrays. Use Items() for complex objects.
+func WithNumberItems(opts ...PropertyOption) PropertyOption {
+	return func(schema map[string]any) {
+		itemSchema := map[string]any{
+			"type": "number",
+		}
+
+		for _, opt := range opts {
+			opt(itemSchema)
+		}
+
+		schema["items"] = itemSchema
+	}
+}
+
+// WithBooleanItems configures an array's items to be of type boolean.
+//
+// Supported options: Description(), DefaultBool()
+// Note: Options like Required() are not valid for item schemas and will be ignored.
+//
+// Examples:
+//
+//	mcp.WithArray("flags", mcp.WithBooleanItems())
+//	mcp.WithArray("permissions", mcp.WithBooleanItems(mcp.Description("User permissions")))
+//
+// Limitations: Only supports simple boolean arrays. Use Items() for complex objects.
+func WithBooleanItems(opts ...PropertyOption) PropertyOption {
+	return func(schema map[string]any) {
+		itemSchema := map[string]any{
+			"type": "boolean",
+		}
+
+		for _, opt := range opts {
+			opt(itemSchema)
+		}
+
+		schema["items"] = itemSchema
+	}
+}

vendor/github.com/mark3labs/mcp-go/mcp/types.go 🔗

@@ -763,6 +763,11 @@ const (
 
 /* Sampling */
 
+const (
+	// MethodSamplingCreateMessage allows servers to request LLM completions from clients
+	MethodSamplingCreateMessage MCPMethod = "sampling/createMessage"
+)
+
 // CreateMessageRequest is a request from the server to sample an LLM via the
 // client. The client has full discretion over which model to select. The client
 // should also inform the user before beginning sampling, to allow them to inspect
@@ -865,6 +870,22 @@ type AudioContent struct {
 
 func (AudioContent) isContent() {}
 
+// ResourceLink represents a link to a resource that the client can access.
+type ResourceLink struct {
+	Annotated
+	Type string `json:"type"` // Must be "resource_link"
+	// The URI of the resource.
+	URI string `json:"uri"`
+	// The name of the resource.
+	Name string `json:"name"`
+	// The description of the resource.
+	Description string `json:"description"`
+	// The MIME type of the resource.
+	MIMEType string `json:"mimeType"`
+}
+
+func (ResourceLink) isContent() {}
+
 // EmbeddedResource represents the contents of a resource, embedded into a prompt or tool call result.
 //
 // It is up to the client how best to render embedded resources for the

vendor/github.com/mark3labs/mcp-go/mcp/utils.go 🔗

@@ -222,6 +222,17 @@ func NewAudioContent(data, mimeType string) AudioContent {
 	}
 }
 
+// Helper function to create a new ResourceLink
+func NewResourceLink(uri, name, description, mimeType string) ResourceLink {
+	return ResourceLink{
+		Type:        "resource_link",
+		URI:         uri,
+		Name:        name,
+		Description: description,
+		MIMEType:    mimeType,
+	}
+}
+
 // Helper function to create a new EmbeddedResource
 func NewEmbeddedResource(resource ResourceContents) EmbeddedResource {
 	return EmbeddedResource{
@@ -476,6 +487,16 @@ func ParseContent(contentMap map[string]any) (Content, error) {
 		}
 		return NewAudioContent(data, mimeType), nil
 
+	case "resource_link":
+		uri := ExtractString(contentMap, "uri")
+		name := ExtractString(contentMap, "name")
+		description := ExtractString(contentMap, "description")
+		mimeType := ExtractString(contentMap, "mimeType")
+		if uri == "" || name == "" {
+			return nil, fmt.Errorf("resource_link uri or name is missing")
+		}
+		return NewResourceLink(uri, name, description, mimeType), nil
+
 	case "resource":
 		resourceMap := ExtractMap(contentMap, "resource")
 		if resourceMap == nil {

vendor/github.com/mark3labs/mcp-go/server/sampling.go 🔗

@@ -0,0 +1,37 @@
+package server
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/mark3labs/mcp-go/mcp"
+)
+
+// EnableSampling enables sampling capabilities for the server.
+// This allows the server to send sampling requests to clients that support it.
+func (s *MCPServer) EnableSampling() {
+	s.capabilitiesMu.Lock()
+	defer s.capabilitiesMu.Unlock()
+}
+
+// RequestSampling sends a sampling request to the client.
+// The client must have declared sampling capability during initialization.
+func (s *MCPServer) RequestSampling(ctx context.Context, request mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error) {
+	session := ClientSessionFromContext(ctx)
+	if session == nil {
+		return nil, fmt.Errorf("no active session")
+	}
+
+	// Check if the session supports sampling requests
+	if samplingSession, ok := session.(SessionWithSampling); ok {
+		return samplingSession.RequestSampling(ctx, request)
+	}
+
+	return nil, fmt.Errorf("session does not support sampling")
+}
+
+// SessionWithSampling extends ClientSession to support sampling requests.
+type SessionWithSampling interface {
+	ClientSession
+	RequestSampling(ctx context.Context, request mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error)
+}

vendor/github.com/mark3labs/mcp-go/server/stdio.go 🔗

@@ -9,6 +9,7 @@ import (
 	"log"
 	"os"
 	"os/signal"
+	"sync"
 	"sync/atomic"
 	"syscall"
 
@@ -51,10 +52,21 @@ func WithStdioContextFunc(fn StdioContextFunc) StdioOption {
 
 // stdioSession is a static client session, since stdio has only one client.
 type stdioSession struct {
-	notifications chan mcp.JSONRPCNotification
-	initialized   atomic.Bool
-	loggingLevel  atomic.Value
-	clientInfo    atomic.Value // stores session-specific client info
+	notifications   chan mcp.JSONRPCNotification
+	initialized     atomic.Bool
+	loggingLevel    atomic.Value
+	clientInfo      atomic.Value                     // stores session-specific client info
+	writer          io.Writer                        // for sending requests to client
+	requestID       atomic.Int64                     // for generating unique request IDs
+	mu              sync.RWMutex                     // protects writer
+	pendingRequests map[int64]chan *samplingResponse // for tracking pending sampling requests
+	pendingMu       sync.RWMutex                     // protects pendingRequests
+}
+
+// samplingResponse represents a response to a sampling request
+type samplingResponse struct {
+	result *mcp.CreateMessageResult
+	err    error
 }
 
 func (s *stdioSession) SessionID() string {
@@ -100,14 +112,86 @@ func (s *stdioSession) GetLogLevel() mcp.LoggingLevel {
 	return level.(mcp.LoggingLevel)
 }
 
+// RequestSampling sends a sampling request to the client and waits for the response.
+func (s *stdioSession) RequestSampling(ctx context.Context, request mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error) {
+	s.mu.RLock()
+	writer := s.writer
+	s.mu.RUnlock()
+
+	if writer == nil {
+		return nil, fmt.Errorf("no writer available for sending requests")
+	}
+
+	// Generate a unique request ID
+	id := s.requestID.Add(1)
+
+	// Create a response channel for this request
+	responseChan := make(chan *samplingResponse, 1)
+	s.pendingMu.Lock()
+	s.pendingRequests[id] = responseChan
+	s.pendingMu.Unlock()
+
+	// Cleanup function to remove the pending request
+	cleanup := func() {
+		s.pendingMu.Lock()
+		delete(s.pendingRequests, id)
+		s.pendingMu.Unlock()
+	}
+	defer cleanup()
+
+	// Create the JSON-RPC request
+	jsonRPCRequest := struct {
+		JSONRPC string                  `json:"jsonrpc"`
+		ID      int64                   `json:"id"`
+		Method  string                  `json:"method"`
+		Params  mcp.CreateMessageParams `json:"params"`
+	}{
+		JSONRPC: mcp.JSONRPC_VERSION,
+		ID:      id,
+		Method:  string(mcp.MethodSamplingCreateMessage),
+		Params:  request.CreateMessageParams,
+	}
+
+	// Marshal and send the request
+	requestBytes, err := json.Marshal(jsonRPCRequest)
+	if err != nil {
+		return nil, fmt.Errorf("failed to marshal sampling request: %w", err)
+	}
+	requestBytes = append(requestBytes, '\n')
+
+	if _, err := writer.Write(requestBytes); err != nil {
+		return nil, fmt.Errorf("failed to write sampling request: %w", err)
+	}
+
+	// Wait for the response or context cancellation
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	case response := <-responseChan:
+		if response.err != nil {
+			return nil, response.err
+		}
+		return response.result, nil
+	}
+}
+
+// SetWriter sets the writer for sending requests to the client.
+func (s *stdioSession) SetWriter(writer io.Writer) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.writer = writer
+}
+
 var (
 	_ ClientSession         = (*stdioSession)(nil)
 	_ SessionWithLogging    = (*stdioSession)(nil)
 	_ SessionWithClientInfo = (*stdioSession)(nil)
+	_ SessionWithSampling   = (*stdioSession)(nil)
 )
 
 var stdioSessionInstance = stdioSession{
-	notifications: make(chan mcp.JSONRPCNotification, 100),
+	notifications:   make(chan mcp.JSONRPCNotification, 100),
+	pendingRequests: make(map[int64]chan *samplingResponse),
 }
 
 // NewStdioServer creates a new stdio server wrapper around an MCPServer.
@@ -224,6 +308,9 @@ func (s *StdioServer) Listen(
 	defer s.server.UnregisterSession(ctx, stdioSessionInstance.SessionID())
 	ctx = s.server.WithContext(ctx, &stdioSessionInstance)
 
+	// Set the writer for sending requests to the client
+	stdioSessionInstance.SetWriter(stdout)
+
 	// Add in any custom context.
 	if s.contextFunc != nil {
 		ctx = s.contextFunc(ctx)
@@ -256,7 +343,29 @@ func (s *StdioServer) processMessage(
 		return s.writeResponse(response, writer)
 	}
 
-	// Handle the message using the wrapped server
+	// Check if this is a response to a sampling request
+	if s.handleSamplingResponse(rawMessage) {
+		return nil
+	}
+
+	// Check if this is a tool call that might need sampling (and thus should be processed concurrently)
+	var baseMessage struct {
+		Method string `json:"method"`
+	}
+	if json.Unmarshal(rawMessage, &baseMessage) == nil && baseMessage.Method == "tools/call" {
+		// Process tool calls concurrently to avoid blocking on sampling requests
+		go func() {
+			response := s.server.HandleMessage(ctx, rawMessage)
+			if response != nil {
+				if err := s.writeResponse(response, writer); err != nil {
+					s.errLogger.Printf("Error writing tool response: %v", err)
+				}
+			}
+		}()
+		return nil
+	}
+
+	// Handle other messages synchronously
 	response := s.server.HandleMessage(ctx, rawMessage)
 
 	// Only write response if there is one (not for notifications)
@@ -269,6 +378,65 @@ func (s *StdioServer) processMessage(
 	return nil
 }
 
+// handleSamplingResponse checks if the message is a response to a sampling request
+// and routes it to the appropriate pending request channel.
+func (s *StdioServer) handleSamplingResponse(rawMessage json.RawMessage) bool {
+	return stdioSessionInstance.handleSamplingResponse(rawMessage)
+}
+
+// handleSamplingResponse handles incoming sampling responses for this session
+func (s *stdioSession) handleSamplingResponse(rawMessage json.RawMessage) bool {
+	// Try to parse as a JSON-RPC response
+	var response struct {
+		JSONRPC string          `json:"jsonrpc"`
+		ID      json.Number     `json:"id"`
+		Result  json.RawMessage `json:"result,omitempty"`
+		Error   *struct {
+			Code    int    `json:"code"`
+			Message string `json:"message"`
+		} `json:"error,omitempty"`
+	}
+
+	if err := json.Unmarshal(rawMessage, &response); err != nil {
+		return false
+	}
+	// Parse the ID as int64
+	idInt64, err := response.ID.Int64()
+	if err != nil || (response.Result == nil && response.Error == nil) {
+		return false
+	}
+
+	// Look for a pending request with this ID
+	s.pendingMu.RLock()
+	responseChan, exists := s.pendingRequests[idInt64]
+	s.pendingMu.RUnlock()
+
+	if !exists {
+		return false
+	} // Parse and send the response
+	samplingResp := &samplingResponse{}
+
+	if response.Error != nil {
+		samplingResp.err = fmt.Errorf("sampling request failed: %s", response.Error.Message)
+	} else {
+		var result mcp.CreateMessageResult
+		if err := json.Unmarshal(response.Result, &result); err != nil {
+			samplingResp.err = fmt.Errorf("failed to unmarshal sampling response: %w", err)
+		} else {
+			samplingResp.result = &result
+		}
+	}
+
+	// Send the response (non-blocking)
+	select {
+	case responseChan <- samplingResp:
+	default:
+		// Channel is full or closed, ignore
+	}
+
+	return true
+}
+
 // writeResponse marshals and writes a JSON-RPC response message followed by a newline.
 // Returns an error if marshaling or writing fails.
 func (s *StdioServer) writeResponse(

vendor/github.com/mark3labs/mcp-go/server/streamable_http.go 🔗

@@ -40,7 +40,9 @@ func WithEndpointPath(endpointPath string) StreamableHTTPOption {
 // to StatelessSessionIdManager.
 func WithStateLess(stateLess bool) StreamableHTTPOption {
 	return func(s *StreamableHTTPServer) {
-		s.sessionIdManager = &StatelessSessionIdManager{}
+		if stateLess {
+			s.sessionIdManager = &StatelessSessionIdManager{}
+		}
 	}
 }
 
@@ -374,7 +376,7 @@ func (s *StreamableHTTPServer) handleGet(w http.ResponseWriter, r *http.Request)
 	w.Header().Set("Content-Type", "text/event-stream")
 	w.Header().Set("Cache-Control", "no-cache")
 	w.Header().Set("Connection", "keep-alive")
-	w.WriteHeader(http.StatusAccepted)
+	w.WriteHeader(http.StatusOK)
 
 	flusher, ok := w.(http.Flusher)
 	if !ok {

vendor/modules.txt 🔗

@@ -242,7 +242,7 @@ github.com/bmatcuk/doublestar/v4
 github.com/charlievieth/fastwalk
 github.com/charlievieth/fastwalk/internal/dirent
 github.com/charlievieth/fastwalk/internal/fmtdirent
-# github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250607113720-eb5e1cf3b09e
+# github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198
 ## explicit; go 1.23.0
 github.com/charmbracelet/bubbles/v2/cursor
 github.com/charmbracelet/bubbles/v2/filepicker
@@ -254,14 +254,14 @@ github.com/charmbracelet/bubbles/v2/spinner
 github.com/charmbracelet/bubbles/v2/textarea
 github.com/charmbracelet/bubbles/v2/textinput
 github.com/charmbracelet/bubbles/v2/viewport
-# github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891
-## explicit; go 1.24.3
+# github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595
+## explicit; go 1.24.0
 github.com/charmbracelet/bubbletea/v2
 # github.com/charmbracelet/colorprofile v0.3.1
 ## explicit; go 1.23.0
 github.com/charmbracelet/colorprofile
-# github.com/charmbracelet/fang v0.1.0
-## explicit; go 1.23.0
+# github.com/charmbracelet/fang v0.3.1-0.20250711140230-d5ebb8c1d674
+## explicit; go 1.24.0
 github.com/charmbracelet/fang
 # github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe
 ## explicit; go 1.23.0
@@ -269,7 +269,7 @@ github.com/charmbracelet/glamour/v2
 github.com/charmbracelet/glamour/v2/ansi
 github.com/charmbracelet/glamour/v2/internal/autolink
 github.com/charmbracelet/glamour/v2/styles
-# github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.2.0.20250703152125-8e1c474f8a71 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093
+# github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.3 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb
 ## explicit; go 1.24.2
 github.com/charmbracelet/lipgloss/v2
 github.com/charmbracelet/lipgloss/v2/table
@@ -288,7 +288,7 @@ github.com/charmbracelet/x/ansi/parser
 # github.com/charmbracelet/x/cellbuf v0.0.14-0.20250516160309-24eee56f89fa
 ## explicit; go 1.23.0
 github.com/charmbracelet/x/cellbuf
-# github.com/charmbracelet/x/exp/charmtone v0.0.0-20250627134340-c144409e381c
+# github.com/charmbracelet/x/exp/charmtone v0.0.0-20250708181618-a60a724ba6c3
 ## explicit; go 1.23.0
 github.com/charmbracelet/x/exp/charmtone
 # github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a
@@ -403,7 +403,7 @@ github.com/kylelemons/godebug/pretty
 # github.com/lucasb-eyer/go-colorful v1.2.0
 ## explicit; go 1.12
 github.com/lucasb-eyer/go-colorful
-# github.com/mark3labs/mcp-go v0.32.0
+# github.com/mark3labs/mcp-go v0.33.0
 ## explicit; go 1.23
 github.com/mark3labs/mcp-go/client
 github.com/mark3labs/mcp-go/client/transport
@@ -838,5 +838,5 @@ mvdan.cc/sh/v3/fileutil
 mvdan.cc/sh/v3/interp
 mvdan.cc/sh/v3/pattern
 mvdan.cc/sh/v3/syntax
-# github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250708152737-144080f3d891
-# github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250708152830-0fa4ef151093
+# github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595
+# github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb