naively complete built-in functions and constants #18

Closed
wants to merge 1 commit into
from

Conversation

Projects
None yet
3 participants

crishoj commented Mar 28, 2013

Here's a very crude first stab at completing the current statement. Currently only handles built-in functions and constants.

In order to complete user-defined functions and variables I'm guessing some protocol for communicating with the EvalWorker would be needed.

Contributor

d11wtq commented Apr 4, 2013

@crishoj thanks for this. I'm still thinking about how to make this more useful, as I'd prefer if tab completion is going to be added to the main repo, that it actually complete the appropriate terms, instead of being naive, which tends to be more of a hinderance than a help. See #3 for another discussion on this.

I think making a clearly defined protocol for the IPC between the readline client and the eval worker and going to afford the most flexibility, since it can provide insight into what's in scope. I guess the first step there is to make the protocol more extensible/flexible, without changing the behaviour of Boris, then build autocompletion on top of that.

crishoj commented Apr 4, 2013

Oh, I had totally missed the discussion on #3. I completely agree with your approach.

@crishoj crishoj closed this Apr 4, 2013

@crishoj crishoj deleted the crishoj:completion branch Apr 4, 2013

Contributor

d11wtq commented Apr 21, 2013

Just thinking about this, defining a protocol won't be super hard really. If we limit to 255 possible commands (which should be about 253 times more than we need :P) then it can simply be a leading byte included every time input is sent through to the REPL, followed by optional arguments.

Currently the ReadlineClient sends nothing but strings of PHP over the socket to the REPL. Now it will have to send a leading byte that means "eval some code". Let's call that "\x01".

write($socket, "\x01" . $user_input);

Now when a user hits TAB to auto-complete, we send the "autocomplete" instruction, (say, "\x02" . $current_buffer) and wait for a serialized list of completions to come back over the other side of the socket.

The only problem here is likely the fact libreadline and libedit only provide quite a limited amount of the input. If the last thing typed was $foo->, I have a feeling readline will only provide the > for you to auto-complete on. That may be possible to workaround by capturing every single keypress and tracking the buffer contents manually, however.

Just thinking out loud ;)

joddie commented Aug 10, 2013

I also started trying to implement simple function & variable completion before reading this discussion, and ran into the problem described, where the completion callback only receives the last token of input on the line. There is an interesting discussion of this in a comment on http://uk1.php.net/manual/en/function.readline-completion-function.php, which mentions a workaround using readline_info() to get the whole contents of the line currently being entered. Unfortunately, it seems like the workaround only works when PHP is compiled with GNU readline, not with libedit. (The PHP readline extension can apparently work with either library; you can find out which one is in use by looking at the value of 'library_version' in the array returned from readline_info(): it will either be a version string for readline or the string "EditLine wrapper" for libedit.)

Anyway, count this as one more vote of interest in smart tab-completion and an offer to help implement it that's wanted ;-)

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