จะสลับระหว่างการกำหนดค่า vim หลาย ๆ แบบด้วยคำสั่งหรือไฟล์ vimrc ภายในได้อย่างไร


85

ฉันทำงานในหลายกลุ่มซึ่งแต่ละกลุ่มมีมาตรฐานแท็บ / การเยื้อง / ระยะห่างของตัวเองใน C

มีวิธีการกำหนดค่า VIM ที่สามารถเลือกได้แยกกันสำหรับแต่ละรายการหรือไม่เมื่อฉันแก้ไขไฟล์อย่างใดอย่างหนึ่ง:

  • ฉันทำบางอย่างเช่นset group=1เลือกการกำหนดค่า
  • . vimrc ในเครื่องที่อยู่ในไดเร็กทอรีการทำงานถูกใช้เพื่อตั้งค่าคอนฟิกโดยอัตโนมัติ

ตรวจสอบสิ่งนี้: stackoverflow.com/a/14407951/1099240
Dmitry Frank

คำตอบ:


40

สรุป

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

  • Per-directory vimrc - มีข้อเสียที่ต้องเริ่ม Vim ในไดเร็กทอรีที่ถูกต้อง: หากโปรเจ็กต์ของคุณอยู่ใน~/project1และคุณมี~/project1/.vim.customและทำcd ~ ; vim project1/file.cจะไม่พบการตั้งค่าแบบกำหนดเอง
  • Modelines - มีประสิทธิภาพมาก แต่มีข้อเสียที่ต้องเพิ่มลงในไฟล์ทั้งหมด (และอย่าลืมเพิ่มลงในไฟล์ใหม่)
  • คำสั่งอัตโนมัติเฉพาะไดเร็กทอรี - ซึ่งมีประสิทธิภาพมาก
  • สแกนหาส่วนหัวเฉพาะในไฟล์ (ดูด้านล่าง) - นี่คือส่วนหัวที่ฉันเคยใช้มากที่สุดในอดีตที่ทำงานให้กับ บริษัท ต่างๆหรือในโครงการที่มีชื่อชัดเจน
  • vimrc ต่อไดเรกทอรีที่ตรวจสอบเมื่อเปิดไฟล์ (ดูด้านล่าง) อีกวิธีหนึ่งที่ค่อนข้างง่ายในการนำไปใช้โดยเฉพาะอย่างยิ่งถ้ารหัสโครงการของคุณอยู่ในที่เดียว

กำลังสแกนหาส่วนหัว

ในหลาย ๆ องค์กรจะมีส่วนหัวมาตรฐาน (พร้อมประกาศลิขสิทธิ์และชื่อโครงการเป็นต้น) ที่ด้านบนของไฟล์ต้นฉบับทุกไฟล์ ในกรณีนี้คุณจะได้รับ Vim เพื่อสแกนไฟล์แรก (เช่น) 10 บรรทัดโดยอัตโนมัติเพื่อค้นหาคีย์เวิร์ด หากพบก็สามารถเปลี่ยนการตั้งค่าของคุณได้ ฉันได้แก้ไขสิ่งนี้เพื่อให้ง่ายกว่ารูปแบบที่ฉันใช้ (ซึ่งทำสิ่งอื่น ๆ มากมาย) แต่สร้าง~/.vim/after/filetype.vim(ถ้าคุณยังไม่มี) และเพิ่มสิ่งนี้:

au FileType * call <SID>ConfigureFiletypes(expand("<amatch>"))

" List of file types to customise
let s:GROUPNAMETypes = ['c', 'cpp', 'vhdl', 'c.doxygen']

func! <SID>CheckForGROUPNAMECode()
    " Check if any of the first ten lines contain "GROUPNAME".

    " Read the first ten lines into a variable
    let header = getline(1)
    for i in range(2, 10)
        let header = header . getline(i)
    endfor

    if header =~ '\<GROUPNAME\>'
        " Change the status line to make it clear which
        " group we're using
        setlocal statusline=%<%f\ (GROUPNAME)\ %h%m%r%=%-14.(%l,%c%V%)\ %P
        " Do other customisation here
        setlocal et
        " etc
    endif
endfunc

func! <SID>ConfigureFiletypes(filetype)
    if index(s:GROUPNAMETypes, a:filetype) != -1
        call <SID>CheckForGROUPNAMECode()
    endif
endfunc

เมื่อใดก็ตามที่เปิดไฟล์ประเภทใดก็ได้และตั้งค่าประเภทไฟล์ไว้ ( au FileType *บรรทัด) ไฟล์ConfigureFiletypesฟังก์ชันจะถูกเรียกใช้ ซึ่งจะตรวจสอบว่าประเภทไฟล์อยู่ในรายการประเภทไฟล์ที่เชื่อมโยงกับกลุ่มปัจจุบัน (GROUPNAME) หรือไม่ในกรณีนี้คือ "c", "cpp", "vhdl" หรือ "c.doxygen" ถ้าเป็นเช่นนั้นจะเรียกว่า CheckForGROUPNAMECode () ซึ่งอ่าน 10 บรรทัดแรกของไฟล์และหากมี GROUPNAME ก็จะทำการปรับแต่งบางอย่าง เช่นเดียวกับการตั้งค่า expandtabs หรืออะไรก็ตามสิ่งนี้ยังเปลี่ยนแถบสถานะเพื่อแสดงชื่อกลุ่มอย่างชัดเจนเพื่อให้คุณรู้ว่ามันทำงานได้อย่างรวดเร็ว

ตรวจสอบการกำหนดค่าเมื่อเปิด

เช่นเดียวกับคำแนะนำของ JS Bangs การมีไฟล์กำหนดค่าที่กำหนดเองจะมีประโยชน์ อย่างไรก็ตามแทนที่จะโหลดใน vimrc ให้พิจารณาสิ่งนี้ซึ่งจะตรวจสอบเมื่อไฟล์. c ถูกเปิดสำหรับ. vim.custom ในไดเร็กทอรีเดียวกับไฟล์. c

au BufNewFile,BufRead *.c call CheckForCustomConfiguration()

function! CheckForCustomConfiguration()
    " Check for .vim.custom in the directory containing the newly opened file
    let custom_config_file = expand('%:p:h') . '/.vim.custom'
    if filereadable(custom_config_file)
        exe 'source' custom_config_file
    endif
endfunction

66

ฉันมีสิ่งนี้ใน$HOME/.vimrc:

if filereadable(".vim.custom")
    so .vim.custom
endif

สิ่งนี้ทำให้ฉันสามารถใส่.vim.customไฟล์ในทุกไดเร็กทอรีเพื่อโหลดคำสั่งและตัวเลือกเฉพาะสำหรับไดเร็กทอรีนั้น หากคุณกำลังทำงานในหลายโปรเจ็กต์ที่มีโครงสร้างไดเร็กทอรีแบบลึกคุณอาจต้องการบางสิ่งที่ซับซ้อนมากขึ้น (เช่นเดินขึ้นแผนผังไดเร็กทอรีจนกว่า.vim.customจะพบa ) แต่แนวคิดพื้นฐานเดียวกันจะใช้ได้ผล

อัพเดท:

ตอนนี้ฉันทำสิ่งนี้เพื่ออ่าน.vimไฟล์จากไดเร็กทอรีเดียวกับไฟล์ที่ฉันกำลังแก้ไขไม่ว่าไดเร็กทอรีปัจจุบันจะเป็นอย่างไร

let b:thisdir=expand("%:p:h")
let b:vim=b:thisdir."/.vim"
if (filereadable(b:vim))
    execute "source ".b:vim
endif

1
ยอดเยี่ยมขนาดนี้ไม่เคยเห็นมาก่อน!
Jim Mitchener

1
นี่เป็นทางออกที่ยอดเยี่ยมสำหรับโครงการที่อาศัยอยู่ใน repos!
bradreaves

