Làm cách nào để tùy chỉnh chế độ vim của zsh?


25

Ok, cuối cùng tôi đã thực hiện thay đổi lớn. Trong .zshenv của tôi, tôi đã thay đổi EDITOR của mình:

export EDITOR=vim

Có một vài câu hỏi mà tôi có rất ít đến nỗi tôi không muốn bắt đầu những câu hỏi riêng cho chúng. Họ đây rồi:

  1. Làm cách nào để có được zsh để phân biệt giữa chế độ chèn và chế độ lệnh như trong vim? Tốt hơn là điều này sẽ thay đổi con trỏ từ gạch chân thành một khối như trong vim, nhưng hiển thị văn bản ở phía dưới cũng sẽ hoạt động.

  2. Làm thế nào để tôi có được nó để hành động giống như vim? Chẳng hạn, tôi muốn nó ở chế độ lệnh theo mặc định và không đi ra khỏi nó sau một lệnh.


//, Bạn đã nhận được bất kỳ hành vi kỳ lạ với chỉnh sửa dòng lệnh? Tôi đã chạy vào~ nhân vật bị chèn khi tôi nhấn Deletephím zsh. Tôi đã hỏi một câu hỏi về nó ở đây: superuser.com/questions/997593/ từ
Nathan Basan

Câu trả lời:


25

1. ) (xem http://zshwiki.org/home/examples/zlewidgetshttp://pthree.org/2009/03/11/add-vim-editing-mode-to-your-zsh-prompt/ ) :

hàm zle-line-init zle-keymap-select {
    RPS1 = "$ {$ {KEYMAP / Abbeymd / - BÌNH THƯỜNG -} / (chính | viins) / - CHERTN -}"
    RPS2 = $ RPS1
    nhắc nhở thiết lập lại
}
zle -N zle-line-init
zle -N zle-keymap-select

Ở đâu:

  • "RPS" là viết tắt của 'chuỗi dấu nhắc phải' và xác định dấu nhắc xuất hiện ở phía bên phải của thiết bị đầu cuối và cú pháp $ {biến / mẫu / thay thế} là 'mở rộng tham số', xem: http: // mywiki .wooledge.org / BashSheet # Parameter_Operations .

  • 'zle -N' làm cho các widget có thể xác định được của người dùng 'zle-line-init' và 'zle-keymap-select' bị ràng buộc (với các hàm shell cùng tên), do đó chúng sẽ được gọi khi trình soạn thảo dòng được khởi tạo và sơ đồ bàn phím được thay đổi tương ứng, xem: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#SEC125 .

2. ) Tôi nghi ngờ rằng bạn phải viết một tiện ích zsh khác để làm điều đó, lấy cảm hứng từ liên kết đầu tiên trong hai liên kết cho vấn đề đầu tiên.


22

Giải pháp của akira có vấn đề sau khi sử dụng lời nhắc nhiều dòng: khi chuyển từ chế độ in sang cmd, lời nhắc vẽ lại khiến một vài dòng bị xóa khỏi đầu ra trước đó (và lời nhắc mới được hiển thị vài dòng ở trên). Có bao nhiêu dòng phụ thuộc vào số lượng dòng bạn có trong lời nhắc của bạn.

Cách để đối phó với điều đó là sử dụng zle-line-finish, mà không sử dụng zle reset-promptở đó. Một ví dụ:

# perform parameter expansion/command substitution in prompt
setopt PROMPT_SUBST

vim_ins_mode="[INS]"
vim_cmd_mode="[CMD]"
vim_mode=$vim_ins_mode

function zle-keymap-select {
  vim_mode="${${KEYMAP/vicmd/${vim_cmd_mode}}/(main|viins)/${vim_ins_mode}}"
  zle reset-prompt
}
zle -N zle-keymap-select

function zle-line-finish {
  vim_mode=$vim_ins_mode
}
zle -N zle-line-finish

Và sau đó, bạn có thể thêm nó vào dấu nhắc bên phải của mình, ví dụ:

