Colorized readline prompt breaks control-a

巧了我就是萌 提交于 2020-06-27 16:09:11

问题


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:

  1. 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 symbol EL_PROMPT_ESC is defined in histedit.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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!