Skip to content

haskell-process-get-repl-completions result contains unnecessary item #776

Closed
@geraldus

Description

@geraldus

The result of GHCi REPL :complete repl command always outputs results summary in first line, it is consists of number of showed completions, number of all possible completions and of unused part of string for which completions were searched. E.g.

Prelude> :complete repl 2 "map co"
2 6 "map "
"compare"
"concat"

In the example above 2 is a number of returned completions, 6 is a number of all completions ("co" could be completed with 6 unique completions) and "map " is unused part of string (which was ignored, completions were searched only for "co" part). In case when completion requested for single word, for example :complete repl "ma", an empty string is returned as unused part always.

Currently, haskell-process-get-repl-completions1 returns mentioned unused part of input string as first element in resulting list:

(defun haskell-process-get-repl-completions (process inputstr)
  "Perform `:complete repl ...' query for INPUTSTR using PROCESS."
  (let* ((reqstr (concat ":complete repl "
                         (haskell-string-literal-encode inputstr)))
         (rawstr (haskell-process-queue-sync-request process reqstr)))
    (if (string-prefix-p "unknown command " rawstr)
        (error "GHCi lacks `:complete' support (try installing 7.8 or ghci-ng)")
      (let* ((s1 (split-string rawstr "\r?\n" t))
             (cs (mapcar #'haskell-string-literal-decode (cdr s1)))
             (h0 (car s1))) ;; "<cnt1> <cnt2> <quoted-str>"
        (unless (string-match "\\`\\([0-9]+\\) \\([0-9]+\\) \\(\".*\"\\)\\'" h0)
          (error "Invalid `:complete' response"))
        (let ((cnt1 (match-string 1 h0))
              (h1 (haskell-string-literal-decode (match-string 3 h0))))
          (unless (= (string-to-number cnt1) (length cs))
            (error "Lengths inconsistent in `:complete' reponse"))
          (cons h1 cs))))))

It stores this unused part in h1 variable. First, REPL response is being split by newlines into a list and stored in s1. Then it decodes all completions from s1's tail using haskell-string-literal-decode function (e.g. converts "smth" to lisp string object smth) and stores this in cs variable. The first line of response (init of s1) is stored in h0 variable and the last part of it (that is, unused part of input string) is stored in h1 variable using regular expression and string-match function. Finally, if all checks are passed it returns a cons cell of h1 and cs, as you can see in source code. So the first item of resulting list is that unused part of input.

Firstly, I think this is at least inconvenient with the function name, i.e. unused part of input is not a completion itself, while user may expect that all items in resulting list should be a valid completions for given input. Secondly, if there is no completions available the result should be empty list, while currently it always consists of one element at least. Thirdly, I don't know any use case of this information.

So, I want to fix this by not including unused part of input in results list. Any thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions