nonsequitur / inf-ruby

218 stars 69 forks source link

fix completions #162

Closed hikmet517 closed 2 years ago

hikmet517 commented 2 years ago

using prefix parameters causes lots of "no match"es and wrong completions. Example:

123.t TAB brings: 'aint' 'rust' 'o_int' 'ainted?' 'runcate' selecting first prints: 123.aint

This fixes both no-matches and wrong completions

dgutov commented 2 years ago

Hi!

selecting first prints: 123.aint

I'm unable to reproduce this problem. Selecting the first completion results in 123.taint.

Are you using some custom completion UI? Or an unusual Ruby console? Or etc?

hikmet517 commented 2 years ago

I normally use corfu, but I tested without it, result was the same. I use run-ruby command to start shell. Other minor modes enabled are: Compilation-Shell, Display-Line-Numbers, Font-Lock, Tab-Line, Visual-Line. The value of completion-at-point-functions is (inf-ruby-completion-at-point comint-completion-at-point t)

dgutov commented 2 years ago

Are you using Irb? Pry? What's the version of that shell?

hikmet517 commented 2 years ago

irb --version gives: irb 1.4.1 (2021-12-25). It's default system package in Archlinux.

dgutov commented 2 years ago

I see. That version comes with Ruby 3.1. I'll try it later.

Have you tried completion with Pry? If a project is set up to use Pry, inf-ruby-console-auto should pick it up, but you can also evaluate (run-ruby "pry") to launch it explicitly.

hikmet517 commented 2 years ago

The function inf-ruby-completions works great if I write 123.t and eval (inf-ruby-completions "t"). The problem is when I call completion using C-M-i, inf-ruby-completions is called with empty string.

dgutov commented 2 years ago

Here's the callstack when I use the default completion UI:

  (let* ((proc (inf-ruby-proc)) (line (buffer-substring (save-excursion (move-beginning-of-line 1) (point)) (point))) (expr (inf-ruby-completion-expr-at-point)) (prefix-offset (- (length expr) (length prefix))) (comint-filt (process-filter proc)) (kept "") completions inf-ruby-at-top-level-prompt-p) (if (equal "(rdb:1) " inf-ruby-last-prompt) nil (set-process-filter proc #'(lambda (proc string) (setq kept (concat kept string)))) (unwind-protect (let ((completion-snippet (format (concat "proc { |expr, line|" "  require 'ostruct';" "  old_wp = defined?(Bond) && Bond.started? && Bond..." "  begin" "    Bond.agent.instance_variable_set('@weapon'," "      OpenStruct.new(:line_buffer => line)) if old..." "    if defined?(_pry_.complete) then" "      puts _pry_.complete(expr)" "    elsif defined?(pry_instance.complete) then" "      puts pry_instance.complete(expr)" "    else" "      completer = if defined?(_pry_) then" "        Pry.config.completer.build_completion_proc..." "      elsif old_wp then" "        Bond.agent" "      elsif defined?(IRB::InputCompletor::Completi..." "        IRB::InputCompletor::CompletionProc" "      end and puts completer.call(expr).compact" "    end" "  ensure" "    Bond.agent.instance_variable_set('@weapon', ol..." "  end " "}.call('%s', '%s')\n") (ruby-escape-single-quoted expr) (ruby-escape-single-quoted line)))) (process-send-string proc completion-snippet) (while (and (not (string-match inf-ruby-prompt-pattern kept)) (accept-process-output proc 2))) (setq completions (butlast (split-string kept "\15?\n") 2)) (if (and completions (string= (concat ... "\n") completion-snippet)) (progn (setq completions (cdr completions))))) (set-process-filter proc comint-filt))) (mapcar #'(lambda (str) (substring str prefix-offset)) completions))
  inf-ruby-completions(#("t" 0 1 (fontified t)))
  try-completion(#("t" 0 1 (fontified t)) #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil)
  completion-basic-try-completion(#("t" 0 1 (fontified t)) #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil 1)
  completion--some(#f(compiled-function (style) #<bytecode 0x178cc3c3e6e56c41>) (basic partial-completion emacs22))
  completion--nth-completion(1 #("t" 0 1 (fontified t)) #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil 1 (metadata))
  completion-try-completion(#("t" 0 1 (fontified t)) #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil 1 (metadata))
  completion--do-completion(#<marker at 150 in *ruby*> 151)
  completion--in-region-1(#<marker at 150 in *ruby*> 151)
  apply(#f(compiled-function (start end collection predicate) #<bytecode 0x1231d665da849ec6>) (#<marker at 150 in *ruby*> 151 #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil))
  completion--in-region(#<marker at 150 in *ruby*> 151 #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil)
  completion-in-region(#<marker at 150 in *ruby*> 151 #f(compiled-function (string pred action) #<bytecode -0x1280f574e6774acc>) nil)
  completion-at-point()
  complete-symbol(nil)
  funcall-interactively(complete-symbol nil)
  apply(#<subr call-interactively> complete-symbol (nil nil))
  call-interactively@ido-cr+-record-current-command(#<subr call-interactively> complete-symbol nil nil)
  apply(call-interactively@ido-cr+-record-current-command #<subr call-interactively> (complete-symbol nil nil))
  call-interactively(complete-symbol nil nil)
  command-execute(complete-symbol)
hikmet517 commented 2 years ago

I found the problem, it was orderless package, it uses its own completion-style. When I disable it everything works perfectly. Sorry to bother.

dgutov commented 2 years ago

Thank you for the clarification.

I've pushed a slightly different patch which I hope will support orderless better. I've only tested it with partial-completion, but the effect should be the same.

hikmet517 commented 2 years ago

Thanks, works great. It works with orderless too. When I enter 123.ain it suggests 123.taint 123.untaint. Thanks again.