diff --git a/docs/Config.md b/docs/Config.md index e791c257955..c64e56d2edf 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -87,6 +87,11 @@ gui: # - 'top': split the window vertically (side panel on top, main view below) enlargedSideViewLocation: left + # If true, wrap lines in the staging view to the width of the view. This + # makes it much easier to work with diffs that have long lines, e.g. + # paragraphs of markdown text. + wrapLinesInStagingView: true + # One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' language: auto diff --git a/go.mod b/go.mod index 0db99c641e0..d89d03aeab0 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/integrii/flaggy v1.4.0 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d - github.com/jesseduffield/gocui v0.3.1-0.20241201093724-68c437bbd543 + github.com/jesseduffield/gocui v0.3.1-0.20241223111608-9967d0e928a0 github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e @@ -38,7 +38,7 @@ require ( github.com/stretchr/testify v1.8.1 github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 golang.org/x/exp v0.0.0-20220318154914-8dddf5d87bd8 - golang.org/x/sync v0.9.0 + golang.org/x/sync v0.10.0 gopkg.in/ozeidan/fuzzy-patricia.v3 v3.0.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -75,8 +75,8 @@ require ( github.com/xanzy/ssh-agent v0.2.1 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/term v0.26.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 23f370bac79..5041d10cc1b 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o= -github.com/jesseduffield/gocui v0.3.1-0.20241201093724-68c437bbd543 h1:mizrpmhRsYX6G7pqaLH+Rg9zdQ05S7xYVHTvSuBSX70= -github.com/jesseduffield/gocui v0.3.1-0.20241201093724-68c437bbd543/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= +github.com/jesseduffield/gocui v0.3.1-0.20241223111608-9967d0e928a0 h1:R29+E15wHqTDBfZxmzCLu0x34j5ljsXWT/DhR+2YiOU= +github.com/jesseduffield/gocui v0.3.1-0.20241223111608-9967d0e928a0/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo= github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY= @@ -424,8 +424,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170407050850-f3918c30c5c2/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -475,14 +475,14 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -493,8 +493,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 1148bb94721..36dc02a68a7 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -91,6 +91,10 @@ type GuiConfig struct { // - 'left': split the window horizontally (side panel on the left, main view on the right) // - 'top': split the window vertically (side panel on top, main view below) EnlargedSideViewLocation string `yaml:"enlargedSideViewLocation"` + // If true, wrap lines in the staging view to the width of the view. This + // makes it much easier to work with diffs that have long lines, e.g. + // paragraphs of markdown text. + WrapLinesInStagingView bool `yaml:"wrapLinesInStagingView"` // One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' Language string `yaml:"language" jsonschema:"enum=auto,enum=en,enum=zh-TW,enum=zh-CN,enum=pl,enum=nl,enum=ja,enum=ko,enum=ru"` // Format used when displaying time e.g. commit time. @@ -692,6 +696,7 @@ func GetDefaultConfig() *UserConfig { ExpandedSidePanelWeight: 2, MainPanelSplitMode: "flexible", EnlargedSideViewLocation: "left", + WrapLinesInStagingView: true, Language: "auto", TimeFormat: "02 Jan 06", ShortTimeFormat: time.Kitchen, diff --git a/pkg/gui/context/patch_explorer_context.go b/pkg/gui/context/patch_explorer_context.go index 46d82f5b4f6..eb79dce8667 100644 --- a/pkg/gui/context/patch_explorer_context.go +++ b/pkg/gui/context/patch_explorer_context.go @@ -39,12 +39,13 @@ func NewPatchExplorerContext( mutex: &deadlock.Mutex{}, getIncludedLineIndices: getIncludedLineIndices, SimpleContext: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: view, - WindowName: windowName, - Key: key, - Kind: types.MAIN_CONTEXT, - Focusable: true, - HighlightOnFocus: true, + View: view, + WindowName: windowName, + Key: key, + Kind: types.MAIN_CONTEXT, + Focusable: true, + HighlightOnFocus: true, + NeedsRerenderOnWidthChange: types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_WIDTH_CHANGES, })), SearchTrait: NewSearchTrait(c), } @@ -58,6 +59,8 @@ func NewPatchExplorerContext( }), ) + ctx.SetHandleRenderFunc(ctx.OnViewWidthChanged) + return ctx } @@ -106,13 +109,13 @@ func (self *PatchExplorerContext) FocusSelection() { state := self.GetState() bufferHeight := view.InnerHeight() _, origin := view.Origin() - numLines := view.LinesHeight() + numLines := view.ViewLinesHeight() newOriginY := state.CalculateOrigin(origin, bufferHeight, numLines) view.SetOriginY(newOriginY) - startIdx, endIdx := state.SelectedRange() + startIdx, endIdx := state.SelectedViewRange() // As far as the view is concerned, we are always selecting a range view.SetRangeSelectStart(startIdx) view.SetCursorY(endIdx - newOriginY) @@ -140,3 +143,11 @@ func (self *PatchExplorerContext) GetMutex() *deadlock.Mutex { func (self *PatchExplorerContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition { return nil } + +func (self *PatchExplorerContext) OnViewWidthChanged() { + if state := self.GetState(); state != nil { + state.OnViewWidthChanged(self.GetView()) + self.setContent() + self.RenderAndFocus() + } +} diff --git a/pkg/gui/context/simple_context.go b/pkg/gui/context/simple_context.go index d78db719075..579f975e625 100644 --- a/pkg/gui/context/simple_context.go +++ b/pkg/gui/context/simple_context.go @@ -7,6 +7,7 @@ import ( type SimpleContext struct { *BaseContext + handleRenderFunc func() } func NewSimpleContext(baseContext *BaseContext) *SimpleContext { @@ -54,6 +55,13 @@ func (self *SimpleContext) HandleFocusLost(opts types.OnFocusLostOpts) { } func (self *SimpleContext) HandleRender() { + if self.handleRenderFunc != nil { + self.handleRenderFunc() + } +} + +func (self *SimpleContext) SetHandleRenderFunc(f func()) { + self.handleRenderFunc = f } func (self *SimpleContext) HandleRenderToMain() { diff --git a/pkg/gui/controllers/helpers/confirmation_helper.go b/pkg/gui/controllers/helpers/confirmation_helper.go index 7b0b8ddb23b..f7f6f8720c4 100644 --- a/pkg/gui/controllers/helpers/confirmation_helper.go +++ b/pkg/gui/controllers/helpers/confirmation_helper.go @@ -3,12 +3,11 @@ package helpers import ( goContext "context" "fmt" - "strings" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/theme" - "github.com/mattn/go-runewidth" + "github.com/jesseduffield/lazygit/pkg/utils" ) type ConfirmationHelper struct { @@ -57,61 +56,9 @@ func (self *ConfirmationHelper) DeactivateConfirmationPrompt() { self.clearConfirmationViewKeyBindings() } -// Temporary hack: we're just duplicating the logic in `gocui.lineWrap` func getMessageHeight(wrap bool, message string, width int) int { - return len(wrapMessageToWidth(wrap, message, width)) -} - -func wrapMessageToWidth(wrap bool, message string, width int) []string { - lines := strings.Split(message, "\n") - if !wrap { - return lines - } - - wrappedLines := make([]string, 0, len(lines)) - - for _, line := range lines { - n := 0 - offset := 0 - lastWhitespaceIndex := -1 - for i, currChr := range line { - rw := runewidth.RuneWidth(currChr) - n += rw - - if n > width { - if currChr == ' ' { - wrappedLines = append(wrappedLines, line[offset:i]) - offset = i + 1 - n = 0 - } else if currChr == '-' { - wrappedLines = append(wrappedLines, line[offset:i]) - offset = i - n = rw - } else if lastWhitespaceIndex != -1 && lastWhitespaceIndex+1 != i { - if line[lastWhitespaceIndex] == '-' { - wrappedLines = append(wrappedLines, line[offset:lastWhitespaceIndex+1]) - offset = lastWhitespaceIndex + 1 - n = i - lastWhitespaceIndex - } else { - wrappedLines = append(wrappedLines, line[offset:lastWhitespaceIndex]) - offset = lastWhitespaceIndex + 1 - n = i - lastWhitespaceIndex + 1 - } - } else { - wrappedLines = append(wrappedLines, line[offset:i]) - offset = i - n = rw - } - lastWhitespaceIndex = -1 - } else if currChr == ' ' || currChr == '-' { - lastWhitespaceIndex = i - } - } - - wrappedLines = append(wrappedLines, line[offset:]) - } - - return wrappedLines + wrappedLines, _, _ := utils.WrapViewLinesToWidth(wrap, message, width) + return len(wrappedLines) } func (self *ConfirmationHelper) getPopupPanelDimensionsForContentHeight(panelWidth, contentHeight int, parentPopupContext types.Context) (int, int, int, int) { @@ -329,7 +276,7 @@ func (self *ConfirmationHelper) layoutMenuPrompt(contentWidth int) int { var promptLines []string prompt := self.c.Contexts().Menu.GetPrompt() if len(prompt) > 0 { - promptLines = wrapMessageToWidth(true, prompt, contentWidth) + promptLines, _, _ = utils.WrapViewLinesToWidth(true, prompt, contentWidth) promptLines = append(promptLines, "") } self.c.Contexts().Menu.SetPromptLines(promptLines) diff --git a/pkg/gui/controllers/helpers/patch_building_helper.go b/pkg/gui/controllers/helpers/patch_building_helper.go index 63744167f94..cde561fbcf3 100644 --- a/pkg/gui/controllers/helpers/patch_building_helper.go +++ b/pkg/gui/controllers/helpers/patch_building_helper.go @@ -91,7 +91,7 @@ func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpt oldState := context.GetState() - state := patch_exploring.NewState(diff, selectedLineIdx, oldState, self.c.Log) + state := patch_exploring.NewState(diff, selectedLineIdx, context.GetView(), oldState) context.SetState(state) if state == nil { self.Escape() diff --git a/pkg/gui/controllers/helpers/staging_helper.go b/pkg/gui/controllers/helpers/staging_helper.go index a6b8705179c..69760a1939a 100644 --- a/pkg/gui/controllers/helpers/staging_helper.go +++ b/pkg/gui/controllers/helpers/staging_helper.go @@ -63,11 +63,11 @@ func (self *StagingHelper) RefreshStagingPanel(focusOpts types.OnFocusOpts) { secondaryContext.GetMutex().Lock() mainContext.SetState( - patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetState(), self.c.Log), + patch_exploring.NewState(mainDiff, mainSelectedLineIdx, mainContext.GetView(), mainContext.GetState()), ) secondaryContext.SetState( - patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetState(), self.c.Log), + patch_exploring.NewState(secondaryDiff, secondarySelectedLineIdx, secondaryContext.GetView(), secondaryContext.GetState()), ) mainState := mainContext.GetState() diff --git a/pkg/gui/controllers/patch_building_controller.go b/pkg/gui/controllers/patch_building_controller.go index ea181cd054d..7bc0ffb8320 100644 --- a/pkg/gui/controllers/patch_building_controller.go +++ b/pkg/gui/controllers/patch_building_controller.go @@ -65,7 +65,7 @@ func (self *PatchBuildingController) GetMouseKeybindings(opts types.KeybindingsO func (self *PatchBuildingController) GetOnFocus() func(types.OnFocusOpts) { return func(opts types.OnFocusOpts) { // no need to change wrap on the secondary view because it can't be interacted with - self.c.Views().PatchBuilding.Wrap = false + self.c.Views().PatchBuilding.Wrap = self.c.UserConfig().Gui.WrapLinesInStagingView self.c.Helpers().PatchBuilding.RefreshPatchBuildingPanel(opts) } @@ -73,6 +73,8 @@ func (self *PatchBuildingController) GetOnFocus() func(types.OnFocusOpts) { func (self *PatchBuildingController) GetOnFocusLost() func(types.OnFocusLostOpts) { return func(opts types.OnFocusLostOpts) { + self.context().SetState(nil) + self.c.Views().PatchBuilding.Wrap = true if self.c.Git().Patch.PatchBuilder.IsEmpty() { @@ -134,13 +136,13 @@ func (self *PatchBuildingController) toggleSelection() error { if err != nil { return err } - currentLineIsStaged := lo.Contains(includedLineIndices, state.GetSelectedLineIdx()) + currentLineIsStaged := lo.Contains(includedLineIndices, state.GetSelectedPatchLineIdx()) if currentLineIsStaged { toggleFunc = self.c.Git().Patch.PatchBuilder.RemoveFileLineRange } // add range of lines to those set for the file - firstLineIdx, lastLineIdx := state.SelectedRange() + firstLineIdx, lastLineIdx := state.SelectedPatchRange() if err := toggleFunc(filename, firstLineIdx, lastLineIdx); err != nil { // might actually want to return an error here diff --git a/pkg/gui/controllers/patch_explorer_controller.go b/pkg/gui/controllers/patch_explorer_controller.go index d84ff48a08b..315d392ec8b 100644 --- a/pkg/gui/controllers/patch_explorer_controller.go +++ b/pkg/gui/controllers/patch_explorer_controller.go @@ -170,9 +170,9 @@ func (self *PatchExplorerController) GetMouseKeybindings(opts types.KeybindingsO } func (self *PatchExplorerController) HandlePrevLine() error { - before := self.context.GetState().GetSelectedLineIdx() + before := self.context.GetState().GetSelectedViewLineIdx() self.context.GetState().CycleSelection(false) - after := self.context.GetState().GetSelectedLineIdx() + after := self.context.GetState().GetSelectedViewLineIdx() if self.context.GetState().SelectingLine() { checkScrollUp(self.context.GetViewTrait(), self.c.UserConfig(), before, after) @@ -182,9 +182,9 @@ func (self *PatchExplorerController) HandlePrevLine() error { } func (self *PatchExplorerController) HandleNextLine() error { - before := self.context.GetState().GetSelectedLineIdx() + before := self.context.GetState().GetSelectedViewLineIdx() self.context.GetState().CycleSelection(true) - after := self.context.GetState().GetSelectedLineIdx() + after := self.context.GetState().GetSelectedViewLineIdx() if self.context.GetState().SelectingLine() { checkScrollDown(self.context.GetViewTrait(), self.c.UserConfig(), before, after) diff --git a/pkg/gui/controllers/staging_controller.go b/pkg/gui/controllers/staging_controller.go index 4ae9a946b45..fbcbc049bdd 100644 --- a/pkg/gui/controllers/staging_controller.go +++ b/pkg/gui/controllers/staging_controller.go @@ -118,8 +118,9 @@ func (self *StagingController) GetMouseKeybindings(opts types.KeybindingsOpts) [ func (self *StagingController) GetOnFocus() func(types.OnFocusOpts) { return func(opts types.OnFocusOpts) { - self.c.Views().Staging.Wrap = false - self.c.Views().StagingSecondary.Wrap = false + wrap := self.c.UserConfig().Gui.WrapLinesInStagingView + self.c.Views().Staging.Wrap = wrap + self.c.Views().StagingSecondary.Wrap = wrap self.c.Helpers().Staging.RefreshStagingPanel(opts) } @@ -220,7 +221,7 @@ func (self *StagingController) applySelection(reverse bool) error { return nil } - firstLineIdx, lastLineIdx := state.SelectedRange() + firstLineIdx, lastLineIdx := state.SelectedPatchRange() patchToApply := patch. Parse(state.GetDiff()). Transform(patch.TransformOpts{ @@ -249,7 +250,7 @@ func (self *StagingController) applySelection(reverse bool) error { } if state.SelectingRange() { - firstLine, _ := state.SelectedRange() + firstLine, _ := state.SelectedViewRange() state.SelectLine(firstLine) } @@ -290,7 +291,7 @@ func (self *StagingController) editHunk() error { } lineOffset := 3 - lineIdxInHunk := state.GetSelectedLineIdx() - hunkStartIdx + lineIdxInHunk := state.GetSelectedPatchLineIdx() - hunkStartIdx if err := self.c.Helpers().Files.EditFileAtLineAndWait(patchFilepath, lineIdxInHunk+lineOffset); err != nil { return err } diff --git a/pkg/gui/patch_exploring/state.go b/pkg/gui/patch_exploring/state.go index 4c20b7a51b4..c10807c8c07 100644 --- a/pkg/gui/patch_exploring/state.go +++ b/pkg/gui/patch_exploring/state.go @@ -1,15 +1,19 @@ package patch_exploring import ( + "strings" + "github.com/jesseduffield/generics/set" + "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/patch" - "github.com/sirupsen/logrus" + "github.com/jesseduffield/lazygit/pkg/utils" ) // State represents the current state of the patch explorer context i.e. when // you're staging a file or you're building a patch from an existing commit // this struct holds the info about the diff you're interacting with and what's currently selected. type State struct { + // These are in terms of view lines (wrapped), not patch lines selectedLineIdx int rangeStartLineIdx int // If a range is sticky, it means we expand the range when we move up or down. @@ -18,6 +22,11 @@ type State struct { diff string patch *patch.Patch selectMode selectMode + + // Array of indices of the wrapped lines indexed by a patch line index + viewLineIndices []int + // Array of indices of the original patch lines indexed by a wrapped view line index + patchLineIndices []int } // these represent what select mode we're in @@ -29,7 +38,7 @@ const ( HUNK ) -func NewState(diff string, selectedLineIdx int, oldState *State, log *logrus.Entry) *State { +func NewState(diff string, selectedLineIdx int, view *gocui.View, oldState *State) *State { if oldState != nil && diff == oldState.diff && selectedLineIdx == -1 { // if we're here then we can return the old state. If selectedLineIdx was not -1 // then that would mean we were trying to click and potentiall drag a range, which @@ -43,6 +52,8 @@ func NewState(diff string, selectedLineIdx int, oldState *State, log *logrus.Ent return nil } + viewLineIndices, patchLineIndices := wrapPatchLines(diff, view) + rangeStartLineIdx := 0 if oldState != nil { rangeStartLineIdx = oldState.rangeStartLineIdx @@ -51,6 +62,10 @@ func NewState(diff string, selectedLineIdx int, oldState *State, log *logrus.Ent selectMode := LINE // if we have clicked from the outside to focus the main view we'll pass in a non-negative line index so that we can instantly select that line if selectedLineIdx >= 0 { + // Clamp to the number of wrapped view lines; index might be out of + // bounds if a custom pager is being used which produces more lines + selectedLineIdx = min(selectedLineIdx, len(viewLineIndices)-1) + selectMode = RANGE rangeStartLineIdx = selectedLineIdx } else if oldState != nil { @@ -58,9 +73,9 @@ func NewState(diff string, selectedLineIdx int, oldState *State, log *logrus.Ent if oldState.selectMode == HUNK { selectMode = HUNK } - selectedLineIdx = patch.GetNextChangeIdx(oldState.selectedLineIdx) + selectedLineIdx = viewLineIndices[patch.GetNextChangeIdx(oldState.patchLineIndices[oldState.selectedLineIdx])] } else { - selectedLineIdx = patch.GetNextChangeIdx(0) + selectedLineIdx = viewLineIndices[patch.GetNextChangeIdx(0)] } return &State{ @@ -70,10 +85,33 @@ func NewState(diff string, selectedLineIdx int, oldState *State, log *logrus.Ent rangeStartLineIdx: rangeStartLineIdx, rangeIsSticky: false, diff: diff, + viewLineIndices: viewLineIndices, + patchLineIndices: patchLineIndices, } } -func (s *State) GetSelectedLineIdx() int { +func (s *State) OnViewWidthChanged(view *gocui.View) { + if !view.Wrap { + return + } + + selectedPatchLineIdx := s.patchLineIndices[s.selectedLineIdx] + var rangeStartPatchLineIdx int + if s.selectMode == RANGE { + rangeStartPatchLineIdx = s.patchLineIndices[s.rangeStartLineIdx] + } + s.viewLineIndices, s.patchLineIndices = wrapPatchLines(s.diff, view) + s.selectedLineIdx = s.viewLineIndices[selectedPatchLineIdx] + if s.selectMode == RANGE { + s.rangeStartLineIdx = s.viewLineIndices[rangeStartPatchLineIdx] + } +} + +func (s *State) GetSelectedPatchLineIdx() int { + return s.patchLineIndices[s.selectedLineIdx] +} + +func (s *State) GetSelectedViewLineIdx() int { return s.selectedLineIdx } @@ -143,8 +181,8 @@ func (s *State) SelectLine(newSelectedLineIdx int) { func (s *State) selectLineWithoutRangeCheck(newSelectedLineIdx int) { if newSelectedLineIdx < 0 { newSelectedLineIdx = 0 - } else if newSelectedLineIdx > s.patch.LineCount()-1 { - newSelectedLineIdx = s.patch.LineCount() - 1 + } else if newSelectedLineIdx > len(s.patchLineIndices)-1 { + newSelectedLineIdx = len(s.patchLineIndices) - 1 } s.selectedLineIdx = newSelectedLineIdx @@ -178,12 +216,12 @@ func (s *State) CycleHunk(forward bool) { change = -1 } - hunkIdx := s.patch.HunkContainingLine(s.selectedLineIdx) + hunkIdx := s.patch.HunkContainingLine(s.patchLineIndices[s.selectedLineIdx]) if hunkIdx != -1 { newHunkIdx := hunkIdx + change if newHunkIdx >= 0 && newHunkIdx < s.patch.HunkCount() { start := s.patch.HunkStartIdx(newHunkIdx) - s.selectedLineIdx = s.patch.GetNextChangeIdx(start) + s.selectedLineIdx = s.viewLineIndices[s.patch.GetNextChangeIdx(start)] } } } @@ -216,16 +254,17 @@ func (s *State) CycleRange(forward bool) { // returns first and last patch line index of current hunk func (s *State) CurrentHunkBounds() (int, int) { - hunkIdx := s.patch.HunkContainingLine(s.selectedLineIdx) + hunkIdx := s.patch.HunkContainingLine(s.patchLineIndices[s.selectedLineIdx]) start := s.patch.HunkStartIdx(hunkIdx) end := s.patch.HunkEndIdx(hunkIdx) return start, end } -func (s *State) SelectedRange() (int, int) { +func (s *State) SelectedViewRange() (int, int) { switch s.selectMode { case HUNK: - return s.CurrentHunkBounds() + start, end := s.CurrentHunkBounds() + return s.viewLineIndices[start], s.viewLineIndices[end] case RANGE: if s.rangeStartLineIdx > s.selectedLineIdx { return s.selectedLineIdx, s.rangeStartLineIdx @@ -240,8 +279,13 @@ func (s *State) SelectedRange() (int, int) { } } +func (s *State) SelectedPatchRange() (int, int) { + start, end := s.SelectedViewRange() + return s.patchLineIndices[start], s.patchLineIndices[end] +} + func (s *State) CurrentLineNumber() int { - return s.patch.LineNumberOfLine(s.selectedLineIdx) + return s.patch.LineNumberOfLine(s.patchLineIndices[s.selectedLineIdx]) } func (s *State) AdjustSelectedLineIdx(change int) { @@ -257,13 +301,13 @@ func (s *State) RenderForLineIndices(includedLineIndices []int) string { } func (s *State) PlainRenderSelected() string { - firstLineIdx, lastLineIdx := s.SelectedRange() + firstLineIdx, lastLineIdx := s.SelectedPatchRange() return s.patch.FormatRangePlain(firstLineIdx, lastLineIdx) } func (s *State) SelectBottom() { s.DismissHunkSelectMode() - s.SelectLine(s.patch.LineCount() - 1) + s.SelectLine(len(s.patchLineIndices) - 1) } func (s *State) SelectTop() { @@ -272,15 +316,13 @@ func (s *State) SelectTop() { } func (s *State) CalculateOrigin(currentOrigin int, bufferHeight int, numLines int) int { - firstLineIdx, lastLineIdx := s.SelectedRange() + firstLineIdx, lastLineIdx := s.SelectedViewRange() - return calculateOrigin(currentOrigin, bufferHeight, numLines, firstLineIdx, lastLineIdx, s.GetSelectedLineIdx(), s.selectMode) + return calculateOrigin(currentOrigin, bufferHeight, numLines, firstLineIdx, lastLineIdx, s.GetSelectedViewLineIdx(), s.selectMode) } -func (s *State) RangeStartLineIdx() (int, bool) { - if s.selectMode == RANGE { - return s.rangeStartLineIdx, true - } - - return 0, false +func wrapPatchLines(diff string, view *gocui.View) ([]int, []int) { + _, viewLineIndices, patchLineIndices := utils.WrapViewLinesToWidth( + view.Wrap, strings.TrimSuffix(diff, "\n"), view.InnerWidth()) + return viewLineIndices, patchLineIndices } diff --git a/pkg/utils/lines.go b/pkg/utils/lines.go index c70d02ffcef..197b779757e 100644 --- a/pkg/utils/lines.go +++ b/pkg/utils/lines.go @@ -3,6 +3,8 @@ package utils import ( "bytes" "strings" + + "github.com/mattn/go-runewidth" ) // SplitLines takes a multiline string and splits it on newlines @@ -100,3 +102,81 @@ func ScanLinesAndTruncateWhenLongerThanBuffer(maxBufferSize int) func(data []byt return 0, nil, nil } } + +// Wrap lines to a given width, and return: +// - the wrapped lines +// - the line indices of the wrapped lines, indexed by the original line indices +// - the line indices of the original lines, indexed by the wrapped line indices +// If wrap is false, the text is returned as is. +// This code needs to behave the same as `gocui.lineWrap` does. +func WrapViewLinesToWidth(wrap bool, text string, width int) ([]string, []int, []int) { + lines := strings.Split(text, "\n") + if !wrap { + indices := make([]int, len(lines)) + for i := range lines { + indices[i] = i + } + return lines, indices, indices + } + + wrappedLines := make([]string, 0, len(lines)) + wrappedLineIndices := make([]int, 0, len(lines)) + originalLineIndices := make([]int, 0, len(lines)) + + for originalLineIdx, line := range lines { + wrappedLineIndices = append(wrappedLineIndices, len(wrappedLines)) + + // convert tabs to spaces + for i := 0; i < len(line); i++ { + if line[i] == '\t' { + numSpaces := 4 - (i % 4) + line = line[:i] + " "[:numSpaces] + line[i+1:] + i += numSpaces - 1 + } + } + + appendWrappedLine := func(str string) { + wrappedLines = append(wrappedLines, str) + originalLineIndices = append(originalLineIndices, originalLineIdx) + } + + n := 0 + offset := 0 + lastWhitespaceIndex := -1 + for i, currChr := range line { + rw := runewidth.RuneWidth(currChr) + n += rw + + if n > width { + if currChr == ' ' { + appendWrappedLine(line[offset:i]) + offset = i + 1 + n = 0 + } else if currChr == '-' { + appendWrappedLine(line[offset:i]) + offset = i + n = rw + } else if lastWhitespaceIndex != -1 { + if line[lastWhitespaceIndex] == '-' { + appendWrappedLine(line[offset : lastWhitespaceIndex+1]) + } else { + appendWrappedLine(line[offset:lastWhitespaceIndex]) + } + offset = lastWhitespaceIndex + 1 + n = runewidth.StringWidth(line[offset : i+1]) + } else { + appendWrappedLine(line[offset:i]) + offset = i + n = rw + } + lastWhitespaceIndex = -1 + } else if currChr == ' ' || currChr == '-' { + lastWhitespaceIndex = i + } + } + + appendWrappedLine(line[offset:]) + } + + return wrappedLines, wrappedLineIndices, originalLineIndices +} diff --git a/pkg/utils/lines_test.go b/pkg/utils/lines_test.go index 2192a3780ef..5fc6a07b063 100644 --- a/pkg/utils/lines_test.go +++ b/pkg/utils/lines_test.go @@ -5,6 +5,7 @@ import ( "strings" "testing" + "github.com/jesseduffield/gocui" "github.com/stretchr/testify/assert" ) @@ -164,3 +165,238 @@ func TestScanLinesAndTruncateWhenLongerThanBuffer(t *testing.T) { assert.EqualValues(t, s.expectedLines, result) } } + +func TestWrapViewLinesToWidth(t *testing.T) { + tests := []struct { + name string + wrap bool + text string + width int + expectedWrappedLines []string + expectedWrappedLinesIndices []int + expectedOriginalLinesIndices []int + }{ + { + name: "Wrap off", + wrap: false, + text: "1st line\n2nd line\n3rd line", + width: 5, + expectedWrappedLines: []string{ + "1st line", + "2nd line", + "3rd line", + }, + expectedWrappedLinesIndices: []int{0, 1, 2}, + expectedOriginalLinesIndices: []int{0, 1, 2}, + }, + { + name: "Wrap on space", + wrap: true, + text: "Hello World", + width: 5, + expectedWrappedLines: []string{ + "Hello", + "World", + }, + expectedWrappedLinesIndices: []int{0}, + expectedOriginalLinesIndices: []int{0, 0}, + }, + { + name: "Wrap on hyphen", + wrap: true, + text: "Hello-World", + width: 6, + expectedWrappedLines: []string{ + "Hello-", + "World", + }, + }, + { + name: "Wrap on hyphen 2", + wrap: true, + text: "Blah Hello-World", + width: 12, + expectedWrappedLines: []string{ + "Blah Hello-", + "World", + }, + }, + { + name: "Wrap on hyphen 3", + wrap: true, + text: "Blah Hello-World", + width: 11, + expectedWrappedLines: []string{ + "Blah Hello-", + "World", + }, + }, + { + name: "Wrap on hyphen 4", + wrap: true, + text: "Blah Hello-World", + width: 10, + expectedWrappedLines: []string{ + "Blah Hello", + "-World", + }, + }, + { + name: "Wrap on space 2", + wrap: true, + text: "Blah Hello World", + width: 10, + expectedWrappedLines: []string{ + "Blah Hello", + "World", + }, + }, + { + name: "Wrap on space with more words", + wrap: true, + text: "Longer word here", + width: 10, + expectedWrappedLines: []string{ + "Longer", + "word here", + }, + }, + { + name: "Split word that's too long", + wrap: true, + text: "ThisWordIsWayTooLong", + width: 10, + expectedWrappedLines: []string{ + "ThisWordIs", + "WayTooLong", + }, + }, + { + name: "Split word that's too long over multiple lines", + wrap: true, + text: "ThisWordIsWayTooLong", + width: 5, + expectedWrappedLines: []string{ + "ThisW", + "ordIs", + "WayTo", + "oLong", + }, + }, + { + name: "Lots of hyphens", + wrap: true, + text: "one-two-three-four-five", + width: 8, + expectedWrappedLines: []string{ + "one-two-", + "three-", + "four-", + "five", + }, + }, + { + name: "Several lines using all the available width", + wrap: true, + text: "aaa bb cc ddd-ee ff", + width: 5, + expectedWrappedLines: []string{ + "aaa", + "bb cc", + "ddd-", + "ee ff", + }, + }, + { + name: "Several lines using all the available width, with multi-cell runes", + wrap: true, + text: "ðŸĪðŸĪðŸĪ 🐝🐝 🙉🙉 ðŸĶŠðŸĶŠðŸĶŠ-🐎🐎 ðŸĶĒðŸĶĒ", + width: 9, + expectedWrappedLines: []string{ + "ðŸĪðŸĪðŸĪ", + "🐝🐝 🙉🙉", + "ðŸĶŠðŸĶŠðŸĶŠ-", + "🐎🐎 ðŸĶĒðŸĶĒ", + }, + }, + { + name: "Space in last column", + wrap: true, + text: "hello world", + width: 6, + expectedWrappedLines: []string{ + "hello", + "world", + }, + }, + { + name: "Hyphen in last column", + wrap: true, + text: "hello-world", + width: 6, + expectedWrappedLines: []string{ + "hello-", + "world", + }, + }, + { + name: "English text", + wrap: true, + text: "+The sea reach of the Thames stretched before us like the bedinnind of an interminable waterway. In the offind the sea and the sky were welded todether without a joint, and in the luminous space the tanned sails of the bardes drifting blah blah", + width: 81, + expectedWrappedLines: []string{ + "+The sea reach of the Thames stretched before us like the bedinnind of an", + "interminable waterway. In the offind the sea and the sky were welded todether", + "without a joint, and in the luminous space the tanned sails of the bardes", + "drifting blah blah", + }, + }, + { + name: "Tabs", + wrap: true, + text: "\ta\tbb\tccc\tdddd\teeeee", + width: 50, + expectedWrappedLines: []string{ + " a bb ccc dddd eeeee", + }, + }, + { + name: "Multiple lines", + wrap: true, + text: "First paragraph\nThe second paragraph is a bit longer.\nThird paragraph\n", + width: 10, + expectedWrappedLines: []string{ + "First", + "paragraph", + "The second", + "paragraph", + "is a bit", + "longer.", + "Third", + "paragraph", + "", + }, + expectedWrappedLinesIndices: []int{0, 2, 6, 8}, + expectedOriginalLinesIndices: []int{0, 0, 1, 1, 1, 1, 2, 2, 3}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wrappedLines, wrappedLinesIndices, originalLinesIndices := WrapViewLinesToWidth(tt.wrap, tt.text, tt.width) + assert.Equal(t, tt.expectedWrappedLines, wrappedLines) + if tt.expectedWrappedLinesIndices != nil { + assert.Equal(t, tt.expectedWrappedLinesIndices, wrappedLinesIndices) + } + if tt.expectedOriginalLinesIndices != nil { + assert.Equal(t, tt.expectedOriginalLinesIndices, originalLinesIndices) + } + + // As a sanity check, also test that gocui's line wrapping behaves the same way + view := gocui.NewView("", 0, 0, tt.width+1, 1000, gocui.OutputNormal) + assert.Equal(t, tt.width, view.InnerWidth()) + view.Wrap = tt.wrap + view.SetContent(tt.text) + assert.Equal(t, wrappedLines, view.ViewBufferLines()) + }) + } +} diff --git a/schema/config.json b/schema/config.json index ee5726740c1..ee6f37ca508 100644 --- a/schema/config.json +++ b/schema/config.json @@ -96,6 +96,11 @@ "description": "How the window is split when in half screen mode (i.e. after hitting '+' once).\nPossible values:\n- 'left': split the window horizontally (side panel on the left, main view on the right)\n- 'top': split the window vertically (side panel on top, main view below)", "default": "left" }, + "wrapLinesInStagingView": { + "type": "boolean", + "description": "If true, wrap lines in the staging view to the width of the view. This\nmakes it much easier to work with diffs that have long lines, e.g.\nparagraphs of markdown text.", + "default": true + }, "language": { "type": "string", "enum": [ diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index 0ea2a737973..7caa174a286 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -335,7 +335,7 @@ func (g *Gui) SetView(name string, x0, y0, x1, y1 int, overlaps byte) (*View, er g.Mutexes.ViewsMutex.Lock() - v := newView(name, x0, y0, x1, y1, g.outputMode) + v := NewView(name, x0, y0, x1, y1, g.outputMode) v.BgColor, v.FgColor = g.BgColor, g.FgColor v.SelBgColor, v.SelFgColor = g.SelBgColor, g.SelFgColor v.Overlaps = overlaps diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 190a653a4c3..5a331b43e64 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -402,8 +402,8 @@ func (l lineType) String() string { return str } -// newView returns a new View object. -func newView(name string, x0, y0, x1, y1 int, mode OutputMode) *View { +// NewView returns a new View object. +func NewView(name string, x0, y0, x1, y1 int, mode OutputMode) *View { v := &View{ name: name, x0: x0, @@ -494,31 +494,15 @@ func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) { bgColor = v.BgColor ch = v.Mask } else if v.Highlight { - var ry, rcy int - - _, ry, ok := v.realPosition(x, y) - if !ok { - return - } - _, rrcy, ok := v.realPosition(v.cx, v.cy) - // out of bounds is fine - if ok { - rcy = rrcy - } - - rangeSelectStart := rcy - rangeSelectEnd := rcy + rangeSelectStart := v.cy + rangeSelectEnd := v.cy if v.rangeSelectStartY != -1 { - _, realRangeSelectStart, ok := v.realPosition(0, v.rangeSelectStartY-v.oy) - if !ok { - return - } - - rangeSelectStart = min(realRangeSelectStart, rcy) - rangeSelectEnd = max(realRangeSelectStart, rcy) + relativeRangeSelectStart := v.rangeSelectStartY - v.oy + rangeSelectStart = min(relativeRangeSelectStart, v.cy) + rangeSelectEnd = max(relativeRangeSelectStart, v.cy) } - if ry >= rangeSelectStart && ry <= rangeSelectEnd { + if y >= rangeSelectStart && y <= rangeSelectEnd { // this ensures we use the bright variant of a colour upon highlight fgColorComponent := fgColor & ^AttrAll if fgColorComponent >= AttrIsValidColor && fgColorComponent < AttrIsValidColor+8 { @@ -1103,6 +1087,8 @@ func (v *View) updateSearchPositions() { if v.searcher.modelSearchResults != nil { for _, result := range v.searcher.modelSearchResults { + // This code only works when v.Wrap is false. + if result.Y >= len(v.lines) { break } @@ -1131,8 +1117,9 @@ func (v *View) updateSearchPositions() { } } } else { - for y, line := range v.lines { - v.searcher.searchPositions = append(v.searcher.searchPositions, searchPositionsForLine(line, y)...) + v.refreshViewLinesIfNeeded() + for y, line := range v.viewLines { + v.searcher.searchPositions = append(v.searcher.searchPositions, searchPositionsForLine(line.line, y)...) } } } @@ -1373,6 +1360,8 @@ func (v *View) ViewBufferLines() []string { v.writeMutex.Lock() defer v.writeMutex.Unlock() + v.refreshViewLinesIfNeeded() + lines := make([]string, len(v.viewLines)) for i, l := range v.viewLines { str := lineType(l.line).String() @@ -1512,18 +1501,20 @@ func lineWrap(line []cell, columns int) [][]cell { lines = append(lines, line[offset:i]) offset = i n = rw - } else if lastWhitespaceIndex != -1 && lastWhitespaceIndex+1 != i { + } else if lastWhitespaceIndex != -1 { // if there is a space in the line and the line is not breaking at a space/hyphen if line[lastWhitespaceIndex].chr == '-' { // if break occurs at hyphen, we'll retain the hyphen lines = append(lines, line[offset:lastWhitespaceIndex+1]) - offset = lastWhitespaceIndex + 1 - n = i - offset } else { // if break occurs at space, we'll omit the space lines = append(lines, line[offset:lastWhitespaceIndex]) - offset = lastWhitespaceIndex + 1 - n = i - offset + 1 + } + // Either way, continue *after* the break + offset = lastWhitespaceIndex + 1 + n = 0 + for _, c := range line[offset : i+1] { + n += runewidth.RuneWidth(c.chr) } } else { // in this case we're breaking mid-word diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index ccba391c9fb..6ebc48b3fec 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -321,6 +321,9 @@ const ( AUDIT_INTEGRITY_STATUS = 0x70a AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f + AUDIT_IPE_ACCESS = 0x58c + AUDIT_IPE_CONFIG_CHANGE = 0x58d + AUDIT_IPE_POLICY_LOAD = 0x58e AUDIT_KERNEL = 0x7d0 AUDIT_KERNEL_OTHER = 0x524 AUDIT_KERN_MODULE = 0x532 @@ -489,6 +492,7 @@ const ( BPF_F_ID = 0x20 BPF_F_NETFILTER_IP_DEFRAG = 0x1 BPF_F_QUERY_EFFECTIVE = 0x1 + BPF_F_REDIRECT_FLAGS = 0x19 BPF_F_REPLACE = 0x4 BPF_F_SLEEPABLE = 0x10 BPF_F_STRICT_ALIGNMENT = 0x1 @@ -1166,6 +1170,7 @@ const ( EXTA = 0xe EXTB = 0xf F2FS_SUPER_MAGIC = 0xf2f52010 + FALLOC_FL_ALLOCATE_RANGE = 0x0 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -1799,6 +1804,8 @@ const ( LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 + LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1 + LANDLOCK_SCOPE_SIGNAL = 0x2 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_HALT = 0xcdef0123 @@ -1924,6 +1931,7 @@ const ( MNT_FORCE = 0x1 MNT_ID_REQ_SIZE_VER0 = 0x18 MNT_ID_REQ_SIZE_VER1 = 0x20 + MNT_NS_INFO_SIZE_VER0 = 0x10 MODULE_INIT_COMPRESSED_FILE = 0x4 MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_VERMAGIC = 0x2 @@ -2970,6 +2978,7 @@ const ( RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 SCHED_DEADLINE = 0x6 + SCHED_EXT = 0x7 SCHED_FIFO = 0x1 SCHED_FLAG_ALL = 0x7f SCHED_FLAG_DL_OVERRUN = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 0c00cb3f3af..c0d45e32050 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -109,6 +109,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -297,6 +298,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -335,6 +338,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index dfb364554dd..c731d24f025 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -109,6 +109,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -298,6 +299,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -336,6 +339,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index d46dcf78abc..680018a4a7c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -303,6 +304,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -341,6 +344,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 3af3248a7f2..a63909f308d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -112,6 +112,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -205,6 +206,7 @@ const ( PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + POE_MAGIC = 0x504f4530 PPPIOCATTACH = 0x4004743d PPPIOCATTCHAN = 0x40047438 PPPIOCBRIDGECHAN = 0x40047435 @@ -294,6 +296,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -332,6 +336,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 292bcf0283d..9b0a2573fe3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -109,6 +109,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -290,6 +291,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -328,6 +331,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 782b7110fa1..958e6e0645a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -296,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -334,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 84973fd9271..50c7f25bd16 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -296,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -334,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 6d9cbc3b274..ced21d66d95 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -296,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -334,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 5f9fedbce02..226c0441902 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -296,6 +297,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -334,6 +337,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index bb0026ee0c4..3122737cd46 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -351,6 +352,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -389,6 +392,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 46120db5c9a..eb5d3467edf 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -355,6 +356,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -393,6 +396,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 5c951634fbe..e921ebc60b7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -355,6 +356,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -393,6 +396,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 11a84d5af20..38ba81c55c1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -287,6 +288,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -325,6 +328,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index f78c4617cac..71f0400977b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -108,6 +108,7 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -359,6 +360,8 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a @@ -397,6 +400,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index aeb777c3442..c44a313322c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -112,6 +112,7 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -350,6 +351,8 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x58 + SCM_DEVMEM_LINEAR = 0x57 SCM_TIMESTAMPING = 0x23 SCM_TIMESTAMPING_OPT_STATS = 0x38 SCM_TIMESTAMPING_PKTINFO = 0x3c @@ -436,6 +439,9 @@ const ( SO_CNX_ADVICE = 0x37 SO_COOKIE = 0x3b SO_DETACH_REUSEPORT_BPF = 0x47 + SO_DEVMEM_DMABUF = 0x58 + SO_DEVMEM_DONTNEED = 0x59 + SO_DEVMEM_LINEAR = 0x57 SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index d003c3d4378..17c53bd9b33 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -462,11 +462,14 @@ type FdSet struct { const ( SizeofIfMsghdr = 0x70 + SizeofIfMsghdr2 = 0xa0 SizeofIfData = 0x60 + SizeofIfData64 = 0x80 SizeofIfaMsghdr = 0x14 SizeofIfmaMsghdr = 0x10 SizeofIfmaMsghdr2 = 0x14 SizeofRtMsghdr = 0x5c + SizeofRtMsghdr2 = 0x5c SizeofRtMetrics = 0x38 ) @@ -480,6 +483,20 @@ type IfMsghdr struct { Data IfData } +type IfMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Snd_len int32 + Snd_maxlen int32 + Snd_drops int32 + Timer int32 + Data IfData64 +} + type IfData struct { Type uint8 Typelen uint8 @@ -512,6 +529,34 @@ type IfData struct { Reserved2 uint32 } +type IfData64 struct { + Type uint8 + Typelen uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Recvquota uint8 + Xmitquota uint8 + Unused1 uint8 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Recvtiming uint32 + Xmittiming uint32 + Lastchange Timeval32 +} + type IfaMsghdr struct { Msglen uint16 Version uint8 @@ -557,6 +602,21 @@ type RtMsghdr struct { Rmx RtMetrics } +type RtMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Refcnt int32 + Parentflags int32 + Reserved int32 + Use int32 + Inits uint32 + Rmx RtMetrics +} + type RtMetrics struct { Locks uint32 Mtu uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 0d45a941aae..2392226a743 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -462,11 +462,14 @@ type FdSet struct { const ( SizeofIfMsghdr = 0x70 + SizeofIfMsghdr2 = 0xa0 SizeofIfData = 0x60 + SizeofIfData64 = 0x80 SizeofIfaMsghdr = 0x14 SizeofIfmaMsghdr = 0x10 SizeofIfmaMsghdr2 = 0x14 SizeofRtMsghdr = 0x5c + SizeofRtMsghdr2 = 0x5c SizeofRtMetrics = 0x38 ) @@ -480,6 +483,20 @@ type IfMsghdr struct { Data IfData } +type IfMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Snd_len int32 + Snd_maxlen int32 + Snd_drops int32 + Timer int32 + Data IfData64 +} + type IfData struct { Type uint8 Typelen uint8 @@ -512,6 +529,34 @@ type IfData struct { Reserved2 uint32 } +type IfData64 struct { + Type uint8 + Typelen uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Recvquota uint8 + Xmitquota uint8 + Unused1 uint8 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Recvtiming uint32 + Xmittiming uint32 + Lastchange Timeval32 +} + type IfaMsghdr struct { Msglen uint16 Version uint8 @@ -557,6 +602,21 @@ type RtMsghdr struct { Rmx RtMetrics } +type RtMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Refcnt int32 + Parentflags int32 + Reserved int32 + Use int32 + Inits uint32 + Rmx RtMetrics +} + type RtMetrics struct { Locks uint32 Mtu uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 8daaf3faf4c..5537148dcbb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -2594,8 +2594,8 @@ const ( SOF_TIMESTAMPING_BIND_PHC = 0x8000 SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x10000 - SOF_TIMESTAMPING_MASK = 0x1ffff + SOF_TIMESTAMPING_LAST = 0x20000 + SOF_TIMESTAMPING_MASK = 0x3ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -3541,7 +3541,7 @@ type Nhmsg struct { type NexthopGrp struct { Id uint32 Weight uint8 - Resvd1 uint8 + High uint8 Resvd2 uint16 } @@ -3802,7 +3802,7 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2c + ETHTOOL_MSG_USER_MAX = 0x2d ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3842,7 +3842,7 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2c + ETHTOOL_MSG_KERNEL_MAX = 0x2e ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3850,7 +3850,7 @@ const ( ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_NAME = 0x2 ETHTOOL_A_HEADER_FLAGS = 0x3 - ETHTOOL_A_HEADER_MAX = 0x3 + ETHTOOL_A_HEADER_MAX = 0x4 ETHTOOL_A_BITSET_BIT_UNSPEC = 0x0 ETHTOOL_A_BITSET_BIT_INDEX = 0x1 ETHTOOL_A_BITSET_BIT_NAME = 0x2 @@ -4031,11 +4031,11 @@ const ( ETHTOOL_A_CABLE_RESULT_UNSPEC = 0x0 ETHTOOL_A_CABLE_RESULT_PAIR = 0x1 ETHTOOL_A_CABLE_RESULT_CODE = 0x2 - ETHTOOL_A_CABLE_RESULT_MAX = 0x2 + ETHTOOL_A_CABLE_RESULT_MAX = 0x3 ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC = 0x0 ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR = 0x1 ETHTOOL_A_CABLE_FAULT_LENGTH_CM = 0x2 - ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x2 + ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x3 ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED = 0x1 ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED = 0x2 @@ -4200,7 +4200,8 @@ type ( } PtpSysOffsetExtended struct { Samples uint32 - Rsv [3]uint32 + Clockid int32 + Rsv [2]uint32 Ts [25][3]PtpClockTime } PtpSysOffsetPrecise struct { @@ -4399,6 +4400,7 @@ const ( type LandlockRulesetAttr struct { Access_fs uint64 Access_net uint64 + Scoped uint64 } type LandlockPathBeneathAttr struct { diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 4510bfc3f5c..4a325438685 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -168,6 +168,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW //sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) //sys DisconnectNamedPipe(pipe Handle) (err error) +//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) +//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) //sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) //sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW //sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 51311e205ff..9d138de5fed 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -176,6 +176,7 @@ const ( WAIT_FAILED = 0xFFFFFFFF // Access rights for process. + PROCESS_ALL_ACCESS = 0xFFFF PROCESS_CREATE_PROCESS = 0x0080 PROCESS_CREATE_THREAD = 0x0002 PROCESS_DUP_HANDLE = 0x0040 diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 6f5252880ce..01c0716c2c4 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -280,8 +280,10 @@ var ( procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount") procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW") + procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId") procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") + procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -1612,7 +1614,7 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si } func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { - r0, _, _ := syscall.SyscallN(procCancelMibChangeNotify2.Addr(), uintptr(notificationHandle)) + r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1652,7 +1654,7 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) { } func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { - r0, _, _ := syscall.SyscallN(procGetIfEntry2Ex.Addr(), uintptr(level), uintptr(unsafe.Pointer(row))) + r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1660,7 +1662,7 @@ func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { } func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { - r0, _, _ := syscall.SyscallN(procGetUnicastIpAddressEntry.Addr(), uintptr(unsafe.Pointer(row))) + r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1672,7 +1674,7 @@ func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsa if initialNotification { _p0 = 1 } - r0, _, _ := syscall.SyscallN(procNotifyIpInterfaceChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -1684,7 +1686,7 @@ func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext if initialNotification { _p0 = 1 } - r0, _, _ := syscall.SyscallN(procNotifyUnicastIpAddressChange.Addr(), uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle))) + r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) if r0 != 0 { errcode = syscall.Errno(r0) } @@ -2446,6 +2448,14 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er return } +func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) if r1 == 0 { @@ -2462,6 +2472,14 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3 return } +func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { var _p0 uint32 if wait { diff --git a/vendor/modules.txt b/vendor/modules.txt index ba86a7a524d..7d5bb258992 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem github.com/jesseduffield/go-git/v5/utils/merkletrie/index github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame github.com/jesseduffield/go-git/v5/utils/merkletrie/noder -# github.com/jesseduffield/gocui v0.3.1-0.20241201093724-68c437bbd543 +# github.com/jesseduffield/gocui v0.3.1-0.20241223111608-9967d0e928a0 ## explicit; go 1.12 github.com/jesseduffield/gocui # github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 @@ -313,19 +313,19 @@ golang.org/x/exp/slices golang.org/x/net/context golang.org/x/net/internal/socks golang.org/x/net/proxy -# golang.org/x/sync v0.9.0 +# golang.org/x/sync v0.10.0 ## explicit; go 1.18 golang.org/x/sync/errgroup -# golang.org/x/sys v0.27.0 +# golang.org/x/sys v0.28.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows -# golang.org/x/term v0.26.0 +# golang.org/x/term v0.27.0 ## explicit; go 1.18 golang.org/x/term -# golang.org/x/text v0.20.0 +# golang.org/x/text v0.21.0 ## explicit; go 1.18 golang.org/x/text/encoding golang.org/x/text/encoding/internal/identifier