Nếu tôi có văn bản sau:
foo
bar
Tôi trực quan chọn nó và sao chép nó.
Văn bản hiện được lưu trữ trong thanh ghi không tên "
và đây là nội dung của nó (đầu ra của :reg "
):
"" foo^Jbar^J
Theo biểu đồ này , có vẻ như ^J
là ký hiệu dấu mũ cho Line Feed.
Nếu tôi muốn sao chép thanh ghi không tên trong thanh a
ghi bằng cách gõ: :let @a = @"
Đây là nội dung của nó (đầu ra của :reg a
):
"a foo^Jbar^J
Nó không thay đổi.
Nếu bây giờ tôi sao chép nó trong sổ đăng ký tìm kiếm bằng cách gõ :let @/ = @"
, thì đây là nội dung của nó (đầu ra của :reg /
):
"/ foo^@bar^@
Theo biểu đồ trước đó, có vẻ như ^@
ký hiệu dấu mũ cho một nhân vật Null.
Tại sao Line Feed tự động được chuyển đổi thành ký tự Null bên trong thanh ghi tìm kiếm (nhưng không phải là a
thanh ghi)?
Nếu tôi chèn thanh ghi không tên trên dòng lệnh (hoặc bên trong tìm kiếm sau /
), bằng cách nhập :<C-R>"
, đây là những gì được chèn:
:foo^Mbar^M
Một lần nữa, theo biểu đồ cuối cùng, ^M
dường như là ký hiệu dấu mũ cho Vận chuyển trở lại.
Tại sao Line Feed tự động được chuyển đổi thành Vận chuyển trở lại trên dòng lệnh?
Chỉnh sửa :
Thông thường bạn có thể chèn một ký tự điều khiển bằng chữ bằng cách gõ:
<C-V><C-{character in caret notation}>
Ví dụ: bạn có thể chèn một chữ <C-R>
bằng cách gõ <C-V><C-R>
.
Bạn có thể làm điều đó cho dường như bất kỳ nhân vật điều khiển.
Tuy nhiên, tôi nhận thấy rằng tôi không thể chèn một chữ viết tắt trong một bộ đệm hoặc trên dòng lệnh, bởi vì nếu tôi gõ: <C-V><C-J>
nó sẽ chèn ^@
, một ký tự null, thay vì ^J
.
Có phải vì lý do tương tự, một LF được chuyển đổi thành NUL trong sổ đăng ký tìm kiếm?
Chỉnh sửa 2 :
Trong :h key-notation
, chúng ta có thể đọc điều này:
<Nul> zero CTRL-@ 0 (stored as 10) <Nul>
<NL> linefeed CTRL-J 10 (used for <Nul>)
Phần stored as 10
trên dòng đầu tiên và used for <Nul>
trên dòng thứ hai có thể chỉ ra rằng có một số loại trùng lặp giữa một LF và NUL, và chúng có thể được hiểu là cùng một thứ. Nhưng chúng không thể giống nhau, vì sau khi thực hiện lệnh trước đó :let @/ = @"
, nếu tôi gõ n
ở chế độ bình thường để đến lần xuất hiện tiếp theo của 2 dòng foo
và bar
, thay vì nhận được kết quả trùng khớp, tôi có thông báo lỗi sau:
E486: Pattern not found: foo^@bar^@
Bên cạnh đó, liên kết này dường như giải thích rằng một NUL biểu thị sự kết thúc của một chuỗi, trong khi đó, một biểu thị cho một kết thúc của một dòng trong một tệp văn bản.
Và nếu một NUL stored as 10
đúng như sự trợ giúp nói, đó là mã giống như đối với một LF, làm thế nào Vim có thể tạo ra sự khác biệt giữa 2?
Chỉnh sửa 3 :
Có thể một LF và NUL được mã hóa với cùng một mã thập phân 10
, như sự giúp đỡ nói. Và Vim tạo ra sự khác biệt giữa 2 nhờ bối cảnh. Nếu nó gặp một ký tự có mã thập phân nằm 10
trong bộ đệm hoặc bất kỳ thanh ghi nào, ngoại trừ các thanh ghi lệnh tìm kiếm và lệnh, nó sẽ hiểu nó là một LF.
Nhưng trong thanh ghi tìm kiếm ( :reg /
) nó diễn giải nó là NUL vì trong ngữ cảnh tìm kiếm, Vim chỉ tìm kiếm một chuỗi trong đó khái niệm end of line in a file
không có ý nghĩa vì một chuỗi không phải là một tệp (điều này thật lạ vì bạn có thể vẫn sử dụng nguyên tử \n
trong một mẫu tìm kiếm, nhưng có lẽ đó chỉ là một tính năng của công cụ regex?). Vì vậy, nó sẽ tự động diễn giải 10
như một NUL bởi vì đó là khái niệm gần nhất ( end of string
≈ end of line
).
Và theo cách tương tự, trên dòng lệnh / thanh ghi lệnh ( :reg :
) nó diễn giải mã 10
là CR, vì khái niệm end of line in a file
không có ý nghĩa ở đây. Khái niệm gần nhất là end of command
Vim diễn giải 10
như một CR, bởi vì đánh Enter
là cách kết thúc / thực thi lệnh và CR giống như đánh Enter
, vì khi bạn chèn một chữ theo nghĩa đen <C-V><Enter>
, ^M
sẽ được hiển thị.
Có thể cách giải thích của nhân vật có mã 10
thay đổi theo ngữ cảnh:
- cuối dòng trong bộ đệm (
^J
) - kết thúc chuỗi trong tìm kiếm (
^@
) - kết thúc lệnh trên dòng lệnh (
^M
)
someFunction(arg1, "")
trong đó arg 2 ""
là "mục giữa các dấu ngoặc kép, nghĩa đen là không có gì - một" trống ". làm thế nào bạn sẽ kiểm tra điều này - nhưng nó xuất hiện trong tâm trí như một nguyên nhân có thể.
\r
và \n
sự khác biệt trong:substitute
.
NULL
ký tự không mong muốn là do hàm C nằm bên dưới đang xử lý các chuỗi. Đây giải thích về cách C xử lý chuỗi mà bạn liên quan đến giải thích rằng trong nội bộ C delimits dây với mộtNULL
.NULL
s hiếm khi xảy ra trong văn bản mà nó làm cho nó trở thành một nhân vật tốt cho mục đích này. Hậu quả của việc này là nếu chương trình C (vim) cố gắng chuyển một chuỗi "trống" vào một hàm C bên trong