3
'exrc'ตัวเลือกแล้วอนุญาตให้ทำอะไรบางอย่างที่คล้ายกันนี้ มันจะโหลด a .vimrc/ .exrc/ .gvimrcในไดเร็กทอรีการทำงานปัจจุบัน
jamessan

ความคิดเห็นเกี่ยวกับexrcควรเป็นคำตอบที่ถูกต้อง อย่างอื่นดูเหมือนจะแฮ็คและซับซ้อน
silvenon

การใช้exrcเป็นสิ่งที่ดี แต่ฉันขอขอบคุณที่ได้รับไฟล์ที่ถูกต้องแม้ว่าฉันจะไม่ได้อยู่ในไดเร็กทอรีการทำงานเดียวกันกับไฟล์ที่ฉันกำลังแก้ไข
JSB ձոգչ

34

นอกจากนี้คุณยังสามารถใส่autocommandsของคุณใน.vimrcตัวเลือกเฉพาะชุดบนพื้นฐานต่อเส้นทาง

au BufRead,BufNewFile /path/to/project1/* setl sw=4 et
au BufRead,BufNewFile /path/to/project2/* setl sw=3 noet

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

17

ปลั๊กอินทำสิ่งที่ถูกต้อง: http://www.vim.org/scripts/script.php?script_id=441

“ ปลั๊กอินนี้ค้นหาไฟล์ vimrc ในระบบในโครงสร้างระบบไฟล์ของไฟล์ที่เปิดอยู่ในปัจจุบัน โดยค่าเริ่มต้นจะค้นหาไฟล์ ".lvimrc" ทั้งหมดจากไดเร็กทอรีของไฟล์ไปยังไดเร็กทอรี root และโหลดตามลำดับย้อนกลับ ชื่อไฟล์และจำนวนไฟล์ที่โหลดสามารถปรับแต่งได้ผ่านตัวแปรส่วนกลาง”


3
และเวอร์ชัน github ยังรองรับการโหลดด้วยเชื้อโรคด้วย :-)
Graza

ปลั๊กอินอื่นที่คล้ายกันคือ localrc.vim; นอกจากนี้ยังอนุญาตการตั้งค่าเฉพาะประเภทไฟล์ต่อไดเรกทอรี ฉันพบว่ามันขาดไม่ได้ vim.org/scripts/script.php?script_id=3393
Ingo Karkat

12

สมมติว่านักพัฒนาคนอื่น ๆ ของคุณจะไม่บ่นเกี่ยวกับเรื่องนี้คุณสามารถเพิ่มการตั้งค่ากลุ่มให้กับแต่ละไฟล์ในความคิดเห็นได้ตลอดเวลา

/*
 * vim:ts=4:sw=4:expandtab:...
 */

