มีวิธีปฏิบัติที่ดีที่สุดในการพับไฟล์ vimrc หรือไม่


21

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

  • ฉันพยายามตั้งค่าวิธีการพับเป็นindentแต่ฉันไม่ชอบผลลัพธ์ (มันยุ่งเกินไปเป็นส่วนใหญ่เพราะส่วนใหญ่ของฉันvimrcไม่ได้เยื้องจริงๆ)
  • ฉันยังพยายามชุดfoldmethodไปexprและsyntaxแต่ผมก็ไม่สามารถที่จะพับอะไรถูกต้อง
  • ที่นี่ใช้diffเป็นวิธีการพับดูไม่เกี่ยวข้อง (หรือถ้าฉันไม่เข้าใจวิธีใช้)
  • ดังนั้นสำหรับตอนนี้ฉันใช้markerวิธีที่ไม่พอใจฉันอย่างสมบูรณ์เพราะ"{{{และ"}}}เครื่องหมายซึ่งฉันพบว่า "มีเสียงดัง" ในไฟล์

ดังนั้นฉันต้องการทราบว่ามีแนวทางปฏิบัติที่ดีที่สุดหรือแนวทางทั่วไปเกี่ยวกับการพับกอย่างถูกต้องvimrcหรือไม่

หมายเหตุ 1:เราทุกคนรู้ดีว่าไม่ใช่ฟอรัมและไม่ได้รวบรวมความคิดเห็นส่วนตัวและนั่นไม่ใช่สิ่งที่ฉันกำลังมองหา: แน่นอนฉันเดาว่าบางคนมีความชอบ แต่พวกเขาต้องการทราบว่าทำไมใช้ เครื่องหมาย (ตัวอย่าง) ปรับปรุงความสามารถในการอ่านได้มากกว่าการใช้การเยื้อง

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

แก้ไข 1:ฉันควรจะคิดว่าฉันvimrcได้แบ่งย่อยแล้วในส่วน (และบางครั้งส่วนย่อย) เป็นคนหลัก

  • ตัวเลือกทั่วไป
  • ปลั๊กอิน (มีส่วนย่อยสำหรับแต่ละปลั๊กอินและการกำหนดค่า)
  • แมป
  • การนำทาง (ยังมีส่วนย่อย)
  • สี
  • ฯลฯ ...

และนี่เป็นโครงสร้างที่ทำให้ฉันคิดถึงการพับ: ฉันรู้สึกว่าสามารถส่งออกเฉพาะส่วนที่ฉันสนใจในบางจุดนั้นเป็นสิ่งที่สะดวกมาก

แก้ไข 2:คำตอบที่กล่าวถึงการแบ่งย่อยของvimrcในหลาย ๆ ไฟล์นั้นถูกต้อง แต่ตามความชอบส่วนตัวฉันควรใช้การพับเนื่องจากฉันคิดว่ามันง่ายกว่าที่จะรักษาเพียงหนึ่งไฟล์ใน git repo ที่มี dotfiles ของฉัน นั่นเป็นเพียงการตั้งค่าส่วนตัวและฉันรู้ว่ามันเป็นไปได้ที่จะใช้วิธีการนี้ แต่ฉันชอบที่จะใช้การพับ


ฉันคิดว่าการใช้"{{{เป็น 'วิธีชอบ' ที่สุดในการทำสิ่งต่าง ๆ ปลั๊กอิน
โซลาร์เซลล์

คำตอบ:


22

ฉันมีโมเดลดังต่อไปนี้ที่ด้านล่างของฉันvimrcซึ่งฉันคัดลอกมาจาก godlygeek ผู้เขียนตาราง :

"" vim:fdm=expr:fdl=0
"" vim:fde=getline(v\:lnum)=~'^""'?'>'.(matchend(getline(v\:lnum),'""*')-2)\:'='

สิ่งนี้จะทำให้บรรทัดใด ๆ ที่เริ่มต้นด้วย 2+ "'s fold ยิ่ง"'s ลึกพับ สิ่งนี้ช่วยให้คุณสามารถแบ่งส่วนย่อยหากคุณต้องการ


ฉันไม่สามารถทดสอบได้ในตอนนี้ แต่ดูเหมือนจะเป็นทางออกที่ดีสำหรับฉัน! ขอบคุณสำหรับการแบ่งปัน!
statox

