Sbt parsers and dynamic improvements

I am trying to build a git command parser in sbt.

The purpose of the parser is not so much to check the actual git command, but to provide automatic completion in the sbt console.

The parser relies on bash completion scripts, so it's fair to say that generating completions is quite expensive as the process has to appear periodically. So I would like to minimize the number of calls made in the bash -completion process.

I have a working solution that looks like this:

def autoCompleteParser(state: State) = {
  val extracted = Project.extract(state)
  import extracted._

  val dir = extracted.get(baseDirectory)

  def suggestions(args: Seq[String]): Seq[String] = {
    // .. calling Process and collecting the completions into a Seq[String]
  }

  val gitArgsParser: Parser[Seq[String]] = {

    def loop(previous: Seq[String]): Parser[Seq[String]] =
      token(Space) ~> NotSpace.examples(suggestions(previous): _*).flatMap(res => loop(previous :+ res))

    loop(Vector())

  }

  gitArgsParser
}

val test = Command("git-auto-complete")(autoCompleteParser _)(autoCompleteAction)

      

However, I have two problems:

  • the completion process is called for every character that is larger than I would like
  • potential completions appear to be passed as a parameter to another round of completions, which means more calls to the external process.

My question is this: how can I tell sbt to reuse / cache the rework it received for the rest of the argument, without calling the process for each character? For example:

completion for git a ':

dd m nnotate pply rchive

Then the completion for git ad ':

d

without having to call the suggestions method again. I tried to implement ExampleSource, but I couldn't get the behavior I was looking for.

Any pointer is appreciated. And if anyone understands why potential rework seems to be pushed into another round of rework, that helped me a lot.

Thank.

+3


source to share





All Articles