Adding basic quoting to your use of GNU Readline
Suppose that you have a program (or) that makes basic use of GNU Readline
(essentially just calling readine()
) and you want to add the feature
of quoting filename expansions when it's needed. Sadly the GNU Readline
documentation is a little bit scanty on what you need to do, so here is
what has worked for me.
(The rest of this assumes that you've read the Readline programming documentation.)
As documented in the manual (eventually) you first need a function
that will actually do the quoting, which you will activate by pointing
rl_filename_quoting_function
at. Although the documentation neglects
to mention it, this function must return a malloc()
'd string; Readline
will free()
it for you. As far as I can tell from running my code
under valgrind, you don't need to free()
the TEXT
argument you are
handed.
You must also set rl_filename_quote_characters
and
rl_completer_quote_characters
to appropriate values. To be fully
correct you probably also want to define a dequoter function, but
I've gotten away without it so far. In simple cases Readline will
simply ignore your quote character at the front when doing further
filename completion; I think you only need a dequoter function to
handle the case were you've had to escape something in the filename.
With a sane library this would be good enough. But contrary to what the documentation alleges, this doesn't seem to be sufficient for Readline. Instead you need to hook into Readline completion in order to tell Readline that yes really, it should quote things. You do this by the following:
char **my_rl_yesquote(const char *init, int start, int end) { rl_filename_quoting_desired = 1; return NULL; } /* initialize by setting: rl_attempted_completion_function = my_rl_yesquote; */
Your 'attempted completion function' exists purely for this, although you can of course do more if you want. Note that the need for this function and its actions is in direct contradiction to the Readline documentation as far as I can tell. On the other hand, following the documentation doesn't work (yes, I tried it). Possibly there is some magic involved in just how you invoke Readline and some unintentional side effects going on.
(On the other hand I got this from a Stackoverflow answer, so other people are having the same problem.)
Note that a really good job of quoting and dequoting filenames needs a certain number of other functions, per the Readline documentation. I can't be bothered to worry about them (or write them) so far.
I was going to put my actual code in here as an example but it turns out it is too embarrassingly ugly and hacky for me to do it in its current state and I'm not willing to include cleaner code that I haven't actually run and tested. Check back later for acceptable code that I know doesn't explode.
(Normally I clean up my hacky 'it finally works' first pass code, but I was rather irritated by the time I got something that worked so I just stopped and put the whole thing out of my mind.)
Update: my example quoting function is now in ReadlineQuotingExample.
|
|