Issue #13050 has been updated by George Brocklehurst.


It looks like my original implementation is correct: Readline doesn't support multibyte quote characters.

The source code I'm looking at is here: http://git.savannah.gnu.org/cgit/readline.git/tree/complete.c

The `_rl_find_completion_word` function (line 1083) returns the quote character that is eventually assigned to `rl_completion_quote_character`.

`_rl_find_completion_word` does scan through the string character by character instead of byte by byte (`MB_NEXTCHAR` on line 1105), which is why I thought multibyte should be supported when I looked at the source code yesterday. However, in spite of going character by character through the input, the actual quote character handling is all byte-oriented. First, it uses `strchr` to detect if the first byte of the current character is in `rl_completer_quote_characters` (line 1134), which could lead to all kinds of strange results if used with multibyte characters. Second, it only takes a single byte as the return value (assigned on line 1137, and returned on line 1212).

I have a look at the libedit source code too, but only far enough to confirm that it doesn't support `rl_completion_quote_character`.

It's possible we should raise if any multibyte characters are passed to `Readline::completer_quote_characters=`, but I think that's out-of-scope for this patch.

----------------------------------------
Feature #13050: Readline: expose rl_completion_quote_character variable
https://bugs.ruby-lang.org/issues/13050#change-62116

* Author: George Brocklehurst
* Status: Feedback
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
This patch makes the GNU Readline variable `rl_completion_quote_character` available to Ruby users via a method called `Readline.completion_quote_character`.

`rl_completion_quote_character` returns the character used to quote the argument currently being tab completed, which lets users implement more complex quoting an escaping schemes. For example when using Ruby to build an interpreter for a shell-like language, if the current argument isn't being quoted, the user might want to escape spaces contained in the argument, but if the argument is being quoted, the user might want to leave spaces unescaped.

Here's an example:

~~~ ruby
require "readline"

COMPLETION_OPTIONS = [
  "with several spaces",
]

Readline.completer_quote_characters = "\"'"
Readline.completion_proc = proc do |input|
  matching_options = COMPLETION_OPTIONS.select { |o| o.start_with?(input) }
  if Readline.completion_quote_character.nil?
    matching_options.map { |o| o.gsub(" ", "\\ ") }
  else
    matching_options
  end
end

Readline.readline("> ", false)
~~~

This allows the user to input things like:

~~~
wit\t   # => with\ several\ spaces
"wit\t  # => "with several spaces"
~~~

The patch includes tests and documentation.

(Like #12659, this patch is an upstream contribution from the gitsh project: https://github.com/thoughtbot/gitsh)

---Files--------------------------------
readline_completion_quote_character.patch (4.43 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>