int main(int argc, char **argv)
{
    ...

2
ฉันเท่านั้นอะแฮ่ม dev พุทธะในส่วนของทีมงานของฉันดังนั้นไม่มีใครควรทราบ นี่เป็นวิธีแก้ปัญหาที่เรียบร้อยจริงๆต่อไฟล์
bradreaves

1
ฉันชอบเพิ่มไว้ที่ด้านล่างเพื่อไม่ให้สร้างความรำคาญ แต่ฉันเดาว่าเป็นเรื่องของสไตล์
nyuszika7h

5

ฉันสร้างเครื่องมือโอเพนซอร์ซเพื่อจุดประสงค์นี้ ลืมส่วนหัวการสแกนการกำหนดค่าและไฟล์ vimrc ในเครื่อง

ลองว่ายน้ำ.


ว่ายน้ำ

swimเป็นเครื่องมือที่รวดเร็วสำหรับการสลับไฟล์ vimrc และสร้างนามแฝงที่สะดวก นี่คือรายการการใช้งานสั้น ๆ ดูGithub repoสำหรับคำแนะนำแบบแนะนำและดาวน์โหลดคำแนะนำ:


การใช้งาน

swim add ~/dotfiles/myVimrc favorite    #Add new swim alias
swim ls                                 #Show available swim aliases
swim add https://raw.githubusercontent.com/dawsonbotsford/swim/master/exampleVimrcs/vimrcWikia.vim example
swim with favorite         #Set alias favorite as primary .vimrc
swim with main             #Set alias main as primary .vimrc

อ่านเพิ่มเติม

https://github.com/dawsonbotsford/swim


4

หลังจากลองใช้ปลั๊กอิน localvimrc ที่แนะนำโดยผู้โพสต์ก่อนหน้านี้ฉันชอบที่จะมีการควบคุมการตั้งค่า vim แบบไม่ต่อโปรเจ็กต์

จะขอการยืนยันก่อนที่จะโหลดไฟล์. lvimrc ตามค่าเริ่มต้น แต่มีการตั้งค่าให้โหลดไฟล์. lvimrc โดยอัตโนมัติ บางคนอาจมองว่านี่เป็นช่องโหว่ด้านความปลอดภัย แต่ก็ใช้ได้ตามที่โฆษณาไว้

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


1
สคริปต์นี้เป็นที่น่าตื่นตาตื่นใจ: github.com/MarcWeber/vim-addon-local-vimrc 1) ตอนนี้จะถามเพียงครั้งเดียวและทำเครื่องหมายแฮชไฟล์ว่าตกลง 2) มันจะย้ายทรีไดเร็กทอรีจากรูทไปยัง dir ปัจจุบันโดยจัดหาไฟล์ที่มีลำดับความสำคัญสูงกว่าให้เป็นลำดับสุดท้าย
Ciro Santilli 郝海东冠状病六四事件法轮功

เพิ่ม.lvimrcไฟล์ไป.gitignoreทำไม? ประเด็นก็คือทุกคนที่ใช้ vim และติดตั้งปลั๊กอินจะได้รับการตั้งค่าเดียวกัน
nyuszika7h

2
@ nyuszika7h ต้องบังคับใช้การตั้งค่าบางอย่างในขณะที่การตั้งค่าอื่น ๆ เป็นเรื่องส่วนตัวล้วนๆ สำหรับการตั้งค่าที่ต้องบังคับใช้กับทุกคน EditorConfig จะดียิ่งขึ้นไปอีกเนื่องจากเป็นโปรแกรมแก้ไขที่ไม่เชื่อเรื่องพระเจ้า: github.com/editorconfig/editorconfig-vim
Ciro Santilli 郝海东冠状病六四事件法轮功

1

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

let g:localvimrc_whitelist='/development/kernel/.lvimrc'


1

นี่คือรูปแบบของ jamessan

function! ConditionalLoad()
    let cwd = getcwd()
    if getcwd() =~ $HOME . "/src/mobile"
        so $HOME/.vim.mobile
    endif
endfunction
autocmd VimEnter * call ConditionalLoad()

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


สิ่งที่ฉันกำลังมองหา ในฐานะที่เป็นตัวอย่างของการใช้งาน: ฉันวางรหัสนี้ใน~/.vimrcการเปลี่ยนแปลง/src/mobileไปยังไดเรกทอรีโครงการของฉัน Symfony (ในกรณีของฉันมันเป็น/www/symfony) และแก้ไข.vim.mobileไป.vim.symfonyแล้ววางอยู่ภายในใหม่ .vimrc การตั้งค่า~/.vim.symfonyไฟล์
jmarceli

1

ฉันทำงานในหลายกลุ่มซึ่งแต่ละกลุ่มมีมาตรฐานแท็บ / การเยื้อง / ระยะห่างของตัวเองใน C

ฉันทำงานกับโอเพ่นซอร์สทุกประเภทในเวลาเดียวกัน การสร้าง.vimrcไฟล์แยกต่างหากและกำหนดค่ามาตรฐานการจัดรูปแบบใหม่ไม่เป็นประโยชน์ กว่าทศวรรษที่แล้วในที่สุดฉันก็เบื่อที่จะจัดการกับการกำหนดค่าตัวแก้ไขและเขียนโปรแกรมที่เรียกว่าautotabจัดการมัน

