[Update: extract.variable and extract-variable.all are done. So is inline-variable. Retitled to narrower scope of inline-all. --adonovan]
Original title: codeaction: replace every use-case of a variable with its defined expression, extract every identical expression within function to a new variable
gopls version
Build info
golang.org/x/tools/gopls (devel) golang.org/x/tools/gopls@(devel) github.com/BurntSushi/toml@v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/google/go-cmp@v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= golang.org/x/exp/typeparams@v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y= golang.org/x/mod@v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/sync@v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/telemetry@v0.0.0-20240927184629-19675431963b h1:PfPrmVDHfPgLVpiYnf2R1uL8SCXBjkqT51+f/fQHR6Q= golang.org/x/text@v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/tools@v0.21.1-0.20240508182429-e35e4ccd0d2d => ../ golang.org/x/vuln@v1.0.4 h1:SP0mPeg2PmGCu03V+61EcQiOjmpri2XijexKdzv8Z1I= honnef.co/go/tools@v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs= mvdan.cc/gofumpt@v0.7.0 h1:bg91ttqXmi9y2xawvkuMXyvAA/1ZGJqYAEGjXuP0JXU= mvdan.cc/xurls/v2@v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8= go: go1.23.2
go env
GO111MODULE='auto'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/xzb/Library/Caches/go-build'
GOENV='/Users/xzb/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/xzb/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/xzb/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.2'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/xzb/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD=''
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/gv/r110hgbx1gbgzp95kf_q71x40000gn/T/go-build1846322804=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
https://github.com/user-attachments/assets/11cb0a62-807d-41e8-8b40-260f13fa57e5
the first half part is :Rafactor inline_var
, and second part is :Rafactor extract_var new_var
, it is from a nvim plugin refactoring.nvim using treesitter under the hood, I use this two quite frequently to eliminate unnecessary variable as well as introduce new variable for some repeated expression, the problem is it fails (or not accurate) in complex situations, so I wish gopls would support this directly.
What did you see happen?
Currently gopls supports extract a single expression to a new variable, I'd say extract every repeated expression under selection would be more useful, since the latter contains the former.
What did you expect to see?
see above
Editor and settings
No response
Logs
No response
Comment From: gabyhelp
Related Issues and Documentation
- x/tools/gopls: Add refactor "move to a new file" #65707 (closed)
- x/tools/gopls: Feature Request: Support for "Inline Method" refactoring code action #59243 (closed)
- x/tools/gopls: feature: offer quickfix for variable name that is incorrectly initialized #69980
- x/tools/gopls: extract variable returns an extra lhs expression and no template edit support is available #65944
- x/tools/gopls: implement code action to split and group args/elements/return values into single/separate lines #65156 (closed)
- x/tools/gopls: disable code actions from gopls #68783 (closed)
- x/tools/gopls: feature: code action to generate a stub function from a "no function f" type error #69692 (closed)
- x/tools/gopls: Extract variable from type switch produces invalid code #67905 (closed)
- x/tools/gopls: Extract Function refactor doesn't put testing.T/B first #69341 (closed)
- x/tools/gopls: Provide automatic conversion of structure A to structure B #65451
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: gopherbot
Change https://go.dev/cl/623637 mentions this issue: gopls/internal/golang: use correct imports in HTML pkg doc links
Comment From: xzbdmw
Hmm, how could I know two expression is identical regardless their tok.Pos value? Am I supposed to write a util function similar to types.Identical()?
Comment From: gopherbot
Change https://go.dev/cl/624035 mentions this issue: gopls/internal/codeaction: replace all occurrences of expression (refactor.extract.variable.all)
Comment From: xzbdmw
@adonovan Hey Alan, may you take a look? The logic is relatively simple :)
Comment From: adonovan
Sorry for the delay and thanks for the contribution, but I am overwhelmed with reviews at the moment and am also out of office at a Go conference. I will attend to this next week.
Comment From: xzbdmw
Thanks! No rush—enjoy the conference!
Comment From: adonovan
https://go.dev/cl/624035 added "extract n occurrences of expr to a variable"; "inline all" has not one but two dedicated issues (#68567 and #66370). Therefore this issue is complete.
Comment From: xzbdmw
66370 only mentions inline functions, this issue is about inlining expressions, are they essentially the same?
Comment From: adonovan
Ah, good point. Let's reopen this issue and narrow its scope to inlining var/const expressions.
Comment From: gopherbot
Change https://go.dev/cl/673636 mentions this issue: gopls/internal/golang: implement "inline local variable" code action