Add keybinding to cycle log tail line count in Logs tab

Lets you press 't' while focused on the containers panel to cycle
through common --tail presets (all, 50, 100, 200, 500) for the
selected container's Logs tab, instead of only being able to set a
fixed value via the logs.tail config option. The current value is
shown in the Logs tab subtitle.
This commit is contained in:
DevLeonardoK 2026-07-14 21:21:26 -03:00
parent 7e7aadc207
commit d8d6ec7d7a
14 changed files with 57 additions and 2 deletions

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: anbinden
<kbd>m</kbd>: zeige Protokolle
<kbd>E</kbd>: exec shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: führe vordefinierten benutzerdefinierten Befehl aus
<kbd>b</kbd>: view bulk commands
<kbd>w</kbd>: open in browser (first port is http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: attach
<kbd>m</kbd>: view logs
<kbd>E</kbd>: exec shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: run predefined custom command
<kbd>b</kbd>: view bulk commands
<kbd>w</kbd>: open in browser (first port is http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: attach
<kbd>m</kbd>: ver logs
<kbd>E</kbd>: ejecutar shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: ejecutar comando personalizado
<kbd>b</kbd>: ver comandos masivos
<kbd>w</kbd>: abrir en navegador (first port is http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: attacher
<kbd>m</kbd>: voir les enregistrements
<kbd>E</kbd>: exécuter le shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: exécuter une commande prédéfinie
<kbd>b</kbd>: voir les commandes groupées
<kbd>w</kbd>: ouvrir dans le navigateur (le premier port est http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: verbinden
<kbd>m</kbd>: bekijk logs
<kbd>E</kbd>: exec shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: draai een vooraf bedacht aangepaste opdracht
<kbd>b</kbd>: view bulk commands
<kbd>w</kbd>: open in browser (first port is http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: przyczep
<kbd>m</kbd>: pokaż logi
<kbd>E</kbd>: exec shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: wykonaj predefiniowaną własną komende
<kbd>b</kbd>: view bulk commands
<kbd>w</kbd>: open in browser (first port is http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: anexar
<kbd>m</kbd>: ver logs
<kbd>E</kbd>: executar shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: executar comando personalizado predefinido
<kbd>b</kbd>: ver comandos em massa
<kbd>w</kbd>: abrir no navegador (primeira porta é http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: bağlan/iliştir
<kbd>m</kbd>: kayıt defterini görüntüle
<kbd>E</kbd>: exec shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: önceden tanımlanmış özel komutu çalıştır
<kbd>b</kbd>: view bulk commands
<kbd>w</kbd>: open in browser (first port is http)

View file

@ -25,6 +25,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>a</kbd>: attach
<kbd>m</kbd>: 查看日志
<kbd>E</kbd>: 执行shell
<kbd>t</kbd>: cycle how many log lines are shown
<kbd>c</kbd>: 运行预定义的自定义命令
<kbd>b</kbd>: 查看批量命令
<kbd>w</kbd>: 在浏览器中打开(第一个端口为http)

View file

@ -11,11 +11,40 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/stdcopy"
"github.com/fatih/color"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazydocker/pkg/commands"
"github.com/jesseduffield/lazydocker/pkg/tasks"
"github.com/jesseduffield/lazydocker/pkg/utils"
)
// containerLogsTailPresets are the values we cycle through when the user asks to
// change how many lines of logs are displayed. An empty string means 'show all logs'.
var containerLogsTailPresets = []string{"", "50", "100", "200", "500"}
func containerLogsTailLabel(tail string) string {
if tail == "" {
return "all"
}
return tail
}
// cycleContainerLogsTail moves to the next tail preset (wrapping back to the start)
// and forces the logs tab to re-render with the new value.
func (gui *Gui) cycleContainerLogsTail(g *gocui.Gui, v *gocui.View) error {
currentIdx := 0
for i, preset := range containerLogsTailPresets {
if preset == gui.State.ContainerLogsTail {
currentIdx = i
break
}
}
gui.State.ContainerLogsTail = containerLogsTailPresets[(currentIdx+1)%len(containerLogsTailPresets)]
return gui.Panels.Containers.HandleSelect()
}
func (gui *Gui) renderContainerLogsToMain(container *commands.Container) tasks.TaskFunc {
return gui.NewTickerTask(TickerTaskOpts{
Func: func(ctx context.Context, notifyStopped chan struct{}) {
@ -36,6 +65,7 @@ func (gui *Gui) renderContainerLogsToMainAux(container *commands.Container, ctx
}()
mainView := gui.Views.Main
mainView.Subtitle = fmt.Sprintf("tail: %s (%s to cycle)", containerLogsTailLabel(gui.State.ContainerLogsTail), "t")
if err := gui.writeContainerLogs(container, ctx, mainView); err != nil {
gui.Log.Error(err)
@ -110,7 +140,7 @@ func (gui *Gui) writeContainerLogs(ctr *commands.Container, ctx context.Context,
ShowStderr: true,
Timestamps: gui.Config.UserConfig.Logs.Timestamps,
Since: gui.Config.UserConfig.Logs.Since,
Tail: gui.Config.UserConfig.Logs.Tail,
Tail: gui.State.ContainerLogsTail,
Follow: true,
})
if err != nil {

View file

@ -68,7 +68,7 @@ func (gui *Gui) getContainersPanel() *panels.SideListPanel[*commands.Container]
// where a container restarts but the new logs don't get read.
// Note that this might be jarring if we have a lot of logs and the container
// restarts a lot, so let's keep an eye on it.
return "containers-" + container.ID + "-" + container.Container.State
return "containers-" + container.ID + "-" + container.Container.State + "-" + gui.State.ContainerLogsTail
},
},
ListPanel: panels.ListPanel[*commands.Container]{

View file

@ -82,6 +82,12 @@ type guiState struct {
// if true, we show containers with an 'exited' status in the containers panel
ShowExitedContainers bool
// the number of lines to pass as `--tail` when reading a container's logs. Empty
// string means we show all of the logs. This starts out as whatever is configured
// in the user's config, and can be cycled through ContainerLogsTailPresets via a
// keybinding.
ContainerLogsTail string
ScreenMode WindowMaximisation
// Maintains the state of manual filtering i.e. typing in a substring
@ -136,6 +142,7 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
ViewStack: []string{},
ShowExitedContainers: true,
ContainerLogsTail: config.UserConfig.Logs.Tail,
ScreenMode: getScreenMode(config),
}

View file

@ -241,6 +241,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleContainersExecShell,
Description: gui.Tr.ExecShell,
},
{
ViewName: "containers",
Key: 't',
Modifier: gocui.ModNone,
Handler: gui.cycleContainerLogsTail,
Description: gui.Tr.CycleContainerLogsTail,
},
{
ViewName: "containers",
Key: 'c',

View file

@ -65,6 +65,7 @@ type TranslationSet struct {
NextContext string
Attach string
ViewLogs string
CycleContainerLogsTail string
UpProject string
DownProject string
ServicesTitle string
@ -196,6 +197,7 @@ func englishSet() TranslationSet {
NextContext: "next tab",
Attach: "attach",
ViewLogs: "view logs",
CycleContainerLogsTail: "cycle how many log lines are shown",
UpProject: "up project",
DownProject: "down project",
RemoveImage: "remove image",