Tại sao `ESC` di chuyển con trỏ trở lại trong vim?


62

Trong vim, khi tôi nhấn ESCđể trở về chế độ lệnh, con trỏ di chuyển một ký tự sang trái. Đây không phải là điều tôi mong muốn, thỉnh thoảng tôi lập tức nhấn lđể di chuyển trở lại vị trí đó, có lẽ để xóa một nhân vật.

Có một lý do cho hành vi này? Điều này có thuận tiện cho một mô hình sử dụng mà tôi đang thiếu không?


1
Tôi thậm chí chưa bao giờ nhận thấy điều này cho đến bây giờ ... và tôi sử dụng vim hàng ngày. Tôi không biết tại sao, nhưng tôi thích nghe câu trả lời.
gabe.

5
khi quay lại chế độ chèn, bạn có thể nhấn 'a' để nối thay vì 'i' để chèn. Sau đó, bạn sẽ di chuyển trở lại vị trí bạn đang ở trước khi nhấn thoát.
chim cánh cụt359

Câu trả lời:


40

Trong chế độ chèn, con trỏ nằm giữa các ký tự hoặc trước ký tự đầu tiên hoặc sau ký tự cuối cùng. Trong chế độ bình thường, con trỏ ở trên một ký tự (dòng mới không phải là ký tự cho mục đích này). Điều này hơi bất thường: hầu hết các biên tập viên luôn đặt con trỏ giữa các ký tự và có hầu hết các lệnh tác động lên ký tự sau (không, nói đúng ra, bên dưới ) con trỏ. Điều này có lẽ một phần là do trước GUI, các thiết bị đầu cuối văn bản luôn hiển thị con trỏ trên một ký tự (gạch chân hoặc khối, có lẽ nhấp nháy). Sự trừu tượng hóa này không thành công trong chế độ chèn vì yêu cầu thêm một vị trí (bài viết so với hàng rào).

Chuyển đổi giữa các chế độ phải di chuyển con trỏ bằng một nửa ký tự, có thể nói như vậy. Các iđộng thái lệnh trái, đặt con trỏ trước khi nhân vật nó đã kết thúc. Các alệnh di chuyển ngay. Đi ra khỏi chế độ chèn (bằng cách nhấn Esc) di chuyển con trỏ sang trái nếu có thể (nếu ở đầu dòng, thay vào đó, nó sẽ di chuyển sang phải).

Tôi cho rằng các Escloại hành vi có ý nghĩa. Thông thường, bạn đang gõ ở cuối dòng và Escchỉ có thể đi bên trái. Vì vậy, hành vi chung là hành vi phổ biến nhất.

Hãy nghĩ về ký tự dưới con trỏ là ký tự thú vị cuối cùng và của lệnh chèn là a. Bạn có thể lặp lại a Escmà không di chuyển con trỏ, ngoại trừ việc bạn sẽ bị va vào một vị trí ngay nếu bạn bắt đầu ở đầu một dòng không trống.


21

Trực quan, nó có ý nghĩa hơn trong gvim:

Khi chỉnh sửa, con trỏ của bạn ở giữa các ký tự:
nhập mô tả hình ảnh ở đây

Khi ở chế độ bình thường, nó ở trên cùng của ký tự cuối cùng:
nhập mô tả hình ảnh ở đây

Vì vậy, nó không thực sự quay trở lại một nhân vật, chỉ cần không bị giữa rsđể trở về r


1
Bức tranh tuyệt vời. Thành thật mà nói, tôi đang ở trong trại nói rằng nhân vật mnên được tô sáng khi trở lại chế độ bình thường ...
Steven Lu

Úi. liên kết hình ảnh bây giờ đã chết.
Steven Lu

1
liên kết hình ảnh bây giờ đã chết.
Steven Lu

1
Yeah lưu trữ thủ công hình ảnh của bạn vừa làm việc vừa kém tin cậy hơn là chỉ sử dụng công cụ trong trình chỉnh sửa markdown trên trang web này.
Steven Lu

1
Có tất cả mọi thứ ok với họ một lần nữa? Đó là "Con trỏ" những gì họ đã nhập và văn bản của bạn đề cập đến "j"
poige

15

Hành vi này có thể chỉnh sửa như được trả lời ở đây , nhưng hãy dừng lại và suy nghĩ về những gì đang diễn ra trong một giây. Khi bạn ở chế độ chèn, bạn không thực sự vượt qua một ký tự mà GIỮA họ. Khi bạn chèn một cái gì đó, con trỏ sẽ nhảy đến cuối của những gì bạn đã chèn để thứ tiếp theo được chèn sẽ nằm sau đó. Bây giờ hãy nghĩ về nếu bạn vừa gõ một lá thư, sau đó muốn làm một cái gì đó cho nó. Đánh Escsẽ đặt con trỏ chọn trực tiếp lên ký tự cuối cùng bạn chèn. Nếu nó không làm điều này, nó thực sự sẽ khá khó xử.

