Tùy chọn Tab Vs Space trong Vim


87

Vim rất có sức chứa khi nói đến tab Vs. sở thích về không gian. Theo tôi hiểu, tabstopcài đặt cho biết chiều rộng của một ký tự tab. Các shiftwidthquy định cụ thể thiết lập bao nhiêu cột để tăng / giảm khi sử dụng <<>>các lệnh, trong khi softtabstopảnh hưởng thiết lập số lượng khoảng trắng sẽ được chèn vào khi bạn nhấn Tabquan trọng trong chế độ chèn. Nếu expandtabđược bật, phím tab sẽ chèn softtabstopsố ký tự khoảng trắng. Trong khi expandtabtắt, nhấn Tabphím sẽ chèn một số ký tự tab + khoảng trắng nhỏ nhất có thể khớp với nhau softtabstop. (Hãy sửa lại cho tôi nếu tôi sai.)

Điểm cuối cùng này khiến tôi tự hỏi: có trường hợp thực tế nào mà bạn không muốn shiftwidth == tabstop && tabstop == softtabstopkhông? Tôi không thể nghĩ ra một. Theo như tôi được biết, sẽ là thuận tiện nhất nếu tôi có thể đặt cả 3 giá trị này thành cùng một giá trị, trong một lần gán duy nhất. ví dụ: gọi:

:set stab=4

tương đương với chạy:

:set tabstop=4 softtabstop=4 shiftwidth=4 

Bất cứ ai có thể đề nghị làm thế nào điều này có thể được thực hiện?


CẬP NHẬT

Cảm ơn các câu trả lời cho đến nay từ quá nhiều php , hobbskaiser.se . Thay vì trả lời từng người một, tôi đang cập nhật câu hỏi ở đây.

Softtabstop với expandtab bị tắt

Tôi đã nói ở trên rằng khi tắt mở rộng, nhấn phím Tab sẽ chèn số ký tự tab + dấu cách nhỏ nhất có thể khớp với nhau softtabstop. Tôi đứng đó, nhưng tôi nghĩ tôi cần phải giải thích ý của tôi. Tôi sẽ cố gắng làm như vậy bằng một vài ví dụ. Để làm theo, hãy chạy :set listđể bạn có thể nhìn thấy các ký tự tab.

tabstop=4 softtabstop=2 shiftwidth=4 noexpandtab

Trong chế độ chèn, nhấn phím tab sẽ chèn 2 ký tự khoảng trắng. Nhấn phím tab lần thứ hai và thay vì chèn thêm hai ký tự khoảng trắng (tổng cộng là 4 ký tự khoảng trắng), nó sẽ thay thế 2 khoảng trắng trước đó bằng một ký tự tab. Tabstop được đặt thành 4, do đó, một ký tự tab duy nhất có cùng chiều rộng bằng 4 dấu cách.

tabstop=4 softtabstop=6 shiftwidth=4 noexpandtab

Trong chế độ chèn, nhấn phím tab sẽ chèn 1 ký tự tab cộng với 2 dấu cách. Ký tự tab có chiều rộng là 4, do đó, tổng chiều rộng là 6 và đạt được điều này bằng cách sử dụng 3 ký tự. Nhấn phím tab lần thứ hai sẽ chèn hai ký tự tab và xóa hai khoảng trắng đã được chèn trước đó. Tổng chiều rộng là 12 và đạt được điều này bằng cách sử dụng 3 ký tự.

Trong cả hai ví dụ này, Vim chèn số ký tự tab + khoảng trắng tối thiểu có thể phù hợp với softtabstop.

Nếu tôi đang làm việc với expandtab bị tắt, tôi không thể thấy mình muốn kiểm soát chi tiết hơn có thể đạt được bằng cách đặt softtabstop thành một giá trị khác với tabstop. Nó vẫn sẽ có ích cho tôi để có thể thiết lập tabstop, softtabstopshiftwidthđể cùng giá trị với một lệnh duy nhất.

Expandtab có làm cho softtabstop dư thừa không?

tabstop=4 softtabstop=0 shiftwidth=4 expandtab

