ฉันจะเปลี่ยนเคอร์เซอร์ระหว่างโหมดปกติและโหมดแทรกในกลุ่มได้อย่างไร


108

ฉันต้องการทราบวิธีการเปลี่ยนเคอร์เซอร์ใน Vim (เป็นสีรูปร่าง ฯลฯ ) ขึ้นอยู่กับโหมดที่คุณอยู่

ฉันลืมไปตลอดเวลาว่าฉันไม่ได้อยู่ในโหมดแทรกและเริ่มพิมพ์โค้ดซึ่งส่งผลให้เกิดเรื่องบ้าๆขึ้นมากมาย จะเป็นประโยชน์หากมีการแสดงภาพบางอย่างบนเคอร์เซอร์


20
ฉันขอแนะนำให้คุณเรียนรู้กฎข้อหนึ่ง: หยุดพิมพ์ => ออกจากโหมดแทรก จากนั้นคุณจะไม่สังเกตเห็นสถานการณ์ที่คุณลืมไปว่าคุณไม่ได้อยู่ในโหมดแทรก
ZyX

2
@ZyX ยกเว้นเมื่อคุณลืมออกจากโหมดแทรกหลังจากหยุดพิมพ์: p
gented

3
@ZyX นั่นเป็นกฎที่ดีและฉันก็ทำมาตลอด แต่ตัวบ่งชี้ภาพยังคงมีความสำคัญ กัญชาเป็นสิ่งถูกกฎหมายและฉันลืมสิ่งที่ฉันทำอยู่ตลอดเวลา
felwithe

คำตอบ:


108

ตัวเลือกยอดนิยมในการระบุการสลับไปยังและจากโหมดแทรกคือการสลับcursorlineตัวเลือกซึ่งรับผิดชอบว่าเส้นหน้าจอปัจจุบันถูกเน้นหรือไม่ (ดู:help cursorline):

:autocmd InsertEnter,InsertLeave * set cul!

หรืออีกทางหนึ่ง:

:autocmd InsertEnter * set cul
:autocmd InsertLeave * set nocul

แก้ไขCursorLineกลุ่มไฮไลต์เพื่อเปลี่ยนสไตล์ของเส้นเคอร์เซอร์ตามที่คุณต้องการ (ดู:help :highlightและ :help highlight-groups)


6
ฉันยังตั้งค่า cul เป็น higlight bg แทนการขีดเส้นใต้เริ่มต้น: hi CursorLine cterm = NONE ctermbg = black
Nikita Prokopov

มีเหตุผลที่สิ่งนี้จะใช้ไม่ได้ในกลุ่มของ cygwin หรือไม่? ฉันอยู่ในตัวแก้ไขและป้อนทั้งสองชุดของบรรทัดและฉันไม่สามารถตั้งค่าการไฮไลต์ใด ๆ นอกเหนือจากคอลัมน์แบบเต็มหรือแถวสูง
TankorSmash

@Tankor: cursorlineตัวเลือกนี้ไม่ได้ขึ้นอยู่กับความสามารถเฉพาะแพลตฟอร์มใด ๆ มันมีอยู่ในอินสแตนซ์ Vim ใด ๆ ที่คอมไพล์ด้วย+syntaxฟีเจอร์ (ซึ่งโดยปกติจะเป็นเช่นนั้น)
ib.

แน่นอนบันทึกไว้ที่ ~ / .vimrc ของคุณเพื่อความคงทนเช่น zo:echo 'autocmd InsertEnter,InsertLeave * set cul!' >>~/.vimrc
alchemy

76

ต่อไปนี้ทำงานใน xterm, urxvt และโปรแกรมจำลองเทอร์มินัลอื่น ๆ บน Linux iTerm2 บน macOS; Git Bash กับ ConEmu บน Windows; และอื่น ๆ (ดูความคิดเห็น):

let &t_SI = "\e[6 q"
let &t_EI = "\e[2 q"

