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

REPL tab completion #1114

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

REPL tab completion #1114

wants to merge 1 commit into from

Conversation

cspotcode
Copy link
Collaborator

Took a quick stab at completions in the REPL.

Issues:

first time you get tab completions, the input line freezes while the language service spins up. We'd probably want to force it to spin up before the first prompt is shown

TS tab completions sometimes replace already-entered text. For example, they may propose rewriting .f into ?.foo Node's built-in completion doesn't support this. Is it worth using a third-party library? Does one exist with the features we need?

@cspotcode cspotcode changed the title WIP REPL tab completion REPL tab completion Aug 13, 2020
@blakeembrey
Copy link
Member

This sounds really great! Is the main blocker right now the second issue? I assume the first one is workaround-able or we can put this behind a flag until we resolve it.

@cspotcode
Copy link
Collaborator Author

Yeah, second issue is the blocker. I don't remember off the top of my head, but I don't think there's any way for us to register an event listener when tab-completion "uses" a completion item. If there was, we could maybe rewrite the input to replace . with ?.

@cspotcode
Copy link
Collaborator Author

cspotcode commented May 16, 2021

I did some more research here. Rewriting the line of input can be done like this:

replService.stdin.on('keypress', keypress => {
    if(keypress === '\t') {
      const completion = '?.bar';
      const completeOn = '.';
      const moveCursorToEnd = repl.cursor > repl.line.length - completeOn.length;
      repl.line = repl.line.slice(0, -completeOn.length) + completion;
      if(moveCursorToEnd) {
        repl.cursor = repl.line.length;
      }
      repl._refreshLine();
    }
  });

Implementation must:

  • only do this for a TTY
  • take care to update repl.cursor only if it is in or right of the affected part of the line
  • Trigger on a known tab keypress, NOT trigger in completer() which is called by node even when the user does not want completions
  • If async completions, wait for completions to finish before applying. Will require coordination between completer() and keypress event
  • Never allow built-in completer to complete a common prefix. If one exists, return no completions and instead apply the common prefix ourselves.

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

Successfully merging this pull request may close these issues.

2 participants