问题
The following program prints a colorized readline prompt. It breaks control-a (the cursor ends up much farther to the right than it should be):
#include <readline/readline.h>
#include <readline/history.h>
#define CYELLOW "\001\e[0;31m\002"
#define RESET "\001\e[0m\002"
int main(int argc, char **argv)
{
readline(CYELLOW "prompt> " RESET);
return 0;
}
control-a works when I call readline() without a colorized prompt:
readline("prompt> ");
I'm using Mac OS X 10.9.4. Here's the output of otool:
/usr/lib/libreadline.dylib:
/usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)
/usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1
There are a couple of stackoverflow questions that seem to touch on this:
Colorized output breaks linewrapping with readline
Look how to fix column calculation in Python readline if use color prompt
Both of them mention that color markers need to be bracketed by \001 and \002. I followed those instructions but control-a is still broken.
回答1:
Mac OS X uses the NetBSD editline
library, which includes a partial compatibility implementation of readline
.
It appears that an attempt was made to add readline's feature of allowing the user to bracket terminal control sequences in the prompt using the characters RL_PROMPT_START_IGNORE
and RL_PROMPT_END_IGNORE
(defined as '\1'
and '\2'
respectively in readline.h
). Unfortunately, due to a small typo, the feature is never enabled in rl_initialize
.
As I read the code (I haven't tested this), the fix would be to change line 327 of readline.c
[see note 1] from:
el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
to:
el_set(e, EL_PROMPT_ESC, _get_prompt, RL_PROMPT_START_IGNORE);
That would require you to find the source code for libedit
, make that trivial change, reconfigure and recompile it, and then install it. I don't have a Mac so I can't guide you through that process. (See Note 1 for links to source repositories which might be useful.)
Another solution would be to use the GNU readline library in your project. It's apparently available in MacPorts, so if you use that, it should be easy enough to install.
Notes:
- I got that line number from this OS X source repository. In the head revision of the NetBSD distribution, it's at line 337. But it should be easy enough to find by searching for
EL_PROMPT
. Just make sure that the symbolEL_PROMPT_ESC
is defined inhistedit.h
; if it isn't, the version of the editline library you've found is probably too old.
来源:https://stackoverflow.com/questions/31329952/colorized-readline-prompt-breaks-control-a