" Optionally reset the cursor on start:
augroup myCmds
au!
autocmd VimEnter * silent !echo -ne "\e[2 q"
augroup END

ตัวเลือกอื่น ๆ (แทนที่หมายเลขหลัง\e[):

Ps = 0  -> blinking block.
Ps = 1  -> blinking block (default).
Ps = 2  -> steady block.
Ps = 3  -> blinking underline.
Ps = 4  -> steady underline.
Ps = 5  -> blinking bar (xterm).
Ps = 6  -> steady bar (xterm).

เมื่อคุณใช้tmuxสิ่งสำคัญคือต้องใช้แบบนั้น (โดยไม่มีไฟล์\<Esc>Ptmux;หนี) tmux จะติดตามรูปร่างเคอร์เซอร์ที่ถูกต้องเมื่อคุณสลับหน้าต่าง / บานหน้าต่าง

หากไม่ได้ผลให้ลองตั้งค่าTERM=xterm-256colorก่อนเริ่ม tmux หรือเพิ่มสิ่งนี้ใน.tmux.conf( ขอบคุณ @Steven Lu ):

set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'

2
ใช้งานได้ดีใน alacritty ตอนนี้
Steven Lu

ทำงานได้สมบูรณ์แบบใน xfce4-terminal
korst1k

@ ชาร์ลส์เกี่ยวกับสาเหตุที่มันไม่ทำงานในผงสำหรับอุดรูดูสิ่งนี้: superuser.com/questions/304318/…
WesternGun

1
การอัปเดตของฉัน: ในที่สุดก็ทำงานร่วมกับset -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'การกำหนดค่า tmux ของฉัน เห็นได้ชัดว่าถ้าคุณใช้setสำหรับการterminal-overridesได้โดยไม่ต้อง-aก็จะแทนที่การตั้งค่าที่มีอยู่แล้วนี้โดยมีการเริ่มต้น
Steven Lu

1
การแก้ปัญหามีความล่าช้าอย่างมากในการเปลี่ยนรูปร่างจากโหมดแทรกเป็นโหมดปกติบนเทอร์มินัลแบบธรรมดา (suckless st)
daGo

16

หากคุณใช้tmuxและiTerm2บนMacOS ,
ต่อไปนี้การเปลี่ยนแปลงเคอร์เซอร์จากบล็อกที่จะเคอร์เซอร์และไฮไลต์บรรทัดปัจจุบัน

if exists('$TMUX')
  let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
  let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\"
else
  let &t_SI = "\<Esc>]50;CursorShape=1\x7"
  let &t_EI = "\<Esc>]50;CursorShape=0\x7"
endif
:autocmd InsertEnter * set cul
:autocmd InsertLeave * set nocul

เครดิต: https://gist.github.com/andyfowler/1195581


1
ทราบว่านี่เป็นที่เฉพาะเจาะจงเพื่อ iTerm เนื่องจากมาตรฐานนั้นใช้งานได้จริง แต่ยังทำงานในเทอร์มินัลสนับสนุนอื่น ๆ ทั้งหมดนี่อาจเป็นคำตอบที่ผิด ดูที่นี่ -> stackoverflow.com/a/42118416/340947
Steven Lu

@StevenLu จริงๆแล้วคำตอบที่คุณแนะนำใช้ไม่ได้กับ iTerm2 (Mac) ในขณะที่อันนี้ใช้งานได้ สิ่งนี้เป็นเรื่องยุ่งเหยิงมากกว่าที่คุณคาดหวัง
CS

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

ฉันคิดสิ่งนี้ออก วิธีแก้ปัญหาคือการปรับแต่ง tmux เพื่อจัดการกับมันอย่างถูกต้องและอาจไม่ชัดเจน สิ่งที่ฉันต้องทำคือตรวจสอบให้แน่ใจว่าการกำหนดค่า tmux ของฉันterminal-overridesถูกต่อท้ายเท่านั้นดังนั้นจึงไม่ทำให้,*:Ss=\E[%p1%d q:Se=\E[2 qส่วนหนึ่งของterminal-overrides. ดังนั้น config ของฉันจึงดูเหมือนset -sa terminal-overrides ",xterm-256color-italic:Tc"(เพื่อตั้งค่าการเปิดใช้งานสี 24 บิตโดยไม่ต้องเหยียบย่ำรูปแบบเคอร์เซอร์ Ss / Se
Steven Lu

13

หากต้องการเปลี่ยนรูปร่างของเคอร์เซอร์ในโหมดต่างๆคุณสามารถเพิ่มสิ่งต่อไปนี้ลงใน.vimrcไฟล์ของคุณได้

สำหรับ GNOME Terminal (เวอร์ชัน 2.26):

if has("autocmd")
  au InsertEnter * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
  au InsertLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape block"
  au VimLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
endif

หากคุณใช้มากกว่าหนึ่งโปรไฟล์ใน GNOME Terminal คุณอาจต้องปรับให้เข้ากับโปรไฟล์ของคุณ

สำหรับ Konsole ใน KDE4:

let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"

ใช้ได้กับหลายแท็บและหน้าต่าง

ดูเพิ่มเติม:“ รูปร่างเปลี่ยนเคอร์เซอร์ในโหมดที่แตกต่าง ” ในกลุ่มเคล็ดลับวิกิพีเดีย


13
ฉันใช้ vim เป็นหลักใน tmux มากกว่า ssh ด้วยผงสำหรับอุดรู มีตัวเลือกที่เป็นสากลมากขึ้นหรือไม่?
lanrat

ทำงานอย่างมีเสน่ห์ ขอบคุณ.
เออร์เนสต์

1
การเปลี่ยนการตั้งค่าของ gnome-terminal ผ่านคำสั่ง gconftool-2 เป็นความคิดที่แย่มาก ไม่เพียงส่งผลต่อเทอร์มินัลที่ vim ของคุณกำลังทำงานอยู่ แต่ยังรวมถึงแท็บ gnome-terminal อื่น ๆ ในปัจจุบันและอนาคตทั้งหมดที่มีโปรไฟล์เดียวกัน
egmont

ใช้งานได้กับ konsole ขอบคุณ แต่ปัญหาหนึ่งคือการออกจากโหมดแทรกนั้นเป็นเรื่องสโลวไม่แน่ใจว่าทำไม
Hoang Tran

1
@HoangTran useset ttimeoutlen=0
Bananach

10

คุณสามารถลองใช้ปลั๊กอิน Terminus Vim :

ในโหมดแทรกรูปร่างเคอร์เซอร์จะเปลี่ยนเป็นแถบแนวตั้งแบบบาง ในโหมดแทนที่มันจะเปลี่ยนเป็นขีดเส้นใต้ เมื่อกลับสู่โหมดปกติระบบจะเปลี่ยนกลับเป็นรูปทรง "บล็อก" มาตรฐาน


นี่เป็นวิธีแก้ปัญหาที่สมเหตุสมผลที่สุด ควรมี: ตั้งค่าสำหรับสิ่งนี้โดยตรงใน VIM มาตรฐาน
user12711

ข้อกำหนด: gnome-terminal ( wiki.gnome.org/Apps/Terminal ) และเทอร์มินัลอื่น ๆ โดยใช้ไลบรารี VTE ( github.com/GNOME/vte ): รองรับบางส่วน (ตัวอย่างเช่นรองรับการเปลี่ยนแปลงรูปร่างเคอร์เซอร์ แต่ไม่เน้นการรายงาน) ในกรณีของฉัน (gnome-terminal 3.6.2) มันใช้ไม่ได้เลย
daGo

8

ฉันพบว่ามีประโยชน์เพียงให้เคอร์เซอร์กะพริบในโหมดแทรกและคงที่ในโหมดอื่น ๆ

set guicursor+=n-v-c:blinkon0

2

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

จริงๆแล้วฉันใช้ iTerm2 และใช้ Vim ภายในเทอร์มินัลบน macOS และเมื่อเข้าสู่โหมดแทรกเคอร์เซอร์ยังคงเป็นบล็อกและสร้างความสับสนเมื่อคุณอยู่ในโหมดแทรกหรือโหมดปกติ

ฉันต้องการแสดงเส้นบาง ๆ เป็นเคอร์เซอร์เมื่ออยู่ในโหมดแทรกและกลับไปที่บล็อกเมื่ออยู่ในโหมดปกติเหมือนที่ MacVim ทำ และจะทำเช่นนั้นก็สวยง่ายเพียงเพิ่มรายการนี้ลงของฉัน.vimrcเป็นไฟล์อธิบายไว้ที่นี่ :

let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_SR = "\<Esc>]50;CursorShape=2\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"

ป้อนคำอธิบายภาพที่นี่

แต่อย่างที่คุณเห็นมีความล่าช้าเมื่อกดปุ่มESCเพื่อออกจากโหมดแทรกกลับสู่โหมดปกติและแสดงบล็อกเป็นเคอร์เซอร์อีกครั้ง ดังนั้นเพื่อแก้ไขฉันพบสิ่งนี้:

set ttimeout
set ttimeoutlen=1
set listchars=tab:>-,trail:~,extends:>,precedes:<,space:.
set ttyfast

และตอนนี้มันใช้งานได้ดีอย่างที่คุณเห็น:

แก้ไขการหน่วงเวลากลับไปบล็อกเป็นเคอร์เซอร์

ฉันหวังว่ามันจะช่วยคนอื่นได้! 👻


1

ฉันไม่คิดว่าสิ่งนี้จะเพิ่มคำตอบที่คนอื่นให้ไปแล้วมากนัก แต่ฉันต้องการสรุปสิ่งต่างๆในที่เดียวและยังมีลิงก์ไปยังข้อมูลอ้างอิงที่เกี่ยวข้องด้วย

นี่คือสิ่งที่ตัวอย่างข้อมูลที่เกี่ยวข้องจาก.vimrcลักษณะของฉัน:

    " Cursor appearance
    "
    " See also: [1]'ANSI Control Functions Summary', [2]DECSCUSR, [3]xterm+tmux
    "   entry in terminfo.src.
    " [1] https://www.vt100.net/docs/vt510-rm/chapter4.html
    " [2] https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
    " [3] https://raw.githubusercontent.com/mirror/ncurses/master/misc/terminfo.src
    "
    " On:
    " - entered insert mode
    let &t_SI = "^[[5 q^[]12;Magenta\007" " blinking bar (Ss) in magenta (Cs)
    " - entered replace mode
    let &t_SR = "^[[0 q^[]12;Red\007" " blinking block (Ss) in red (Cs)
    " - leaving insert/replace mode
    let &t_EI = "^[[2 q^[]112\007" " terminal power-on style (Se) and colour (Cr)

หมายเหตุ: '^['จริงๆแล้วESCอักขระเป็นอักขระควบคุมหนึ่งตัว(ลำดับการหลีกเลี่ยง)


0

สิ่งนี้ทำงานได้อย่างถูกต้องบน xfce4-terminal:

เพิ่มสคริปต์ต่อไปนี้ในไฟล์ .vimrc

if has("autocmd")
  au InsertEnter * silent execute "!sed -i.bak -e 's/TERMINAL_CURSOR_SHAPE_BLOCK/TERMINAL_CURSOR_SHAPE_IBEAM/' ~/.config/xfce4/terminal/terminalrc"                                                                                          
  au InsertLeave * silent execute "!sed -i.bak -e 's/TERMINAL_CURSOR_SHAPE_IBEAM/TERMINAL_CURSOR_SHAPE_BLOCK/' ~/.config/xfce4/terminal/terminalrc"                                                                                          
  au VimLeave * silent execute "!sed -i.bak -e 's/TERMINAL_CURSOR_SHAPE_IBEAM/TERMINAL_CURSOR_SHAPE_BLOCK/' ~/.config/xfce4/terminal/terminalrc"  
endif

โดยย่อ: ดังที่คุณทราบว่า xfce4-terminal เก็บการตั้งค่าไว้ใน.config/xfce4/terminal/terminalrcไฟล์ สคริปต์TERMINAL_CURSOR_SHAPE_BLOCKจะเปลี่ยนเป็นTERMINAL_CURSOR_SHAPE_IBEAMเมื่อคุณอยู่ในโหมดแทรกและกลับไปที่บล็อกเมื่อคุณออกจากโหมดแทรกหรือกลุ่ม รู้สึกอิสระที่จะเปลี่ยนIBEAMเพื่อสิ่งที่คุณต้องการ ( BLOCK, IBEAMและUNDERLINEสามารถใช้ได้)


0

หากคุณกำลังใช้เวอร์ชันที่ทันสมัยnvimและคุณต้องการบรรลุเป้าหมายนี้คุณสามารถหลีกเลี่ยงวิธีแก้ปัญหาบางอย่างที่ระบุไว้ข้างต้นได้

การตั้งค่าด้านล่างจะเปลี่ยนจากบล็อกเคอร์เซอร์ในโหมดปกติเป็นการขีดเส้นใต้เคอร์เซอร์แทนที่เป็นเคอร์เซอร์บรรทัดในการแทรก

# ~/.tmux.conf
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",*256col*:Tc"
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q',w

" ~/.vimrc
" Sets cursor styles
" Block in normal, line in insert, underline in replace
set guicursor=n-v-c-sm:block,i-ci-ve:ver25-Cursor,r-cr-o:hor20

ฉันจัดการเพื่อให้สิ่งนี้ทำงานได้ด้วยการตั้งค่าต่อไปนี้ที่ดึงมาจากแหล่งข้อมูลทั้งสองนี้

ตุ้ยเคอร์เซอร์รูปร่าง

นักกีตาร์


-2

ฉันมักจะมีโหมด vim ปัจจุบันในสเตตัสไลน์เหนือสิ่งอื่นใด ถ้าคุณแสวงหาความเรียบง่ายคุณสามารถตั้งค่าเฉพาะข้อมูลนี้ลง statusline

อย่างไรก็ตามโดยปกติแล้วสิ่งที่บ้าคลั่งจริงๆจะเกิดขึ้นเมื่อคุณกดแคปล็อคและอยู่ในโหมดคำสั่ง (เนื่องจากตอนนี้ hjkl เป็น HJKL - แค่ J และ K ก็เพียงพอแล้วที่จะทำให้คุณดึงผมออกเมื่อคุณไม่เข้าใจว่าเกิดอะไรขึ้น:h Jและ:h Kเพื่อดูว่าฉันหมายถึงอะไร) เพียงแค่ระวังปุ่ม caps lockและคุณจะสามารถใช้ได้เกือบตลอดเวลา IMO


46
สิ่งนี้ตอบคำถามได้อย่างไร?
David Rivers

1
@DavidRivers เป็นแอปพลิเคชันของปัญหา XY ที่ OP กำลังขอวิธีแก้ไขปัญหาของเขา (ไม่รู้ว่าอยู่ในโหมดปกติเป็นกลุ่มและต้องการให้เคอร์เซอร์เปลี่ยนเพื่อระบุ) แต่กลับกลายเป็นว่าพอใจกับทางเลือกอื่น (และไม่ IMO วิธีแก้ปัญหาที่ยอดเยี่ยม (เสริมสร้างสถานะของเขากับรัฐ)
Steven Lu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.