เมื่อautotabใดที่ตั้งค่าด้วย Vim ที่แนะนำแต่ละครั้งที่คุณโหลดไฟล์ลงใน Vim autotabจะถูกเรียกใช้และเอาต์พุตการตั้งค่า Vim autotabจะถูกส่งไปยัง:setคำสั่ง

autotabอ่านหลายพันเส้นจากแฟ้มวิเคราะห์พวกเขาและกำหนดค่าติดตั้งสำหรับexpandtab, tabstopและshiftwidthพารามิเตอร์

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

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

นอกจากนี้ยังเป็นประเภทไฟล์ "ไม่เชื่อเรื่องพระเจ้า" และทำงานได้ดีกับภาษาต่างๆ ฉันใช้มันไม่เพียง แต่ใน C เท่านั้น แต่ยังมีเชลล์สคริปต์, Lisp, Makefiles, HTML และคุณมีอะไรบ้าง

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


0

มองหาปัญหาเดียวกันเป็นส่วนใหญ่ฉันยังพบปลั๊กอิน Sauce: http://www.vim.org/scripts/script.php?script_id=3992

อ้างว่า:

Sauce เป็นตัวจัดการที่มีน้ำหนักเบาสำหรับไฟล์ vimrc หลายไฟล์ซึ่งสามารถใช้เพื่อโหลดการตั้งค่าต่างๆสำหรับสภาพแวดล้อมที่แตกต่างกัน ในระยะสั้นคุณสามารถรักษาไฟล์การตั้งค่าเป็นกลุ่มต่างๆได้มากมายและโหลดเฉพาะไฟล์ที่คุณต้องการเมื่อคุณต้องการเท่านั้น

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

ฉันยังไม่ได้ทดสอบเลย


0

คุณสามารถใช้ที่เก็บเพื่อเปลี่ยนการกำหนดค่า (dotfiles ใด ๆ ไม่เพียงเท่านั้น.vimrc)

ติดตั้งstow:

$ apt install stow

สร้างไดเรกทอรีหลายรายการสำหรับการกำหนดค่าแต่ละรายการ:

~$ ls -d ~/dotfiles/vim*
vim-all vim-webdev vim-go

ใส่สิ่งที่แตกต่างกัน.vimrcในพวกเขา:

$ find ~/dotfiles -name .vimrc
/home/username/vim-golang/.vimrc
/home/username/vim-webdev/.vimrc
/home/username/vim-all/.vimrc

ตอนนี้คุณสามารถสร้างอินสแตนซ์ vim-golang config ด้วยคำสั่งนี้ (ควรรันในไดเร็กทอรี dotfiles)

~$ cd ~/dotfiles

dotfiles$ stow -v vim-golang
LINK: .vimrc => dotfiles/vim-golang/.vimrc

ตอนนี้ลิงก์แล้ว:

$ cd ~ && ls -l .vimrc 
.vimrc -> dotfiles/vim-golang/.vimrc

หากคุณต้องการเปลี่ยนการกำหนดค่าให้ทำใหม่stow:

~$ cd dotfiles

dotfiles$ stow -v -D vim-golang
UNLINK: .vimrc

dotfiles$ stow -v vim-webdev
LINK: .vimrc => dotfiles/vim-webdev/.vimrc

$ cd ~ && ls -l .vimrc 
.vimrc -> dotfiles/vim-webdev/.vimrc

อ่านเพิ่มเติมได้ที่นี่: การจัดการ dotfiles ด้วย GNU stow

จุดเด่น : สวยเรียบง่ายไม่มีเสียงเรียกปลั๊กอินอ้างอิงสามารถนำมาใช้สำหรับการจัดการ dotfiles .vimrcทั้งหมดไม่เพียง แต่

จุดด้อย : การกำหนดค่าเป็นอิสระจากกันคุณต้องจัดการ / อัปเดตแต่ละรายการแยกกัน (หากคุณไม่เปลี่ยน / อัปเดตคุณกำหนดค่าบ่อยเกินไป - มันจะไม่ใช่ปัญหา)

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