RPROMPT='${vim_mode}'

Đây là trực tiếp từ bài viết trên blog của tôi về nó:


Câu trả lời này sẽ nhận được rất nhiều phiếu bầu. Đây là lần đầu tiên tôi thấy giải pháp này và nó hoạt động ở những nơi khác. Tôi đã dành một giờ loay hoay với các zle-line-inittiện ích không có kết quả. Thay đổi nó để phù hợp với những gì Pawel cung cấp và chơi lô tô!
Colin R

Cảm ơn! Nó vẫn không thể chống đạn 100% - thỉnh thoảng tôi gặp một tình huống trong đó một số dòng từ đầu ra trước đó của tôi bị xóa - nhưng nó hiếm khi xảy ra đến mức tôi chỉ bỏ qua nó.
Paweł Gościcki

1
RPROMPT2cũng nên được đặt để trạng thái được hiển thị trong các dòng tiếp tục. Ngoài ra, khi sử dụng, bạn có thể muốn làm setopt transient_rpromptnhư vậy để các chế độ cho các dòng được chấp nhận trước đó không được hiển thị.
qqx

Một điều vẫn còn thiếu: Nếu tôi quay lại chế độ emacs ( bindkey -e) thì nó vẫn hiển thị [INS].
Daniel

1
@cheflo bạn có thể xem phiên bản hiện tại của thiết lập này tại đây: github.com/pjg/dotfiles/blob/master/.zshrc#L518-L584 - có lẽ điều đó sẽ giúp bạn
Paweł Gościcki 24/2/2016

5
zle-line-init() { zle -K vicmd; }
zle -N zle-line-init

hai dòng này đảm bảo nó bắt đầu trong chế độ lệnh


Không hoạt động, zsh vẫn bắt đầu ở chế độ chèn
baldrs

0

Dưới đây sẽ thiết lập cho bạn một con trỏ được sửa đổi và lời nhắc hiển thị chế độ bạn đang ở. Bạn có thể thay đổi DEFAULT_VI_MODEthành viinshoặc vicmd. Chỉ cần dán bên dưới vào một cái mới .zshrcđể bắt đầu:

# Prefer vi shortcuts
bindkey -v
DEFAULT_VI_MODE=viins
KEYTIMEOUT=1

__set_cursor() {
    local style
    case $1 in
        reset) style=0;; # The terminal emulator's default
        blink-block) style=1;;
        block) style=2;;
        blink-underline) style=3;;
        underline) style=4;;
        blink-vertical-line) style=5;;
        vertical-line) style=6;;
    esac

    [ $style -ge 0 ] && print -n -- "\e[${style} q"
}

# Set your desired cursors here...
__set_vi_mode_cursor() {
    case $KEYMAP in
        vicmd)
          __set_cursor block
          ;;
        main|viins)
          __set_cursor vertical-line
          ;;
    esac
}

__get_vi_mode() {
    local mode
    case $KEYMAP in
        vicmd)
          mode=NORMAL
          ;;
        main|viins)
          mode=INSERT
          ;;
    esac
    print -n -- $mode
}

zle-keymap-select() {
    __set_vi_mode_cursor
    zle reset-prompt
}

zle-line-init() {
    zle -K $DEFAULT_VI_MODE
}

zle -N zle-line-init
zle -N zle-keymap-select

# Optional: allows you to open the in-progress command inside of $EDITOR
autoload -Uz edit-command-line
bindkey -M vicmd 'v' edit-command-line
zle -N edit-command-line

# PROMPT_SUBST enables functions and variables to re-run everytime the prompt
# is rendered
setopt PROMPT_SUBST

# Single quotes are important so that function is not run immediately and saved
# in the variable
RPROMPT='$(__get_vi_mode)'

Lưu ý: Tôi chỉ thử nghiệm điều này trong Terminal.app (2.7.3) trên MacOS (10.12.6) với zsh (5.3.1). Ngoài ra, nếu bạn thêm edit-command-linethì chế độ cũng sẽ được đặt chính xác.

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.