Tình huống có lẽ bạn đang nghĩ đến là khi bạn ở chế độ chèn di chuyển xung quanh như thể bạn đang ở chế độ bình thường và sau đó chuyển đổi. Trong trường hợp đó, con trỏ dường như quay trở lại một ký tự, nhưng nếu bạn nghĩ như vậy thì nó cho thấy bạn đang ở chế độ chèn và điều cuối cùng bạn đã làm là KHÔNG chèn. Có lẽ bạn nên dành nhiều thời gian hơn trong chế độ bình thường?


15
Điều đó không có ý nghĩa với tôi. Làm thế nào để bạn giải thích hành vi đi lùi của lặp đi lặp lại iESCnhấn phím?
Warren Young

4
Đi vào chế độ chèn, không chèn bất cứ thứ gì, sau đó để lại nó không phải là một thử nghiệm công bằng. Tại sao bạn lại ở chế độ chèn nếu bạn không chèn thứ gì đó. Nếu bạn chèn một cái gì đó, trở lại chế độ bình thường sẽ để lại cho bạn ký tự bạn đã chọn. Rất trực quan.
Caleb

4
Đó không phải là "công bằng", đó là về sức mạnh giải thích. Nếu lý thuyết hoạt động của bạn không giải thích tất cả các hành vi, thì nó không hoàn chỉnh hoặc hành vi của vi không nhất quán. Tôi thích tin rằng vi là hoàn hảo về mọi mặt, và do đó phù hợp. :)
Warren Young

9
@Warren Hành vi "đi lùi" itheo sau ESClà một chức năng ivà hoàn toàn độc lập với ESC; cụ thể, khi bạn nhấn ibạn đang yêu cầu vim chèn một ký tự, theo định nghĩa có nghĩa là "chèn một ký tự trước ký tự tôi đang bật", trái ngược với ađó là "nối thêm một ký tự sau ký tự này".
Kromey

3
Nói chung, sau mỗi thay đổi, khi tôi rời khỏi thay đổi đó, tôi đã hoàn thành với thay đổi đó và điều tiếp theo tôi muốn làm có lẽ sẽ liên quan đến việc thực hiện một thay đổi khác nhau. Do đó, với tôi, khi rời khỏi chế độ chèn (cho dù tôi đã nhập nó như thế nào), tôi thường thích con trỏ ở trên ký tự tiếp theo để tôi sẵn sàng cho thay đổi tiếp theo của mình , thay vì sẵn sàng thay đổi những gì tôi vừa làm chèn vào.
Kyle Strand

6

Nhập Alt+ Lđể trở về chế độ lệnh.

Nó không yêu cầu bất kỳ thay đổi cấu hình hoặc vim cấu hình. Nó hoạt động vì trên hầu hết các trình giả lập thiết bị đầu cuối Alt+ KEYgửi Esctheo sau KEY(trên xterm, bạn có thể cần thêm một Xterm*metaSendsEscape: truedòng vào tệp ~ / .Xdefaults của mình). Hành vi đó cho phép bạn thậm chí "tạo" các kết hợp chế độ chèn khác hoạt động ngay trong hộp - như Alt+ Sđến Backspace.

Nhân tiện, việc đặt con trỏ lên trên ký tự bạn vừa viết có thể rất bất tiện. Chẳng hạn, Escdwsẽ không xóa từ theo sau văn bản bạn vừa chèn.


Sự bất tiện mà bạn giới thiệu có thể tránh được bằng cách luôn gõ một khoảng trắng trong chế độ chèn trước khi thoát. Sau đó, con trỏ rời khỏi chế độ chèn được đặt trên khoảng trắng và bạn có thể nhập Esc d eđể xóa từ phía trước. Tôi trở lại hành vi mặc định vì tôi cảm thấy nó đã thay đổi các hành vi khác đã được mã hóa trong đầu tôi.
mljrg

4

Đây là giải pháp của tôi.

Đây là một phiên bản ngắn gọn hơn của giải pháp được cung cấp trên trang wikia về điều này .

au InsertLeave * call cursor([getpos('.')[1], getpos('.')[2]+1])

+1 ở đây cũng vậy, để trích dẫn trang wiki, mặc dù người dùng thực sự không yêu cầu cách thay đổi hành vi này.
Kyle Strand

Bạn sẽ lưu ý nếu bạn đào đủ sâu vào Vim rằng nhiều plugin dựa vào hành vi mặc định (hơi không trực quan), vì vậy nếu bạn thấy một số thứ ngẫu nhiên ăn hoặc xé một ký tự, có thể do nguyên nhân này. Tôi không sử dụng autocommand này cho mình; nó hoạt động tốt, mặc dù.
Steven Lu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.