.C / .h arabelleklerini değiştirme


8

Normalde dikey olarak bölünmüş 2 pencere ile çalışırım.

Çözmek istediğim sorun şu: başlık <-> uygulama dosyasından kolayca ileri geri atlamak

Şanssız, bunu yapmanın 2 yolunu araştırıyorum:

  1. Geçerli pencerede alternatif dosyayı aç : Bunu yapmanın birçok yolu var, ancak önceki dosyada nerede olduğumu hatırlayan bir yol bulamıyorum (yani başlığa atla, geri atla, ama aynı yere gitmedim) ).
  2. Diğer pencerede alternatif dosyayı açın : Bu, sadece 2 pencereyle çalıştığım için iyi tanımlanmış, ancak bunu yapmak için vim bilgisi yok.

1
1. sorunun bir ipucu için, bkz. :h line()(Genel çözüm): "Bu otomatik komut," "işareti ayarlanmışsa, dosyayı açtıktan hemen sonra son bilinen konuma atlar:: au BufReadPost * eğer satır (" ' \ "")> 1 && satırı ("'\" ") <= satır (" $ ") | exe "normal! g` \" "| endif
VanLaser

Bir atlama listesi ve / veya çapraz dosya işaretleri kullanamaz mısınız?
fruglemonkey


2
belki de arıyorsunuz A.vim
Christian Brabandt

Yanıtlar:


5

Sorduğunuz şeyi gerçekleştirmenin üç ana adımı vardır:

  • alternatif dosyanın adını almak
  • o dosyayı geçerli pencerede veya istendiği gibi başka bir pencerede açma
  • söz konusu dosyadaki imleç konumunu geri yükleme

Alternatif dosya adını bulmak için, geçerli dosya adını "kök" ve "uzantıya" bölmek istersiniz. Bunu yapmanın basit bir yolu:

let parts = split(expand("%:p"), "[.]");
let root = parts[0]
let extension = parts[1]

Yalnızca dosyalar .hve .cppdosyalar arasında geçiş yaptığınızı biliyorsanız , uzantıyı birinden diğerine kolayca değiştirebilirsiniz:

if extension == "h"
  let extension = "cpp"
else
  let extension = "h"
endif

Alternatif olarak, bilinen uzantıları potansiyel olarak geçerli alternatif uzantılarla eşleyen bir sözlük oluşturun . Veya geçerli dosya için olası tüm alternatifleri globpath()almak için kullanın :

let alternates = globpath(expand("%:h"), root . ".*")

ve ilkini seçin, ya da her neyse. globpathYaklaşımı tercih ederim, daha sonra anlatacağım bazı ek akıllılar. Hedef uzantıyı seçtikten sonra, tam hedef yolu oluşturun:

let target = root . "." . alternates[whicheverAlternateExtensionYouWant]

Şimdi alternatif dosyayı geçerli pencerede açabilirsiniz:

execute "edit " . target

Veya winnr()"diğer pencere" numarasını almak için kullanın ( atlayacağınız winnr("#")penceredir <C-W>pveya kurulumunuz için her zaman aynı olacağını biliyorsanız sabit kodlayabilirsiniz) ve şöyle bir şey yapın:

let window = winnr("#")
execute window . "wincmd w"
execute "edit " . target

Bu, alternatif dosyaları açmak için gerçekten temel bir çözüm sağlar. Yukarıdaki yaklaşımda birkaç eksiklik var, çünkü bunu basit olarak yazdım ve biraz kelepçelendi. Alternatif dosya geçişi "istediğim gibi" yapan bir eklenti yazdım (mevcut tüm globpath()sonuçlar arasında geçiş). Yukarıdakilerin basitliği ile ilgili bazı problemleri ele alır, daha fazlasını keşfetmek istiyorsanız uygulamasına göz atabilirsiniz.

Son olarak, "imleç konumunu geri yükle" noktası. Alternatif anahtarlama şeyine dik olduğu için son olarak sakladım (eklentim örneğin işlemez), ancak kendi başınıza yuvarlayacaksanız, işlevinize koyabilirsiniz. :help line()imleç konumunu dosyanın son açıldığı andaki konumuna geri yüklemek için yararlı bir otomatik komut içerir:

:au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif

.vimrcDavranışı her zaman tercih ettiğimden beri bunu ya da çok benzer bir şeyi koydum . Kodu kolayca başka bir yere koyabilirsiniz.


2

Vim-fswitch eklentisini .vimrcdosyanızda aşağıdaki yapılandırmayla birlikte kullanabilirsiniz :

au! BufEnter *.cpp,*.cc,*.c let b:fswitchdst = 'h,hpp'    | let b:fswitchlocs = 'reg:/src/include/,../include,./'
au! BufEnter *.h,*.hpp      let b:fswitchdst = 'cpp,cc,c' | let b:fswitchlocs = 'reg:/include/src/,../src,./'

nmap <silent> <Leader>s :FSHere<cr>