Trong chế độ chèn, nhấn phím tab sẽ chèn 4 khoảng trắng. Nhấn phím xóa sẽ xóa một khoảng trắng - vì vậy bạn phải xóa lùi 4 lần nếu vô tình nhấn phím tab.

tabstop=4 softtabstop=4 shiftwidth=4 expandtab

Trong chế độ chèn, nhấn phím tab sẽ chèn 4 khoảng trắng. Nhấn phím xóa lùi sẽ xóa 4 khoảng trắng.

Nếu tôi đang làm việc với expandtabbật, tôi muốn phím xóa để loại bỏ cùng một lượng khoảng trắng như phím tab chèn. Vì vậy, trong trường hợp này cũng vậy, tôi cảm thấy rằng nó sẽ hữu ích để có thể gán giá trị tương tự để tabstop, softtabstopshiftwidthcùng một lúc.

Một phím tắt sẽ vẫn hữu ích

Thật tuyệt khi Vim cung cấp rất nhiều tính linh hoạt, nhưng tôi không thấy mình cần nó. Tôi chỉ muốn có thể chọn chiều rộng của tab và cho dù đó là tab 'cứng' (sử dụng ký tự tab) hay tab 'mềm' (được tạo thành từ các khoảng trắng). Chuyển đổi giữa các tab cứng và mềm là đủ dễ dàng ( :set expandtab!), nhưng tôi ước nó đơn giản hơn để đặt độ rộng của tab mà không cần phải loay hoay với 3 tham số khác nhau.

Vì vậy, đề xuất được đề xuất của tôi cho một cái gì đó như :set stab=4vẫn còn tốt cho tôi.


Có vẻ như bạn có hai câu hỏi khác nhau ở đây, có lẽ bạn nên chia câu hỏi của mình thành hai.
Greg Hewgill

Bạn đúng! Tôi đã chuyển câu hỏi thứ hai thành một chủ đề của riêng nó.
nelstrom

1
Đây có vẻ giống như một RFE hơn là một câu hỏi. Do đó, bạn có thể nên đề xuất với cộng đồng VIM: vim.org/community.php - hoặc đơn giản là viết một bản vá. Ngoài ra, VIM có một cơ sở macro mở rộng cho phép bạn xác định các hoạt động mới, vì vậy rất có thể bạn chỉ cần tạo một macro thực hiện những gì bạn muốn.
kdgregory

@nelstrom Đối với câu hỏi của bạn is there a practical case where you wouldn't want shiftwidth == tabstop && tabstop == softtabstop?, mã nguồn của Vim sử dụng set shiftwidth=4 tabstop=8 noexpandtab. Có, một người thường muốn shiftwidth == softtabstop, nhưng điều đó không phụ thuộc vào giá trị tabstopcó.
jamessan

Câu trả lời:


56

Bản thân việc tạo một stabtùy chọn trong Vim sẽ không dễ dàng, nhưng tôi đã đưa ra lệnh / chức năng này mà bạn có thể thả vào .vimrc(hoặc tệp plugin nếu bạn có tổ chức siêu cao). Sử dụng :Stabvà bạn sẽ được nhắc về mức thụt lề và có sử dụng hay không expandtab. Nếu bạn nhấn enter mà không đặt mức thụt lề mới, nó sẽ chỉ in các cài đặt hiện tại.

"đặt tất cả những thứ này vào tệp .vimrc hoặc plugin của bạn
chỉ huy! -nargs = * Stab call Stab ()
chức năng! Cú đâm()
  let l: tabstop = 1 * input ('set shiftwidth =')

  nếu l: tabstop> 0
    "chúng ta có muốn cả expandtab không?
    let l: expandtab = confirm ('set expandtab?', "& Yes \ n & No \ n & Cancel")
    nếu l: expandtab == 3
      " Huỷ bỏ?
      trở về
    endif

    let & l: sts = l: tabstop
    let & l: ts = l: tabstop
    let & l: sw = l: tabstop

    nếu l: expandtab == 1
      tab mở rộng setlocal
    khác
      setlocal noexpandtab
    endif
  endif

  "hiển thị các tùy chọn đã chọn
  thử
    echohl ModeMsg
    echon 'set tabstop ='
    Câu hỏi echohl
    echon & l: ts
    echohl ModeMsg
    echon 'shiftwidth ='
    Câu hỏi echohl
    echon & l: sw
    echohl ModeMsg
    echon 'sts ='
    Câu hỏi echohl
    echon & l: sts. ''. (& l: et? '': 'không')
    echohl ModeMsg
    echon 'expandtab'
  cuối cùng
    echohl Không có
  sự cố gắng
