Repository: jesseduffield/lazygit (language: go)

Issue:
Line wrap for diff/staging mode (or hunk navigation in files mode)
Hi,
I would find it very useful with a line wrapping key binding/toggle/config param to get the full line content overview in that mode.

Motivation:
For me the motivation is that I have files where I am storing text files with very long line content where I store paragraph long text in a single line on many places. Making a modification to such paragraph/line will not too rarely put my changes out of initial view when reviewing and commenting my changes for the commit text. Even so in fullscreen mode for the "Staged changes" pane.
I know I have the options to scroll sideways in diff/staging mode or use the files view instead. The reasons I find them insufficient is that scrolling long lines is tedious, and in the files view there is no binding for jumping to next/previous hunk.
If there was a binding for next/previous hunk I would think that it would also suffice as a solution for me. I also tried changing the git->paging->pager to ydiff, but could see that it does not affect the diff/staging mode, only the files mode.
If this is enough motivation for you to implement it though is of course up to you, but would be greatly appreciated! :) 


Discussion / hints:
This would be an amazing feature to have! This is particularly challenging when working with .tex files or markdown. I work on shared projects with several collaborators where the convention is for each line in the file to be a sentence for ease of diffing. Right now I revert to using an editor with soft-wrapping enabled to manually stage hunks or view diffs because often the changes are beyond the scrolloff of the diff view in lazygit. Entering the diff view and scrolling is annoying since I need to keep scrolling back and forth for different lines. 
:+1: on this feature or at least another scroll bar
:+1: 
We already have this in commit messages, would be very nice

Fix patch:
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/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


Test patch:
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())
+		})
+	}
+}