CMEV · VERIFICATION ENGINEER TOOLKIT

A0_SCRIPTS · VIM · TCSH

Giáo trình học thuộc toàn bộ phím tắt và lệnh — theo HỌ PHÍM, có bản đồ bàn phím

Biên soạn trên máy Verifier giả lập B31_Veri_Client · CentOS 6.10 · Vim 7.4.712 · tcsh 6.17 · Python 2.6.6
Mã nguồn: ~/.cshrc (313 dòng) · ~/.vimrc (442 dòng) · ~/A0_scripts (HEAD 752473e)
Phiên bản 1.0 — 19/09/2026



Lời nói đầu

Cuốn sách này dành cho kỹ sư verification làm việc trên máy Verifier (RHEL/CentOS, tcsh, Vim 7.4, Python 2.6, không Internet) và muốn thuộc lòng bộ công cụ cá nhân gồm ba lớp: file cấu hình shell ~/.cshrc, file cấu hình Vim ~/.vimrc cùng 9 module AS010_VIMRC/source/00..09, và kho script ~/A0_scripts (21 module AS000–AS020).

Cách trình bày khác một bảng tra thông thường ở ba điểm:

Kỷ luật nguồn

Mỗi con số, mỗi tên phím, mỗi hành vi trong sách truy được về một trong ba nguồn: (1) mã nguồn đang chạy (đọc thẳng ~/.cshrc, ~/.vimrc, AS010_VIMRC/source/*.vim, các script AS0xx); (2) tài liệu nội bộ có số đo thật (09_README.md, project-overview.md, sổ ghi nhớ kỹ thuật của dự án); (3) màn hình hệ thống sống chụp ngày 19/09/2026 trên B31. Chỗ nào không truy được thì đã bỏ, không đoán cho đủ trang. Dưới nhiều mục có dòng chữ nhỏ Nguồn: … chỉ đúng file và dòng.

Trạng thái hệ thống lúc biên soạn

Hạng mục

Giá trị đo được

Cách đo

Máy

B31_Veri_Client — CentOS release 6.10 (Final)

cat /etc/redhat-release

Vim

VIM 7.4, Included patches: 1-712

vim --version

Shell

tcsh 6.17.00 (Astron) 2009-07-10

tcsh --version

Python

Python 2.6.6 (không có python3)

python -V · which python3

Git

git version 1.7.1 (chưa có git -C)

git --version

Phím Vim đã nạp

187 Normal · 26 Visual · 19 Insert (+1 map csh mọi mode)

:verbose nmap / xmap / imap

Alias tcsh

98 alias khai báo trong .cshrc (107 dòng alias, 9 dòng lặp theo user)

grep ^alias .cshrc

A0_scripts

60 commit, HEAD 752473e

git -C A0_scripts log

Môi trường mẫu

/0_ENV — list.txt 39 916 dòng

wc -l /0_ENV/list.txt



GHI CHÚ · VÌ SAO B31 CHỨ KHÔNG PHẢI MÁY THẬT

B31 là container giả lập đúng phiên bản máy Verifier (Vim 7.4, tcsh 6.17, Python 2.6). Trên B31 không có /common/ENV/System.env của công ty, nên khi chụp ảnh tôi nạp .cshrc sau khi vô hiệu 4 dòng dùng thư mục đó (dòng 4 và 94–96). Mọi alias khác giữ nguyên.



Những lỗi phát hiện trong lúc biên soạn

Chạy thật từng phím trên B31 làm lộ ra một số chỗ không chạy như chú thích trong mã nói. Sách vẫn dạy đúng ý đồ của phím, nhưng mỗi chỗ dưới đây có hộp LƯU Ý ngay tại mục liên quan, kèm cách chữa tạm. Chi tiết tái hiện ở Chương 27.

#

Phím / lệnh

Hiện tượng trên B31

Nguyên nhân gốc

1

dgg

E117: Unknown function: trim

Vim 7.4.712 chưa có hàm trim(); B31 còn thiếu cả git -C

2

tm1..tm9

E117: Unknown function: win_getid

win_getid() có từ Vim 7.4.1557

3

F7

E492: Not an editor command: SignifyToggle

08_signify chỉ nạp khi v:version >= 800

4

fd

Cửa sổ .sfindNoAnsi.fuz rỗng

fuz_filter.py thiếu dòng coding, Python 2.6 báo SyntaxError

5

vdc

E15 rồi 'No commit ID provided.'

mapping thừa <CR> — input() nuốt phím Enter đó

6

vdl · :VDL · :VDLR

'Invalid line number:' / E488

thừa <CR> như trên + thiếu dấu cách trước tên file

7

ff f1..f6 tt vv

Mở sai đường dẫn / không thấy file

$lwd, $lwdN là biến shell (set), Vim chỉ thấy biến môi trường

8

cf (Vim)

Không còn ghi ~/.tmp/cf

cf định nghĩa 2 lần (.vimrc dòng 255 và 420) — bản sau thắng

9

of / oof

oof báo Not found

of ghi ~/.tmp/of nhưng oof đọc ~/.tmp/op

10

showList

Permission denied.

showList.sh không có quyền thực thi

11

:CommentSet

E482: Can't create file ~/.vim/CommentSlots.txt

máy chưa có thư mục ~/.vim

12

simdone · emcp

command not found

B31 không cài zenity, emacs



Cách dùng sách

1. Đọc Phần I một lần để nắm bản đồ tổng thể và 'ngữ pháp' đặt tên phím.

2. Mỗi ngày học một họ phím theo lộ trình 7 ngày (Hình 3.1). Mở đúng chương, nhìn bản đồ bàn phím, gõ thử trên máy.

3. Làm bài thực hành cuối sách (Chương 28) tương ứng với họ vừa học.

4. Tự kiểm bằng thẻ nhớ ở Phụ lục D: che cột phải, đọc phím, nói ra công dụng.

5. Khi quên: tra Phụ lục A (mọi phím Vim theo họ) hoặc Phụ lục B (mọi alias tcsh).

MẸO · QUY ƯỚC TRONG SÁCH

Chữ như thế này là phím hoặc lệnh gõ nguyên văn. Ctrl+H nghĩa là GIỮ Ctrl rồi bấm H. fa nghĩa là gõ LẦN LƯỢT f rồi a (trong vòng 3 giây — timeoutlen=3000). <CR> là phím Enter. Trên bản đồ bàn phím: mũi tên = gõ lần lượt; phím tô màu cạnh Ctrl/Shift/Alt không có mũi tên = giữ cùng lúc.



⟳ Mở bằng Microsoft Word rồi bấm Ctrl+A → F9 để sinh mục lục kèm số trang.



PHẦN I

BẢN ĐỒ TỔNG THỂ — HỌC CÁCH HỌC





Chương 1 — Ba tầng công cụ và 'bộ nhớ chung' ~/.tmp

Trước khi học phím nào, hãy thấy toàn cảnh: có ba tầng gọi lẫn nhau, và một thư mục nhỏ ~/.tmp làm nơi hai thế giới shell và Vim trao đổi dữ liệu.

Hình 1.1. Ba tầng: tcsh là cửa vào, Vim là nơi làm việc, A0_scripts là động cơ cả hai cùng gọi.

1.1 Tầng 1 — tcsh và ~/.cshrc

Mỗi lần mở terminal, tcsh đọc ~/.cshrc: đặt history = 1000, TERM xterm-256color, thêm /opt/python2.6/bin vào đầu path, dựng dấu nhắc 2 dòng (ngày giờ + thư mục ở dòng trên, [user@máy]# ở dòng dưới), in lịch tháng bằng cal, rồi khai báo toàn bộ alias. Alias là 'phím tắt của shell': gõ sfind thực ra là chạy pythonVer $home/A0_scripts/AS002_sfind/sfind_py27.py.

1.2 Tầng 2 — Vim, ~/.vimrc và AS010_VIMRC

~/.vimrc khai báo các biến g:cc_* cho code completion, tắt Signify mặc định, rồi source file AS010_VIMRC/vimrc_source.vim. File này nạp lần lượt 9 module:

Module

Việc

Phím tiêu biểu

00_common_func.vim

Hàm dùng chung: tab, diff tab, fs, tt/vv, csf, fe, ccf, cf, \all, \help

dff dgg fs tt1 vv1 zzz

01_toggle_comment.vim

Comment nhiều ngăn (slot 1..5), giữ thụt lề

caa css cdd ccc cvv Ctrl+/

02_smart_gf.vim

gf hiểu token [N_L] của sfind và file:dòng

gf

03_smart_run.vim

Chạy file .csh/.py dưới con trỏ hoặc file đang mở

F5

04b_screen_layout_VIM7.4.vim

Lưu/khôi phục bố cục cửa sổ (bản cho Vim 7.4)

ss1..5 sr1..5 sss srr

05_copyword_replace_cwrwra.vim

Chép từ ra ~/.tmp/yiw rồi thay ở nơi khác

cw rw ra :RL

06_inline_vimdiff.vim

So sánh với Git bằng git difftool, so 2 file trong buffer

vdd vd0..5 vdc vdl

07_move_screen.vim

Dời cửa sổ: đánh dấu rồi đặt lại, đẩy bằng mũi tên

gtt gta gtd gtw gts Ctrl+mũi tên

09_code_completion.vim

Gợi ý code SV/UVM/C bằng tags + cây phân cấp

Tab F6 \all_09 cl ep

08_signify_vim8.vim

Dấu +/- lề trái (CHỈ nạp khi Vim >= 8.0)

F7 ]c [c



Nguồn: ~/A0_scripts/AS010_VIMRC/vimrc_source.vim dòng 1–22

1.3 Tầng 3 — A0_scripts

Kho script là một git repo riêng. Phần lớn không cần gọi trực tiếp: alias tcsh hoặc phím Vim gọi hộ. Hình 1.2 xếp 21 module theo công dụng; chữ đậm là module có alias hoặc phím gọi thẳng.

Hình 1.2. 21 module của A0_scripts xếp theo công dụng.

1.4 ~/.tmp — nơi shell và Vim nói chuyện với nhau

Shell và Vim là hai tiến trình khác nhau, không chia sẻ biến. Chúng trao đổi qua các file một dòng trong ~/.tmp. Nắm bảng này là hiểu vì sao swd1 gõ ở shell lại dùng được trong Vim, vì sao cw ở một cửa sổ Vim rồi rw ở một Vim khác vẫn chạy.

Hình 1.3. Ai ghi, ai đọc từng file trong ~/.tmp.

LƯU Ý · HAI CHỖ LỆCH TRONG BẢNG

of ghi ~/.tmp/of nhưng oof lại đọc ~/.tmp/op — hai phím không gặp nhau (.vimrc dòng 257–258). Phím cf của Vim hiện KHÔNG ghi ~/.tmp/cf nữa vì bị định nghĩa lại ở dòng 420. Xem Chương 17.



Chương 2 — Ngữ pháp phím tắt — chữ đầu là HỌ, chữ sau là VIỆC, số là NGĂN

Hơn 180 phím nghe thì nhiều, nhưng chúng được đặt tên theo một ngữ pháp rất đều. Thuộc ngữ pháp là đoán được 80% phím mà không cần nhớ.

Hình 2.1. Bản đồ tổng thể: mỗi phím đầu tô màu là một họ lệnh.

2.1 Chữ đầu = họ

Chữ đầu

Họ

Thành viên

Chương

f

Find — tìm / mở file ghim

fa fc fd fˋ fs fl ff f1..f6 fe

16, 17

d

Diff trong tab

dff dgg

19

v

Vimdiff

vdd vd0..vd5 vdc vdl vv0..vv5 vvv

19, 20

z

zzz = diff một dòng kết quả diff2

zzz

20

t

Tab

tnn tqq t1..t9 tm1..tm9 trn tcl0..7 · tt0..5 ttt (xem tham chiếu)

14, 20

g

Go — đi / mở theo đường dẫn

gf gr gd · gtt gta gtd gtw gts

13, 17

s

Screen — bố cục

ss1..5 sss sr1..5 srr sf sa · swd0..5

13, 15, 17

c

Comment / Copy

caa css cdd ca1..5 cs1..5 cd1..5 ccc cc1..5 cvv · cw cf ccf csf cl cch

21, 22

r

Replace

rw ra

22

o

Open path

of oof ocf

17

m

Mark-copy file

mcp mpst mrmrmrm

17

q w e

Quit / Write / Edit lại

qq qf qo ww wq ee

12

\

Leader — build completion

\all_09 \tg \hr \hp \hh \help_09 \all \help

24

F2..F12

Bật/tắt chế độ

F2 F3 F4 F5 F6 F7 F8 F9 F12

11



2.2 Chữ sau = việc cụ thể

2.3 Chữ số = ngăn (slot)

Khắp bộ công cụ, chữ số ở cuối là số ngăn. Cùng một con số có thể được dùng xuyên suốt từ shell sang Vim:

Ngăn

Ở tcsh

Ở Vim

Ý nghĩa

0..5

swdN lwdN cwdN (0 = swd/lwd/cwd)

swdN ttN vvN (ttt/vvv = 5)

thư mục đã lưu trong ~/.tmp/swdN

1..5

—

ssN srN (sss/srr = 1)

bố cục cửa sổ đã lưu

1..5

—

caN csN cdN ccN

ngăn tiền tố comment (:CommentSet N …)

0..5

—

vdN (vdd = vd0)

lùi N commit: HEAD~N

1..9

—

tN tmN

số thứ tự tab

0..7

—

tclN

màu tab (0 xoá màu)

1..6

showList1..10 (độ sâu)

fN

file ghim sẵn / độ sâu cây



Hình 2.2. Ngăn thư mục ở tcsh: s(ave) · l(oad) · c(lear) + wd + số.

MẸO · MỘT CÂU ĐỂ NHỚ CẢ PHẦN I

Chữ đầu nói bạn đang ở KHU nào, chữ sau nói LÀM gì, con số nói NGĂN nào. Quên phím nào thì nghĩ theo ba câu hỏi đó trước khi tra bảng.



Chương 3 — Phương pháp học thuộc trong 7 ngày

Hình 3.1. Lộ trình 7 ngày: mỗi ngày một họ phím.

3.1 Ba nguyên tắc

1. Học theo họ, gõ trên máy thật. Đọc bản đồ bàn phím 1 phút, rồi gõ mỗi phím 5 lần trên một file thật (ví dụ /0_ENV/top.v). Tay nhớ nhanh hơn mắt.

2. Nói thành lời khi gõ. fa = 'find all', vd2 = 'vimdiff hai commit trước'. Âm thanh gắn nghĩa vào phím.

3. Ôn cách quãng. Cuối mỗi ngày dùng thẻ nhớ Phụ lục D cho họ của ngày đó và của ngày hôm trước.

3.2 Nhịp gõ: timeoutlen = 3000

.vimrc đặt set timeoutlen=3000: sau phím đầu, Vim chờ tối đa 3 giây để xem bạn có gõ tiếp thành một chuỗi đã map hay không. Hệ quả thực tế:

Nguồn: ~/.vimrc dòng 112–113

LƯU Ý · NORMAL MODE TRƯỚC ĐÃ

Gần như mọi phím trong sách là phím Normal mode. Nếu gõ ww mà thấy chữ 'ww' hiện ra trong file, bạn đang ở Insert mode: bấm jj (hoặc Esc) rồi gõ lại. Ngoại lệ: Tab / S-Tab / mũi tên / F6 / Ctrl+Space trong popup completion là phím Insert (Chương 24); caa css cdd ccc ca1.. và Ctrl+/ chạy được cả ở Visual mode.





PHẦN II

TCSH — ~/.CSHRC VÀ CÁC ALIAS





Chương 4 — Mở terminal: .cshrc nạp những gì

Hình 4.1. Terminal ngay sau khi nạp .cshrc trên B31: dấu nhắc 2 dòng và lịch tháng.

Số

Thành phần

Ý nghĩa

1

Dòng trên dấu nhắc

[%d %D%w %p] %~ = thứ, ngày+tháng, giờ:phút:giây am/pm, thư mục hiện tại (~ = home). Màu xanh 38;5;68.

2

Dòng dưới dấu nhắc

[%n@%m]%# = user@tên máy rồi # (root) hoặc > (user thường). Tách 2 dòng để đường dẫn dài không đẩy lệnh sang phải.

3

Lịch tháng

Lệnh cal ở cuối phần alias (.cshrc dòng 269) — mở terminal là thấy ngày.



4.1 Thứ tự nạp

1. source /common/ENV/System.env — môi trường chung của công ty (chỉ có trên máy thật).

2. Khối switch ("$OS_VERSION") cho HP-UX / SunOS / Linux 2.4 / Linux 2.6 — hiện toàn bộ nhánh chỉ còn chú thích, không đặt gì.

3. source /common/ENV/uniq_path_com rồi set path=( $NEW_PATH_DAAD ) — loại đường dẫn trùng trong path.

4. set history = 1000; tắt bracketed-paste printf '\e[?2004l'; setenv TERM xterm-256color; đưa /opt/python2.6/bin lên đầu path.

5. Khối theo user (bảng 4.1) — đặt home, A0, pythonVer, prompt, LM_PROJECT.

6. Gọi prompt để áp dấu nhắc; khai báo alias; đọc 6 ngăn thư mục lwd0..5 và cf từ ~/.tmp; chạy cal.

Điều kiện

LM_PROJECT

pythonVer =

A0 =

$HOST == WORK_PC, hoặc USER root / rỗng

—

python

/root/A0_scripts (và home = /root/)

USER == dungtr_u5m_vf

RCAR_U5M8

/common/appl/Renesas/MUVE/tools/python3/Python-3.6.8/bin/python3

~/A0_scripts/

USER == dungtr_u5l_vf

RCAR_U5L8

như trên (Python 3.6.8)

~/A0_scripts/

USER == dungtr_u2b_vf

RCAR_U3B

/bin/python3.8

~/A0_scripts/



Nguồn: ~/.cshrc dòng 101–166

GHI CHÚ · PYTHONVER LÀ ALIAS, KHÔNG PHẢI CHƯƠNG TRÌNH

Mọi alias chạy Python (sfind, rcb, rm, run_all, sumLog, piplist) đều đi qua pythonVer, nên đổi phiên bản Python chỉ cần sửa MỘT dòng trong khối user. Riêng phím Vim fa/fc/fd gọi thẳng python (Chương 16).



LƯU Ý · TRÊN B31: .TCSHRC CHE MẤT .CSHRC

tcsh đọc ~/.tcshrc nếu file này tồn tại, và chỉ đọc ~/.cshrc khi không có .tcshrc. B31 có sẵn /root/.tcshrc (3 alias rm/cp/mv -i) nên mở tcsh trên B31 sẽ KHÔNG có alias nào của sách. Muốn thử: source ~/.cshrc bằng tay (và chấp nhận lỗi ở dòng 4 vì B31 không có /common/ENV).



4.2 Alias sửa và nạp lại chính cấu hình

Alias

Chạy

Ghi nhớ

vimrc

vi $home/.vimrc

sửa cấu hình Vim

cshrc

vi $home/.cshrc

sửa cấu hình shell

scshrc

source $home/.cshrc

s = source. Nạp lại ngay, không cần mở terminal mới

prompt

đặt lại biến prompt

gọi lại nếu dấu nhắc bị script khác ghi đè

home · A0

cd /root/ · cd /root/A0_scripts

đồng thời có biến $home, $A0 cùng tên

clr

clear

xoá màn hình



MẸO · LƯU .VIMRC / .CSHRC LÀ TỰ CẬP NHẬT CHEATSHEET

Cuối .vimrc có autocmd A0_Cheatsheet_Sync: mỗi lần :w file tên kết thúc bằng vimrc hoặc cshrc, Vim chạy python3 ~/A0_scripts/docs/generate_data_js.py để làm mới cổng tra cứu cheatsheet.html. Trên máy chỉ có Python 2.6 lệnh này âm thầm không chạy (có silent!), không ảnh hưởng việc ghi file.



Chương 5 — Sáu ngăn thư mục: swd · lwd · cwd · llwd · cf

Làm verification là nhảy qua lại giữa vài thư mục sâu hoắm: môi trường testcase, thư mục log, bản vendor drop, repo Git. Thay vì gõ lại đường dẫn, lưu chúng vào 6 ngăn đánh số 0..5.

Hình 5.1. Ba động từ s / l / c + wd + số ngăn.

Hình 5.2. Lưu 2 ngăn, liệt kê, rồi nhảy về ngăn 0 — chụp trên B31.

Số

Thành phần

Ý nghĩa

1

swd

Lưu pwd hiện tại vào ngăn 0 (~/.tmp/swd0) và đặt biến shell $lwd, $lwd0.

2

swd1

Lưu vào ngăn 1 (~/.tmp/swd1), đặt $lwd1.

3

llwd

In cả 6 ngăn và nạp lại 6 biến $lwd0..5 từ file (dùng khi terminal khác vừa lưu).

4

0: …

Ngăn 0 đang giữ /0_ENV/testcase.

5

1: …

Ngăn 1 đang giữ /tmp/ENV_B. Ngăn trống in ra rỗng; ngăn 4, 5 còn giữ giá trị cũ từ lần trước.

6

lwd

cd tới ngăn 0 — dấu nhắc đổi thành /0_ENV/testcase.



Alias

Làm gì

Mẹo nhớ

swd · swd0

lưu pwd vào ngăn 0

s = save

swd1..swd5

lưu pwd vào ngăn 1..5


lwd · lwd0

cd tới ngăn 0

l = load

lwd1..lwd5

cd tới ngăn 1..5


cwd · cwd0 .. cwd5

xoá ngăn (ghi chuỗi rỗng)

c = clear

llwd

liệt kê 6 ngăn + nạp lại biến

ll = list

cf

lưu pwd vào ~/.tmp/cf, đặt $cf

cf = current folder

$lwd1 …

dùng trong lệnh: cp a.v $lwd1/

biến shell, có sẵn sau khi swd hoặc llwd



Nguồn: ~/.cshrc dòng 170–200

Hình 5.3. Ngăn thư mục là cầu nối tcsh ↔ Vim — và bước setenv cần thêm.

LƯU Ý · VIM KHÔNG NHÌN THẤY $LWD1

Alias swd1 dùng set lwd1=… — đó là BIẾN SHELL, chỉ tcsh thấy. Vim chỉ đọc BIẾN MÔI TRƯỜNG. Kiểm trên B31: sau swd; swd1, trong Vim :echo $lwd1 in ra rỗng. Vì vậy các phím Vim ff f1..f6 tt0..5 vv0..5 chỉ chạy khi đã có biến môi trường cùng tên. Cách tạm trước khi mở Vim — gõ ở tcsh (hoặc sửa alias swdN thêm setenv):



setenv lwd `cat ~/.tmp/swd0`

setenv lwd1 `cat ~/.tmp/swd1` # tương tự lwd2 .. lwd5

# hoặc sửa alias, ví dụ:

alias swd1 'pwd > $home/.tmp/swd1; set lwd1=`pwd`; setenv lwd1 `pwd`'



Chương 6 — Tìm và liệt kê: ls · sfind · vfind · showList

6.1 Nhóm ls / grep (có màu)

Alias

Chạy

Ghi chú

ls

ls --color=auto -hCF

cột, kích thước dễ đọc, ký hiệu loại file (/ * @)

ll

ls --color=auto -alhAF

danh sách dài, kể cả file ẩn

la

ls --color=auto -hlA

dài, có file ẩn trừ . và ..

grep

grep --color=auto

tô màu chỗ khớp

duh · duh1 · duh2 · duh3

du -h · --max-depth=1/2/3

dung lượng thư mục theo độ sâu



6.2 sfind — công cụ tìm của cả bộ

sfind (AS002, sfind_py27.py) là động cơ đằng sau phím Vim fa fc fd. Cú pháp 4 tham số:

sfind <NỘI DUNG regex> <TÊN FILE regex[-bỏ]> <SỐ KẾT QUẢ/FILE> <THƯ MỤC[-bỏ]> [-s | -sa | -sn]



Tham số

Ý nghĩa

Viết tắt sẵn có

Ví dụ

1. Nội dung

Regex (ERE), không phân biệt hoa thường. Dùng | thì bọc nháy kép

all = ".*"

"SD_ADDR|WRITE_.*_ENA"

2. Tên file

Danh sách regex nhận, sau dấu - là danh sách loại

all · vsv = \.(v|sv) · hide = ^\.

vsv-test,tmp

3. Số kết quả

Số dòng tối đa hiển thị MỖI file

first = 1 · all

3

4. Thư mục

Danh sách thư mục nhận, sau - là thư mục loại

hide

.-logs,hide · etc,tb-tbtop.*

-s / -sa / -sn

Mở menu chọn thư mục con trước khi tìm

-sa chọn sẵn hết · -sn bỏ chọn hết

sfind -sn SD_ADDR vsv all .



Hình 6.1. Gõ sfind không tham số: trang trợ giúp. Thiếu tham số nào, sfind in trợ giúp của tham số đó.

Số

Thành phần

Ý nghĩa

1

1.CONTENT

Mục trợ giúp tham số 1. Tương tự có 2.FILENAME, 3.RESULT COUNT, 4.FILE PATH (gõ sfind -h để xem cả 4).

2

ALIAS all

Viết tắt cho '.*' — không quan tâm nội dung (dùng khi chỉ muốn liệt kê file theo tên).

3

Ví dụ regex

write.*ADC khớp write8ADC, write16ADC…

4

INTERACTIVE MENU

-s/-sa/-sn đặt ĐẦU hoặc CUỐI lệnh để bật menu chọn thư mục.



Hình 6.2. sfind PATH_SYSAWO vsv 3 testcase — 11 kết quả trong 5 file, 0,64 giây.

Số

Thành phần

Ý nghĩa

1

Lệnh

Tìm PATH_SYSAWO trong file .v/.sv, tối đa 3 dòng mỗi file, chỉ trong thư mục testcase.

2

[File 1][N1] đường dẫn

Tiêu đề file (nền xanh): số thứ tự file và tổng số dòng khớp trong file đó.

3

[File 2][N3]

File thứ hai có 3 dòng khớp (bị cắt ở 3 vì tham số 3).



Mỗi dòng kết quả có dạng [k][N_L]: k là số thứ tự trong file, N_L là file số N, dòng L. Token N_L này chính là thứ phím gf trong Vim hiểu để nhảy thẳng tới (Chương 16). Kết quả được lưu 2 bản: ~/.tmp/.sfind (có màu) và ~/.tmp/.sfindNoAnsi (không màu, có dòng ##### trước mỗi file).

Alias

Chạy

Ghi chú

sfind …

tìm (xem trên)

động cơ của fa / fc / fd

sfindCat

cat ~/.tmp/.sfind

in lại kết quả lần trước, CÓ màu

sfindVi

vi ~/.tmp/.sfindNoAnsi

mở kết quả lần trước trong Vim để gf

vfind <từ>

sfind <từ> all all $home/INOUTREGWIRE/

tìm trong kho khai báo cổng/tín hiệu

vfindreg · vfindwire

cat …/reg* | grep -E "reg\s+.*<từ>" (wire*)

chỉ dòng khai báo reg / wire

vfindin · vfindout

như trên với in / out

chỉ dòng input / output



Nguồn: ~/.cshrc dòng 217–225; AS002_sfind/sfind_py27.py dòng 43–130, 360–372

6.3 showList — sinh list.txt để tìm theo tên

showList (AS009) ghi cây thư mục phẳng (tree -ifF) ra file, mỗi dòng một đường dẫn. File list.txt ở gốc môi trường là nguồn cho phím Vim fs fl ff (Chương 17). Trong /0_ENV trên B31, list.txt dài 39 916 dòng.

Hình 6.3. showList trên B31: alias báo Permission denied; gọi qua bash thì chạy.

Số

Thành phần

Ý nghĩa

1

Permission denied.

showList.sh trong repo không có bit thực thi, nên alias showList hỏng. Chữa: chmod +x ~/A0_scripts/AS009_showList/showList.sh.

2

SHOWLIST

Trợ giúp khi gọi bash …/showList.sh -h.

3

showlist

Không tham số: ghi toàn bộ cây vào ~/.tmp/.showlist.txt.

4

showlist <file>

Tạo mới hoặc cập nhật file chỉ định kèm dấu thời gian — dùng để sinh list.txt.



Alias

Chạy

Ghi chú

showList [file]

ghi cây ra ~/.tmp/.showlist.txt hoặc [file]

hỏng quyền x — xem trên

showListCatResult

cat ~/.tmp/.showlist.txt


showListViResult

vi ~/.tmp/.showlist.txt


showList1 .. showList10

tree -ifFL N > ~/.tmp/.showlist.txt && vi …

N = độ sâu tối đa; mở luôn trong Vim



Chương 7 — Chạy mô phỏng song song và tổng hợp kết quả

Nhóm này xoay quanh screen: mỗi testcase chạy trong một phiên screen riêng, log được ghi ra thư mục chung, rồi tổng hợp PASS/FAIL.

Alias

Chạy

Ghi chú

run_all <scomp|sim> <N>

runAll.py: đọc file run_list ở thư mục hiện tại; scomp chỉ biên dịch; sim biên dịch hết rồi chạy tối đa N phiên screen song song

log mỗi phiên vào LOG_DIR, giữ 3 ngày; trạng thái ghi run_log.txt ([DONE] / [=> RUNNING])

ss

screen -ls | sort -n -k1

liệt kê phiên screen

sw

showScreen.csh: hardcopy màn hình MỌI phiên screen rồi vi -O tất cả

nhìn cùng lúc mọi phiên đang chạy

sf

showScreen2.csh: mở vi -O file log của mọi phiên trong LOG_DIR

log đầy đủ, không chỉ 1 màn hình

ska

killall screen

NGUY HIỂM: giết mọi phiên

simdone [msg]

zenity --info --text="Sim Done. msg"

hộp thông báo; B31 không có zenity

ok

./check_result.csh

script kiểm kết quả của môi trường

sumComp · sumComp2

grep -rl lỗi Error occurred in.*gmake trong testcase/sysss_uvm/clma (vmon)

tìm testcase biên dịch lỗi

sumLog · sumLog2 [PASS|FAIL]

sumLog.py -f $home/sumLog_conf_RELU5M(_2).yml

bảng PASS/FAIL SIM + SVA theo regex trong YAML

sum · sum2

(sumComp && sumLog FAIL) | tee sim_result.txt rồi xoá mã màu

một lệnh ra file báo cáo sạch

cleanTestcase

find + rm -rf mọi .log .map .lvh .mot .dump .elf .obj .rpt .c.o .s.o

NGUY HIỂM: xoá thật, không qua rcb

cleanTestcase_listonly

cùng find nhưng chỉ in

luôn chạy cái này TRƯỚC

bsjob · bsvim

bs -os "RHEL7 RHEL8" · bs -os RHEL8 vim

đẩy job / mở Vim trên máy tính toán qua bs



Nguồn: ~/.cshrc dòng 213–216, 268, 280–291, 310–312; AS003_runAll/runAll.py; AS001_showScreen/.csh; AS011_sumLog/sumLog.py*

NGUY HIỂM · CLEANTESTCASE XOÁ THẬT

Alias này gọi thẳng rm -rf {} bên trong find -exec — lệnh rm ở đây là chương trình /bin/rm, KHÔNG đi qua alias rm → thùng rác. Chạy cleanTestcase_listonly trước để xem danh sách.



GHI CHÚ · SW VÀ SF BỔ SUNG CHO NHAU

sw chụp màn hình hiện tại của từng phiên (screen hardcopy) — nhanh, nhưng chỉ thấy phần đang hiển thị. sf mở file log mà run_all ghi (mỗi dòng có dấu giờ [HH:MM:SS.mmm]) — đầy đủ từ đầu. Hai chữ cùng họ s = screen.



Chương 8 — Git và so sánh thư mục từ shell

8.1 gitmap — bản đồ nhánh

Hình 8.1. gitmap trong repo mẫu: đồ thị commit, ngày giờ, thời gian tương đối.

Số

Thành phần

Ý nghĩa

1

fb8b029

Commit mới nhất (HEAD, master). Màu xanh đậm = mã commit rút gọn.

2

0d63409

Commit trước đó (HEAD~1).

3

28560d3

Commit gốc. Mỗi commit 2 dòng: dòng 1 mã + ngày + (bao lâu trước) + nhãn nhánh; dòng 2 tiêu đề + tác giả.



Lệnh

Chạy

Ghi chú

gitmap

git fetch origin rồi git log --graph --oneline --decorate --all định dạng màu

repo không có origin thì fetch báo lỗi nhưng log vẫn in

gitmapall

gitmap --name-only

kèm danh sách file của từng commit

git all "msg" <tag>

AS015_CSHRC/git_all.csh: add -A, commit, tag, push

cần cài 1 lần bằng git config (dưới)

git vimdiff c1 c2 [-- f]

git difftool -t vimdiff

hỏi từng file

git vd c1 c2 [-- f]

git difftool -t vimdiff --no-prompt

không hỏi — cùng động cơ với phím Vim vd0..vd5



# cài alias git MỘT LẦN (các dòng #!# trong .cshrc, dòng 244-248)

git config --global alias.all '!`echo $HOME`/A0_scripts/AS015_CSHRC/git_all.csh'

git config --global alias.vimdiff 'difftool -t vimdiff'

git config --global alias.vd 'difftool -t vimdiff --no-prompt'



8.2 diff2 — so hai thư mục

diff2 A B [danh_sách] (AS013) so hai cây thư mục, in mỗi file khác một dòng với ký hiệu đầu dòng, rồi lưu đường dẫn gốc A, B vào ~/.tmp/diff2_A.txt, ~/.tmp/diff2_B.txt. Mở kết quả trong Vim, đặt con trỏ lên một dòng rồi bấm zzz là vimdiff đúng cặp file đó (Chương 20).

Hình 8.2. Kết quả diff2 AAA BBB trên bộ mẫu của AS013.

Số

Thành phần

Ý nghĩa

1

< AAA/a.txt

Chỉ có ở A (bên trái).

2

| AAA/b.txt

Có ở cả hai nhưng nội dung khác.

3

> BBB/d.txt

Chỉ có ở B. Thứ tự: mọi dòng < và | trước (theo ABC), rồi mới tới >.



LƯU Ý · FILE KẾT QUẢ NẰM Ở ~/.TMP, KHÔNG PHẢI THƯ MỤC HIỆN TẠI

Chú thích đầu diff2.csh nói 'writes results to diff2_result.txt', nhưng lần chạy trên B31 in ra Results saved in ~/.tmp/diff2_result.txt và thư mục hiện tại không có file đó. Mở bằng vi ~/.tmp/diff2_result.txt.



Vòng lặp thu hẹp: sửa file kết quả, xoá những dòng không quan tâm, rồi chạy lại diff2 A B ~/.tmp/diff2_result.txt (hoặc /dev/stdin < file) — lần này chỉ so các file còn lại.

8.3 AS014 — đưa bản giao mới của nhà cung cấp vào Git

Hình 8.3. Năm bước AS014 và điểm nối sang phím zzz.

Alias

Làm gì

Ghi chú

AS014_GitVendorDrop.S0_repoCreate <repo.git>

tạo bare repo chia sẻ nhóm (sharedRepository=group, denyNonFastForwards, gc.auto=0), commit README đầu tiên

chạy 1 lần

…S1_Diff_Vendor_Drop <c1> <c2>

so 2 commit, phân loại < xoá · | sửa · > thêm → S1_diff_vendor_drop_for_diff2.txt


…S2_call_diff2 <drop> <git> <list>

gọi diff2 với danh sách từ S1 → S2_diff2_result.txt

nhắc dùng zzz

…S3_push_with_message_tag <nhánh> "msg" <tag>

hỏi xác nhận 3 lần đã giải xung đột, rồi add/commit/tag/push


…S4_Quick_3Dir_Update <cũ> <mới> <git>

diff cũ→mới, lọc, đổi đường dẫn, diff mới→git; ra AS014_OUT_1..4_*.txt

zzz tự đọc AS014_PATH_1..3



Nguồn: ~/.cshrc dòng 242–250, 293, 301–305; AS013_diff2/diff2.csh dòng 1–50; AS014_GitVendorDrop/S0..S4

Chương 9 — An toàn và tiện ích: rm → thùng rác, ansi, PCA …

9.1 rm không xoá thật

Hình 9.1. rm là alias sang thùng rác rcb (AS008).

Hình 9.2. rcb -h: bốn nhóm lệnh.

Số

Thành phần

Ý nghĩa

1

[1] List Group

ls path tree [path|./] — xem nội dung thùng rác tương ứng với thư mục hiện tại.

2

[2] Del/Restore

delete <path> (chính là rm) · restore <path|all> · clean [path] · empty (đổ sạch).

3

[3] Info/Help

info — cấu hình, top 10 file lớn nhất · help -h --help.

4

[4] Other

daily_maintenance (cron 01:00) · daily_log · clear_log.



Tham số rcb.conf

Giá trị trong repo

Ý nghĩa

RECYCLE_BIN_ROOT_DIR

/root/test/.recycle_bin

nơi chứa thùng rác

MAX_CYCLE_BIN_SIZE_GB

20

quá thì xoá file cũ nhất

MAX_STORE_DAY

30

giữ tối đa 30 ngày

CHECK_FILE_SIZE_AND_TYPE / MAX_FILE_SIZE_MB

True / 1000

file > 1000 MB không giữ

IGNORE_FILE_TYPE

.vpd .fsdb

dạng sóng không vào thùng rác

RECYCLE_BIN_EXPIRE_YYYYMMDD

2026-03-01

từ ngày này rcb ngừng: rm = xoá thật, thùng rác bị xoá



NGUY HIỂM · NGÀY HẾT HẠN ĐÃ QUA

Giá trị RECYCLE_BIN_EXPIRE_YYYYMMDD = "2026-03-01" trong repo đã qua (sách biên soạn 19/09/2026). Theo chú thích của rcb.conf, sau ngày này rm hoạt động như xoá thường. Kiểm rcb info trên máy thật và gia hạn nếu vẫn muốn có thùng rác.



9.2 Tiện ích khác

Hình 9.3. ansi: bảng 256 màu nền và chữ — tra mã \x1b[48;5;Nm / \x1b[38;5;Nm.

Số

Thành phần

Ý nghĩa

1

Bảng nền

Mã 0..255 cho màu nền \x1b[48;5;Nm.

2

Bảng chữ

Mã 0..255 cho màu chữ \x1b[38;5;Nm. Dấu nhắc của .cshrc dùng 68 (xanh).



Alias

Chạy

Ghi chú

ansi

in bảng 256 màu

chọn màu cho prompt / script

clearAnsi

echo "\e[0m"

trả màu terminal về mặc định khi bị 'dính' màu

piplist

liệt kê module Python cài sẵn (pkgutil) của pythonVer

máy không có pip

jubei <chữ>

echo "xin chao <chữ> de den"

ví dụ minh hoạ \!* = mọi tham số

emcp <file>

mở emacs, chép toàn bộ file vào clipboard

Vim có phím emcp tương tự; B31 không có emacs

as006_make

make -f AS006_encDecData/makefile

mã hoá/giải mã dữ liệu (openssl 1.0.2k)

PCA1

python AS016_PCA/PCA.py

biến dữ liệu nhị phân thành khung ảnh

PCA2

trình chiếu tmp/ bằng eog rồi tự đóng sau (số ảnh + 10) giây


AS019_Trans_PCA

01_sync_transfer.py --config …/03_sync_config.cfg

đồng bộ A→B, gom file đổi thành zip

wiki · wiki2

ssh -X TWIDC-R640-51 · ssh -X TWIDC-R6625-01

máy wiki nội bộ



Nguồn: ~/.cshrc dòng 168, 202, 252–275, 307–313; AS008_recycleBin/src/rcb.conf, rcb.py dòng 380–470



PHẦN III

VIM — NỀN TẢNG: TUỲ CHỌN, PHÍM F, GHI VÀ THOÁT





Chương 10 — Vim trông thế nào sau khi nạp .vimrc

Trước khi học phím, cần đọc được màn hình. .vimrc đặt một bộ tuỳ chọn làm Vim 'biết nói': dòng đang sửa đổi màu khi file chưa lưu, thanh trạng thái in đường dẫn đầy đủ, thanh tab có số tab và số cửa sổ.

Hình 10.1. Vim trên B31: 3 tab có tên và màu, 2 cửa sổ dọc, dòng hiện tại tô đỏ vì file đã sửa.

Số

Thành phần

Ý nghĩa

1

[T1/2]path_define.v+

Tab 1, đang có 2 cửa sổ; tên = file của cửa sổ đang chọn; dấu + = có thay đổi chưa lưu.

2

[T2/1]UVM_TB

Tab 2 đã đổi tên bằng trn và tô màu xanh lá bằng tcl2.

3

[T3/1]REVIEW

Tab 3 tên REVIEW, màu đỏ tcl1.

4

Thanh trạng thái

%F %M %Y %R %p%% = đường dẫn đầy đủ, dấu + nếu đã sửa, loại file, [RO] nếu chỉ đọc, phần trăm vị trí. Cửa sổ đang chọn: chữ vàng; cửa sổ khác: chữ xám.



Tuỳ chọn

Tác dụng thấy được

cursorline + autocmd CursorLineColor

Dòng con trỏ nền xám 238; khi buffer ĐÃ SỬA chưa lưu, nền chuyển đỏ sẫm 52 (Hình 10.1 cột phải). Nhìn màu là biết cần ww.

nu · nowrap · splitright · noequalalways

Có số dòng; dòng dài không gập; :vsplit mở bên PHẢI; mở split không tự chia đều.

hlsearch · incsearch · ignorecase

Tô sáng mọi chỗ khớp (nền tím, chữ trắng), tô ngay khi đang gõ, không phân biệt hoa thường.

expandtab · tabstop=4

Tab thành 4 dấu cách.

mouse=a

Click chọn cửa sổ, kéo thanh chia bằng chuột.

wildmenu · wildmode=list:longest

Tab khi gõ lệnh : liệt kê như bash; bỏ qua .docx .jpg .png .pdf .pyc .xlsx …

showcmd · showmatch · history=1000

Hiện phím đang gõ dở ở góc phải dưới — rất có ích khi tập chuỗi fa, vd1…

viminfo='100,<1000,s100,h

Nhớ mark, thanh ghi, lịch sử sau khi thoát.

filetype .sv .sva .v = verilog

Tô màu Verilog cho cả SV/SVA; comment kiểu // %s.

DiffAdd/Change/Delete/Text

Diff: thêm = nền xanh lá, đổi = xanh dương, xoá = đỏ, chữ khác trong dòng = vàng đảo màu.

Visual ctermbg=17

Vùng chọn nền xanh navy.



Nguồn: ~/.vimrc dòng 110–177, 196–212, 303–328

Chương 11 — Hàng phím F — bật / tắt

Hình 11.1. Hàng F: nhìn (F2 F3 F4 F8 F9), chạy (F5), gợi ý (F6), diff (F7), dán (F12).

Phím

Làm gì

Khi nào dùng

F2

bật/tắt cursorcolumn (cột dọc theo con trỏ)

căn thẳng cột khi đọc bảng/port

F3

bật/tắt wrap

đọc dòng log rất dài

F4

bật/tắt số dòng

tắt đi để copy bằng chuột không dính số

F5

SmartRun: chạy .csh/.py dưới con trỏ, không có thì chạy file đang mở

Chương 23

F6

bật/tắt auto-popup completion (Normal và Insert)

Chương 24

F7

:SignifyToggle — dấu +/- git ở lề trái

CHỈ Vim 8 (xem dưới)

F8

bật/tắt list — hiện ký tự ẩn ($ cuối dòng, ^I tab)

tìm tab lẫn dấu cách, dấu cách thừa cuối dòng

F9

bật/tắt spell, ngôn ngữ en_us

soát chính tả chú thích

F12

pastetoggle

bật trước khi dán từ clipboard để không bị thụt lề bậc thang



Hình 11.2. F2 + F8 trên file mẫu: cột con trỏ và dấu $ ở cuối mỗi dòng.

Hình 11.3. F7 trên Vim 7.4 của B31: E492 vì plugin Signify không được nạp.

LƯU Ý · F7 CHỈ DÀNH CHO VIM 8

vimrc_source.vim chỉ source 08_signify_vim8.vim khi v:version >= 800. Trên máy Vim 7.4, F7 báo E492: Not an editor command: SignifyToggle. Dùng các phím so sánh ở Phần VI thay thế. Trên Vim 8, Signify tắt mặc định (g:signify_disable_by_default = 1) cho nhẹ; F7 bật cho buffer hiện tại, ]c / [c nhảy giữa các hunk.



Chương 12 — Ghi, thoát, nạp lại — gấp đôi phím là xong

Hình 12.1. Q W E: thoát, ghi, nạp lại. Space thay cho dấu hai chấm.

Phím

Tương đương

Ghi nhớ

ww

:w

ghi

qq

:q

đóng cửa sổ

qf

:q!

đóng, BỎ thay đổi (f = force)

wq

:wq

ghi rồi đóng

qo

:only

chỉ giữ cửa sổ này (o = only)

ee

:e rồi G

nạp lại file từ đĩa và nhảy xuống cuối — theo dõi log đang chạy

Space

:

Space là phím to nhất — dùng để mở dòng lệnh

jj (Insert)

Esc

thoát Insert không cần với tay lên Esc

Y

y$

chép từ con trỏ tới cuối dòng (giống D, C)

Ctrl+Z

không làm gì

khoá lại để lỡ tay không đẩy Vim xuống nền; muốn thật thì gõ :suspend

vimrc

:source $MYVIMRC

nạp lại .vimrc ngay trong Vim



Nguồn: ~/.vimrc dòng 180–182, 207–212, 347–355

NGUY HIỂM · QF BỎ MẤT THAY ĐỔI

qf = :q! không hỏi lại. Nhìn màu dòng con trỏ trước: nền ĐỎ nghĩa là còn thay đổi chưa lưu.





PHẦN IV

VIM — CỬA SỔ, TAB VÀ BỐ CỤC





Chương 13 — Cửa sổ: đi, dời, phóng to

Hình 13.1. Ctrl+H/J/K/L để ĐI; gtt rồi gtW/A/S/D để DỜI; mũi tên + Ctrl/Alt để ĐẨY.

13.1 Đi giữa các cửa sổ

Phím

Làm gì

Mẹo nhớ

Ctrl+H / J / K / L

sang cửa sổ trái / dưới / trên / phải

H J K L là 4 hướng gốc của Vim

Tab

sang cửa sổ kế tiếp (vòng) rồi về đầu dòng

không cần chọn hướng

Shift+Tab

sang cửa sổ bên TRÁI

đi ngược



13.2 Dời và đẩy cửa sổ

Phím

Làm gì

Mẹo nhớ

gtt

đánh dấu cửa sổ hiện tại là 'cửa sổ cần dời'

g t t = go-to, target

gta / gtd

mở lại cửa sổ đã đánh dấu thành cột bên TRÁI / PHẢI cửa sổ hiện tại, đóng chỗ cũ

A = trái, D = phải

gtw / gts

…thành ngăn ngang phía TRÊN / DƯỚI cửa sổ hiện tại

W = lên, S = xuống

Ctrl+← / Ctrl+→

tách khỏi cột, chèn sang cột kề trái / phải

đổi chỗ nhanh 2 cột

Ctrl+↑ / Ctrl+↓

trong cột: lên/xuống một bậc; cột 1 cửa sổ: xếp chồng vào cột bên phải


Alt+← → ↑ ↓

dạt cửa sổ ra hẳn mép trái / phải / trên / dưới (wincmd H L K J)

chiếm trọn cạnh



Hình 13.2. Trước: 3 cột top.v | Makefile | path_define.v.

Hình 13.3. Sau gtt (trên path_define.v), chuyển sang Makefile, gts: path_define.v xếp xuống dưới Makefile.

Nguồn: AS010_VIMRC/source/07_move_screen.vim dòng 1–20, 389–393; ~/.vimrc dòng 187–197, 357–370

13.3 Kích thước

Phím

Làm gì

Mẹo nhớ

sf

phóng to cửa sổ hiện tại hết cỡ (resize 999, vertical resize 999)

f = Full

sa

chia đều mọi cửa sổ (wincmd =)

a = All equal

qo

chỉ giữ cửa sổ này

o = Only



MẸO · BỘ BA SF → SA

Đọc log bên cạnh code: sf để xem log toàn màn hình, xong sa để trả lại bố cục chia đều. Không mất cửa sổ nào.



Chương 14 — Tab: mỗi tab là một bàn làm việc

Hình 14.1. Họ T: tạo/đóng, nhảy theo số, đặt tên, tô màu.

Phím

Làm gì

Mẹo nhớ

tnn

tab mới chứa cửa sổ hiện tại (:tab split)

n = new

tqq

đóng tab

q = quit

t1 .. t9

nhảy tới tab số N

nhìn số [TN/..] trên thanh tab

Shift+← / Shift+→

tab trước / sau


trn

đặt tên tab (hỏi Tab name:), đặt lại màu trắng

r n = rename

tcl1 .. tcl7

màu tab: 1 đỏ · 2 xanh lá · 3 vàng · 4 xanh dương · 5 tím · 6 lục lam · 7 trắng

cl = color

tcl0

xoá màu


tm1 .. tm9

chuyển cửa sổ hiện tại sang tab N (thành cột trái)

m = move — HỎNG trên Vim 7.4



Nguồn: ~/.vimrc dòng 237–298; 00_common_func.vim GLRenameTab, GLSetTabColor, GLTabLineRender

LƯU Ý · TM1..TM9 CẦN VIM 7.4.1557+

Hàm GLMoveWindowToTab dùng win_getid() / win_gotoid(). Vim trên B31 (7.4.712) báo E117: Unknown function: win_getid. Cách tạm: ở tab đích gõ :vsplit + tên file (hoặc :sb <số buffer>), rồi qq cửa sổ ở tab cũ.



GHI CHÚ · TAB [DIFF] TỰ QUAY VỀ TAB GỌI

Các phím dff, dgg, vv0..5 mở kết quả trong tab mới tên [DIFF]/[GIT]. Hệ thống ghi nhớ tab nào đã gọi nó; khi bạn tqq tab diff, Vim tự nhảy về đúng tab cũ chứ không về tab kề.



Chương 15 — Lưu và khôi phục bố cục: ss / sr

Hình 15.1. Họ S: ss+số lưu, sr+số khôi phục; sf, sa phóng to / chia đều; swd lưu thư mục.

Phím

Làm gì

Mẹo nhớ

ss1 .. ss5

lưu bố cục (các cửa sổ, file, vị trí) vào ngăn N

s s = screen save

sss

= ss1

gấp ba = ngăn mặc định

sr1 .. sr5

khôi phục bố cục ngăn N

s r = screen restore

srr

= sr1




Bản dành cho Vim 7.4 (04b_screen_layout_VIM7.4.vim) dùng :mksession, ghi vào ~/.tmp/legacy_screen_session_N.vim và legacy_screen_data_N.vim. Khi khôi phục, buffer đang sửa dở được giữ lại; file nằm ngoài bố cục đã lưu bị gom sang một tab mới tên WAIT_CLOSE_… để bạn tự đóng — không file nào bị đóng mất.

Nguồn: AS010_VIMRC/source/04b_screen_layout_VIM7.4.vim dòng 1–30, 213–229



PHẦN V

VIM — TÌM KIẾM: HỌ F VÀ HỌ G





Chương 16 — fa · fc · fd · fˋ · gf · * — tìm từ dưới con trỏ

Đây là nhóm phím dùng nhiều nhất. Cả bốn phím đầu đều bắt đầu bằng f (find), đều lấy từ dưới con trỏ, đều gọi cùng một động cơ sfind (Chương 6) và đều mở kết quả ở cửa sổ dọc bên phải. Chúng chỉ khác nhau ở chỗ LỌC: lọc loại file nào, và có lọc riêng dòng định nghĩa hay không.

Hình 16.1. Họ F (1): A-S-D + C + L — bốn phím tìm nằm sát nhau dưới ngón tay trái.

Hình 16.2. Đường ống tìm kiếm: từ con trỏ → sfind → ~/.tmp → gf nhảy tới đúng dòng.

16.1 So sánh ba phím tìm nội dung


fa

fc

fd

Nhớ

find ALL

find COMmon

find DEFINE

Loại file

mọi file (all)

file mã/tài liệu 'com': .v .sv .vh .svh .f .list .c .cpp .h .md .txt .cfg .yaml .tcl .py .pl .sh .csh .json .xml .csv .ini .inc …

chỉ .v .sv .vh .svh .f .list .c .cpp .cc .h .hh .ini .inc

Thư mục

. (thư mục hiện tại của Vim)

. (như fa)

gnu_cmn, script, tb, testcase

Lọc thêm

không

không

chỉ giữ DÒNG KHAI BÁO: define, module, class, function, task, parameter, input/output, reg/wire/logic, typedef, property, sequence, covergroup …

Kết quả

~/.tmp/.sfindNoAnsi

~/.tmp/.sfindNoAnsi

~/.tmp/.sfindNoAnsi.fuz (mở lại bằng fˋ)

Đo trên /0_ENV với PATH_SYSAWO

414 dòng

401 dòng

3 dòng — đúng 3 file định nghĩa (sau khi sửa lỗi 16.4)



Nguồn: ~/.vimrc dòng 330–340; 00_common_func.vim FuzSearch dòng 99–145; sfind_py27.py dòng 360–363

MẸO · CHỌN PHÍM NÀO?

Muốn biết một tín hiệu được DÙNG ở đâu → fc (bỏ rác nhị phân, log). Muốn biết nó được ĐỊNH NGHĨA ở đâu → fd. Tìm cả trong log, file lạ → fa. Luôn mở Vim từ GỐC môi trường (lwd rồi vi …) vì fa/fc tìm trong thư mục hiện tại của Vim.



16.2 fa từng bước

Hình 16.3. Con trỏ trên PATH_SYSAWO, bấm fa: kết quả mở bên phải.

Số

Thành phần

Ý nghĩa

1

Từ dưới con trỏ

<cword> = PATH_SYSAWO ở dòng 2 file path_define.v.

2

##### [File 1][N1] …

Dòng tiêu đề mỗi file: số thứ tự file, tổng dòng khớp, đường dẫn tương đối.

3

[1][1_2]

Kết quả thứ 1, nằm ở File 1 dòng 2. Đặt con trỏ lên 1_2 rồi gf.



Hình 16.4. gf trên token [2_181]: mở file số 2 ở cửa sổ mới và nhảy đúng dòng 181.

Số

Thành phần

Ý nghĩa

1

Dòng đích

Vim mở sysss_clk_common_dmon.sv (File 2) ở cột thứ ba, con trỏ đứng dòng 181.



Hình 16.5. fc cùng từ: 401 dòng — ít hơn fa 13 dòng vì bỏ các file không thuộc nhóm 'com'.

16.3 gf thông minh — cầu nối từ kết quả tới mã nguồn

Con trỏ ở đâu

gf làm gì

Ghi chú

gf trên 18_25 hoặc 18:25

tìm dòng ##### [File 18] trong CHÍNH buffer kết quả, lấy đường dẫn, vsplit, nhảy dòng 25

chạy được cả trên .sfindNoAnsi lẫn .fuz

gf trên file:123 / file:123:45

vsplit file, nhảy dòng 123 cột 45

dạng thông báo lỗi của trình biên dịch

gf trên file,123,45 / file,123|45

như trên

dạng một số log

gf trên đường dẫn thường

vsplit file đó

hành vi gf quen thuộc, nhưng luôn mở cửa sổ mới



Nguồn: AS010_VIMRC/source/02_smart_gf.vim dòng 1–143

16.4 fd — chỉ dòng định nghĩa

fd chạy hai pha: pha 1 dùng sfind tìm từ trong 4 thư mục mã nguồn; pha 2 đưa kết quả qua fuz_filter.py với một regex chỉ giữ những dòng mà trước từ đó là một từ khoá khai báo (define, module, class, function, parameter, input, reg, wire, typedef, property …).

Hình 16.6. fd trên B31: cửa sổ .sfindNoAnsi.fuz rỗng.

Số

Thành phần

Ý nghĩa

1

.sfindNoAnsi.fuz

File kết quả pha 2 không được tạo nên cửa sổ trống.



LƯU Ý · FD HỎNG TRÊN MÁY CHỈ CÓ PYTHON 2.6

Vim chọn python3 nếu có, không thì python. B31 (và máy Verifier) chỉ có Python 2.6. fuz_filter.py có chú thích tiếng Việt nhưng thiếu dòng khai báo mã hoá, nên Python 2.6 dừng ngay: SyntaxError: Non-ASCII character '\xe1' … line 25, but no encoding declared. Chữa: thêm đúng một dòng vào đầu file AS010_VIMRC/source/fuz_filter.py: # -*- coding: utf-8 -*-.



Hình 16.7. Cùng thao tác sau khi thêm dòng coding (chạy bản sao đã sửa, mở bằng fˋ): còn đúng 3 dòng define.

Số

Thành phần

Ý nghĩa

1

.sfindNoAnsi.fuz

3 file, mỗi file 1 dòng ˋdefine PATH_SYSAWO … — đúng 3 nơi định nghĩa. gf trên [1_2] nhảy thẳng tới định nghĩa.



16.5 Hai phím phụ trợ

Phím

Làm gì

Ghi chú

fˋ

mở lại kết quả fd lần trước (~/.tmp/.sfindNoAnsi.fuz) ở vsplit, về dòng 1

phím dấu huyền cạnh số 1

*

tô sáng mọi chỗ có đúng TỪ dưới con trỏ, KHÔNG nhảy con trỏ

bản gốc của Vim nhảy tới chỗ kế — bản này đứng yên



Nguồn: ~/.vimrc dòng 397, 408

Chương 17 — fs · fl · ff · f1..f6 và các phím mở theo đường dẫn

Nếu Chương 16 là tìm theo NỘI DUNG, chương này là tìm và mở theo ĐƯỜNG DẪN. Nguồn dữ liệu chính là list.txt do showList sinh ở gốc môi trường (Chương 6).

17.1 fs — tìm đường dẫn dưới con trỏ trong list.txt

Đứng trên một đường dẫn tương đối (thường là dòng include), fs bỏ các tiền tố ./ và ../ rồi grep trong ./list.txt. Số kết quả quyết định hành vi:

Số kết quả

fs làm gì

0

báo vàng: fs: "…" not found in list.txt

1

mở luôn ở vsplit, về đầu file

2 .. 9

in danh sách, file sửa gần nhất ở trên, hỏi Select [1-N] (0 = huỷ)

> 9

mở buffer tạm (không lưu) chứa danh sách, tô sáng phần khớp



Hình 17.1. fs trên ../../testcase/common/path_define.v: 1 kết quả — mở luôn.

Số

Thành phần

Ý nghĩa

1

Đường dẫn dưới con trỏ

fs bỏ ../../ còn testcase/common/path_define.v.

2

File được mở

Chỉ 1 dòng khớp trong list.txt nên mở thẳng ở vsplit.



Hình 17.2. fs trên ../tb_uvm.sv: 3 kết quả, xếp theo thời gian sửa, chờ chọn số.

Số

Thành phần

Ý nghĩa

1

fs: found 3 matches

Tìm thấy 3 dòng chứa tb_uvm.sv (gồm cả liên kết mềm và file thư viện).

2

Select [1-3]

Gõ số rồi Enter để mở, 0 để huỷ.



17.2 fl — tìm log theo từ

fl lấy TỪ dưới con trỏ (không phải đường dẫn), grep trong ./list.txt, rồi xoá mọi dòng không kết thúc bằng .log. Kết quả mở trong buffer tạm (nofile) bên phải, phần khớp được tô sáng. Đứng lên một dòng rồi gf để mở log.

Hình 17.3. fl trên ASVMON_5: danh sách file .log của lần chạy regress ASVMON_5.

Số

Thành phần

Ý nghĩa

1

Từ dưới con trỏ

ASVMON_5.

2

Danh sách log

Mỗi dòng một đường dẫn .log lấy từ list.txt.



17.3 ff, f1..f6 — file ghim sẵn

Hình 17.4. Họ F (2) — f + số: file ghim sẵn trong $lwd; họ G: mở đường dẫn dưới con trỏ.

Phím

Mở (vsplit)

Ghi chú

ff · f1

$lwd/list.txt

danh sách file của môi trường

f2

$lwd/testcase/usr/test/vmon/usr_sysss_as_vmon_test_lib.sv

thư viện test VMON

f3

$lwd/testcase/usr/top/vmon/usr_top_sysss_as_vmon_vseq_lib.sv

thư viện virtual sequence VMON

f4

$lwd/gnu_cmn/rv32i/include/defines.h

define phía C

f5

$lwd/debug.log rồi nhảy xuống cuối

log mới nhất

f6

$lwd/testcase/common/path_define.v

đường dẫn hierarchy



Hình 17.5. ff sau khi setenv lwd /0_ENV: list.txt mở bên phải.

Số

Thành phần

Ý nghĩa

1

/0_ENV/list.txt

39 916 dòng. Trên máy thật, sửa 6 đường dẫn f2..f6 cho đúng dự án của bạn trong .vimrc dòng 398–404.



LƯU Ý · CẦN BIẾN MÔI TRƯỜNG LWD

Như Chương 5: swd chỉ đặt biến shell. Không setenv lwd … trước khi mở Vim thì ff mở /list.txt (sai).



17.4 Mở theo đường dẫn dưới con trỏ — họ G và họ O

Phím

Làm gì

Mẹo nhớ

gf

mở file (xem 16.3)

go file

gr

mở file ở vsplit CHỈ ĐỌC

go read-only — xem mà không sợ sửa nhầm

gd

mở THƯ MỤC chứa file dưới con trỏ (netrw) ở vsplit

go directory — che mất 'go to definition' gốc

fe

mở thư mục chứa FILE ĐANG MỞ ở vsplit

file explorer

of

ghi đường dẫn tuyệt đối của file đang mở vào ~/.tmp/of

o f = output file

oof

mở file có đường dẫn trong ~/.tmp/op

HỎNG cặp: xem dưới

ocf

mở đường dẫn trong ~/.tmp/cf (thường do alias tcsh cf ghi)

open cf

ccf

chép đường dẫn tuyệt đối của file ĐANG MỞ vào thanh ghi " (và * + nếu có clipboard)

copy current file

cf

chép đường dẫn tuyệt đối của file DƯỚI CON TRỎ vào thanh ghi " (* +)

copy file-under-cursor

swd0 .. swd5

ghi THƯ MỤC của file dưới con trỏ vào ~/.tmp/swdN

cùng ngăn với alias tcsh



LƯU Ý · HAI PHÍM LỆCH NHAU

(1) of ghi ~/.tmp/of nhưng oof đọc ~/.tmp/op (.vimrc dòng 257–258) — dùng oof sau of sẽ báo Not found. Muốn chuyển file giữa hai Vim: ccf ở Vim này rồi :vs + dán (Ctrl+R ") ở Vim kia. (2) cf được map hai lần: dòng 255 (ghi ~/.tmp/cf) và dòng 420 (chép thanh ghi). Vim giữ bản SAU, nên cf hiện chỉ chép vào thanh ghi; ocf chỉ còn dùng được với giá trị do alias tcsh cf ghi (là một THƯ MỤC).



17.5 Tạo / chép / xoá file ngay từ Vim

Phím

Làm gì

Mẹo nhớ

touch

tạo thư mục cha + file rỗng theo đường dẫn dưới con trỏ

gõ 5 chữ t-o-u-c-h

mcp

chép file dưới con trỏ vào ~/.tmp/.vimMarkCopy

mark copy

mpst

dán file đã mcp ra đường dẫn dưới con trỏ (tạo thư mục nếu thiếu)

mark paste

mrmrmrm

rm -rdf đường dẫn dưới con trỏ

NGUY HIỂM — gõ dài cố ý

emcp

mở file đang sửa bằng emacs và chép toàn bộ vào clipboard

cần emacs

csf

xoá các file swap CŨ của buffer này, giữ swap đang dùng

clean swap files



NGUY HIỂM · MRMRMRM KHÔNG QUA THÙNG RÁC

Phím gọi \rm -rdf — dấu \ bỏ qua alias, xoá thật, không hỏi. Chữ 'rm' lặp 3 lần là để không thể gõ nhầm.



Nguồn: ~/.vimrc dòng 219–233, 255–258, 301, 393, 411–420; 00_common_func.vim dòng 147–190, 454–555



PHẦN VI

VIM — SO SÁNH: DFF · DGG · VD · VV · TT · VDL · ZZZ





Chương 18 — Bản đồ so sánh — chọn phím theo câu hỏi 'so với cái gì?'

Có tới 25 phím và 3 lệnh so sánh, nhưng tất cả trả lời cùng MỘT câu hỏi: file này so với cái gì? Đi theo cây dưới đây là chọn được phím.

Hình 18.1. Cây quyết định: câu hỏi → phím → nơi hiển thị.

Nhóm

Phím

Hiển thị ở đâu

Cửa sổ trái / phải

Bản đĩa

dff

tab mới [DIFF] trong Vim

buffer đang sửa / nội dung trên đĩa

Git HEAD

dgg

tab mới [GIT] trong Vim (Vim 8)

buffer / git show HEAD:file

Git HEAD~N

vdd vd0..vd5

vimdiff ngoài (git difftool), :qa để quay lại

bản HEAD~N / file hiện tại

Git tự chọn

vdc

như trên, sau khi chọn commit

commit chọn / file hiện tại

Môi trường khác

vv0..vv5 vvv

tab mới [DIFF] trong Vim

file ở đây / cùng đường dẫn trong $lwdN (read-only)

Xem môi trường khác

tt0..tt5 ttt

vsplit read-only, không diff

—

2 file trong buffer

vdl · :VDL · :VDLR

vimdiff ngoài

file 1 / file 2 (VDLR: chỉ một đoạn dòng)

2 thư mục

diff2 (tcsh) → zzz

vimdiff ngoài

file bên A / bên B

3 thư mục

AS014 S4 → zzz

vimdiff ngoài

cũ↔mới hoặc mới↔git tuỳ file kết quả



18.1 Trong khi đang ở màn hình diff

Các phím sau là phím GỐC của Vim — không nằm trong .vimrc — nhưng cần cho mọi màn hình ở phần này:

Phím

Làm gì

Mẹo nhớ

]c · [c

nhảy tới khối khác tiếp theo / trước đó

c = change

do · dp

diff obtain: lấy khối từ bên kia sang · diff put: đẩy khối sang bên kia

o = obtain, p = put

:diffupdate

tính lại diff sau khi sửa tay


zo · zc

mở / gập vùng giống nhau bị gập


Ctrl+W W · Ctrl+H/L

chuyển giữa hai bên

Ctrl+H/L là phím của .vimrc

:qa

thoát vimdiff ngoài để quay về Vim gốc

với vdd/vd*/vdc/zzz

tqq

đóng tab diff, tự về tab gọi

với dff/dgg/vv*



Chương 19 — So với bản cũ của chính file: dff · dgg · vdd · vd0..vd5 · vdc

Hình 19.1. d = diff trong tab; vd + số = vimdiff với HEAD~số.

19.1 dff — đã sửa gì từ lần lưu cuối?

Trước khi ww, bấm dff để xem lại mọi thay đổi chưa lưu. Vim mở tab mới tên [DIFF] <tên file>: bên trái là buffer đang sửa, bên phải là nội dung đọc lại từ đĩa (buffer tạm, không lưu).

Hình 19.2. Thêm 1 dòng 'wire busy;' chưa lưu rồi bấm dff.

Số

Thành phần

Ý nghĩa

1

Tab [DIFF] fifo_ctrl.sv

Tab mới T2 có 2 cửa sổ; tab T1 vẫn giữ nguyên.

2

wire busy;

Dòng thêm mới — phía đĩa hiện một dải gạch ngang ở đúng chỗ.



19.2 dgg — so với Git HEAD (chỉ Vim 8)

Hình 19.3. dgg trên Vim 7.4: lỗi E117 trim.

Số

Thành phần

Ý nghĩa

1

E117: Unknown function: trim

Hàm GLDiffGitTab dùng trim() — có từ Vim 8.0.1630.



LƯU Ý · DÙNG VDD THAY DGG TRÊN MÁY VERIFIER

Ngoài trim(), hàm còn gọi git -C <dir> — git 1.7.1 trên B31 chưa có tuỳ chọn -C (có từ git 1.8.5). Trên máy Vim 7.4 hãy dùng vdd (cùng ý nghĩa: so với HEAD, hiển thị bằng vimdiff ngoài).



19.3 vdd, vd0..vd5 — lùi N commit

Đặt con trỏ lên tên file (trong một danh sách, trong git status đã chép ra, hoặc chính tên file trong buffer) rồi gõ vd + số. Vim chạy git difftool -t vimdiff --no-prompt HEAD~N -- <file> ở shell, mở vimdiff toàn màn hình; :qa để quay lại.

Hình 19.4. vd1 trong repo mẫu: trái = HEAD~1 (chưa có 'empty'), phải = bản đang làm việc.

Số

Thành phần

Ý nghĩa

1

DEPTH = 32

Thay đổi đang làm chưa commit hiện ở bên phải.



19.4 vdc — chọn commit từ git log

Hình 19.5. vdc trên B31: lịch sử hiện ra nhưng kết thúc bằng 'No commit ID provided.'

Số

Thành phần

Ý nghĩa

1

No commit ID provided.

Phím Enter thừa của mapping đã trả lời thay bạn câu hỏi 'Enter commit ID'.



LƯU Ý · VDC TỰ TRẢ LỜI RỖNG — GỌI HÀM TRỰC TIẾP

Mapping là :call GitLogAndDiffSilent()<CR><CR>. Enter thứ hai nằm sẵn trong hàng đợi phím nên input() đọc nó ngay → chuỗi rỗng. Dòng echo "0 gõ dở trong hàm còn sinh thêm E15. Cách dùng đúng hiện nay: gõ :call GitLogAndDiffSilent() rồi Enter.



Hình 19.6. Gọi trực tiếp: danh sách commit của file và dấu nhắc chờ nhập.

Số

Thành phần

Ý nghĩa

1

Recent changed for

git log --oneline chỉ của file dưới con trỏ.

2

=> Enter commit ID

Gõ (hoặc dán) mã commit, Enter.



Hình 19.7. Nhập 28560d3 (commit đầu tiên): vimdiff bản v1 với bản đang làm.

Số

Thành phần

Ý nghĩa

1

DEPTH = 8

Giá trị ở commit v1.



Nguồn: AS010_VIMRC/source/06_inline_vimdiff.vim dòng 1–125; 00_common_func.vim GLDiffOrigTab, GLDiffGitTab

Chương 20 — So với nơi khác: vv · tt · vdl · :VDL · :VDLR · zzz

Hình 20.1. vv + số = diff với cùng file trong $lwdN; tt + số = chỉ xem; zzz = diff từ kết quả diff2.

20.1 vv0..vv5 — cùng file ở môi trường khác

Tình huống quen thuộc: hai bản môi trường (bản của bạn và bản release, bản trước và bản sau vendor drop) có cùng cấu trúc thư mục. Lưu gốc môi trường kia vào ngăn 1 (swd1 ở tcsh, rồi setenv lwd1 …), mở một file bất kỳ ở môi trường này và bấm vv1: Vim ghép $lwd1 + đường dẫn tương đối của file và mở tab diff.

Hình 20.2. vv1 trên path_define.v với $lwd1 = /tmp/ENV_B.

Số

Thành phần

Ý nghĩa

1

Tab [DIFF] path_define.v

Tab mới; khi đóng (tqq) sẽ quay về tab gọi.

2

Dòng khác

Dòng 3 ở ENV_B bị thay — tô màu DiffChange/DiffText. Bên phải có cờ RO (chỉ đọc).



Nếu con trỏ đang đứng trên một đường dẫn tồn tại, vv/tt dùng đường dẫn đó thay cho file đang mở — tiện khi đang xem một danh sách file.

Hình 20.3. tt1: chỉ mở bản ở $lwd1 cạnh bên, chỉ đọc, không diff.

Số

Thành phần

Ý nghĩa

1

VERILOG RO

Thanh trạng thái có RO — không sửa nhầm được bản tham chiếu.



Phím

Làm gì

Mẹo nhớ

vv0 .. vv5

tab diff với $lwd0..$lwd5/<cùng đường dẫn>

vv = vimdiff

vvv

= vv5

gấp ba = ngăn cuối

tt0 .. tt5

vsplit read-only $lwdN/<cùng đường dẫn>

tt = tham khảo

ttt

= tt5




20.2 vdl, :VDL, :VDLR — hai file có đường dẫn nằm trong buffer

Phím / lệnh

Ý đồ

Trên B31

vdl

hỏi 'Compare with line number:', so file dưới con trỏ với file ở dòng đó

HỎNG — xem dưới

:VDL 7 14

so file có đường dẫn ở dòng 7 với file ở dòng 14

HỎNG — E488

:VDLR 15 10,20 50 30,40

so ĐOẠN dòng 10..20 của file ở dòng 15 với đoạn 30..40 của file ở dòng 50

HỎNG — E488



Hình 20.4. vdl: câu hỏi bị Enter thừa trả lời ngay → Invalid line number.

Số

Thành phần

Ý nghĩa

1

Invalid line number:

Cùng lỗi <CR><CR> như vdc.



LƯU Ý · HAI LỖI CHỒNG NHAU Ở NHÓM VDL

(1) Mapping vdl thừa <CR> như vdc. (2) Cả ba hàm ghép lệnh thiếu dấu cách: '!vimdiff ' . jumpTopCmd . shellescape(file1) tạo ra -c "windo call cursor(1, 1)"'AAA/b.txt' → Vim báo E488: Trailing characters (đã thử gọi thẳng :call VdlCompare() trên B31). Chữa: thêm . ' ' . giữa jumpTopCmd và tên file ở 3 chỗ trong 06_inline_vimdiff.vim. Trong lúc chờ sửa, gõ tay :!vimdiff file1 file2.



20.3 zzz — mở vimdiff từ một dòng kết quả diff2 / AS014

Sau diff2 A B (Chương 8), mở ~/.tmp/diff2_result.txt, đặt con trỏ lên dòng < …, | … hoặc > … và bấm zzz. Hàm DiffAB bỏ ký hiệu đầu dòng, đọc gốc A/B từ ~/.tmp/diff2_A.txt và diff2_B.txt, ghép đường dẫn tương đối rồi chạy vimdiff. File chỉ có một bên thì so với /dev/null. Nếu buffer là một file AS014_OUT_*_1vs2 / _2vs3, gốc được đọc từ AS014_PATH_1..3.txt tương ứng.

Hình 20.5. ~/.tmp/diff2_result.txt trong Vim — mỗi dòng là một cặp file có thể zzz.

Số

Thành phần

Ý nghĩa

1

< AAA/a.txt

zzz → vimdiff a.txt với /dev/null (chỉ có ở A).

2

| AAA/b.txt

zzz → vimdiff AAA/b.txt với BBB/b.txt.

3

> BBB/d.txt

zzz → vimdiff /dev/null với d.txt (chỉ có ở B).



Hình 20.6. zzz trên dòng | AAA/b.txt: vimdiff hai bản b.txt, con trỏ về dòng 1 ở cả hai bên.

Nguồn: 00_common_func.vim DiffAB dòng 379–448, GLOpenRef dòng 655–720; ~/.vimrc dòng 376–391

MẸO · CÔNG THỨC ĐẦY ĐỦ SO HAI BẢN MÔI TRƯỜNG

tcsh: cd <bản B>; swd1 → setenv lwd1 <bản B> → cd <bản A>; diff2 . $lwd1 → vi ~/.tmp/diff2_result.txt → zzz từng dòng; hoặc mở một file bất kỳ ở A rồi vv1. Xem Chương 25, kịch bản 3.





PHẦN VII

VIM — SOẠN THẢO: COMMENT, CHÉP VÀ THAY, CHẠY SCRIPT





Chương 21 — Comment: caa · css · cdd · ccc · ngăn 1..5 · Ctrl+/

Hình 21.1. A-S-D từ trái sang phải = đầu dòng → sau thụt lề → cuối dòng.

Tiền tố comment mặc định lấy theo loại file (// cho Verilog/SV/C, # cho Python/shell…). Có thêm 5 ngăn để lưu tiền tố riêng như //DEBUG hay //TODO_DUNG , rất tiện khi cần đánh dấu rồi gỡ đúng những dòng đó.

Phím

Làm gì

Mẹo nhớ

caa

THÊM comment mặc định ở CỘT 0 (tuyệt đối)

a — phím trái nhất = đầu dòng

css

THÊM comment mặc định sau phần thụt lề

s — giữa = sau khoảng trắng đầu dòng

cdd

THÊM comment mặc định ở CUỐI dòng

d — phải = cuối

ca1..ca5 · cs1..cs5 · cd1..cd5

như trên nhưng dùng tiền tố ngăn 1..5

chữ lặp → số ngăn

ccc

XOÁ comment mặc định (ở mọi vị trí trên)

c c c = clear

cc1..cc5

XOÁ comment của ngăn 1..5


Ctrl+/

BẬT/TẮT: dòng chưa comment → thêm ở cột 0; đã comment (ở bất kỳ thụt lề nào) → gỡ

một phím cho thói quen IDE

cvv

in nội dung 5 ngăn + hướng dẫn gán

view

:CommentSet N tiền_tố

gán tiền tố cho ngăn N, lưu vào ~/.vim/CommentSlots.txt

vd :CommentSet 1 //DEBUG

:CommentReset N · :CommentShow

xoá ngăn N · như cvv




Mọi phím comment chạy cả ở Visual mode: chọn nhiều dòng bằng V rồi css là comment cả khối, giữ nguyên thụt lề.

Hình 21.2. Dòng 2 caa, dòng 3 css, dòng 4 cdd, dòng 7 cs1 với ngăn 1 = //DEBUG.

Số

Thành phần

Ý nghĩa

1

caa

// dính sát cột 0, thụt lề giữ phía sau.

2

css

// chèn sau 2 dấu cách thụt lề.

3

cs1

Tiền tố ngăn 1 //DEBUG chèn sau thụt lề (dòng 7).



Hình 21.3. cvv: 5 ngăn và hướng dẫn gán.

Số

Thành phần

Ý nghĩa

1

Slot1: "//DEBUG "

Ngăn 1 đã gán; ngăn 2..5 trống.



Hình 21.4. Sau ccc trên dòng 2 và cc1 trên dòng 7: chỉ comment của đúng loại đó bị gỡ.

GHI CHÚ · THÊM LÀ THÊM, XOÁ LÀ XOÁ

caa css cdd KHÔNG bật/tắt: gõ hai lần là hai tiền tố (//DEBUG//DEBUG). Muốn gỡ dùng ccc / cc1..5. Chỉ Ctrl+/ là phím bật/tắt. Thiết kế này giúp gỡ đúng loại comment mình đã thêm mà không đụng comment gốc của file.



LƯU Ý · :COMMENTSET BÁO E482 TRÊN MÁY MỚI

Ngăn được lưu vào ~/.vim/CommentSlots.txt. B31 chưa có thư mục ~/.vim nên :CommentSet in E482: Can't create file /root/.vim/CommentSlots.txt (ngăn vẫn gán trong phiên hiện tại, chỉ không nhớ sang lần sau). Chữa một lần: mkdir -p ~/.vim.



Nguồn: AS010_VIMRC/source/01_toggle_comment.vim dòng 1–70, 165–200, 370–411

Chương 22 — Chép và thay: cw → rw / ra / :RL

Hình 22.1. c = copy, r = replace; w = word, a = all, f = file path.

Bộ này giải quyết việc Vim thường làm vụng: đổi tên một tín hiệu ở nhiều nơi, qua nhiều file, nhiều cửa sổ, thậm chí nhiều phiên Vim. Bí quyết: từ được chép vào một FILE (~/.tmp/yiw), không chỉ vào thanh ghi.

1. Đặt con trỏ lên tên MỚI (ví dụ clk_div_new) — bấm cw. Từ được ghi vào ~/.tmp/yiw, thanh ghi a, " (và * + nếu có clipboard); dòng lệnh in lại từ đó.

2. Đi tới chỗ có tên CŨ, đặt con trỏ lên nó:

3. rw — thay đúng từ đó (như ciw + dán).

4. ra — thay MỌI chỗ có nguyên từ đó trong file (:%s/\<cũ\>/mới/g).

5. :RL 13,200 — chỉ thay trong dòng 13..200; ^ = dòng đầu, $ = dòng cuối (vd :RL ^,$, :RL 50,$). Con trỏ được trả về dòng ban đầu.

Phím

Làm gì

Mẹo nhớ

cw

chép từ dưới con trỏ → ~/.tmp/yiw + thanh ghi a " * +

copy word

rw

thay từ dưới con trỏ bằng nội dung ~/.tmp/yiw

replace word

ra

thay tất cả (nguyên từ) trong file

replace all

:RL x,y

thay trong dòng x..y

Replace Lines

cf · ccf

chép đường dẫn file dưới con trỏ / file đang mở

Chương 17

Y

chép tới cuối dòng




LƯU Ý · CW VÀ CL ĐÃ THAY LỆNH GỐC

Trong Vim gốc cw = 'change word' (xoá từ rồi vào Insert). Ở đây cw chỉ CHÉP. Muốn đổi từ kiểu gốc, dùng ciw hoặc ce. Tương tự rw/ra không còn là 'thay 1 ký tự bằng w/a' — dùng r + ký tự khác hoặc s.



Nguồn: AS010_VIMRC/source/05_copyword_replace_cwrwra.vim dòng 1–82

Chương 23 — Chạy script từ Vim: F5 SmartRun và các phím nhỏ

Phím

Làm gì

Mẹo nhớ

F5

lưu buffer nếu đã sửa; nếu con trỏ đứng trên một file .csh/.py tồn tại → chạy file đó; không thì chạy chính file đang mở (.csh → csh, .py → pythonVer); xoá màn hình trước khi chạy

Smart Run

csh

chỉ in nhắc 'Please Use SmartRun <F5>'

chặn thói quen cũ

csf

dọn file swap cũ của buffer (Chương 17)

clean swap files

cch

in nhắc nhanh các phím completion

code completion help

\all · \help

liệt kê mọi lệnh build / trang hướng dẫn đã đăng ký

Chương 24



GHI CHÚ · F5 TRÊN MÁY VERIFIER

F5 gọi pythonVer bằng :! — tức là qua shell con. Alias pythonVer chỉ có khi shell con đọc .cshrc; với tcsh mặc định thì có. Nếu thấy pythonVer: Command not found, chạy tay :!python %.



Nguồn: AS010_VIMRC/source/03_smart_run.vim dòng 1–65



PHẦN VIII

VIM — GỢI Ý CODE (MODULE 09)





Chương 24 — Code completion cho SV / UVM / C: Tab, F6, \all_09, cl, ep

Hình 24.1. Leader \ = build DB; Tab = gợi ý; cl / ep = rút gọn / bung đường dẫn.

Hình 24.2. Bốn cơ sở dữ liệu và việc mà từng DB phục vụ.

24.1 Ba điều cần nhớ

1. Lần đầu (và sau khi mã thay đổi nhiều): Normal mode gõ \all_09 — build project.tags, project.hier, project.pathmap, project.hdlmap. Theo tài liệu module: tags ~30 s, pathmap ~20 s, hdlmap ~30 s với 2000+ file.

2. Gõ code, bấm Tab để gợi ý. F6 để popup tự bật khi gõ.

3. Quên lệnh: \help_09, hoặc \all / \help để liệt kê mọi module đã đăng ký.

Hình 24.3. \help_09: bảng lệnh và ví dụ in ngay trong Vim.

Hình 24.4. \all (đợi 3 giây): liệt kê các lệnh build-tất-cả đã đăng ký — hiện có \all_09.

Số

Thành phần

Ý nghĩa

1

[\all] …

Danh sách để khỏi nhớ tên. Module mới chỉ cần đăng ký, không phải sửa file 00.



24.2 Phím trong Insert mode

Phím

Làm gì

Ghi chú

Tab

gợi ý thông minh: tên symbol, đường dẫn phân cấp, define, chuỗi UVM; khi popup đang mở = xuống


Shift+Tab · ↑

lên trong popup


↓

xuống trong popup


→ · ←

sang trang sau / trước trong popup

PageDown / PageUp

Enter

chọn mục đang sáng (không xuống dòng)


Ctrl+Space

ép bung popup


F6

bật/tắt auto-popup

cũng dùng được ở Normal



Hình 24.5. Gõ PATH_SYSA rồi Tab: 169 gợi ý, nhãn [v] = thế giới Verilog.

Số

Thành phần

Ý nghĩa

1

PATH_SYSA

Tiền tố đang gõ; dòng dưới cùng báo match 1 of 169.



24.3 Các dạng gõ đặc biệt

Bạn gõ

Được gì

tên<Tab>

symbol khớp (substring; bật fuzzy vì g:cc_fuzzy = 1 và từ 5 ký tự trở lên)

top.dut.<Tab>

con của instance theo cây phân cấp thật (instance trước, signal sau)

ˋPATH_X.<Tab>

dịch define Verilog → đường dẫn thật → liệt kê con

"sysctl.<Tab>

trong chuỗi UVM: dịch hdl-key → đường dẫn → liệt kê con

PATH_SYS<Tab>

chèn ˋPATH_SYSCTL — tự thêm dấu huyền cho define

pr@<Tab> · f@init<Tab>

chỉ một LOẠI symbol: pr property, f function, p parameter, d define, seq, tsk, if, mod, cl, var …

@@<Tab>

liệt kê mọi loại lọc kèm tên đầy đủ; chọn một → tự thành 'loại@' và bung luôn



Hình 24.6. @@ rồi Tab: danh sách các loại lọc (d@, prg@, var@ …).

24.4 cl / ep — rút gọn và bung đường dẫn (Normal mode)

Đặt con trỏ trên một đường dẫn phân cấp. cl (collapse) liệt kê các cách viết NGẮN hơn dùng define (ngoài chuỗi) hoặc hdl-key (trong chuỗi "…"); ep (expand) làm ngược lại tới đường dẫn tuyệt đối.

Hình 24.7. cl trên top.dut.systop.SYSCTL.sysawo.cggtop_awo.adc_div.CLK: 3 lựa chọn.

Thành phần menu

Ý nghĩa

[cc] Page 1/1 · num+<Enter> · <Space>/n · p · <Esc>/q

trang hiện tại · chọn bằng số rồi Enter · trang sau · trang trước · huỷ

1. [2|6] ˋDUT.systop… [common_define_hierarchy.v]

[x|y]: rút x cấp bằng define, còn y cấp; cột phải là file định nghĩa define

3.*[0|8] top.dut…

dấu * = cách viết hiện tại (không rút)

> select num (1-3):

gõ số để thay đường dẫn trong dòng



24.5 Lệnh build (Normal mode, leader = \)

Phím

Làm gì

Ghi nhớ

\all_09

build cả 4 DB

dùng cái này là đủ

\tg

chỉ project.tags

tags

\hr

project.hier (+ gộp Verdi nếu có verdi_hier.txt) + pathmap + hdlmap

hierarchy

\hp

chỉ project.pathmap (define ↔ đường dẫn)

pathmap

\hh

chỉ project.hdlmap (hdl-key UVM ↔ đường dẫn)

hdlmap

\help_09 · cch

hướng dẫn đầy đủ · nhắc 1 dòng




24.6 Cấu hình trong .vimrc

Biến

Giá trị hiện tại

Ý nghĩa

g:PRJ_DIR

/design04/rcaru5l4_fed/u5l4/usr/CME/trandung/U5L8_Env

gốc dự án — SỬA cho máy của bạn

g:cc_scan_root

0

\tg chỉ quét g:cc_inc_dirs (1 = quét cả gốc)

g:cc_db

g:PRJ_DIR/project.tags

nơi ghi/đọc DB tags

g:cc_inc_dirs

gnu_cmn, testcase, tb

thư mục quét; phần tử đầu ưu tiên cao nhất trong popup

g:cc_fuzzy · _minlen · _cap

1 · 5 · 150

fuzzy từ 5 ký tự, chấm tối đa 150 ứng viên

g:cc_bufscan_max

2000

buffer > 2000 dòng chỉ quét quanh con trỏ

g:cc_bufscan_skip

.txt .log .list .csv .tsv .md .out .json .xml .dat

không lấy từ trong các buffer dữ liệu

g:cc_complete

'.,w,u,t'

bỏ nguồn 'b' để list.txt mở ẩn không lọt vào gợi ý

g:cc_kind_sep · g:cc_kind_filter

'@' · 1

cú pháp loại@từ



LƯU Ý · TRÊN B31 PHẢI CHỈ LẠI G:CC_DB

g:PRJ_DIR trỏ tới /design04/… của máy thật. Để chụp Hình 24.5 trên B31 tôi gõ :let g:cc_db='/0_ENV/project.tags'. Trên máy của bạn: sửa g:PRJ_DIR ở .vimrc dòng 41 rồi \all_09.



GHI CHÚ · VERDI LÀM CÂY PHÂN CẤP CHUẨN 100%

Parser tĩnh không tính được ifdef / generate-if, nên có thể sinh 'instance ma' của cả hai nhánh. Trên máy có Verdi + license: trong console Tcl của Verdi gõ source ~/A0_scripts/AS010_VIMRC/source/09_extract_verdi_hier.tcl → ra 0_ENV/verdi_hier.txt → về Vim gõ \hr để gộp. Xem Phụ lục E.



Nguồn: ~/.vimrc dòng 1–101; AS010_VIMRC/source/09_README.md; 09_code_completion.vim dòng 2319–2399, 2860–2926



PHẦN IX

KẾT HỢP CÁC HỌ PHÍM — KỊCH BẢN LÀM VIỆC THẬT





Chương 25 — Sáu kịch bản nối tcsh ↔ Vim ↔ A0_scripts

Mỗi phím đơn lẻ chỉ tiết kiệm vài giây. Sức mạnh nằm ở CHUỖI phím. Sáu kịch bản dưới đây gom những chuỗi dùng nhiều nhất; mỗi bước ghi rõ đang ở tcsh hay Vim.

Kịch bản 1 — Tín hiệu này định nghĩa ở đâu, được dùng ở đâu?

1. tcsh: lwd (về gốc môi trường) → vi testcase/…/file.sv.

2. Vim: con trỏ lên tên tín hiệu → fd → cửa sổ phải chỉ còn dòng định nghĩa (cần sửa lỗi 16.4 trên máy Python 2.6).

3. Vim: con trỏ lên token [1_2] → gf → mở đúng file, đúng dòng định nghĩa.

4. Vim: quay về (Ctrl+H), cùng từ → fc → mọi nơi dùng tín hiệu trong file mã nguồn.

5. Vim: * để tô sáng từ trong file đang đọc; sf phóng to cửa sổ kết quả, sa trả lại.

Kịch bản 2 — Đổi tên tín hiệu trên nhiều file

1. Vim: con trỏ lên tên MỚI → cw (vào ~/.tmp/yiw).

2. Vim: fc trên tên CŨ → danh sách file; gf từng kết quả.

3. Mỗi file: con trỏ lên tên cũ → ra (cả file) hoặc :RL 100,250 (một đoạn) → dff xem lại → ww.

4. Trước khi commit: vdd trên tên file để so với HEAD lần cuối.

Kịch bản 3 — So hai bản môi trường (bản của mình và bản release)

1. tcsh: cd <bản release> → swd1 → setenv lwd1 <bản release>.

2. tcsh: cd <bản của mình> → swd → diff2 . $lwd1.

3. tcsh: vi ~/.tmp/diff2_result.txt → Vim: zzz trên từng dòng |, :qa để quay lại danh sách.

4. Hoặc đang sửa một file bất kỳ: vv1 → tab [DIFF] với bản release; do / dp lấy/đẩy khối; tqq về tab cũ.

5. Chỉ muốn liếc bản release: tt1 (read-only).

Kịch bản 4 — Chạy regression và đọc kết quả

1. tcsh: soạn run_list → run_all sim 4 (4 phiên screen song song).

2. tcsh: ss xem phiên; sw xem màn hình mọi phiên cùng lúc; sf mở log đầy đủ.

3. Xong: sum → sim_result.txt (danh sách lỗi biên dịch + FAIL, không mã màu).

4. Vim: vi sim_result.txt → con trỏ lên tên testcase → fl → danh sách log → gf → ee để nạp lại log đang ghi.

Kịch bản 5 — Nhận bản vendor drop mới

1. tcsh: AS014_GitVendorDrop.S4_Quick_3Dir_Update <drop cũ> <drop mới> <git>.

2. Vim: mở AS014_OUT_4_FILTER_diff2_result_2vs3.txt → zzz trên từng dòng (tự đọc AS014_PATH_2/3).

3. Giải xung đột xong: AS014_GitVendorDrop.S3_push_with_message_tag <nhánh> "msg" <tag>.

Kịch bản 6 — Soạn một khối debug rồi gỡ sạch

1. Vim: :CommentSet 1 //DBG_DUNG (một lần; lưu vào ~/.vim).

2. Chọn các dòng muốn tắt tạm bằng V → cs1.

3. Test xong: chọn lại khối → cc1 — chỉ gỡ tiền tố //DBG_DUNG, comment gốc giữ nguyên.



PHẦN X

BẪY, LỖI VÀ BÀI THỰC HÀNH





Chương 26 — Phím gốc của Vim đã bị thay

Bộ phím được chọn để NGẮN, nên nhiều phím trùng lệnh gốc của Vim. Biết trước để khỏi bất ngờ khi đọc tài liệu Vim chuẩn hoặc làm việc trên máy người khác (không có .vimrc này).

Phím

Lệnh gốc của Vim

Ở đây là

Muốn dùng lệnh gốc

f + a c d e f l s ˋ 1..6

nhảy tới ký tự đó trên dòng

họ tìm / mở

dùng t + ký tự rồi l, hoặc /

cw

change word

chép từ

ciw · ce

cl

change ký tự (= s)

collapse đường dẫn

s

cc (tiền tố)

change cả dòng

cc chờ 3 s vì còn ccc/cc1..5/ccf/cch

S

rw · ra

thay 1 ký tự bằng w / a

replace từ

r + ký tự khác

qq

ghi macro vào thanh ghi q

thoát

qa, qw … (thanh ghi khác)

gd

đi tới định nghĩa cục bộ

mở thư mục

fd

gr

thay ký tự ảo

mở read-only

—

t1..t9 · tt*

nhảy tới trước ký tự 1..9 / t

tab / tham khảo

—

sa · sf · ss · sr

s = xoá ký tự rồi Insert

bố cục

cl gốc đã bị chiếm nên dùng xi

ww · ee · wq

hai lần chuyển từ

ghi / nạp lại / ghi-thoát

2w · 2e

dff · dgg

xoá tới chữ f / xoá tới đầu file

diff tab

thận trọng (xem dưới)

vdd · vd0..5

vào Visual rồi …

vimdiff git

—

zzz

zz = cuộn dòng về giữa

diff dòng diff2

zz vẫn dùng được (chờ 3 s)

of · ocf · oof

o = mở dòng mới dưới rồi gõ f …

đường dẫn

o rồi đợi 3 s

*

tìm từ và NHẢY

chỉ tô sáng

* rồi n

Y

chép cả dòng (= yy)

chép tới cuối dòng

yy

Tab · Shift+Tab

Tab = Ctrl+I (nhảy tới)

đổi cửa sổ

Ctrl+I không còn

Ctrl+H/J/K/L

trái / xuống / … (con trỏ)

đổi cửa sổ

h j k l

Ctrl+Z

đẩy Vim xuống nền

không làm gì

:suspend

Space

sang phải 1 ký tự

dấu hai chấm

l



NGUY HIỂM · DGG TRÊN MÁY KHÔNG CÓ .VIMRC = XOÁ NỬA FILE

Ở Vim gốc, dgg nghĩa là 'xoá từ dòng hiện tại lên đầu file'. Nếu bạn quen tay gõ dgg trên một máy/phiên chưa nạp .vimrc này (hoặc sau :set all&), nó xoá thật. Gặp thì u ngay. Tương tự dff xoá tới chữ f kế tiếp.



MẸO · ĐỢI 3 GIÂY LÀ LẤY LẠI LỆNH GỐC

Khi một phím chỉ là TIỀN TỐ (vd zz, cc), gõ xong đứng yên 3 giây — Vim chạy lệnh gốc. Khi phím là mapping trọn vẹn (vd cw, qq), lệnh gốc mất hẳn; dùng cách ở cột phải.



Chương 27 — Lỗi phát hiện khi biên soạn — tái hiện và cách chữa

Mỗi lỗi dưới đây đã được tái hiện trên B31 ngày 19/09/2026 (ảnh hoặc lệnh kiểm kèm theo). Sách KHÔNG sửa mã của A0_scripts — việc sửa thuộc quyền chủ repo; cột cuối là đề xuất.

#

Phím

Tái hiện

Đề xuất sửa

1

dgg

Hình 19.3 — E117 trim; và git -C báo Unknown option trên git 1.7.1

thay trim() bằng substitute(…,'\n','','g'); thay git -C d bằng cd d && git …

2

tm1..tm9

call GLMoveWindowToTab(1) → E117 win_getid

dùng winnr()/bufnr() thay win_getid (7.4 tương thích)

3

F7

Hình 11.3 — E492 SignifyToggle

trên 7.4 map F7 sang lời nhắc, hoặc bỏ điều kiện version nếu plugin chạy được

4

fd

Hình 16.6 + SyntaxError khi chạy fuz_filter.py bằng python 2.6

thêm # -*- coding: utf-8 -*- ở dòng 1 fuz_filter.py

5

vdc

Hình 19.5 — E15 rồi No commit ID provided

bỏ <CR> thứ hai trong mapping; xoá dòng echo "0

6

vdl · :VDL · :VDLR

Hình 20.4; gọi thẳng VdlCompare() → E488

bỏ <CR> thừa; thêm . ' ' . sau jumpTopCmd ở 3 hàm

7

ff f1..f6 tt vv

:echo $lwd1 rỗng sau swd1

alias swdN thêm setenv lwdN; hoặc hàm Vim đọc ~/.tmp/swdN trực tiếp

8

cf

:verbose nmap cf → CopyCursorFilePath() — tức bản ở dòng 420

đổi tên một trong hai (vd giữ cf = chép, đặt scf = lưu ~/.tmp/cf)

9

of / oof

of ghi ~/.tmp/of, oof đọc ~/.tmp/op

thống nhất một tên file

10

showList

Hình 6.3 — Permission denied.

chmod +x AS009_showList/showList.sh (và commit mode)

11

:CommentSet

E482 khi thiếu ~/.vim

mkdir() trong s:save_slots trước khi writefile

12

simdone · emcp

which zenity emacs trên B31: không có

chỉ dùng trên máy có GUI

13

rcb

rcb.conf EXPIRE = 2026-03-01 đã qua

gia hạn ngày trong rcb.conf

14

diff2

kết quả ở ~/.tmp/diff2_result.txt, chú thích đầu file nói thư mục hiện tại

sửa chú thích



# Kiểm nhanh trên máy của bạn (Vim 7.4): hàm nào thiếu?

vim -N -u NONE -es -c 'redir! > /tmp/fx.txt' \

-c 'for f in ["trim","win_getid","systemlist"] | echo f exists("*".f) | endfor' \

-c 'redir END' -c 'qa!' ; cat /tmp/fx.txt

# B31 in ra: trim 0 · win_getid 0 · systemlist 1



Chương 28 — Tám bài thực hành

Lab 1 — Ghi, thoát, nhìn màu (Ngày 1)

1. Mở /0_ENV/top.v. Sửa 1 ký tự: quan sát dòng con trỏ đổi đỏ.

2. dff xem thay đổi, tqq đóng tab diff.

3. ww; màu trở lại xám. F2 F8 bật cột và ký tự ẩn, bấm lần nữa tắt.

Đạt khi: Không cần gõ dấu : lần nào; biết đọc màu CursorLine.

Lab 2 — Cửa sổ (Ngày 2)

1. Mở 3 file bằng :vs. Dùng Ctrl+H/L đi qua lại, Tab đi vòng.

2. gtt trên cửa sổ phải, sang cửa sổ trái, gts.

3. sf rồi sa. qo giữ lại 1 cửa sổ.

Đạt khi: Dựng lại đúng bố cục Hình 13.3 trong dưới 30 giây.

Lab 3 — Tab và bố cục (Ngày 3)

1. tnn hai lần, trn đặt tên CODE / LOG, tcl2 tcl1.

2. t1 t3 Shift+→.

3. ss2, đóng hết cửa sổ, sr2.

Đạt khi: Thanh tab hiện [T1/..] [T2/..]CODE [T3/..]LOG đúng màu; sr2 dựng lại đúng.

Lab 4 — Tìm (Ngày 4)

1. Trong /0_ENV mở path_define.v, con trỏ lên PATH_SYSAWO: fa, ghi số dòng kết quả; fc, so sánh.

2. gf trên một token [N_L].

3. Ở một dòng include: fs. Ở tên testcase: fl.

Đạt khi: Giải thích được vì sao fa ra nhiều hơn fc.

Lab 5 — So sánh với Git (Ngày 5)

1. Trong một repo git, sửa 1 file chưa commit.

2. vdd, :qa; vd1, :qa.

3. :call GitLogAndDiffSilent() và chọn commit gốc.

Đạt khi: Chỉ ra được dòng nào đổi ở mỗi mức HEAD~N.

Lab 6 — So sánh hai môi trường (Ngày 5)

1. Sao một thư mục testcase sang /tmp/ENV_B, sửa 1 dòng.

2. tcsh: cd /tmp/ENV_B; swd1; setenv lwd1 /tmp/ENV_B.

3. Mở file gốc, vv1, rồi tt1. tcsh: diff2 <gốc> /tmp/ENV_B, Vim: zzz.

Đạt khi: Cả ba đường (vv1, tt1, diff2+zzz) đều chỉ ra đúng dòng đã sửa.

Lab 7 — Comment và đổi tên (Ngày 6)

1. :CommentSet 1 //LAB ; V chọn 3 dòng; cs1; cvv; cc1.

2. caa css cdd trên 3 dòng; ccc.

3. cw trên tên mới, ra trên tên cũ, dff kiểm.

Đạt khi: File trở về nguyên trạng sau cc1/ccc; ra đổi đúng mọi chỗ.

Lab 8 — Một vòng tcsh (Ngày 7)

1. swd, swd1…llwd, lwd1, cwd1.

2. sfind PATH_SYSAWO vsv 3 testcase, sfindVi, gf.

3. rm file_thu rồi rcb ls, rcb restore file_thu.

Đạt khi: Kể lại được đường đi của dữ liệu qua ~/.tmp ở mỗi bước (Hình 1.3).

Phụ lục A — Toàn bộ phím Vim theo họ (sinh từ :verbose map trên B31)

Bảng này sinh TỰ ĐỘNG từ lệnh :verbose nmap, :verbose xmap, :verbose imap chạy trên B31 với .vimrc thật, rồi mới gắn mô tả — nên mọi phím đang nạp đều có mặt. Các chuỗi đánh số (vd vd0..vd5) được gộp một dòng. Cột Mode: N = Normal, V = Visual, I = Insert.

A.1 Tìm

Phím

Mode

Làm gì

*

N

tô sáng nguyên từ dưới con trỏ, không nhảy

fa

N

sfind từ dưới con trỏ, mọi file, thư mục hiện tại → .sfindNoAnsi

fc

N

như fa nhưng chỉ file 'com' (mã nguồn, cấu hình)

fd

N

chỉ dòng định nghĩa trong gnu_cmn,script,tb,testcase → .sfindNoAnsi.fuz

fl

N

tìm file .log chứa từ dưới con trỏ trong ./list.txt

fs

N

tìm đường dẫn dưới con trỏ trong ./list.txt

fˋ

N

mở lại kết quả fd lần trước



A.2 Mở file

Phím

Mode

Làm gì

ccf

N

chép đường dẫn file đang mở vào thanh ghi

cf

N

chép đường dẫn file dưới con trỏ vào thanh ghi

csf

N

xoá file swap cũ của buffer, giữ swap đang dùng

emcp

N

emacs chép toàn bộ file đang mở vào clipboard

f1

N

vsplit $lwd/list.txt

f2

N

vsplit $lwd/testcase/usr/test/vmon/usr_sysss_as_vmon_test_lib.sv

f3

N

vsplit $lwd/testcase/usr/top/vmon/usr_top_sysss_as_vmon_vseq_lib.sv

f4

N

vsplit $lwd/gnu_cmn/rv32i/include/defines.h

f5

N

vsplit $lwd/debug.log rồi xuống cuối

f6

N

vsplit $lwd/testcase/common/path_define.v

fe

N

vsplit thư mục chứa file đang mở (netrw)

ff

N

vsplit $lwd/list.txt

gd

N

vsplit thư mục chứa file dưới con trỏ

gf

N

gf thông minh: [N_L], file:dòng, rồi đường dẫn thường — luôn vsplit

gr

N

vsplit read-only file dưới con trỏ

mcp

N

chép file dưới con trỏ vào ~/.tmp/.vimMarkCopy

mpst

N

dán file đã mcp ra đường dẫn dưới con trỏ

mrmrmrm

N

rm -rdf đường dẫn dưới con trỏ (xoá thật)

ocf

N

mở đường dẫn trong ~/.tmp/cf

of

N

ghi đường dẫn file đang mở vào ~/.tmp/of

oof

N

mở đường dẫn trong ~/.tmp/op (lệch với of)

swd0 .. swd5

N

ghi thư mục của file dưới con trỏ vào ~/.tmp/swdN

touch

N

tạo thư mục cha + file rỗng theo đường dẫn dưới con trỏ



A.3 So sánh

Phím

Mode

Làm gì

dff

N

tab [DIFF]: buffer đang sửa vs bản trên đĩa

dgg

N

tab [GIT]: buffer vs git HEAD (Vim 8)

tt0 .. tt5

N

vsplit read-only cùng file trong $lwdN

ttt

N

= tt5

vd0 .. vd5

N

git difftool vimdiff HEAD~N -- <cfile>

vdc

N

git log file → nhập commit → difftool

vdd

N

git difftool vimdiff HEAD -- <cfile>

vdl

N

vimdiff <cfile> với file ở dòng nhập vào

vv0 .. vv5

N

tab diff với cùng file trong $lwdN

vvv

N

= vv5

zzz

N

vimdiff cặp file của dòng kết quả diff2 / AS014



A.4 Tab

Phím

Mode

Làm gì

<S-Left>

N

tab trước

<S-Right>

N

tab sau

t1 .. t9

N

nhảy tới tab N

tcl0 .. tcl7

N

màu tab N (N = xoá)

tm1 .. tm9

N

chuyển cửa sổ sang tab N (cần Vim N.N.NNNN+)

tnn

N

tab mới (:tab split)

tqq

N

đóng tab

trn

N

đặt tên tab



A.5 Cửa sổ

Phím

Mode

Làm gì

<C-Down>

N

xuống trong cột / xếp chồng

<C-H>

N

sang cửa sổ trái

<C-K>

N

sang cửa sổ trên

<C-L>

N

sang cửa sổ phải

<C-Left>

N

đẩy cửa sổ sang cột trái

<C-Right>

N

đẩy cửa sổ sang cột phải

<C-Up>

N

lên trong cột / xếp chồng

<Esc>[1;3A

N

mã thô Alt+mũi tên — dạt cửa sổ ra mép (wincmd H/L/K/J)

<Esc>[1;3B

N

mã thô Alt+mũi tên — dạt cửa sổ ra mép (wincmd H/L/K/J)

<Esc>[1;3C

N

mã thô Alt+mũi tên — dạt cửa sổ ra mép (wincmd H/L/K/J)

<Esc>[1;3D

N

mã thô Alt+mũi tên — dạt cửa sổ ra mép (wincmd H/L/K/J)

<Esc>[1;5A

N

mã thô Ctrl+mũi tên (terminal cũ) — như Ctrl+mũi tên

<Esc>[1;5B

N

mã thô Ctrl+mũi tên (terminal cũ) — như Ctrl+mũi tên

<Esc>[1;5C

N

mã thô Ctrl+mũi tên (terminal cũ) — như Ctrl+mũi tên

<Esc>[1;5D

N

mã thô Ctrl+mũi tên (terminal cũ) — như Ctrl+mũi tên

<NL>

N

Ctrl+J: sang cửa sổ dưới

<S-Tab>

N

cửa sổ trái, về đầu dòng

<Tab>

N

cửa sổ kế tiếp, về đầu dòng

gta

N

đặt cửa sổ đã đánh dấu thành cột trái

gtd

N

… cột phải

gts

N

… ngăn dưới

gtt

N

đánh dấu cửa sổ cần dời

gtw

N

… ngăn trên

qo

N

:only

sa

N

chia đều cửa sổ

sf

N

phóng to cửa sổ hết cỡ



A.6 Bố cục

Phím

Mode

Làm gì

sr1 .. sr5

N

khôi phục bố cục ngăn N

srr

N

= sr1

ss1 .. ss5

N

lưu bố cục vào ngăn N

sss

N

= ss1



A.7 Comment

Phím

Mode

Làm gì

<C-_>

N+V

Ctrl+/: bật/tắt comment

ca1 .. ca5

N+V

thêm tiền tố ngăn N ở cột N

caa

N+V

thêm comment mặc định ở cột 0

cc1 .. cc5

N+V

xoá tiền tố ngăn N

ccc

N+V

xoá comment mặc định

cd1 .. cd5

N+V

thêm tiền tố ngăn N cuối dòng

cdd

N+V

thêm comment mặc định cuối dòng

cs1 .. cs5

N+V

thêm tiền tố ngăn N sau thụt lề

css

N+V

thêm comment mặc định sau thụt lề

cvv

N

xem 5 ngăn



A.8 Chép / thay

Phím

Mode

Làm gì

Y

N

y$

cw

N

chép từ → ~/.tmp/yiw + thanh ghi

ra

N

thay mọi chỗ trong file

rw

N

thay từ bằng ~/.tmp/yiw



A.9 Ghi / thoát

Phím

Mode

Làm gì

<C-Z>

N+V

khoá (không làm gì)

<C-Z>

I

Insert: khoá Ctrl+Z

<Space>

N

= :

ee

N

:e rồi G

jj

I

Insert: = Esc

qf

N

:q!

qq

N

:q

vimrc

N

:source $MYVIMRC

wq

N

:wq

ww

N

:w



A.10 Phím F

Phím

Mode

Làm gì

<F2>

N

cursorcolumn

<F3>

N

wrap

<F4>

N

số dòng

<F5>

N

SmartRun .csh/.py

<F7>

N

:SignifyToggle (Vim 8)

<F8>

N

ký tự ẩn

<F9>

N

spell en_us



A.11 Completion

Phím

Mode

Làm gì

<C-Space>

I

Insert: ép bung popup

<CR>

I

Insert: popup mở thì chọn, không thì xuống dòng

<Down>

I

Insert: xuống trong popup

<F6>

N

bật/tắt auto-popup

<F6>

I

Insert: bật/tắt auto-popup

<Left>

I

Insert: trang trước

<Nul>

I

Insert: Ctrl+Space ép bung popup

<Right>

I

Insert: trang sau

<S-Tab>

I

Insert: lên trong popup

<Tab>

I

Insert: gợi ý thông minh / xuống

<Up>

I

Insert: lên trong popup

\all

N

liệt kê mọi lệnh \all_xx

\all_09

N

build tags + hier + pathmap + hdlmap

\help

N

liệt kê mọi \help_xx

\help_09

N

hướng dẫn module 09

\hh

N

build project.hdlmap

\hp

N

build project.pathmap

\hr

N

build project.hier (+Verdi) + pathmap + hdlmap

\tg

N

build project.tags

cch

N

nhắc phím completion

cl

N

collapse đường dẫn

ep

N

expand đường dẫn



A.12 Khác

Phím

Mode

Làm gì

<Plug>NetrwBrowseX

N

hàm nội bộ của netrw

<Plug>NetrwBrowseXVis

V

hàm nội bộ của netrw

csh

mọi

nhắc dùng F5 (map cho mọi mode)

gx

N+V

plugin netrw gốc của Vim: mở URL dưới con trỏ (không thuộc bộ này)



Tổng số mục map đã liệt kê: 230 (tính riêng từng mode). Mục chưa phân loại: 0.

Phụ lục B — Toàn bộ alias tcsh (sinh từ ~/.cshrc)

Sinh tự động bằng cách đọc mọi dòng alias chưa bị chú thích trong ~/.cshrc. Alias khai báo lặp trong nhiều khối user (A0, pythonVer, prompt) chỉ in một lần kèm số lần khai báo.

Alias

Dòng

Làm gì

home

108

cd /root/ (root/WORK_PC)

A0

110 (x4)

cd tới ~/A0_scripts

pythonVer

112 (x4)

Python dùng cho mọi script (theo user)

prompt

113 (x4)

đặt dấu nhắc 2 dòng

ansi

168

bảng 256 màu

llwd

178

liệt kê 6 ngăn thư mục

swd

179

lưu pwd vào ngăn 0

swd0

180

lưu pwd vào ngăn 0

swd1

181

lưu pwd vào ngăn 1

swd2

182

lưu pwd vào ngăn 2

swd3

183

lưu pwd vào ngăn 3

swd4

184

lưu pwd vào ngăn 4

swd5

185

lưu pwd vào ngăn 5

cf

186

lưu pwd vào ~/.tmp/cf

lwd

187

cd tới ngăn 0

lwd0

188

cd tới ngăn 0

lwd1

189

cd tới ngăn 1

lwd2

190

cd tới ngăn 2

lwd3

191

cd tới ngăn 3

lwd4

192

cd tới ngăn 4

lwd5

193

cd tới ngăn 5

cwd

194

xoá ngăn 0

cwd0

195

xoá ngăn 0

cwd1

196

xoá ngăn 1

cwd2

197

xoá ngăn 2

cwd3

198

xoá ngăn 3

cwd4

199

xoá ngăn 4

cwd5

200

xoá ngăn 5

simdone

202

hộp thông báo zenity

vimrc

204

sửa .vimrc

cshrc

205

sửa .cshrc

scshrc

206

nạp lại .cshrc

clr

207

clear

ll

208

ls -alhAF

la

209

ls -hlA

ls

210

ls -hCF

grep

211

grep có màu

sw

213

hardcopy mọi phiên screen → vi -O

sf

214

mở log mọi phiên screen → vi -O

ss

215

screen -ls

ska

216

killall screen

sfind

217

tìm nội dung (AS002)

sfindCat

218

in kết quả sfind có màu

sfindVi

219

mở kết quả sfind trong Vim

vfind

221

sfind trong ~/INOUTREGWIRE

vfindreg

222

khai báo reg

vfindwire

223

khai báo wire

vfindin

224

khai báo input

vfindout

225

khai báo output

showList

227

cây thư mục phẳng → file (AS009)

showListCatResult

228

in ~/.tmp/.showlist.txt

showListViResult

229

mở ~/.tmp/.showlist.txt

showList1

230

tree độ sâu 1 → vi

showList2

231

tree độ sâu 2 → vi

showList3

232

tree độ sâu 3 → vi

showList4

233

tree độ sâu 4 → vi

showList5

234

tree độ sâu 5 → vi

showList6

235

tree độ sâu 6 → vi

showList7

236

tree độ sâu 7 → vi

showList8

237

tree độ sâu 8 → vi

showList9

238

tree độ sâu 9 → vi

showList10

239

tree độ sâu 10 → vi

gitmap

249

đồ thị nhánh git

gitmapall

250

gitmap + tên file

as006_make

252

make AS006 mã hoá dữ liệu

emcp

253

emacs chép file vào clipboard

piplist

257

liệt kê module Python

jubei

261

ví dụ tham số alias

clearAnsi

266

trả màu terminal

run_all

268

chạy run_list bằng screen song song

rm

274

chuyển vào thùng rác rcb

rcb

275

quản lý thùng rác

duh

280

du -h

duh1

281

du -h --max-depth=1

duh2

282

du -h --max-depth=2

duh3

283

du -h --max-depth=3

ok

284

./check_result.csh

sumComp

285

testcase clma biên dịch lỗi

sumComp2

286

testcase vmon biên dịch lỗi

sumLog

287

bảng PASS/FAIL (RELU5M)

sumLog2

288

bảng PASS/FAIL (RELU5M_2)

sum

289

sumComp + sumLog FAIL → sim_result.txt

sum2

290

như sum với cấu hình 2

bsjob

291

bs -os RHEL7 RHEL8

diff2

293

so hai thư mục (AS013)

wiki

296

ssh -X TWIDC-R640-51

wiki2

297

ssh -X TWIDC-R6625-01

AS014_GitVendorDrop.S0_repoCreate

301

AS014 bước S0_repoCreate

AS014_GitVendorDrop.S1_Diff_Vendor_Drop

302

AS014 bước S1_Diff_Vendor_Drop

AS014_GitVendorDrop.S2_call_diff2

303

AS014 bước S2_call_diff2

AS014_GitVendorDrop.S3_push_with_message_tag

304

AS014 bước S3_push_with_message_tag

AS014_GitVendorDrop.S4_Quick_3Dir_Update

305

AS014 bước S4_Quick_3Dir_Update

PCA1

307

AS016 PCA.py

PCA2

308

trình chiếu tmp/ bằng eog

bsvim

310

Vim trên máy RHEL8 qua bs

cleanTestcase

311

XOÁ THẬT file build/log trong testcase

cleanTestcase_listonly

312

chỉ liệt kê file cleanTestcase sẽ xoá

AS019_Trans_PCA

313

đồng bộ A→B gom thay đổi



Tổng: 98 alias.

Phụ lục C — Các file trong ~/.tmp

File

Ai ghi

Ai đọc

Nội dung

swd0 .. swd5

tcsh swd*, Vim swd0..5

tcsh lwd*, llwd; khởi động .cshrc

1 dòng: đường dẫn thư mục

cf

tcsh cf

tcsh $cf; Vim ocf

1 dòng: thư mục

of

Vim of

(không ai — oof đọc op)

đường dẫn file

yiw

Vim cw

Vim rw ra :RL

1 từ

.sfind

sfind

sfindCat

kết quả có mã màu

.sfindNoAnsi

sfind, fa fc fd

sfindVi, Vim gf

kết quả không màu, có dòng ##### [File N]

.sfindNoAnsi.fuz

fd (fuz_filter.py)

fˋ, gf

chỉ dòng định nghĩa

.showlist.txt

showList, showList1..10

showListCat/ViResult

cây thư mục phẳng

diff2_A.txt · diff2_B.txt

diff2.csh

zzz

gốc thư mục A, B

diff2_result.txt

diff2.csh

người dùng + zzz

danh sách < | >

AS014_PATH_1..3.txt

AS014 S4

zzz trên AS014_OUT_*

gốc 3 thư mục

.vimMarkCopy

Vim mcp

Vim mpst

bản sao file

legacy_screen_session_N.vim · _data_N.vim

Vim ss1..5

Vim sr1..5

phiên :mksession



Ngoài ~/.tmp: ~/.vim/CommentSlots.txt (5 ngăn comment), 0_ENV/project.* (4 DB completion).

Phụ lục D — Thẻ nhớ — che cột phải và tự kiểm

Mỗi họ một bảng. Che cột 'Nghĩa' bằng tờ giấy, đọc phím, nói to công dụng, rồi mở ra so. Làm hằng ngày cho họ vừa học và họ hôm trước.

Thẻ: Tìm

Phím

Nghĩa

fa

find all — mọi file

fc

find common — file mã

fd

find define — dòng định nghĩa

fˋ

mở lại kết quả fd

fs

tìm đường dẫn trong list.txt

fl

tìm log trong list.txt

gf

nhảy tới [N_L] / file:dòng

*

tô sáng từ, không nhảy



Thẻ: Mở

Phím

Nghĩa

ff f1

list.txt

f2..f6

file ghim

fe

thư mục file đang mở

gr

mở read-only

gd

mở thư mục của đường dẫn

ccf / cf

chép đường dẫn file đang mở / dưới con trỏ

mcp / mpst

chép / dán file

touch

tạo file theo đường dẫn



Thẻ: So sánh

Phím

Nghĩa

dff

vs bản trên đĩa

dgg

vs git HEAD (Vim 8)

vdd = vd0

difftool HEAD

vd1..vd5

HEAD~1..5

vdc

chọn commit

vv1

vs $lwd1

tt1

xem $lwd1 read-only

vdl

vs file ở dòng khác

zzz

dòng kết quả diff2



Thẻ: Tab / cửa sổ / bố cục

Phím

Nghĩa

tnn / tqq

tab mới / đóng

t3

tới tab 3

trn / tcl2

tên / màu tab

Ctrl+H/J/K/L

đi cửa sổ

gtt → gtw/a/s/d

dời cửa sổ

sf / sa / qo

to / đều / chỉ 1

ss2 / sr2

lưu / khôi phục bố cục 2



Thẻ: Soạn thảo

Phím

Nghĩa

caa / css / cdd

comment cột 0 / sau thụt lề / cuối

cs1

comment ngăn 1

ccc / cc1

xoá comment mặc định / ngăn 1

Ctrl+/

bật/tắt comment

cw

chép từ

rw / ra

thay từ / thay cả file

:RL 10,50

thay trong đoạn

F5

chạy .csh/.py



Thẻ: Ghi / F / completion

Phím

Nghĩa

ww qq qf wq

:w :q :q! :wq

ee

nạp lại + xuống cuối

jj

Esc

F2 F3 F4 F8 F9 F12

cột · wrap · số · ẩn · spell · paste

\all_09

build 4 DB

Tab / F6

gợi ý / auto-popup

cl / ep

rút / bung đường dẫn



Thẻ: tcsh

Phím

Nghĩa

swd1 / lwd1 / cwd1

lưu / tới / xoá ngăn 1

llwd

liệt kê ngăn

sfind a b c d

nội dung · tên file · số · thư mục

showList3

cây sâu 3 → vi

run_all sim 4

chạy 4 phiên

sw / sf / ss

màn hình / log / danh sách screen

sum

báo cáo FAIL

diff2 A B

so thư mục

rm / rcb restore

thùng rác

gitmap

đồ thị git



Phụ lục E — Kinh nghiệm đã trả giá (từ sổ ghi nhớ kỹ thuật của dự án)

Những câu chuyện dưới đây không hiện ra khi đọc mã, nhưng đã tốn nhiều giờ khi xây bộ công cụ. Mỗi mục: triệu chứng → nguyên nhân thật → cách chữa → bài học.

E.1 Signify báo E475 chỉ trên Vim 8

Triệu chứng: Mở file bằng Vim 8.0 thấy E475: Invalid argument: 3/4 texthl=SignifySignDeleteFirstLine; Vim 7.4 im lặng.

Nguyên nhân: Ký hiệu mặc định '?? 3/4 ' chứa dấu / và khoảng trắng; chuỗi được ghép vào sign define … text= nên Vim tách thành đối số rác. Vim 7.4 bỏ qua, Vim 8 kiểm chặt hơn.

Cách chữa: Đổi mặc định thành '_' (ASCII an toàn).

Bài học: Mọi giá trị ghép vào lệnh sign define không được chứa khoảng trắng; hành vi 7.4 ≠ 8.

E.2 Completion cây phân cấp rỗng vì \t

Triệu chứng: top.<Tab> không ra gì dù project.hier đầy dữ liệu.

Nguyên nhân: Pattern grep viết '^top\t' trong nháy đơn = chữ \ + t, grep hiểu là chữ t, không phải ký tự TAB.

Cách chữa: Dùng let s:TAB = nr2char(9) trong mọi pattern grep.

Bài học: Trong Vimscript, nháy đơn không có escape; tách bằng split() thì '\t' lại đúng vì đó là regex của Vim.

E.3 Instance 'ma' trong cây phân cấp

Triệu chứng: top.<Tab> hiện cả instance của hai nhánh ifdef loại trừ nhau.

Nguyên nhân: Parser tĩnh bỏ dòng directive nhưng không đánh giá điều kiện, nên giữ cả hai nhánh.

Cách chữa: Trích cây thật từ Verdi (09_extract_verdi_hier.tcl) rồi \hr gộp; Verdi là chân lý cho instance/signal, parser tĩnh giữ phần class.

Bài học: Parser tĩnh đủ cho gợi ý, nhưng cây chuẩn phải lấy từ công cụ đã elaborate.

E.4 tcsh: heredoc có nháy không chạy

Triệu chứng: Script csh có << 'EOF' thoát 0 mà không in gì.

Nguyên nhân: tcsh tìm đúng chuỗi 'EOF' (kèm nháy) làm dấu kết thúc; nuốt hết phần còn lại. ! trong chuỗi bị history-expansion, dấu huyền bị thay lệnh.

Cách chữa: Chỉ dùng << EOF không nháy và tự thoát ký tự $; thoát \!.

Bài học: Luôn thử script csh trên B31 (tcsh thật), không trên máy có bsd-csh.

E.5 Sửa .vimrc mà Vim trong container không thấy

Triệu chứng: Sửa .vimrc ở workspace, trong B31 :verbose nmap vẫn là bản cũ.

Nguyên nhân: Docker bind-mount FILE bám theo inode; trình soạn thảo 'ghi file mới rồi đổi tên' làm đổi inode.

Cách chữa: Ghi đè tại chỗ (cat mới > ~/.vimrc giữ inode) hoặc tạo lại container.

Bài học: Với cấu hình được mount từng file, sửa in-place.

E.6 Bẫy tìm thấy lúc làm sách này

Triệu chứng: 12 lỗi ở Chương 27.

Nguyên nhân: Phần lớn đến từ khác biệt Vim 7.4 ↔ 8 (trim, win_getid, Signify), từ <CR> thừa sau lời gọi có input(), và từ biến shell vs biến môi trường.

Cách chữa: Xem cột Đề xuất ở Chương 27.

Bài học: Kiểm mọi phím mới bằng vim -u ~/.vimrc -es -c 'silent verbose nmap <phím>' và chạy thật một lần trên máy 7.4.

Phụ lục F — Danh mục A0_scripts AS000 – AS020

Module

Nội dung chính

Gọi bằng

AS000_General

G01_scriptConvCsh2bash.py — chuyển script csh sang bash

python trực tiếp

AS001_showScreen

showScreen.csh (hardcopy) · showScreen2.csh (log)

sw · sf

AS002_sfind

sfind_py27.py + doc PRD

sfind · fa fc fd

AS003_runAll

runAll.py (screen song song), TYPE_01 tách testcase, z_run.csh

run_all

AS004_gitSvnMonChecker

gitCheck.csh — so HEAD với origin (dùng cho prompt, đang tắt)

—

AS005_ansi

bảng 256 màu

ansi

AS006_encDecData

makefile + script tạo danh sách, mã hoá openssl

as006_make

AS007_addr_alias

alias_maker_py27.py — sinh alias địa chỉ thanh ghi từ address.h

python2.7 trực tiếp

AS008_recycleBin

rcb.py + rcb.conf + daily scan

rm · rcb

AS009_showList

showList.sh / .csh

showList · showList1..10

AS010_VIMRC

vimrc_source.vim + source/00..09 + công cụ 09_*.py/.tcl

~/.vimrc

AS011_sumLog

sumLog.py + YAML cấu hình

sumLog · sum

AS012_pdfToText

pdfToText.py — PDF → TXT (pdftotext), nén

python trực tiếp

AS013_diff2

diff2.csh + bộ mẫu AAA/BBB

diff2 · zzz

AS014_GitVendorDrop

S0..S4 + tài liệu

AS014_GitVendorDrop.S*

AS015_CSHRC

git_all.csh

git all

AS016_PCA

PCA.py, bản obfuscate, build exe Windows

PCA1 · PCA2

AS017_ReferLog

check_refer_log_result.py — kiểm log tham chiếu

python trực tiếp

AS017_VIL_EWS_pat_matching

vil_test_diff.py — so pattern VIL và LIST

python trực tiếp

AS018_regressCov_01

môi trường tập regression + coverage

—

AS019_Trans_PCA

01_sync_transfer.py — đồng bộ A→B, gom thay đổi thành zip

AS019_Trans_PCA

AS020_ContainerReplica

survey_verifier_pc.sh — khảo sát máy Verifier để dựng B31

sh trực tiếp



Phụ lục G — Nguồn và cách dựng tài liệu

Hạng mục

Chi tiết

Mã nguồn đọc

~/.cshrc, ~/.vimrc, AS010_VIMRC/vimrc_source.vim, source/00..09, AS001..AS020 (đầu file + phần xử lý tham số)

Ảnh chụp

51 ảnh: pexpect mở docker exec -it B31_Veri_Client tcsh trong pty 132x34; mọi byte đưa vào bộ giả lập terminal pyte; vẽ ra PNG (DejaVu Sans Mono). Toạ độ phần tử tính từ hàng/cột nên số chú thích đặt chính xác

Đánh số

annotate_kit — vòng tròn chỉ viền, đặt ngoài phần tử

Sơ đồ

matplotlib phẳng: 14 bản đồ bàn phím + 10 sơ đồ luồng

Phụ lục A, B

sinh tự động từ :verbose map trên B31 và từ ~/.cshrc

Dựng

python-docx (doc_kit, khổ A4, Heading thật) → PDF bằng LibreOffice UNO (mục lục điền sẵn)

Mã dựng

tmp/UID04_A0_VIM/{tools,build} trong workspace 000_CMEV



Mở .docx trong Word, bấm Ctrl+A rồi F9 để cập nhật số trang mục lục nếu thấy lệch.