[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

(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