บางคำอธิบาย: getline (v: lnum) ส่งคืนสตริงของบรรทัดที่กำหนดโดยหมายเลขบรรทัด (v: lnum); = ~ หมายถึงการจับคู่นิพจน์ทั่วไป; '^ ""' หมายถึงทุกบรรทัดที่ขึ้นต้นด้วยสอง "s; match (getline (v: lnum)," "* *") - 2 นับจำนวนพิเศษ "ซึ่งหมายความว่า" "" จะพับด้วยระดับ 1 " "" "จะพับด้วยระดับ 2 และอื่น ๆ ; getline (v: lnum) = ~ '^" "' จะคืนค่าจริงหรือเท็จขึ้นอยู่กับบรรทัด v: lnum ที่ขึ้นต้นด้วยสอง" หรือไม่; หากเป็นความจริงค่าการตั้งค่าจะถูกตั้งค่าเป็น>extra number of "(ระดับเริ่มต้นซึ่งนั่งโดยตัวเลขหลังจาก <ที่บรรทัดนี้) หรือ'='(ใช้ระดับของบรรทัดก่อนหน้า) ความหมายสามารถพบได้ที่fold-expr
van abel

หลังจากการปรับปรุงเป็นกลุ่มล่าสุด 1517/01/08) ฉันได้รับ "" ข้อผิดพลาดที่ตรวจพบในขณะที่การประมวลผล modelines" กับการกำหนดค่านี้.
อพอลโล

9

เป็นความคิดที่ดีที่จะกำหนดหมวดหมู่ของคุณเองใน.vimrcรายการแรก(เช่นรายการที่มีรายการย่อยและรายการย่อย) และเพิ่มปลั๊กอิน / การตั้งค่า / ฟังก์ชั่นทั้งหมดของคุณลงในหมวดหมู่นั้น ๆ เมื่อรวมกับการพับแบบกำหนดเองแล้วสามารถใช้งานได้ดี:

ตัวอย่าง

.vimrcตัวอย่างข้างต้นแสดงให้เห็นว่าเป็นไปได้ประเภทที่ผมพบที่เป็นประโยชน์ในการจัดโครงสร้างของฉัน ใช้การตั้งค่าการพับแบบกำหนดเองต่อไปนี้:

""""""""""""""""""""""""
"  THIS IS A CATEGORY  "
""""""""""""""""""""""""
"" Autofolding .vimrc
" see http://vimcasts.org/episodes/writing-a-custom-fold-expression/
""" defines a foldlevel for each line of code
function! VimFolds(lnum)
  let s:thisline = getline(a:lnum)
  if match(s:thisline, '^"" ') >= 0
    return '>2'
  endif
  if match(s:thisline, '^""" ') >= 0
    return '>3'
  endif
  let s:two_following_lines = 0
  if line(a:lnum) + 2 <= line('$')
    let s:line_1_after = getline(a:lnum+1)
    let s:line_2_after = getline(a:lnum+2)
    let s:two_following_lines = 1
  endif
  if !s:two_following_lines
      return '='
    endif
  else
    if (match(s:thisline, '^"""""') >= 0) &&
       \ (match(s:line_1_after, '^"  ') >= 0) &&
       \ (match(s:line_2_after, '^""""') >= 0)
      return '>1'
    else
      return '='
    endif
  endif
endfunction

""" defines a foldtext
function! VimFoldText()
  " handle special case of normal comment first
  let s:info = '('.string(v:foldend-v:foldstart).' l)'
  if v:foldlevel == 1
    let s:line = ' ◇ '.getline(v:foldstart+1)[3:-2]
  elseif v:foldlevel == 2
    let s:line = '   ●  '.getline(v:foldstart)[3:]
  elseif v:foldlevel == 3
    let s:line = '     ▪ '.getline(v:foldstart)[4:]
  endif
  if strwidth(s:line) > 80 - len(s:info) - 3
    return s:line[:79-len(s:info)-3+len(s:line)-strwidth(s:line)].'...'.s:info
  else
    return s:line.repeat(' ', 80 - strwidth(s:line) - len(s:info)).s:info
  endif
endfunction

""" set foldsettings automatically for vim files
augroup fold_vimrc
  autocmd!
  autocmd FileType vim 
                   \ setlocal foldmethod=expr |
                   \ setlocal foldexpr=VimFolds(v:lnum) |
                   \ setlocal foldtext=VimFoldText() |
     "              \ set foldcolumn=2 foldminlines=2
