Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: provide code completion #21

Closed
morangorin opened this issue May 23, 2018 · 7 comments
Closed

Feature request: provide code completion #21

morangorin opened this issue May 23, 2018 · 7 comments
Assignees

Comments

@morangorin
Copy link

Ideally, there would be a function available on fast.Interp like:
Complete(prefix string) []string
which would return the list of possible completions. It seems that such list could be returned to liner using line.SetCompleter to improve the REPL provided in gomacro.

@cosmos72
Copy link
Owner

cosmos72 commented May 24, 2018

I agree it would be very useful :)

The same feature has bee requested and discussed in gophernotes, a Jupyter kernel for Go that uses gomacro - see gopherdata/gophernotes#22
A quick-and-dirty solution is implementing completion against global names - quite easy to implement, but also quite limited.
A thorough completion is much harder: it needs the whole code surrounding the (in)complete word, in order to also find local variables and - this is the real difficulty - their types.

In alternative, I thought about using https://github.com/nsf/gocode and, while somewhat easier, it's not completely trivial (requires writing interpreted code to files) and introduces a significant dependency.

Suggestions are welcome :)

@morangorin
Copy link
Author

What about running the gomacro interpreter and using the reflect package? For instance, if we have:
r := rand.New(rand.NewSource(99))
with the following List function defined:

func List(v interface{}) []string {
	t := reflect.TypeOf(v)
	r := []string{}
	if t.Kind() == reflect.Struct {
		for i := 0; i < t.NumField(); i++ {
			r = append(r, t.Field(i).Name)
		}
	}
	for i := 0; i < t.NumMethod(); i++ {
		r = append(r, t.Method(i).Name)
	}
	return r
}

then evaluating List(r) with the interpreter will return the list of candidates [ExpFloat64 Float32 ... Seed Shuffle Uint32 Uint64] without additional data structures.

I guess there is the special case of package for which this method would not work. But then perhaps global names would be more appropriate for that case and for global variables in general.

@cosmos72
Copy link
Owner

cosmos72 commented May 24, 2018

Yes, looking up fields and methods of an existing variable is relatively straightforward (it's only slightly more complicated than your example code because methods of interpreted types are emulated). And looking up symbols of imported packages is straightforward too.

Maybe that's already enough to be useful...

the missing part would be completion of local variables' fields and methods, as for example:

type S struct { T }
type T int
func (t T) String() string {
  return "T"
}
func foo(s S) {
  println(s.#

Where the input source is not yet complete (parenthesis and braces are not balanced) and the user hit TAB at the # - how can gomacro determine the type of local variable s in order to show its fields and methods?

The only solution I am aware of is to parse the code in a new context (to avoid completion side effects as defining new types, functions, methods...) with an error-resistant parser and type checker - but gomacro currently has neither of them

@morangorin
Copy link
Author

Python code completion in ipython or jupyter only provides what you describe as 'straightforward' and it is already super useful. Can the work done for gophernotes/issues/22 be reused for the terminal prompt?

@cosmos72
Copy link
Owner

You're talking about @jpark-dev comment gopherdata/gophernotes#22 (comment) and his patch, right?
I did not examine it yet - if I have time, I will have a look in the next days

@cosmos72
Copy link
Owner

Done :)
See commit 4159592

Feedback is welcome :)

@cosmos72 cosmos72 self-assigned this May 26, 2018
@morangorin
Copy link
Author

It is brilliant. I am already wondering how I was doing before! Thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants