Linux vim mode | raw / cooked

注:机翻,未校。


vim terminal “raw” mode

Vim 终端 “raw” 模式

1. 原始模式与已处理模式的区别

We know vim puts the terminal in “raw” mode where it receives keystrokes as they are typed, opposed to “cooked” mode where the command is not processed fully unless the end-user enters it in the terminal.
我们知道,vim 会将终端置于“原始”模式,在这种模式下,终端会即时接收按键输入,与“已处理”模式不同,在“已处理”模式下,命令只有在终端中输入后才会被完全处理。

2. 模式切换的机制

How does the shell distinguish when to go into either mode? How does this switch happen? Is there a mode in between “raw” and “cooked” mode?
那么,shell 是如何区分何时进入这两种模式的呢?这种切换是如何发生的?在“原始”模式和“已处理”模式之间是否存在一种中间模式?

To clarify, any process that has access to a terminal can change that terminal’s settings, simply by calling tcsetattr() with the appropriate attributes (the same call used by the termstate_ functions in cush).
需要明确的是,任何能够访问终端的进程都可以通过调用 tcsetattr() 并设置适当的属性来更改该终端的设置(cush 中的 termstate_ 函数也使用了相同的调用)。

vim is an example of a process that does that. Raw mode is also entered by the readline() function cush (and bash) uses. That’s why, for instance, Ctrl-A and Ctrl-E work and many other readline shortcuts. When readline() returns, the terminal is set back into whatever state it was in before the call, so we don’t notice. If we had implemented our shell with, say, scanf() and printf() only, we wouldn’t have put the terminal into the raw state, so a shell could be implemented without raw mode, albeit with less user comfort.
vim 是一个会这样做的进程的例子。cush(以及 bash)使用的 readline() 函数也会进入原始模式。这就是为什么,例如,Ctrl-A 和 Ctrl-E 以及许多其他 readline 快捷键可以正常工作。当 readline() 返回时,终端会恢复到调用之前的状态,所以我们察觉不到。如果我们只用 scanf() 和 printf() 来实现我们的 shell,我们就不会将终端置于原始状态,因此虽然可以实现一个没有原始模式的 shell,但用户体验会差很多。

3. POSIX 中的原始模式定义

As to what “raw” mode is and how to enter it. It turns out that “raw” vs “cooked” mode isn’t actually the official term (anymore). The terms come from Unix System 7. In POSIX, what’s commonly called “raw” mode is a combination of switches. tcsetattr(3) describes it as:
关于“原始”模式是什么以及如何进入它的问题。事实证明,“原始”模式与“已处理”模式并不是官方术语(至少不再是)。这些术语来源于 Unix System 7。在 POSIX 中,通常所说的“原始”模式实际上是一组组合开关。tcsetattr(3) 对其描述如下:

3.1 原始模式的设置

Raw mode
原始模式

cfmakeraw() sets the terminal to something like the “raw” mode of the old Version 7 terminal driver: input is available character by character, echoing is disabled, and all special processing of terminal input and output characters is disabled. The terminal attributes are set as follows:
cfmakeraw() 将终端设置为类似于旧版 Version 7 终端驱动程序中的“原始”模式:输入是逐字符可用的,回显被禁用,并且终端输入和输出字符的所有特殊处理都被禁用。终端属性被设置如下:

termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP| INLCR | IGNCR | ICRNL | IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

You can look up what all these attributes mean, but the key attribute here is ICANON, and that’s how POSIX refers to line-by-line vs key-by-key processing mode, as “canonical” (line-by-line) and “non-canonical” mode.
您可以查阅这些属性的具体含义,但其中的关键属性是 ICANON,POSIX 就是通过它来区分逐行处理模式与逐键处理模式的,分别称为“规范”(逐行)模式和“非规范”模式。

4. 实践原始模式

If you want to try out raw mode yourself, here’s a short program:
如果你想自己尝试原始模式,这里有一个简短的程序:

4.1 示例代码

// raw.c
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>int
main()
{int terminal_fd = open(ctermid(NULL), O_RDWR);assert (terminal_fd != -1);struct termios tty_state;int rc = tcgetattr(terminal_fd, &tty_state);struct termios saved_tty_state = tty_state;assert (rc == 0);tty_state.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP| INLCR | IGNCR | ICRNL | IXON);tty_state.c_oflag &= ~OPOST;tty_state.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);tty_state.c_cflag &= ~(CSIZE | PARENB);tty_state.c_cflag |= CS8;printf("press ctrl-d to exit\n");rc = tcsetattr(terminal_fd, TCSANOW, &tty_state);assert (rc == 0);char c; while (read(0, &c, 1) == 1 && c != 0x4)write(1, &c, 1);// restore sane state on exitrc = tcsetattr(terminal_fd, TCSANOW, &saved_tty_state);assert (rc == 0);
}