augroup END

ในการกำหนดหมวดหมู่และหมวดหมู่ย่อยของคุณเองให้ใช้ไวยากรณ์ต่อไปนี้:

""""""""""""""
"  Category  "
""""""""""""""
"" Subcategory
""" Subsubcategory
" Just a comment, gets ignored no matter where

หมวดหมู่ระดับบนสุดนั้นสามารถสร้างได้ง่ายมากถ้าคุณใช้vim-snippets (เช่นUltiSnips ): เพียงแค่ขยายboxหรือbboxตัวอย่างที่ได้รับจาก vim-snippets (เขียนboxหรือbboxกดไกปืนเพื่อขยาย)

หากต้องการสลับพับเปิดและปิดเร็วขึ้นด้วยการกด space สองครั้ง:

let mapleader = "\<space>"
" Toggle folds
nnoremap <silent> <leader><Space> @=(foldlevel('.')?'za':"\<Space>")<CR>
vnoremap <leader><space> zf

ด้วยวิธีนี้คุณมีโครงสร้างที่ดี.vimrcซึ่งสามารถสำรวจได้อย่างง่ายดาย


+1 สำหรับ gif อนิเมชั่นที่ดี :) แค่อยากรู้อยากเห็นคุณใช้ปุ่มอะไรในการพิมพ์อะไร
mMontu

@mMontu: ฉันใช้ screenkey เพื่อแสดงปุ่มและ gtk-recordmydesktop เพื่อบันทึก (ทั้งใน repos Debian) ด้วย 5fps คลิป 45 วินาทีนั้นน้อยกว่า MiB จากนั้นแปลงเป็นออนไลน์เพื่อ GIF (นั่นคือที่ที่การบิดเบือนเข้ามาก่อนที่คุณภาพของภาพจะสมบูรณ์แบบ)
cbaumhardt

7

ฉันใช้ไฟล์หลักvimrcเป็นลิงค์ไปยังไฟล์ที่ถูกจัดหมวดหมู่อื่น ๆ จัดหาไฟล์แต่ละไฟล์ตามที่ระบุเช่นตัวเลือก Vim ในไฟล์เดียวการตั้งค่าปลั๊กอินในไฟล์อื่น

"--- Vim Options
source ~/.vim/config/vim_options.vim

"--- Here Be Functions!
" (need to be sourced before stuff that uses 'em)
runtime! functions/*.vim

"--- Key Mapping
source ~/.vim/config/key_mapping.vim

"--- Folding
source ~/.vim/config/folding.vim

"--- Autocmds
source ~/.vim/config/autocmds.vim

"--- We Are Plugged In!
source ~/.vim/config/plugins.vim

" vim: ft=vim fdm=marker

ในฐานะที่เป็นคำตอบโดยตรงสำหรับคำถาม OP ฉันใช้วิธีทำเครื่องหมาย แต่ออกไปทางด้านขวาด้วยระยะห่างและรอบหมวดหมู่มากกว่าแต่ละรายการส่วนใหญ่ ฉันทำแต่ละปลั๊กอินแยกต่างหาก


ฉันลืมที่จะแม่นยำว่าในคำถามของฉัน: ฉันไม่ได้เป็นแฟนของ "แยก" vimrcในไฟล์ที่แตกต่างกันเพราะ (IMO) มันเพิ่มความซับซ้อนและทำให้ยากที่จะรักษา เกี่ยวกับการพับคุณหมายถึงอะไรโดย "ออกไปทางด้านขวาด้วยระยะห่าง"
statox

ฉันหมายถึง" {{{มีช่องว่างจำนวนมากในนั้นเพราะtextwidthเครื่องหมายของคุณอยู่ใกล้กับขอบด้านขวา ฉันยังมีฟังก์ชั่น FoldText ส่วนบุคคลในไฟล์ folding.vim ฉันชอบไฟล์แยกกันเพื่อให้ git repo หนึ่ง mod ที่เฉพาะเจาะจงต่อการคอมมิท
Cometsong

7

คุณสามารถพูดได้ว่า "แนวปฏิบัติที่ดีที่สุด" เป็นเรื่องของความเห็นที่ดีกว่า :) แต่มีสองวิธีที่ (1) เข้าใจได้อย่างชัดเจนและ (2) สามารถนำไปใช้กับไฟล์ปรับแต่งทั้งหมดได้ และหัวข้อย่อย (หรือแม้กระทั่งลึกถ้าคุณรู้สึกกล้าหาญ) และแยกการตั้งค่าของคุณเป็นไฟล์ขนาดเล็กหลายแห่งและ:sourceไอเอ็นจีพวกเขา

ฉันชอบการพับแบบส่วนตัวเพราะมันทำให้เข้าถึงได้ง่ายกว่าในขณะที่ยังให้ลำดับชั้นเพื่อรับจากฉัน ฟังก์ชั่นการพับและautocmds ที่อยู่ในระดับลึกสุดนั้นเป็นความคิดที่ดีเนื่องจากสิ่งเหล่านี้ทำให้หน่วยทางลอจิคัล "เป็นธรรมชาติ" markerการพับทำให้เหมาะสมที่สุดสำหรับทั้งหมดนี้เนื่องจากลำดับชั้นแบบลอจิคัลไม่จำเป็นต้องสะท้อนให้เห็นในระดับการเยื้องหรือเป็นการเน้นไวยากรณ์ ฉันยังเพิ่มขึ้นfoldcolumnซึ่งทำให้ฉันเห็นภาพของฉัน:

# vim: filetype=vim foldmethod=marker foldlevel=0 foldcolumn=3

ในหมายเหตุด้านfoldtextฟังก์ชั่นนี้(การปรับเปลี่ยนฟังก์ชั่นที่คล้ายกันโดย Drew Neil, IIRC) ทำให้ฉันรู้สึกดีกว่าค่าเริ่มต้น:

function! MyFoldText()
    let line = getline(v:foldstart)

    let nucolwidth = &foldcolumn + &number * &numberwidth
    let windowwidth = winwidth(0) - nucolwidth - 3
    let foldedlinecount = v:foldend - v:foldstart

    " expand tabs into spaces
    let chunks = split(line, "\t", 1)
    let line = join(map(chunks[:-2], 'v:val . repeat(" ", &tabstop - strwidth(v:val) % &tabstop)'), '') . chunks[-1]

    let line = strpart(line, 0, windowwidth - 2 - len(foldedlinecount))
    let fillcharcount = windowwidth - len(line) - len(foldedlinecount) - 1
    return line . '...' . repeat(' ', fillcharcount) . foldedlinecount . ' '
endfunction
set foldtext=MyFoldText()

ด้วยวิธีการอื่นแบ่งไฟล์ปัญหาหลักคือการค้นหาสิ่งต่าง ๆ และสลับจากไฟล์หนึ่งไปยังอีก วิธีที่ดีมากในการจัดการกับทั้งคู่คือการใช้ปลั๊กอินเช่นCtrlSF , CtrlPหรือคล้ายกัน แต่คุณอาจใช้หนึ่งในนั้นอยู่แล้ว


markerดังนั้นคุณไปด้วย การปรับแต่งแน่นอนfoldcolumnเป็นสิ่งที่ดีที่จะทำฉันจะเห็นว่าค่าที่เหมาะกับความต้องการของฉัน นอกจากนี้ฉันแชร์มุมมองของคุณในไฟล์แยก แต่ฉันไม่รู้ว่าCtrlSFฉันจะดูมันแม้ว่าฉันจะมีความสุขCtrlPมาก
statox

คุณสามารถอธิบายวิธีใช้วิธีการพับแบบกำหนดเองได้ไหม? ผมพยายามที่จะตั้งfdmไปfoldtextและMyFoldText()แต่ดูเหมือนว่ามันไม่ได้เป็นวิธีการที่เหมาะสมที่จะใช้มัน
statox

@statox CtrlSFทำงานได้ดีที่สุดกับagหรือแอ๊กชั่นgrepซึ่งมีความเชี่ยวชาญเป็นหลักรุ่น foldtextไม่ใช่วิธีการพับแบบกำหนดเอง แต่ฟังก์ชั่นเพื่อเปลี่ยนลักษณะการพับข้อความ set foldtext=MyFoldText()บรรทัดสุดท้ายในการแสดงตัวอย่างข้อมูลของฉันวิธีการใช้:
lcd047

2

แนวทางปฏิบัติที่ดีที่สุดขั้นพื้นฐาน:

  • แบ่งออกเป็นส่วน:

    • ปลั๊กอิน
    • การตั้งค่า
    • rebinds
  • แสดงความคิดเห็นแต่ละส่วน / rebind

  • (สำรองข้อมูลของคุณ.vimrcหรือ_vimrcบน Github)

เพียงแค่การตั้งค่าส่วนตัวของฉัน อาจไม่ได้ช่วยอะไรมาก


โดยส่วนตัวฉันไม่ได้ใช้การพับและคุณไม่จำเป็นต้องทำ เพียงแค่จัดการ vimrc ของคุณและมันควรจะดี
Gustav Blomqvist

vimrc ของฉันได้รับการจัดระเบียบในส่วน (ตัวเลือกทั่วไปปลั๊กอินการแมปการนำทางสี ฯลฯ ... ) ความจริงที่ว่าสามารถพับส่วน (หรือส่วนย่อย) ได้ดีจริง ๆ แล้วเน้นที่สิ่งที่คุณกำลังแก้ไข / มองหา
statox

ถูก ขออภัยสำหรับคำตอบที่ไม่ดี
กุสตาฟบลอมวิสต์

นั่นไม่ใช่คำตอบที่ไม่ดีและฉันก็มีความผิดที่ไม่ได้ให้คำถามมากพอไม่จำเป็นต้องขอโทษ ;-)
statox

2

แรงบันดาลใจจากคำตอบของ @ PeterRincker ฉันสร้างสิ่งต่อไปนี้เพื่อใช้ส่วนหัวสไตล์ ATX เพิ่มไปยังจุดสิ้นสุดของคุณ.vimrc

"# Folding

" Fold with ATX style headers - "# is H1, "## is H2, and so on
" vim:fdm=expr:fdl=0
" vim:fde=getline(v\:lnum)=~'^"#'?'>'.(matchend(getline(v\:lnum),'"#*')-1)\:'='

1

หากคุณมีฟังก์ชั่นขนาดใหญ่อย่างฉันคุณสามารถใช้ฟังก์ชั่นนี้เพื่อพับฟังก์ชั่นของคุณ:

fun! MyFoldLevel(linenum)
    if ! exists('w:nextline')
        let w:nextline = 0
        let w:insideafun = 0
    endif

    if w:nextline == 1
        let w:nextline = 0
        let w:insideafun = 0
    endif

    let l:line = getline(a:linenum)

    if l:line =~# '^[[:space:]]*fun'
        let w:insideafun = 1
        return '>1'
    elseif l:line =~# '^[[:space:]]*endf'
        let w:nextline = 1
        return '<1'
    endif

    if w:insideafun == 1
        return 1
    else
        return 0
    endif
endfun

และเพิ่ม modeline นี้ใน vimrc ของคุณ:

" vim:fde=MyFoldLevel(v\:lnum):fdm=expr:

0

ขยายแนวคิดของ @Peter Rincker และ @ go2null หากคุณไม่ต้องการตั้งค่าตัวเลือกการพับใน Vim modeline คุณสามารถใช้ autocmd ต่อไปนี้เพื่อตั้งค่าวิธีการพับและการแสดงออกของการพับ

augroup vim_folding
    autocmd!
    autocmd FileType vim set foldmethod=expr foldlevel=0
    " note that double quote in foldexpr has to be escaped with backslash
    autocmd FileType vim set foldexpr=getline(v:lnum)=~'^\"#'?'>'.(matchend(getline(v:lnum),'\"#*')-1):'='
augroup END

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

หากคุณไม่ชอบfoldexprสายยาวเราสามารถกำหนดฟังก์ชั่นสำหรับ:

function! VimFolds(lnum)
    let s:cur_line = getline(a:lnum)

    if s:cur_line =~ '^"#'
        return '>' . (matchend(s:cur_line, '"#*')-1)
    else
        return '='
    endif

endfunction

จากนั้นให้เปลี่ยนสาย autocmd เกี่ยวกับfoldexprการ

autocmd FileType vim set foldexpr=VimFolds(v:lnum)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.