golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.2k stars 17.46k forks source link

x/tools/gopls: show fmt.Stringer representation of a const on mouse over #61838

Open biohazduck opened 1 year ago

biohazduck commented 1 year ago

What did you do?

Moused over Meters or any of the other consts.

package si

type Distance int64

const (
      Nanometers  = 1
      Micrometers = 1000 * Nanometers
      Millimeters = 1000 * Micrometers
      Meters      = 1000 * Millimeters
)

// String pretty formats the units to a reasonable human readable representation i.e. "100m", "500nm", 
func (v Velocity) String() string {
      return formatWithBase(v, baseNano, 'm')
}

What did you expect to see?

What I want is what is currently done today with the time.Duration type: image

I understand this implies a HUGE change to gopls, since it would mean somehow running arbitrary code. This carries some worrysome implications:

I'd understand if this cannot be done today, however I want to start the discussion since this would be a large quality of life improvement for me since I regularly work with SI unit consts to define program behaviour.

I'd also like to refer you all the TinyGo interp package which safely evaluates Go code on initialization: https://github.com/tinygo-org/tinygo/tree/release/interp.

What did you see instead?

Got very long numbers which are not immediately interpretable, much less when defining other more complex consts with the Distance type. image

findleyr commented 1 year ago

Hi, thanks for starting the conversation.

As you note, gopls doesn't run user code so this would be a huge leap, and one we're unlikely to take. We'd probably need some sort of sandboxed interpreter as you suggest. That's a ton of engineering and risk, for arguably marginal improvement.

In the meantime, could we improve the statically generated hover text? For example by using scientific notation (1e9) or thousands separators (1_000_000_000)?

soypat commented 1 year ago

could we improve the statically generated hover text

Yes! Both options seem better than what is present today. One may be better than the other depending on the amount of trailing zeros though.

Implementation idea: Prefer scientific when significant figures is 3 or less:

1e3   // ok
13e3  // ok
132e3 // ok
1323e3 // not ok, should be 1_323_000

Edit: Another idea: leave a hint for gopls to format numeric const whose type has units:

// Distance is a fixed point representation based on nanometers (1e-9m).
//
//gopls:units=si base=-9 rune=m
type Distance int64
adonovan commented 7 months ago

We could interpret String methods that consist of a single call to fmt.Sprintf, but I doubt it would cover enough cases to make it worthwhile.