4.2 编译与运行

Compile with gcc -o raw raw.c and then you can start it with ./raw. Everything input is echoed back. Ctrl-C and Ctrl-Z don’t work anymore. If you type Enter it goes to the beginning of the line (type Ctrl-J to go to the next line). Type Ctrl-D (0x4) to exit.
使用 gcc -o raw raw.c 编译该程序,然后可以通过 ./raw 启动它。输入的所有内容都会被回显。Ctrl-C 和 Ctrl-Z 不再起作用。如果你按下回车键,光标会回到行首(按下 Ctrl-J 可以移到下一行)。按下 Ctrl-D(0x4)退出。

5. 原始模式与已处理模式的应用

The program above demonstrates how to set a terminal into raw mode and restore its original state upon exit. It reads input character by character and echoes them back to the terminal. This behavior is typical of raw mode, where the terminal processes input and output at the character level without any special handling of control characters like Ctrl-C or Ctrl-Z.
上述程序演示了如何将终端设置为原始模式,并在退出时恢复其原始状态。它逐字符读取输入并将它们回显到终端。这种行为是原始模式的典型特征,在这种模式下,终端会在字符级别处理输入和输出,而不会对像 Ctrl-C 或 Ctrl-Z 这样的控制字符进行特殊处理。

This is particularly useful for applications like text editors (e.g., vim) or interactive shells that require fine-grained control over user input and terminal output. By disabling canonical processing (ICANON) and other terminal attributes, these applications can implement their own input handling mechanisms, such as key bindings and command-line editing features.
这对于像文本编辑器(例如 vim)或交互式 shell 这样的应用程序特别有用,因为它们需要对用户输入和终端输出进行精细控制。通过禁用规范处理(ICANON)和其他终端属性,这些应用程序可以实现自己的输入处理机制,例如按键绑定和命令行编辑功能。

In contrast, “cooked” mode (or canonical mode) is the default mode for most terminal applications. In this mode, the terminal buffers input until a newline character is received, allowing for line editing and processing of special control characters. This mode is more user-friendly for command-line interfaces where users expect to be able to edit their input before executing a command.
相比之下,“已处理”模式(或规范模式)是大多数终端应用程序的默认模式。在这种模式下,终端会将输入缓冲起来,直到接收到换行符,从而允许进行行编辑和处理特殊控制字符。在这种模式下,用户可以在执行命令之前编辑输入,因此对于命令行界面来说,这种模式更加用户友好。

6. 总结

To summarize, the distinction between raw and cooked modes lies in how the terminal handles input and output. Raw mode provides direct, character-by-character access, while cooked mode processes input line by line and interprets control characters. The ability to switch between these modes allows applications to tailor their behavior to the specific needs of the user interface they are implementing.
总之,原始模式和已处理模式的区别在于终端如何处理输入和输出。原始模式提供直接的逐字符访问,而已处理模式逐行处理输入并解释控制字符。能够在这些模式之间切换,使得应用程序可以根据它们所实现的用户界面的具体需求来调整行为。


【Linux】vim 三种模式的切换、常用命令总结

冰冷的希望于 2023-08-25 23:04:37 发布

vim 是一个非常强大而且常用的 Linux 文本工具。

1. 模式

vim 主要有三种模式,分别是命令模式、输入模式、末行模式,三者切换关系如下:

在这里插入图片描述

默认是命令模式,按 iao 进入输入模式,再按 ESC 返回到命令模式。在命令模式输入 : 切换到末行模式,再按 ESC 又返回到命令模式。输入模式和末行模式之间不能直接切换,只能通过命令模式切换。

2. 命令模式

命令说明
xXx 是删除下一个字符,X 是删除上一个字符
数字 + x删除指定数量的字符,例如 10x 表示删除 10 个字符
dd剪切(删除)光标所在行
数字 + dd删除指定数量的行,例如 20dd 表示删除 20 行
yy复制光标所在行
数字 + yy复制指定数量的行,例如 20yy 表示复制 20 行
pPp 是粘贴到下一行,P 是粘贴到上一行
u撤销
Ctrl+r反撤销
.(小数点)重复上一个动作
ggGgg 是回到第一行,G 是回到最后一行
数字 + G跳转到指定行,例如 20G 表示跳转到第 20 行
y1GyGy1G 是复制当前行前面的所有数据,yG 是复制当前行之后的全部数据
d1GdGd1G 是删除当前行前面的所有数据,dG 是删除当前行之后的全部数据
vVCtrl+vv 是光标起始和结束之间的文本会被选中,V 是光标起始和结束之间的所有行被选中,Ctrl+v 是光标起始和结束之间构成的矩形区域被选中

3. 输入模式