chức năng cuối cùng

3
Cảm ơn vì kịch bản! Nó làm được nhiều hơn những gì tôi yêu cầu - tôi nghĩ rằng tôi muốn loại bỏ nó - nhưng tôi có thể dễ dàng tùy chỉnh nó theo ý thích của mình. Bạn đã cung cấp cho tôi một khóa học về lỗi nhỏ trong Vimscript, vì vậy tôi rất biết ơn. Tiền thưởng 100 điểm là của bạn!
nelstrom

9

Đây là nỗ lực đầu tiên của tôi khi viết VimScript, nhưng đây là:

function! Stab(value)
    let &shiftwidth  = a:value
    let &softtabstop = a:value
    let &tabstop     = a:value
endfunc

Nếu tôi đặt nó trong tệp .vimrc của mình, tôi có thể gọi nó bằng cách chạy :call Stab(X), trong đó X là chiều rộng tab mong muốn. Đây là một giải pháp thích hợp cho hiện tại, nhưng nếu ai đó có thể gợi ý cách gọi điện dễ dàng hơn, tôi sẽ rất biết ơn.

Tôi cũng đã tạo một hàm tóm tắt nhanh các cài đặt hiện tại, mà tôi đã ánh xạ tới ctrl-Tab:

nmap <C-Tab> :call TabParams()<CR>
function! TabParams()
    echo "tabstop:     ".&tabstop
    echo "shiftwidth:  ".&shiftwidth
    echo "softtabstop: ".&softtabstop
endfunc

Chà, tôi đã đặt tiền thưởng 100 điểm cho câu trả lời này, và bây giờ tôi đã tự mình giải được một nửa. Không chắc liệu tôi có thể chấp nhận câu trả lời của chính mình hay không ...


+1 yeah, nhưng nếu đây là điều bạn thực sự muốn, thì đó vẫn là một câu trả lời ok.
DaveParillo

2
Có thể bạn sẽ muốn sử dụng let & l: shiftwidth, v.v. để đặt phiên bản cục bộ.
SystemParadox

7

Bạn có thể vào chế độ chỉnh sửa cũng sử dụng Ctrl-Tđể thụt lề và Ctrl-Dđể deindent đến cấp độ thụt đầu dòng tiếp theo là thiết lập bởi shiftwidth, không phụ thuộc vào tabstop, softtabstophoặc expandtabcài đặt. Vim sẽ tự động thêm / bớt khoảng trắng hoặc tab để đưa bạn đến đúng cột.

Nếu bạn sử dụng các lệnh này để kiểm soát thụt lề thay vì Tab/ Backspacebạn không phải lo lắng về việc tất cả các cài đặt tab này khớp với nhau và luôn đạt được mức thụt lề chính xác.


3

Nếu expandtabđược đặt thì (vì quá nhiều php chỉ ra), softtabstopsẽ trở nên thừa. Lý do duy nhất bạn có thể đặt ra shiftwidthkhác với tabstoplà để phục vụ cho một thói quen kỳ quặc; ví dụ: bạn sử dụng thụt lề bốn dấu cách nhưng bạn thích tabchèn tám dấu cách.

