yuzhongdelei0 2019-12-20
Crossline是一个很小的跨平台命令行工具库,类似Linux上的readline。
项目地址:https://github.com/JunchuanWang80/Crossline
因为开发一个项目需要支持跨平台命令行,在Linux上readline是首选,bash/gdb/ftp都使用了这个库,但是Windows上没法直接用。后来搜到了一个开源项目linenoise,这个命令行工具库是Redis的作者开发的,Redis,Andriod和MongoDB都使用了。这个工具库很小,只有1100行左右代码(readline超过3万行代码,并且还依赖ncurses库),但是它只能在Linux上运行,支持的快捷键也很少,功能也少。后来搜到了linenoise-ng,这个项目是ArangoDB开源的,最初是从MongoDB版本的linenoise移植出来的。这个开源项目非常强大,支持Windows/Linux,支持很多快捷键和功能,并且支持Unicode。起初打算用这个库,后来发现这个库依然挺大的,代码大约有4,300行并且挺复杂的,还混合使用了C++和C,还有不少动态内存操作(linenoise也有)。我觉得一个跨平台命令行工具库可以实现的更简单,于是做了原型验证,然后使用了不同的方式实现了这个全新的很小但是功能很多的夸平台命令行工具库。
79个快捷键
和37个功能
。F1
帮助功能,可以在编辑模式和命令行搜索模式下使用,可以随时使用不影响当前已输入命令行。Ctrl-^
键盘调试功能,可以看到按下的键产生的字符序列。Ctrl-C
退出编辑,Linux下支持Ctrl-Z
挂起并恢复编辑,这2个快捷键在编辑模式和命令行搜索模式下都适用。其他命令
快捷键 | 功能 |
---|---|
F1 | 显示快捷键帮助 |
Ctrl-^ | 进入键盘调试模式 |
移动命令
快捷键 | 功能 |
---|---|
Ctrl-B,Left | 左移一个字符 |
Ctrl-F,Right | 右移一个字符 |
Alt-B,ESC+Left,Ctrl-Left,Alt-Left | 左移一个单词(Ctrl-Left,Alt-Left只支持Windows/Xterm) |
Alt-F,ESC+Right,Ctrl-Right,Alt-Right | 右移一个单词(Ctrl-Right,Alt-Right只支持Windows/Xterm) |
Ctrl-A,Home | 移到行首 |
Ctrl-E,End | 移到行尾 |
Ctrl-L | 清屏并显示当前行 |
编辑命令
快捷键 | 功能 |
---|---|
Ctrl-H,Backspace | 删除光标前字符 |
Ctrl-D,DEL | 删除光标处字符 |
Alt-U, ESC+Up,Ctrl-Up,Alt-Up | 将当前单词改成全大写(Ctrl-Up,Alt-Up只支持Windows/Xterm) |
Alt-L,ESC+Down,Ctrl-Down,Alt-Down | 将当前单词改成全小写(Ctrl-Down,Alt-Down只支持Windows/Xterm) |
Alt-C | 将当前单词改成首字母大写 |
Alt-\ | 删除光标左右侧空格 |
Ctrl-T | 交换光标处2个字符 |
剪切粘贴
快捷键 | 功能 |
---|---|
Ctrl-K,ESC+End,Ctrl-End,Alt-End | 从光标处剪切到行尾(Ctrl-End,Alt-End只支持Windows/Xterm) |
Ctrl-U,ESC+Home,Ctrl-Home,Alt-Home | 从光标处剪切到行首(Ctrl-Home,Alt-Home只支持Windows/Xterm) |
Ctrl-X | 剪切整行 |
Alt-Backspace,Esc+Backspace,Clt-Backspace | 剪切光标前面的单词(Clt-Backspace only supports Windows/Xterm) |
Alt-D,ESC+Del,Alt-Del,Ctrl-Del | 剪切光标后面的单词(Alt-Del,Ctrl-Del只支持Windows/Xterm) |
Ctrl-W | 从光标处向左剪切到空格止 |
Ctrl-Y,Ctrl-V,Insert | 粘贴剪切文本 |
自动补齐命令
快捷键 | 功能 |
---|---|
TAB,Ctrl-I | 自动补齐 |
Alt-=,Alt-? | 列出补齐项 |
历史命令
快捷键 | 功能 |
---|---|
Ctrl-P,Up | 取上一个历史命令行 |
Ctrl-N,Down | 取下一个历史命令行 |
Alt-<, PgUp | 取第一个历史命令行 |
Alt->, PgDn | 取最后一个历史命令行(当前输入) |
Ctrl-R,Ctrl-S | 进入命令行搜索模式 |
F4 | 用当前输入进入命令行搜索模式 |
F1 | 在命令行搜索模式下显示搜索匹配语法 |
F2 | 显示历史命令行 |
F3 | 清空历史命令行(需要确认) |
控制命令
快捷键 | 功能 |
---|---|
Enter, Ctrl-J,Ctrl-M | 返回当前命令行 |
Ctrl-C,Ctrl-G | 丢弃当前命令行并返回 |
Ctrl-D | 如果当前命令行为空则返回 |
Alt-R | 清空当前命令行 |
Ctrl-Z | 挂起命令行(Linux适用,fg可以继续编辑) |
原始的readline支持增量搜索(Ctrl-R
,Ctrl-S
)和非增量搜索(Alt-N
,Alt-P
)。这2种方式都不方便,效率也不高,所以实现了全新的交互式命令行搜索功能。
匹配语法
使用空格分开多个匹配项,每个匹配项都不区分大小写(小技巧:可以使用Insert
插入上次搜索关键字继续编辑)
select
: 选择包含select
的命令行-select
: 选择不包含select
的命令行"select from"
: 选择包含select from
的命令行-"select from"
: 选择不包含select from
的命令行"select from" where -"order by" -limit
: 选择包含select from
以及where
,但不包含order by
或者limit
的命令行例子
SQL> <F2> // show history 1 hello world 2 select from user 3 from select table 4 SELECT from student 5 Select from teacher SQL> <Ctrl+R> Input Patterns <F1> help: select from 1 select from user 2 from select table 3 SELECT from student 4 Select from teacher Input history id: 3 SQL> SELECT from student<Alt+R> // Revert line SQL> <F4> Input Patterns <F1> help: <Insert> // paste last history pattern: select from Input Patterns <F1> help: "select from" 1 select from user 2 SELECT from student 3 Select from teacher Input history id: 3 SQL> Select from teacher<Alt+R> SQL> SELECT from<F4> // search with pattern: Select from Input Patterns <F1> help: SELECT from Input Patterns <F1> help: "SELECT from" -user -teacher 1 SELECT from student Input history id: 1 SQL> SELECT from student
// Main API to read a line,return buf if get line,return NULL if EOF。 char* crossline_readline (char *buf,int size,const char *prompt); // Set move/cut word delimiter,default is all not digital and alphabetic characters void crossline_delimiter_set (const char *delim); // History APIs int crossline_history_save (const char *filename); int crossline_history_load (const char *filename); void crossline_history_show (void); void crossline_history_clear (void); /* Completion APIs */ // Register completion callback void crossline_completion_register (crossline_completion_callback pCbFunc); // Add completion in callback。 Word is must,help for word is optional。 void crossline_completion_add (crossline_completions_t *pCompletions,const char *word,const char *help); // Set syntax hints in callback void crossline_hints_set (crossline_completions_t *pCompletions,const char *hints);
代码在example.c
static void completion_hook (char const *buf,crossline_completions_t *pCompletion) { int i; static const char *cmd[] = {"insert","select","update","delete","create","drop","show","describe","help","exit","history",NULL}; for (i = 0; NULL != cmd[i]; ++i) { if (0 == strncmp(buf,cmd[i],strlen(buf))) { crossline_completion_add (pCompletion,cmd[i],NULL); } } } int main () { char buf[256]; crossline_completion_register (completion_hook); crossline_history_load ("history.txt"); while (NULL != crossline_readline (buf,sizeof(buf),"Crossline> ")) { printf ("Read line: \"%s\"\n",buf); } crossline_history_save ("history.txt"); return 0; }
代码在example_sql.c,这个例子实现了一个简单的SQL语法分析器,可以解析如下语法,代码较多这里就不放了。
insert into <table> set column1=value1,column2=value2,... select <* | column1,columnm2,...> from <table> [where] [order by] [limit] [offset] update <table> set column1=value1,column2=value2 [where] [order by] [limit] [offset] delete from <table> [where] [order by] [limit] [offset] create [unique] index <name> on <table> (column1,column2,...) drop {table | index} <name> show {tables | databases} describe <table> help {insert | select | update | delete | create | drop | show | describe | help | exit | history}
可以用这个例子来测试上面的快捷键
SQL> <TAB> // show autocomplete words and help insert Insert a record to table select Select records from table update Update records in table delete Delete records from table create Create index on table drop Drop index or table show Show tables or databases describe Show table schema help Show help for topic exit Exit shell history Show history *** Press <Space> or <Enter> to continue . . . SQL> help <TAB> // show autocomplete words list insert select update delete create drop show describe help exit history SQL> create index <TAB> // show autocomplete hints Please input: index name
Windows MSVC
cl -D_CRT_SECURE_NO_WARNINGS -W4 User32.Lib crossline.c example.c /Feexample.exe cl -D_CRT_SECURE_NO_WARNINGS -W4 User32.Lib crossline.c example_sql.c /Feexample_sql.exe
Windows Clang
clang -D_CRT_SECURE_NO_WARNINGS -Wall -lUser32 crossline.c example.c -o example.exe clang -D_CRT_SECURE_NO_WARNINGS -Wall -lUser32 crossline.c example_sql.c -o example_sql.exe
Linux Clang
clang -Wall crossline.c example.c -o example clang -Wall crossline.c example_sql.c -o example_sql
GCC(Linux, MinGW, Cygwin, MSYS2)
gcc -Wall crossline.c example.c -o example gcc -Wall crossline.c example_sql.c -o example_sql
这里只列出了部分内容,详细信息请参考项目的README.md
项目地址:https://github.com/JunchuanWang80/Crossline