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.pswp.cn/web/72848.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72848.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72848.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker部署dify

1.安裝docker 參考鏈接 https://ascendking.blog.csdn.net/article/details/136407383 設置docker源 vim /etc/docker/daemon.json {"registry-mirrors": ["https://docker.registry.cyou", "https://docker-cf.registry.cyou", "http…

Python Seaborn面試題及參考答案

目錄 如何用 stripplot () 繪制帶隨機偏移的分類散點圖?如何控制 jitter 參數? swarmplot () 如何避免散點重疊?適用場景與數據量限制是什么? 使用 catplot () 繪制箱線圖時,如何通過 kind 參數切換圖表類型? 如何通過 hue 參數在分類圖中添加第三個維度(如性別)? …

Linux應用:Linux的信號

什么是信號 信號是一種軟件中斷&#xff0c;用于通知進程系統中發生了某種特定事件。它是操作系統與進程之間&#xff0c;以及進程與進程之間進行異步通信的一種方式。在 Linux 系統中&#xff0c;信號是一種比較簡單的進程間通信機制。當一個信號產生時&#xff0c;內核會通過…

實時監控、數據分析!Web-Check構建你的網站健康檢測系統實操方案

文章目錄 前言1.關于Web-Check2.功能特點3.安裝Docker4.創建并啟動Web-Check容器5.本地訪問測試6.公網遠程訪問本地Web-Check7.內網穿透工具安裝8.創建遠程連接公網地址9.使用固定公網地址遠程訪問 前言 在數字化運維領域&#xff0c;網站穩定性保障始終是開發者和運維團隊的核…

win32匯編環境,網絡編程入門之八

;在上一教程里&#xff0c;我們學習了簡單的處理服務器返回的數據 ;在這一教程里&#xff0c;我們了解一下&#xff0c;當連接上網站后&#xff0c;應該發送什么數據過去的問題 ;這里有個簡單的方式學習&#xff0c;以下是一個示例 ;我們上網的時候可以用谷歌瀏覽器&#xff0c…

windows 平臺編譯openssl

文章目錄 準備環境安裝perl安裝NASM獲取源碼 源碼編譯配置編譯 準備環境 安裝perl 下載Perl 5.40.0.1 Portable zip strawberryperl 解壓后設置系統環境變量 測試安裝是否成功 perl --versionThis is perl 5, version 40, subversion 0 (v5.40.0) built for MSWin32-x64-m…

一文了解ThreadLocal

什么是ThreadLocal&#xff1f; ThreadLocal是每個線程私有的&#xff0c;線程可以把自己的私有數據放到ThreadLocal里面&#xff0c;不用擔心其他線程訪問到自己ThreadLocal。 通過set()方法將值存入ThreadLocal或者修改值&#xff0c;get()方法取出值&#xff0c;remove()方…

OpenWrt開發第6篇:怎么添加OpenWrt的Package-基于Raspberry Pi 4B開發板

文/指尖動聽知識庫-谷谷 文章為付費內容,商業行為,禁止私自轉載及抄襲,違者必究!!! 文章專欄:Openwrt開發-基于Raspberry Pi 4B開發板 1.如圖1所示,首先創建軟件包所在的目錄,在openwrt根目錄中執行mkdir -p package/mypackages/helloworld命令;

常?CMS漏洞之一:WordPress

WordPress是?個以PHP和MySQL為平臺的?由開源的博客軟件和內容管理系統。WordPress具有插件架構和模板系統。截?2018年4?&#xff0c;排名前1000萬的?站中超過30.6%使?WordPress。 WordPress是最受歡迎的?站 內容管理系統。全球有?約30%的?站(7億5000個)都是使?WordP…

【第17節】windows sdk編程:線程與線程調度

目錄 一、線程 1.1 線程的基本概念 1.2 何時創建線程 二、線程控制 三、遍歷線程 四、線程內核對象 4.1 線程上下文 4.2 暫停次數 4.3 信號 五、線程調度 5.1 什么是線程優先級 5.2 進程優先級與相對線程優先級 5.3 編程改變優先級 5.4 動態優先級的概念 一、線程…

Python數據可視化實戰:從基礎圖表到高級分析

