Project

General

Profile

Actions

Feature #13050

closed

Readline: expose rl_completion_quote_character variable

Added by georgebrock (George Brocklehurst) about 8 years ago. Updated over 6 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:78721]

Description

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:

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) readline_completion_quote_character.patch georgebrock (George Brocklehurst), 12/18/2016 10:48 PM

Updated by nobu (Nobuyoshi Nakada) about 8 years ago

  • Status changed from Open to Feedback

That variable seems an int.
Is it just a single byte, or a code point?

Updated by georgebrock (George Brocklehurst) about 8 years ago

Nobuyoshi Nakada wrote:

That variable seems an int.
Is it just a single byte, or a code point?

I had assumed that it was a single byte, but after reading the Readline source code more carefully it looks like it can also be code point. I'll submit an updated patch that supports multi-byte quote characters.

Updated by nobu (Nobuyoshi Nakada) about 8 years ago

Then you can use rb_enc_uint_chr(), probably.

Updated by georgebrock (George Brocklehurst) about 8 years ago

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.

Updated by georgebrock (George Brocklehurst) almost 8 years ago

I should have mentioned in my previous comment: I also tested Readline with multi-byte quote characters, and got back only the value of the first byte from rl_completion_quote_character.

Anything else I can do to move this forward?

Updated by georgebrock (George Brocklehurst) over 7 years ago

Are there any problems with applying this patch? I'm happy to make changes if something is blocking it.

Unicode support isn't going to be possible without upstream changes in Readline.

Updated by georgebrock (George Brocklehurst) about 7 years ago

This has been open for a year. Is there anything I can do towards getting the patch accepted?

Updated by georgebrock (George Brocklehurst) over 6 years ago

I'd still love to get this merged. Is there anything I can do to help get the patch accepted?

Updated by shevegen (Robert A. Heiler) over 6 years ago

It is now registered for the next upcoming developer meeting at:

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

(I think nobu added it to the developer meeting recently; it was most likely
forgotten for some time).

Hopefully future patches may be simpler for you - I think the most likely
explanation is that it was forgotten. The developer meeting format changed
a few months ago, so you can add issues directly on the ruby developer
tracker. (And if it is not answered yet, it may end up being at "carry
over" from prior meetings.)

To the topic at hand - I use readline a lot so every readline-related support
helps. Whenever I need commandline input in ruby programs, I usually turn
to readline first; and as generic fallback, use $stdin.gets.chomp in a loop
normally. It's good to see other people are also using readline, it is one
of those programs I really need all the time when it comes to user input.

Actions #10

Updated by nobu (Nobuyoshi Nakada) over 6 years ago

  • Status changed from Feedback to Closed

Applied in changeset trunk|r64618.


Readline: expose rl_completion_quote_character variable

[Feature #13050]

From: georgebrock (George Brocklehurst)

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0