命令说明
iIi 是从光标所在位置开始输入,I 是从光标所在行第一个非空白字符开始输入
aAa 是从光标所在的下一个字符开始输入,A 是从光标所在行的最后一个字符开始输入
oOo 是从光标所在行的下一行新的一行开始输入,O 是从光标所在行的上一行新的一行开始输入
rRr 是取代光标所在的字符一次,R 是依次取代光标所在字符

4. 末行模式

命令说明
:w保存
:q退出
:wqZZ保存并退出
:q!ZQ不保存退出
:set nu显示行号
:set nonu隐藏行号
:/搜索的文本搜索指定文本
:%s/要替换的字符/替换后的字符/g全局替换文本,% 表示对整个文件进行操作,g 表示全局替换

via:

  • CS3214 Computer Systems - Spring 2025
    https://courses.cs.vt.edu/cs3214/spring2025/questions/rawmode

  • How to avoid vim set terminal to raw mode when stdin is /dev/null? · Issue #15893 · vim/vim · GitHub
    https://github.com/vim/vim/issues/15893

  • 【Linux】vim 三种模式的切换、常用命令总结_描述一下 vim 命令的状态,不同状态之间的切换方式?-CSDN 博客
    https://blog.csdn.net/qq_39147299/article/details/108972206

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38336.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux线程】——线程概念线程接口

目录 前言 1.线程 2.线程的本质 3.Linux线程库 3.1创建线程——pthread_create 3.2线程终止——pthread_exit 3.3线程等待——pthread_join 3.4线程分离——pthread_detach 3.5获取线程tid——pthread_self 4.线程的优缺点 4.1线程的优点 4.2线程的缺点 结语 前言…

机器学习——KNN超参数

sklearn.model_selection.GridSearchCV 是 scikit-learn 中用于超参数调优的核心工具&#xff0c;通过结合交叉验证和网格搜索实现模型参数的自动化优化。以下是详细介绍&#xff1a; 一、功能概述 GridSearchCV 在指定参数网格上穷举所有可能的超参数组合&#xff0c;通过交叉…

STM32基础教程——定时器

前言 TIM定时器&#xff08;Timer&#xff09;:STM32的TIM定时器是一种功能强大的外设模块&#xff0c;通过时基单元&#xff08;包含预分频器、计数器和自动重载寄存器&#xff09;实现精准定时和计数功能。其核心原理是&#xff1a;内部时钟&#xff08;CK_INT&#xff09;或…

[特殊字符] 树莓派声卡驱动原理全解析:从模拟耳机口到HiFi DAC

一、为什么要关注树莓派的声卡驱动&#xff1f; 树莓派&#xff08;Raspberry Pi&#xff09;作为一款广泛应用的单板计算机&#xff0c;集成了多种音频输出接口&#xff08;如 3.5mm 耳机、HDMI、I2S 外接 DAC 等&#xff09;。但许多用户在使用中会遇到诸如“耳机输出杂音”…

使用若依AI生成springBoot的前后端分离版本

目录 1. 从Git上面下载前后端分离版本 2. 执行SQL脚本 3. 初始化前端 安装Node.js和npm配置 ✅ 第一步&#xff1a;在 Node 安装目录下创建两个文件夹 ✅ 第二步&#xff1a;配置 npm 全局目录和缓存目录 ✅ 第三步&#xff1a;验证配置是否成功 ✅ 第四步&#xff1a;…

神聖的綫性代數速成例題12. 齊次方程組零解充要條件、其齊次方程組非零解、 齊次方程組基礎解系

1. 綫性空間的定義&#xff1a; 設是一個非空集合&#xff0c;是一個數域。 在集合的元素之間定義了加法運算&#xff0c;即對於任意&#xff0c;有唯一的&#xff0c;使得&#xff1b;在數域與集合的元素之間定義了數乘運算&#xff0c;即對於任意和&#xff0c;有唯一的&am…

万亿级数据量的OceanBase应用从JVM到协议栈立体化改造实现性能调优

本文基于某电商平台亿级商品详情页场景&#xff0c;通过Java应用层与数据库层的协同优化&#xff0c;实现98%的查询响应时间低于50ms。 一、JDBC连接池深度调优 HikariCP配置示例&#xff1a; HikariConfig config new HikariConfig(); config.setJdbcUrl("jdbc:ocean…

腾讯:《详解DeepSeek:模型训练、优化及数据处理的技术精髓》23页|附下载方法

导 读 INTRODUCTION 这是一篇来自腾讯的关于DeepSeek大语言模型及其技术特点、应用场景和未来发展趋势的文章&#xff0c;主要介绍了DeepSeek的核心技术优势、行业应用案例以及在AI领域的竞争力和发展趋势。为理解DeepSeek大语言模型的技术优势和应用前景提供了深入的分析&…

