Readline
1 Synopsis
readline 是一个由 GNU 项目开发的库,用于提供交互式命令行编辑功能。它允许用户在命令行中编辑输入内容,支持历史记录、命令补全等功能,被广泛应用于各种交互式程序中,如 bash、Python 解释器等
2 Description
| C | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 | |
-
readline会从终端读取一行输入并返回,同时以prompt作为提示符 -
若
prompt为NULL或空字符串,则不显示提示符 -
返回的行是通过
malloc()动态分配的,调用者需在使用完毕后手动释放内存 -
返回的字符串会移除末尾的换行符,仅保留行的文本内容
-
add_history将用户输入添加到历史命令列表中,使其可通过上/下箭头访问 rl_attempted_completion_function是readline中用于自动补全的回调函数指针,需要把它指向自定义的补全函数,当用户在readline()输入时按下 Tab 键,就会调用这个函数来提供补全,返回一个char **的字符串数组,所有候选项,最后一项为NULLtext: 用户当前要补全的单词,比如输入he|时,text = "he"(|表示光标)start: 当前补全单词在整行输入中的起始位置-
end: 当前补全单词在整行输入中的结束位置 -
rl_completion_matches用于生成补全结果数组,通过调用entry_func()多次,直到返回 NULL,返回一个char **字符串数组,用于 readline 的补全候选 text: 当前补全文本entry_func: 每次调用返回一个候选项的函数command_generator是自定义补全函数,也就是entry_func指向的函数,被rl_completion_matches()调用多次text: 用户当前要补全的单词,比如输入he|时,text = "he"(|表示光标)state: 从 0 开始递增,表示第几次调用,state是由readline库内部自动管理并传给补全生成器函数的
注意
使用上述库函数需要链接 -lreadline 库,gcc readline.c -o readline -I. -lreadline
3 Example
readline 的基础用法以及简单的命令补全
| C | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | |
执行流程图:
flowchart TD
A[用户在命令行输入] --> B[按下 Tab 键]
B --> C[readline 捕获 Tab 事件]
C --> D[调用 rl_attempted_completion_function]
D --> E[command_completion 函数]
subgraph 命令补全处理
E --> F{检查 start 是否为 0?}
F -->|是| G[调用 rl_completion_matches]
F -->|否| T[不处理参数补全]
G --> H[command_generator 函数]
H --> I[generic_generator 函数]
subgraph 生成器处理
I --> J{state 是否为 0?}
J -->|是| K[初始化 list_index 和 len]
J -->|否| L[继续遍历]
K --> M[遍历 commands 数组]
L --> M
M --> N{是否找到匹配?}
N -->|是| O[返回匹配项的副本]
N -->|否| P[返回 NULL]
end
O --> Q[添加到匹配列表]
P --> R[完成匹配]
Q --> S[返回匹配列表]
end
S --> U[显示补全结果]
U --> V[用户继续输入或执行命令]