今天解鎖一個開源的REPL工具——Linenoise。Linenoise是能夠徹底代替readline的,很是輕量級的命令行處理工具。Redis,MongoDB和Android都將Linenoise做爲命令行解析工具,那麼今天咱們就來解鎖這個開源的命令行處理工具,也許某一天在你的項目裏會派上用場。
Linenoise很是易於使用,閱讀該庫附帶的示例將使您儘快熟悉。如下是API調用及其使用方式。
char *linenoise(const char *prompt);
該接口現實命令提示符如hello> ,並返回用戶輸入緩衝區,當內存不足活文件結尾是返回NULL。
使用該接口循環接受用戶輸入命令並現實提示符git
while((line = linenoise("hello> ")) != NULL) { printf("You wrote: %s\n", line); linenoiseFree(line); /* Or just free(line) if you use libc malloc. */ }
默認狀況下linenoise使用單行編輯,若是須要輸入大量內容能夠開啓多行編輯模式。github
linenoiseSetMultiLine(1);
Linenoise支持歷史記錄,所以用戶沒必要一次又一次地鍵入相同的內容,而是可使用向下和向上箭頭來搜索和從新編輯已經插入的命令。——我的以爲這個功能很是有用。api
// 將一條你執行的命令添加到歷史,從而你能夠經過上下鍵找到它 int linenoiseHistoryAdd(const char *line); // 要使用歷史記錄,您必須設置歷史記錄的長度(默認狀況下爲零,所以,若是未設置正確的長度,則將禁用歷史記錄) int linenoiseHistorySetMaxLen(int len); // Linenoise直接支持將歷史記錄保存到歷史記錄文件中,經過下面兩個接口能夠存取歷史文件內容 int linenoiseHistorySave(const char *filename); int linenoiseHistoryLoad(const char *filename);
下面是一段範例代碼函數
while((line = linenoise("hello> ")) != NULL) { /* Do something with the string. */ if (line[0] != '\0' && line[0] != '/') { printf("echo: '%s'\n", line); linenoiseHistoryAdd(line); /* Add to the history. */ linenoiseHistorySave("history.txt"); /* Save the history on disk. */ } else if (!strncmp(line,"/historylen",11)) { /* The "/historylen" command will change the history len. */ int len = atoi(line+11); linenoiseHistorySetMaxLen(len); } else if (line[0] == '/') { printf("Unreconized command: %s\n", line); } free(line); }
Linenoise支持自動補全功能,即用戶按下<TAB>
鍵時會自動補全你的命令。
爲了實現這一功能,你能夠註冊並實現你的補全函數。工具
// 註冊自動補全函數completion linenoiseSetCompletionCallback(completion);
註冊的補全必須是一個void
返回值函數,須要傳入一個const char
指針(該指針是用戶到目前爲止已鍵入的命令字符)和一個linenoiseCompletions
對象指針,該對象指針用做是linenoiseAddCompletion
將回調添加到補全中的參數。一個例子將使其更加清楚:編碼
void completion(const char *buf, linenoiseCompletions *lc) { if (buf[0] == 'h') { linenoiseAddCompletion(lc,"hello"); linenoiseAddCompletion(lc,"hello there"); } }
用戶輸入'h'是會現實補全列表"hello","hello there"。url
Linenoise具備稱爲提示
的功能,當你使用Linenoise實現REPL時,這個功能很是有用。
當用戶鍵入時,該功能會在光標的右側顯示可能有用的提示。提示可使用與用戶鍵入的顏色不一樣的顏色顯示,也能夠加粗。
例如,當用戶開始輸入"git remote add"
提示時,能夠在提示的右側顯示字符串<name> <url>
。
改接口與自動補全功能相似:spa
linenoiseSetHintsCallback(hints);
回調函數實現以下:命令行
char *hints(const char *buf, int *color, int *bold) { if (!strcasecmp(buf,"git remote add")) { *color = 35; *bold = 0; return " <name> <url>"; } return NULL; }
顏色編碼:指針
red = 31 green = 32 yellow = 33 blue = 34 magenta = 35 cyan = 36 white = 37;
有時候你可能想經過輸入某條命令來清屏,好比hello> clear
,那麼可使用下面的接口:
void linenoiseClearScreen(void);
今天主要解鎖了Linenoise的用法,Linenoise很是簡單,且很容易嵌入到你的項目裏。但願對有REPL需求的小夥伴有些幫助。後續將繼續解鎖Linenoise的進化版Linenoise-NG(Linenoise Next Generation)。盡請期待~