Vue 入门到实战 五

第5章 过渡与动画 目录 5.1 单元素/组件过渡 5.1.1 过渡class 5.1.2 CSS 过渡 5.1.3 CSS 动画 5.1.4 同时使用过渡和动画 5.1.5 JavaScript 钩子方法 5.2 多元素/组件过渡 5.2.1 多元素过渡 5.2.2 多组件过渡 5.3 列表过渡 5.3.1 列表的普通过渡 5.3.2 列表的平滑…

L2TP实验

一、拓朴图 二、实验配置 1.基础配置 1.1接口IP及服务配置 [PPPoE Client]interface GigabitEthernet 0/0/0 [PPPoE Client-GigabitEthernet0/0/0]service-manage all permit [NAS]interface GigabitEthernet 0/0/0 [NAS-GigabitEthernet0/0/0]ip add 192.168.0.2 24 [NAS-Gi…

简单实用!百度AI + Raphael AI = 免费生图

简单实用&#xff01;百度AI Raphael AI 免费生图 -- ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b55eda9141d34697b05db0cd60f62b75.png#pic_center) 第一步&#xff1a;下载或截取一些好看的图片当参考图片 第二步&#xff1a;用百度AI描述你想要的图片&…

aws(学习笔记第三十四课) dockerized-app with asg-alb

文章目录 aws(学习笔记第三十四课) dockerized-app with asg-alb学习内容&#xff1a;1. 整体架构1.1 代码链接1.2 代码手动修改部分1.2.1 rds_stack.py1.2.2 efs_stack.py1.2.3 asg_stack.py1.2.4 userdata.sh 1.2 整体架构 2.代码解析2.1 全体app.py2.2 NetworkStatck网络2.3…

面试总结之 Glide自定义的三级缓存策略

一、为什么需要三级缓存&#xff1f; 在移动应用开发中&#xff0c;图片加载性能直接影响用户体验。根据 Google 统计&#xff0c;图片加载延迟超过 1 秒会导致 32% 的用户流失。传统图片加载方案存在以下痛点&#xff1a; 内存占用高&#xff1a;未压缩的大图直接占用大量内…

用Python实现交互式数据可视化:从基础图表到动态仪表板

用Python实现交互式数据可视化&#xff1a;从基础图表到动态仪表板 一、项目背景 本文将通过一个完整的Python项目&#xff0c;展示如何使用Plotly和ipywidgets构建从基础统计到动态交互的全栈数据可视化方案。 二、核心功能模块 1. 数据生成与预处理 np.random.seed(100)…

Linux进程信号

1.信号的认识 生活中例如闹钟&#xff0c;红绿灯&#xff0c;电话铃声等都属于信号&#xff0c;所白了信号就是中断我们正在做的事情&#xff0c;属于进行事件异步通知机制。 在Linux中信号是发给进程的&#xff0c;信号的产生相较于进程是异步的。 信号的相关知识点&#xff…

Java使用FFmpegFrameGrabber进行视频拆帧,结合Thumbnails压缩图片保存到文件夹

引入依赖 <dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.17</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ja…

c++项目-KV存储-模仿redis实现kv键值对存储的基本功能。

KV存储引擎的技术解析&#xff1a;数组、哈希与红黑树实现及其在网络I/O中的应用。 内容概要&#xff1a;本文档深入介绍了基于数组、哈希表和红黑树的键值存储引擎的设计与实现。文档首先阐述了系统的总体架构与类图关系&#xff0c;之后分别对底层存储结构进行了详细解释&am…

vue3:十一、主页面布局(优化页面跳转方式)

:router"true" 一、参考文章 vue3:十一、主页面布局(实现基本左侧菜单右侧内容效果)-CSDN博客 参考上述文章可知&#xff0c;页面跳转是通过在js中定义的菜单中携带的path&#xff0c;然后通过菜单的点击事件完成的跳转&#xff0c;现在可以进行优化&#xff0c;直…

深入解析 Java Stream API:筛选子节点的优雅实现!!!

&#x1f680; 深入解析 Java Stream API&#xff1a;筛选子节点的优雅实现 &#x1f527; 大家好&#xff01;&#x1f44b; 今天我们来聊聊 Java 8 中一个非常常见的操作&#xff1a;使用 Stream API 从 Map 中筛选出特定条件的元素。&#x1f389; 具体来说&#xff0c;我们…

统计学重要概念:自由度

在统计学中&#xff0c;自由度&#xff08;degrees of freedom&#xff0c;简称df&#xff09;是一个重要的概念&#xff0c;它表示在计算某个统计量时可以自由变化的值的数量。对于一个样本量为n的样本&#xff0c;自由度通常为n-1&#xff0c;这是因为我们需要用样本数据来估…