ทำไมการจับคู่โหมดปกติ <Esc> นี้ส่งผลกระทบต่อการเริ่มต้น


13

ฉันกำลังประสบปัญหาแปลก ๆ Escกับการทำแผนที่ของโหมดปกติ

หากคุณสร้างไฟล์escmapvimrcด้วยเนื้อหา:

set nocompatible
set showcmd " Doesn't affect the problem: just makes it easier to see
nnoremap <Esc> :noh<CR><esc>

จากนั้นเริ่มเป็นกลุ่มโดยใช้ vimrc นี้:

vim --noplugin -u escmapvimrc

จากนั้นเป็นกลุ่มจะเริ่มต้นในโหมดผู้ประกอบการที่รอการมีคำสั่งรอสำหรับการป้อนข้อมูลเพิ่มเติมการแสดงไฟล์ที่ว่างเปล่าและมีบรรทัดคำสั่งแสดงc:noh

หากคุณลบnnoremapบรรทัดปัญหาจะหายไป

หากคุณทำการดีบั๊กและทำตามขั้นตอนทุกอย่างที่คุณได้รับผลลัพธ์ต่อไปนี้:

Entering Debug mode.  Type "cont" to continue.
/[...]/escmapvimrc
line 1: set nocompatible
>s
/[...]/escmapvimrc
line 2: set showcmd " Doesn't affect the problem: just makes it easier to see
>s
/[...]/escmapvimrc
line 3: nnoremap <Esc> :noh<CR><esc>
>s
/[...]/escmapvimrc
line 4: End of sourced file
>s
Press ENTER or type command to continue

หลังจากที่คุณกด Enter หน้าจอเริ่มต้นเป็นกลุ่มจะปรากฏขึ้นและใต้:

Entering Debug mode.  Type "cont" to continue.
cmd: noh
>s

จากนั้นหน้าจอเริ่มต้นของ Vim จะหายไปและคุณอยู่ในโหมดรอดำเนินการตามที่อธิบายไว้ข้างต้น

เกิดอะไรขึ้น?

แก้ไข:พฤติกรรมตามที่อธิบายไว้ใน Vim 7.3 ใน Vim 7.4.52 nmapทำให้ Vim เริ่มทำงานในโหมดแทนที่เมื่อเริ่ม Vim โดยไม่มีไฟล์ (หาก Vim 7.4.52 เริ่มต้นด้วยไฟล์อย่างไรก็ตามมันก็จะเริ่มต้นด้วยคำสั่ง c-สัตย์ซื่อ) ทั้งสองวิธีปัญหาจะหายไปเมื่อลบ nmap ออก


ฉันทำซ้ำนี้เป็นกลุ่ม แต่บรรทัดคำสั่งไม่แสดง:nohให้ฉัน การทำเช่นเดียวกันกับ gvim ไม่แสดงพฤติกรรมนี้
PhilippFrank

1
การทำแผนที่ร่วมกันเพื่อล้างไฮไลต์การค้นหาคือ:nnoremap <c-l> :noh<cr><c-l>
Peter Rincker

ในฐานะที่เป็นบันทึกด้านข้างคุณสามารถใช้/alksdjflaskjเพื่อล้างไฮไลต์การค้นหาที่ค่อนข้างเร็วเช่นกัน
Shahbaz

คำตอบ:


11

Vim ส่งรหัสพิเศษบางอย่าง (ซึ่งโดยปกติจะมี<esc>คีย์) ในระหว่างการเริ่มต้นเพื่อตรวจสอบหลายสิ่ง (สี, bs, ... ) หากคุณทำแผนที่<esc>สิ่งนี้อาจทำให้สับสนในการแยกวิเคราะห์ของรหัสส่งคืนและสิ่งแปลก ๆ อาจเกิดขึ้นได้

ดังนั้นให้ใช้แผนที่ด้านบนของคุณหลังจากทุกอย่างถูกตั้งค่าอย่างถูกต้องแล้วเท่านั้น (เช่นผ่าน VimEnter autocommand)


1
พวกมันถูกส่งไปทุกครั้งที่'term'มีการตั้งค่าตัวเลือก ซึ่งโดยปกติจะเกิดขึ้นในระหว่างการเริ่มต้นเท่านั้น แต่อาจมีสถานการณ์ที่ถูกตั้งค่าไว้ที่รันไทม์
jamessan

ในกรณีพิเศษนี้ดูเหมือนว่าจะเกิดจาก may_req_ambiguous_char_width () ซึ่งเรียกว่าเมื่อเริ่มต้นเท่านั้น
Christian Brabandt

ฉันกำลังวางแผนที่จะลองสิ่งนี้ (ซึ่งเป็นสาเหตุที่ฉันไม่ยอมรับคำตอบอื่น ๆ ) ดีที่ได้รับการยืนยันว่าควรใช้งานได้
Rich

สิ่งนี้ได้ทำเคล็ดลับแม้ว่าจะVimEnterไม่ได้ผล
รวย

คุณล้อเล่นใช่ไหม? การหลีกเลี่ยงที่ใช้ในการสื่อสารควรแยกจากการทำแผนที่ปุ่ม Escape
shawnhcorey

11

เทอร์มินัล Linux ใช้ ANSI escape sequences (เช่นสตริงของอักขระที่ขึ้นต้นด้วย<Esc>) เพื่อส่งคีย์พิเศษไปยัง Vim และเป็นส่วนหนึ่งของโปรโตคอลการสื่อสารที่แอพพลิเคชั่นสอบถามความสามารถของมัน การทำแผนที่ของคุณรบกวนสิ่งนั้นและนำไปสู่พฤติกรรม "แปลก" เหล่านี้

