GNU Readline Library and programming introduction

Source: Internet
Author: User

The bash command line must know that Bash has several features:

    • TABKeys can be used to command completion
    • or keys can be used to quickly enter history commands
    • There are also interactive line edit shortcut keys:
      • C-A/ C-E Move cursor to beginning/end of line
      • C-B/ C-F Move the cursor one position to the left/right
      • C-DDelete a character under the cursor
      • C-KDelete the cursor and all characters at the end of the line
      • C-URemove all characters from the cursor to the beginning of the line
      • ...

The same operation in many interactive programs have similar operations, such as FTP, GDB and so on, then you have to think of how these are implemented? If we want to do a command-line interactive open source software, do you want to have these command completion, search history commands, line editing shortcuts, and so on these humanized interactive way?

To achieve this, you have two ways: you can write your own program implementation, or call the Open Source Library Readline Lib. For example, the bash, FTP, GDB, and other software described above use the GNU Open source cross-platform library to provide interactive text editing capabilities. Of course, it is important to note that the Readline library is the GNU Free Software, which is released under the GNU GPL V3 Agreement, so if you need to use the library in your program, you must comply with the relevant agreement.

This article first briefly introduces the basic use of the library, followed by a little detail on how to use Readline to customize the command completion function.

Readline Basic Operation

Many command-line interactive programs interact in the same way, output a prompt, wait for the user to enter a command, enter the command after the user enters, and the program starts parsing the command and executes. So here's an action that reads into the user's input, which we might have used before, and gets() when we use the Readline library, we can readline() replace it with the function, which is defined in ANSI C as follows:

char *readline (char *prompt);

The function has a parameter prompt, which means the command prompt, such as "ftp>" in FTP, the user can enter a command later, when the ENTER key is pressed, the program reads into the line (excluding the last newline character) into the character buffer, readlineThe return value is a pointer to the line's text. Note: when the line text does not need to be used, you need to release the space that the pointer points to to prevent a memory leak. When read-in, it is EOF returned if no other characters have been read, otherwise the read-in end is the same as the (char *) NULL read-wrapped effect.

In addition to being able to read input from the user, we sometimes want the interaction to be simpler, such as command completion. When there are many commands, if you want users to accurately remember the spelling of the command is difficult, then the general practice is to press the TAB key for command prompt and completion, such as FTP under the input of a character c after pressing the TAB key, will list all c the beginning of the command:

ftp> ccase cd cdup chmod   close   cr

readlinefunction has actually given the user the TAB ability to complete the completion of the default: According to the current path under the name of the completion.

If you don't want to Readline based on file name completion, you can rl_bind_key() change TAB the behavior of the key by using a function. The prototype of this function is:

int rl_bind_key(int key, int (*function)());

The function has two parameters:key is the ASCII character representation of the key you want to bind , and function is the address of the calling function when the key key is pressed. If you want to press the TAB key to enter a tab itself, you can TAB bind to the rl_insert() function, which is the function provided by the Readline library. If key is not a valid ASCII code value (between 0~255), the return is not rl_bind_key() 0.

In this way, the TAB default behavior is prohibited, so you can do the following:

rl_bind_key(‘\t‘, rl_insert);

This code needs to be called at the beginning of your program; You can write a function called initialize_readline() to perform this action and some other necessary initialization, such as installing a user-defined completion.

Instead of listing all the files in the current path when we want to enter it, we TAB list some of the commands built into the program, such as the example above that is referred to as FTP, and this behavior is called custom completion . The operation is more complex and we stay in the following section for the main introduction.

The basic operation also has a-- search history . We want to enter the command line, but also can C-p be C-s searched, then we need to add the command line to the history list, you can call the add_history() function to complete. But try to add empty rows to the history list as well, because empty rows occupy the space of the history list and are useless. In summary, we can write a Readline version of the gets() function rl_gets() :

/* A static variable for holding the line. */StaticChar*Line_read=(Char*)Null;/* Read A string, and return a pointer to it. Returns NULL on EOF. */Char*Rl_gets(){/* If The buffer has already been allocated, return the memoryTo the free pool. */If(Line_read){Free(Line_read);line_read =  (char * ) null} /* Get a line from the user. */line_read = readline  ( "/* If the line have any text in it, save it on the The history. */if  (line_read && *line_read) add_history  (line_readreturn  (line_read}     
Custom completion

The above also mentions what is custom completion, which is undoubtedly very important in the command line interactive program and directly affects the user experience. Readline Library provides two kinds of more commonly used complementary methods-according to the file name completion and according to the user name completion, respectively corresponding to the Readline has implemented two functions rl_filename_completion_function and rl_username_completion_function . If we do not want to follow the file name and user name to complete, want to follow the program's command to complete, what should be done? It is also easy to think of, as long as the implementation of their own complement function is good.

The working principle of Readline complement is as follows:

    • A user interface function rl_complete() call rl_completion_matches() to produce a list of possible complements;
    • The intrinsic function rl_completion_matches() uses the generator function provided by the program to produce a complete list and return these matched arrays, before which the address of the generator function needs to be placed rl_completion_entry_function in the variable. For example, the above mentioned by the file name or user name complement function is different generators;
    • The generator function rl_completion_matches() is constantly called in, returning a string at a time. The generator function has two parameters:text is the part of a word that needs to be complete, the state is 0 on the first call of the function, and the next call is not 0. The generator function (char *)NULL returns rl_completion_matches() a notification that there is no possible match left.

There is a variable in the Readline library, and the rl_attempted_completion_function variable type is a function pointer rl_completion_func_t * , which we can set to our custom generated matching function, which is TAB called when the key is pressed, the function has three parameters:

    • text: This parameter is part of the word to be completed, such as entering a character at the bash prompt, c pressing TAB , and text pointing to a pointer to the "C" string; Entering a string after the bash prompt cd /home/gu , press TAB , at which point the text points to a pointer to the "/HOME/GU" string;
    • start: The start position of the text string in the line input, for example, the first case is 0, the second case is 3;
    • End: The text string ends in the line input, for example, the first case is 1, and the second case is 11.

Our custom complement function sets the parameters we want to complete according to the arguments passed in, for example, for commands under Bash, cd we want to start with the command completion, and when the command is complete, followed by the file name completion, which can be used rl_completion_matches() to bind the use of which Generator, rl_completion_matches() the prototype of the function is:

char ** rl_completion_matches (const char *text, rl_compentry_func_t *entry_func)

With two parameters:text is the incoming word for completion as described above, and the second parameter, Entry_func , is a pointer to the generator function described above. The return value of the function is a pointer to a string array of generator that might match the text , and the last item of the array is a NULL pointer.

Well, it says so much about the functions and variables of the custom complement, how to use it, the estimate is still relatively vague, then look at an example is very clear, this example is Readline official sample program, due to the longer, it is not posted here, you can in http:// Cnswww.cns.cwru.edu/php/chet/readline/readline.html#sec49 found.

Summarize

In fact, although said a lot, but also just Readline the fur of the library, the function of this library is far more powerful than this, if you want to understand and use, you have to do three things:

    • Read the fucking Manual: Reading the official documentation
    • Read the fucking sourcecode: Read the official provided example code, if you want to know more in-depth can go to see the source of Readline
    • Show Your Code: Try to write a few examples yourself, if you have the opportunity to apply to your project.

GNU Readline Library and programming introduction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.