Python數據可視化實戰&#xff1a;從基礎圖表到高級分析 數據可視化是數據分析的重要環節&#xff0c;通過直觀的圖表可以快速洞察數據規律。本文將通過5個實際案例&#xff0c;手把手教你使用Python的Matplotlib庫完成各類數據可視化任務&#xff0c;涵蓋條形圖、堆積面積圖、…

【機器學習-分類算法】

比如將一張圖片按尺寸識別分類為橫向或者縱向兩類就是二分類問題 設x軸為圖像的寬、y軸為圖像的高&#xff0c;那么把訓練數據展現在圖上就是這樣的: 若增加更多的數據集有: 如果只用一條線將圖中白色的點和黑色的點分開,那么: 分類的目的就是找到這條線,就可以根據點在線…

Compose Indication:點擊效果設置

Compose Indication&#xff1a;打造獨特點擊效果的秘密武器 在Compose開發中&#xff0c;大家可能都碰到過Indication&#xff0c;不少人第一次接觸它&#xff0c;是在想去掉Material默認的點擊水波紋效果的時候。要是在AI工具里搜“怎么去掉水波紋效果”&#xff0c;會得到這…

Docker build 會在本地產生巨大的文件

Docker build 會在本地產生巨大的文件&#xff0c; 比如 用 這個命令列出本地鏡像 docker images 可見size都是很大的&#xff0c; 到docker目錄下&#xff0c;看到ext4.vhdx的大小 80多G 那只能用這個命令把不用的鏡像刪掉了&#xff1a; &#xff08;rmi后面是鏡像id&a…

臺式機電腦組裝---電腦機箱與主板接線

臺式機電腦組裝—電腦機箱與主板接線 1、機箱連接主板的跳線一般主要有USB 2.0、USB 3.0、前置音頻接口(HD_AUDIO)以及POWER SW、RESET SW、POWER LED、HDD LED四個主板跳線&#xff0c;這些跳線分別的含義如下。 RESET SW&#xff1a;機箱重啟按鍵&#xff1b;注&#xff1a…

【虛幻引擎UE5】SpawnActor生成Character實例不執行AI Move To,未初始化AIController的原因和解決方法

虛幻引擎版本&#xff1a;5.5.4 問題描述 剛創建的Third Person項目里&#xff0c;定義一個BP_Enemy藍圖&#xff0c;拖拽到場景中產生的實例會追隨玩家&#xff0c;但SpawnActor產生的實例會固定不動。BP_Enemy藍圖具體設計如下&#xff1a; BP_Enemy的Event Graph ?? 又定義…

跨平臺RTSP高性能實時播放器實現思路

跨平臺RTSP高性能實時播放器實現思路 目標&#xff1a;局域網100ms以內超低延遲 一、引言 現有播放器&#xff08;如VLC&#xff09;在RTSP實時播放場景中面臨高延遲&#xff08;通常數秒&#xff09;和資源占用大的問題。本文提出一種跨平臺解決方案&#xff0c;通過網絡層…

HTTP 失敗重試(重發)方案

在 Qt 網絡開發中&#xff0c;使用 QNetworkAccessManager 進行 HTTP 請求時&#xff0c;可能會遇到網絡超時、服務器錯誤等情況。為了提高請求的可靠性&#xff0c;可以實現 HTTP 失敗重試&#xff08;重發&#xff09; 機制。下面介紹幾種常見的 失敗重發方案&#xff1a; 單…

大白話詳細解讀React框架的diffing算法

1. Diffing 算法是什么&#xff1f; Diffing 算法是 React 用來比較虛擬 DOM&#xff08;Virtual DOM&#xff09;樹的一種算法。它的作用是找出前后兩次渲染之間的差異&#xff08;diff&#xff09;&#xff0c;然后只更新這些差異部分&#xff0c;而不是重新渲染整個頁面。 …

【Linux內核系列】:動靜態庫詳解

&#x1f525; 本文專欄&#xff1a;Linux &#x1f338;作者主頁&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客勵志語錄&#xff1a; 有些鳥兒是注定是關不住的&#xff0c;因為它們的每一片羽翼都沾滿了自由的光輝 ★★★ 本文前置知識&#xff1a; 編譯與鏈接的過程…