ดังนั้นไม่ <Esc>map ใช้รหัสอื่น ปัญหามีความเด่นชัดน้อยกว่าใน GVIM แต่ฉันไม่อยากแนะนำที่นั่น


โชคไม่ดีที่ฉันได้ทำแผนที่นี้มาเกือบตั้งแต่ฉันเริ่มใช้ Vim ดังนั้นตอนนี้ความทรงจำของกล้ามเนื้อของฉันก็ค่อนข้างดี ขอบคุณสำหรับคำอธิบาย
Rich

ฉันควรจะเพิ่มเพื่อเห็นแก่ปัญหาที่อธิบายไว้เป็นปัญหาเดียวที่ฉันรู้ว่าเกิดจากการทำแผนที่นี้และปัญหาที่ไม่ได้รับการแก้ไขเพียงอย่างเดียวที่ฉันสามารถจำได้ด้วย Vim
Rich

1
@Rich มันยากแค่ไหนที่จะคุ้นเคยกับการใช้สิ่งที่ชอบ<Esc><Esc>?
Random832

@ Random832 นั่นเป็นความคิดที่น่าสนใจ
คนรวย

1
โปรแกรม xterm ทั้งหมดจะทำเช่นนี้เพราะเลียนแบบเทอร์มินัล VT-100 มันไม่มีส่วนเกี่ยวข้องกับ Linux iOS ซึ่งใช้ BSD ไม่ใช่ Linux ก็จะมี xterms ที่เลียนแบบ VT-100
shawnhcorey

1

ลองสิ่งนี้:

augroup escape_mapping
  autocmd TermResponse * nnoremap <Esc> :noh<CR><esc>
augroup end

cf /programming//a/16027716/400545


มันใช้งานไม่ได้กับฉัน หลังจากนั้นแทนที่การแมปในescapemapvimrcไฟล์ของฉันด้วยสิ่งนี้เมื่อการเริ่มต้น Vim เสร็จสมบูรณ์ฉันอยู่ในโหมดบรรทัดคำสั่งด้วยบรรทัดคำสั่งที่มีเนื้อหาต่อไปนี้: :83/94/95^G(นั่นคือตัวอักษรCTRL-Gที่ท้าย) บิตนี้:helpดูเหมือนว่าจะแนะนำนี้อาจจะไม่ได้เวลาที่ดีที่สุดในการตั้งค่าการทำแผนที่:Note that this event may be triggered halfway executing another event, especially if file I/O, a shell command or anything else that takes time is involved.
รวย

1

ฉันพยายามตั้งค่า autocommand เพื่อตั้งค่าการแมปในภายหลังเมื่อเริ่มต้น แต่ปัญหายังคงเกิดขึ้น * * * *

ในที่สุดฉันก็สร้างคำสั่งอัตโนมัติและเกิดขึ้นในครั้งแรกที่ฉันเข้าสู่โหมดแทรก เห็นได้ชัดว่านี่ไม่ใช่วิธีการแก้ปัญหาที่สมบูรณ์แบบ แต่สำหรับฉันมันใช้งานได้เกือบตลอดเวลาและดูเหมือนจะดีที่สุดที่ฉันสามารถทำได้:

อัปเดต : หลังจากใช้รุ่นที่ยาวกว่าด้านล่างโดยไม่มีปัญหาในสองสามปีที่ผ่านมาฉันคิดว่ามันอาจจะมีการออกแบบทางวิศวกรรมเกินเล็กน้อยและตั้งแต่นั้นฉันก็ใช้รุ่นที่ง่ายกว่านี้มากซึ่งแทนที่จะทำการแมปทุกครั้ง

augroup escape_mapping
  autocmd!
  autocmd InsertEnter * call s:setupEscapeMap()
augroup END

function! s:setupEscapeMap()
  nnoremap <Esc> :noh<CR><Esc>
endfunction

การแมปไม่จำเป็นต้องรีเซ็ตทุกครั้งที่คุณเข้าสู่โหมดแทรก แต่ก็ไม่ได้ทำอันตรายใด ๆ สำหรับ Vim

รุ่นดั้งเดิม :

if !exists('g:escape_mapped')  " Only need to set the mapping up once.
  augroup escape_mapping
    autocmd!
    " Create the autocommand, to fire when Insert mode is entered
    autocmd InsertEnter * call s:setupEscapeMap()
  augroup END
endif

function! s:setupEscapeMap()
  " Actually create the mapping
  nnoremap <Esc> :noh<CR><Esc> 

  " Now the map exists, so we won't ever need the autocommand again.
  let g:escape_mapped = 1

  " Tidy up the autocommand and group
  autocmd! escape_mapping InsertEnter *
  augroup! escape_mapping
endfunction

* ฉันพยายามแนบไปกับกิจกรรมต่างๆ: VimEnter, BufReadPost, BufWinEnterและแม้กระทั่งCursorMoved(!) แต่เหล่านี้ทั้งหมดดูเหมือนจะเกิดไฟไหม้เร็วเกินไป


คุณเคยลองชุดคำสั่งอัตโนมัติTermResponseหรือไม่?
Christian Brabandt

@ChristianBrabandt ฉันมีตอนนี้ มันใช้งานไม่ได้สำหรับฉัน :(
รวย

ฉันเพิ่งเรียนรู้ว่า TermResponse ไม่ได้ถูกเรียกใช้สำหรับคำสั่งการสืบค้นที่เกี่ยวข้องกับเทอร์มินัลทั้งหมดซึ่งเสียงเรียกนั้นเพิ่งส่งออกไป ( t_RV, t_u7, t_RF, t_RBและอื่น ๆ อาจจะ.) ดังนั้นอาจนี้ยังขึ้นอยู่กับสถานีของคุณ
คริสเตียน Brabandt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.