Eğer yazarsanız <Leader>(hangi \ardından varsayılan) sbir de .hppya .hdosyada, eşleşen eğer eklenti kontrol edecek .cpp, .ccya da .cdosya var:

  • değiştirerek includetarafından srcgeçerli dosyanın yolunda
  • srcgeçerli dosyanın üzerindeki klasöre bakarak
  • geçerli dosyanın klasörüne bakarak

Daha iyi Projenizi sığacak şekilde kullanabilirsiniz daha fazla seçenek vardır belgelere . Size birkaç dakika sürecek, ancak bir kez doğru alırsanız onu sevmelisiniz. Şahsen çok esnek ve genişletilebilir buluyorum, ayrıca birçok dosya türü için de işe yarıyor (.m, .h, .inl vb ...).


1

Sizin .vimrc

" =====[ Remap to change windows quickly ]=============================
:nnoremap <silent> <C-H> :wincmd h<CR>
:nnoremap <silent> <C-J> :wincmd j<CR>
:nnoremap <silent> <C-K> :wincmd k<CR>
:nnoremap <silent> <C-L> :wincmd l<CR>

Bu, giriş satırındaki Ctrl ve VIM yön tuşlarını kullanarak pencereler arasında hızlı bir şekilde hareket etmenizi sağlar. Bunun mükemmelliği, hızlı düzeltme penceresi de dahil olmak üzere herhangi bir pencereye atlamanın ortak bir yoludur.

vim-scripts/a.vimBurada bulunan başlık ve kaynak arasında hızla geçiş yapmak için : https://github.com/vim-scripts/a.vim , :Ageçiş yapmak için komutu kullanın.

Side Note => tmux kullanıyorsanız, vim veya nvim pencereleri ile bir terminal arasında sorunsuz bir şekilde geçiş yapmak için https://github.com/christoomey/vim-tmux-navigator kullanabilirsiniz .


1

Süper hızlı ve kirli versiyonumu paylaşacağım ...

Eşlemelerimi oluştur; alt-o ilgili dosyayı aynı pencerede açar, alt-shift-o bir bölmede açılır ...

nnoremap <A-o> :call EditRelatedFile()<CR>
nnoremap <A-O> :call SplitRelatedFile()<CR>

Sonra ilgili dosyaların listesini alır bir işlevi var. Dosya adını sondan ziyade ilk noktada kesmek için ince ayar yaptım ama bu hala okuyucu için bir alıştırma.

function! GetRelatedFileList()
    " This function may be overloaded in a site-specific vimrc.
    let l:thisPath = expand("%:p:r") . '.*'
    let l:files = glob(l:thisPath)

    return split(l:files, '[\r\n]\+')
endfunction

.Vimrc kurulumum bazen istemci başına uzmanlaşıyor; bazı kaynak ve ayrı klasör hiyerarşileri içerir, bazı birlikte. Varsayılan olarak hepsinin yakında olduğunu varsayarım ama avlamam gerekirse böyle bir değiştirme işlevi sağlayacağım.

" Override the basic GetRelatedFileList coming from vimrc.
function! GetRelatedFileList()
    let l:thisDir = expand("%:p:h:t")
    if (l:thisDir ==? "src") || (l:thisDir ==? "include")
        let l:thisPath = expand("%:p:h:h")
        let l:searchPaths = l:thisPath.'/include,' . l:thisPath.'/src'
        let l:thisBase = expand("%:t:r") . '.*'
        let l:files = globpath(l:searchPaths, l:thisBase)
    else
        let l:thisPath = expand("%:p:r") . '.*'
        let l:files = glob(l:thisPath)
    endif

    return split(l:files, '[\r\n]\+')
endfunction

Sonra geçerli arabellek dosyasını bulmak ve listedeki bir sonraki dosyaya gitmek için bu dosya listesine bakın. Genellikle bir .cpp / .h çifti kadar basit değildir, genellikle dikkate alınması gereken başka şeyler olur.

function! GetNextRelatedFile()
    let l:fileList = GetRelatedFileList()

    let l:thisFile = expand("%:p")
    let l:index = index(l:fileList, l:thisFile) + 1

    if l:index >= len(l:fileList)
        let l:index = 0
    endif

    return l:fileList[l:index]
endfunction

Ve son olarak, geçerli pencerede açılan veya bir bölme yapan iki işlev ...

function! EditRelatedFile()
    let l:file = GetNextRelatedFile()
    execute "edit" l:file
endfunction

Bölme sürümüm her zaman .cpp ve .c dosyalarını aşağıdaki bölmeye koyar, aksi takdirde bölünmüş varsayılan (benim durumumda yukarıdadır).

function! SplitRelatedFile()
    let l:file = GetNextRelatedFile()
    let l:ext = fnamemodify(l:file, ":e")
    if (l:ext ==? "cpp") || (l:ext ==? "c")
        execute "below split" l:file
    else
        execute "split" l:file
    endif
endfunction
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.