Nếu expandtabkhông được đặt thì mọi thứ trở nên mờ nhạt hơn. Nếu bạn muốn mã của mình trông giống với các trình chỉnh sửa có catvà không phải vim như trong vim, thì mã của tabstopbạn phải luôn được đặt ở 8; trong trường hợp này, bạn sẽ đặt softtabstopshiftwidthcả hai ở mức thụt lề ưa thích của bạn. Thay vào đó, nếu bạn muốn mỗi "tab vật lý" trong tệp đại diện cho một mức thụt lề, bạn sẽ đặt tabstopshiftwidththành mức thụt lề ưa thích của mình và để softtabstopở mức 0 (đặt nó bằng tabstoptương đương ngoại trừ nếu bạn thay đổi tabstopnó sẽ không đồng bộ hóa, trong khi số 0 chỉ có nghĩa là "vui lòng bỏ qua điều này").


3
Tôi nghĩ điều này là sai vì chỉ khi softtabstopđặt thành giá trị phù hợp, backspace sẽ xóa một thụt lề có khoảng cách như thể nó là một tab. đó là điều bắt buộc để sử dụng lành mạnh.
u0b34a0f6ae

2

Bạn hiểu softtabstopexpandtabsai - vì vậy stabtùy chọn bạn đề xuất sẽ không hữu ích lắm.

expandtablà khi bạn muốn sử dụng dấu cách thay vì tab cho mọi thứ . Nếu bạn đặt expandtab, thì Vim sẽ bỏ qua softtabstoptùy chọn và sử dụng tabstopshiftwidthtìm ra bao nhiêu khoảng trắng để chèn.

softtabstopchỉ dành cho trường hợp bạn muốn sử dụng kết hợp các tab và khoảng trắng, cho phép bạn thụt lề với khả năng kiểm soát tốt (2 hoặc 4 khoảng trắng), trong khi vẫn giữ chiều rộng tab ở giá trị cao hơn (thường là 8) để văn bản xuất hiện trong các ứng dụng khác . Cài đặt softtabstop=tabstopkhông thực hiện được bất cứ điều gì vì Vim sẽ luôn sử dụng các tab để thụt lề.

Cập nhật: Như kaizer.se đã chỉ ra, nếu bạn đang sử dụng expandtab, thì bạn vẫn cần đặt softtabstopnếu bạn muốn Vim xóa lùi nhiều khoảng trắng như thể chúng là một tab.


Trong khi bạn đúng điều đó tabstopsofttabstoptrở thành một biến quá nhiều khi extpandtabđược đặt, tôi nghĩ bạn đã sai về mức độ ưu tiên. Chỉ cần thử nó: đặt ts=8 sts=4 etvà nhấn tab; con trỏ sẽ ở cột năm và bốn dấu cách sẽ được chèn vào, giống như khi bạn đã đặt ts=4 sts=0 et.
hobbs

5
Tôi nghĩ điều này là sai vì chỉ khi softtabstopđặt thành giá trị phù hợp, backspace sẽ xóa một thụt lề có khoảng cách như thể nó là một tab. đó là điều bắt buộc để sử dụng lành mạnh.
u0b34a0f6ae

2

Bạn có thường xuyên thay đổi cài đặt khoảng trắng đến mức bạn thực sự cần một chức năng để quản lý điều đó không? Nếu bạn đang gặp rắc rối với tabstop và cũng cài đặt expandtab, bạn có thể sẽ gặp rắc rối theo thời gian khi bạn thay đổi tệp với các giá trị khác nhau được chuyển đến stab. Hôm nay tôi sử dụng :call stab (4), ngày mai nó :call stab (2)và tuần trước nó đã được :call stab (8). Có vẻ như ngay cả khi bạn viết nó, bạn sẽ sớm ngừng sử dụng nó.

Nếu bạn định luôn vượt qua cùng một giá trị, tại sao không chỉ chỉnh sửa cài đặt chung của mình? Trong vim:

:e $MYVIMRC

và thêm những thứ sau:

set tabstop=4
set shiftwidth=4  "tabs are 4 spaces wide (default = 8)
set expandtab     "Convert tabs to spaces

Đây là cách .vimrc của tôi được thiết lập.


1

Một tùy chọn hữu ích là softtabstop=-1sẽ đặt nó thành giá trị shiftwidth.
Bạn cũng có thể đặt shiftwidththành 0, trong trường hợp đó tabstopgiá trị sẽ được sử dụng.

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.