`
totoxian
  • 浏览: 1074265 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

快捷键和控制序列--自己实现vi

 
阅读更多

从《快捷键和控制序列--bash的命令行编辑原理以及其它杂述》中已经明白了按键和控制序列的原理,现在可以猜一下vi的原理了,大体上vi可能会包含类似下面的结构,也就是一些键映射,其中有一个命令映射和一个插入映射:
KEYMAP map_cmd = {
{'w',func_cmd_w},
{'b',func_cmd_b},
...
}
KEYMAP map_inst = {
{'w',func_inst_w},
{'b',func_inst_b},
...
}
...
可是看了vi的源代码之后发现并不是这回事,normal函数够看一阵了了,edit函数也够喝一壶的,不过这两个函数的逻辑都很简单的。好了,既然vi不是上面猜测的那样,可是我还是不甘心,上面的那个猜测多好啊,多么OO啊,不用岂不可惜,于是就着这个猜测自己实现一个vi,虽然简陋但是可以说明问题:
#include <termios.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
typedef int Function ();
typedef struct key {
char c; //输入的字符
Function *function; //对应该字符的处理函数
}KEY;
char bufline[1024] = {0}; //简化起见,只编辑一行,不处理换行回车符
int pos = 0; //光标的当前位置
int a_ifunc(); //这里定义一大堆函数,用来处理字符输入
...
KEY key_i[] = {
{'a', a_ifunc},
{'b', b_ifunc},
{'c', c_ifunc},
{'d', d_ifunc},
};
KEY key_c[] = {
{'a', a_cfunc},
{'b', b_cfunc},
{'c', c_cfunc},
{'d', d_cfunc},
};
KEY *cur = key_i;
int set_position(row, line) //设置光标的位置,vt100兼容终端下可用
{
char cmd[32] = {0};
sprintf(cmd, "/033[%d;%dH", row, line);
printf(cmd);
}
int a_ifunc() //插入模式下的字符a处理函数
{
bufline[pos] = 'a';
pos ++;
set_position(1,0);
printf("%s", bufline); //注意不要最后写/n换行符,否则光标就“回车并换行”了,光标的列总是0,而行总是需要的下一行
set_position(1,pos);
return 1;
}
int b_ifunc() //插入模式下的字符b处理函数
{
bufline[pos] = 'b';
pos ++;
set_position(1,0);
printf("%s", bufline);
set_position(1,pos);
return 1;
}
int c_ifunc() //插入模式下的字符c处理函数
{
bufline[pos] = 'c';
pos ++;
set_position(1,0);
printf("%s", bufline);
set_position(1,pos);
return 1;
}
int d_ifunc() //插入模式下的字符d处理函数,切换模式
{
cur = key_c;
return 1;
}
int a_cfunc() //命令模式下的字符a处理函数,前移光标
{
char cmd[64] = {0};
pos ++;
set_position(1,pos);
return 1;
}
int b_cfunc() //命令模式下的字符b处理函数,后退光标
{
char cmd[64] = {0};
pos --;
if (pos <= 0)
pos = 0;
set_position(1,pos);
return 1;
}
int c_cfunc() //命令模式下的字符c处理函数,自定义
{
...
return 1;
}
int d_cfunc() //命令模式下的字符d处理函数,切换模式
{
cur = key_i;
return 1;
}
int main(int argc, char **argv)
{
char c; //定义键盘输入的字符
struct termios s, t; //终端设置,主要是为了取消回显
FILE *in = fopen ("/dev/tty", "w+"); //这个代码是从coreutils中的getpass函数中复制下来的(读源码的好处)
if (tcgetattr (fileno (in), &t) == 0) {
t.c_lflag &= ~(ECHO|ISIG);
int tty_changed = (tcsetattr (fileno (in), TCSAFLUSH, &t) == 0);
}
printf("/033[2J/n" ); //学习vi,清屏,配置一个好的试验场
set_position(1,0); //光标设置到最上面的一行开始
memset(bufline, 32, 1024); //将缓冲区设置成空格,方便使用printf打印,否则全部初始化为0的话就要逐字符打印了
while (1) { //何时退出呢?输入一个除了a,b,c,d之外的就段错误了...
c = fgetc(stdin); //简化设计,因此该简陋的vi每输入一个字符后需要敲入一个回车
if (c != 10) { //忽略换行
cur[c-'a'].function(); //处理
}
}
}
编译它:
gcc minivi.c -o minivi
然后执行minivi,输入一下,切换一下,再输入一下...输入一个a,b,c,d之外的字符就以段错误退出,并且minivi只能处理4个字符只有两个模式,这问题决定了minivi是一个很值得扩展的程序,大框架在此,懒得扩展了,骨架好身材就好,不在乎肉多肉少

分享到:
评论

相关推荐

    VI和VIM编辑器快捷键图文教程.zip

    VI(Visual Editor)和VIM(Vi Improved)是Linux和Unix系统中广泛使用的文本编辑器,因其高效的操作方式和丰富的快捷键而深受程序员和系统管理员喜爱。本教程旨在通过图文并茂的方式,帮助用户深入理解和掌握这两款...

    Linux vi-vim-.pdf

    ### Linux vi-vim 文本编辑器详解 #### vi与vim的区别及重要性 在Linux以及所有Unix-like系统中,vi(Visual Editor)是最为经典的文本编辑器之一,它几乎无处不在,是进行文本编辑的基本工具。随着技术的发展,...

    VI高级命令集锦

    - 功能: 定义新的键盘快捷键或映射序列。 10. **设置选项** - 命令: `:set [option]` - 示例: `:set nu` - 功能: 显示每行的行号。 11. **复制多行** - 命令: `n y y` - 功能: 复制从光标行开始的n行。...

    vi命令入门详解.txt

    此外,用户还可以根据个人需求定制Vi,使其更加符合自己的使用习惯,这是许多其他编辑器所不具备的功能。 值得注意的是,Vi并非一个排版程序,不能像Word或WPS那样对字体、格式、段落等进行编辑和排版。它仅仅是一...

    Learning the vi and Vim Editors, Seventh Edition

    ### 学习vi和Vim编辑器第七版 #### 基础与高级vi **1. vi文本编辑器** - **简短的历史视角**(第5页):本章节首先介绍了vi编辑器的发展历史,从其起源到如何演变成现今的形式。 - **打开和关闭文件**(第6页):...

    vi命令简介

    - **`vi -c "&lt;commands&gt;"`**:执行指定的命令序列后启动vi编辑器。 - **`vi -X`**:禁止加载用户的个人配置文件。 #### 四、常用快捷键 - **`u`**:撤销最近的一次更改。 - **`.`**:重复最后一次更改。 - **`ZQ`**...

    unix power tools 3ed.pdf

    - **流程控制**: 如何使用条件语句和循环控制程序流程。 - **函数**: 在shell脚本中定义和使用函数。 **6.10 shell编程进阶 (Chapter 36: Shell Programming for the Initiated)** - **高级特性**: shell脚本中的...

    LabView-keyboard.rar_LabVIEW 键盘_keyboard_keyboard labview_labvie

    此外,LabVIEW的键盘程序还可以结合其他功能,如定时器、事件结构等,实现更复杂的功能,比如自动按键序列、延迟输入、按键组合识别等。这些特性使得LabVIEW成为创建定制化键盘解决方案的理想工具,尤其适合那些需要...

    模拟版图Skill基础教程.pdf

    - **布局管理**: 控制图形对象的位置和大小。 **3.3 菜单** - **创建菜单**: 设计用户界面中的菜单项。 - **响应事件**: 当用户选择菜单项时触发相应的动作。 **3.4 一键导出GDS** - **GDS文件**: 用于集成电路...

    VIM配置文件

    - **macros**:存储用户定义的宏或快捷键序列。 - **scripts**:可能包含自定义的VIM脚本或工具。 通过合理地配置`.vimrc`和`.vim`目录,VIM可以被改造成一个功能丰富的集成开发环境(IDE),提供代码补全、语法...

    68个Linux内部命令用法简介

    `bg` 命令返回成功状态,除非作业控制未启用或出现错误。 #### 3. bind - 设置Readline键绑定和变量 **功能描述:** `bind` 命令用于设置Readline的键绑定和变量。这使得用户能够自定义shell的行为,如快捷键映射...

    wince6.0系统下的labview串口程序

    在描述中提到的主程序“快捷键最终版.vi”,很可能是整个串口通信系统的控制中心,它可能包含了设置波特率、数据位、停止位、校验方式等串口参数,并负责调度其他子程序来完成具体的串口操作。 接下来,我们看下四...

    Vim键位分布图(全面)

    5. **键位分布图**: `vi-vim-cheat-sheet.gif`和`vim键盘图.png`是Vim的快捷键参考图,它们展示了各种常用操作对应的键位,帮助初学者快速记忆和查找。 6. **SVG教程**: `vi-vim-tutorial-svg`可能是Vim的SVG格式...

    rtc.rar_secureCRT_超级终端 串口

    6. 键绑定和脚本支持:支持VCP(Vi Control Panel)和ANSI转义序列,使得程序员和系统管理员可以使用熟悉的命令和快捷键。 7. 连接稳定性:SecureCRT有自动重连功能,即使网络连接暂时中断,也能自动恢复,保持会话...

    Labview应用技术 设计简单的正弦波发生器(课堂实训).docx

    10. **保存与运行**:完成设计后,可以保存VI为.LVVI文件,并通过运行按钮或快捷键执行程序,验证其功能是否满足设计要求。 通过这个实训,学生不仅可以掌握基本的LabVIEW编程技巧,还能提升问题解决能力,理解信号...

    用labview写的虚拟键盘程序

    后面板则是程序逻辑,包含了实现键盘功能的LabVIEW代码和各种子VI。 在LabVIEW中,编程是通过连接各种不同的图标(称为“函数”或“控件”)来完成的,这些图标代表了不同的操作或数据类型。例如,可能有一个用于...

    Xterm一个用于远程连接linux的图形可视化工具

    4. **丰富的控制序列**:Xterm支持一系列扩展的控制序列,使得应用程序能够更灵活地控制终端的行为,如改变窗口大小、清除屏幕等。 5. **Unicode支持**:Xterm支持UTF-8编码,可以正确显示多种语言字符,包括中文,...

Global site tag (gtag.js) - Google Analytics