Chuyển đổi bộ đệm .c / .h


8

Tôi thường làm việc với 2 cửa sổ, chia theo chiều dọc.

Vấn đề tôi muốn giải quyết là: dễ dàng nhảy qua nhảy lại từ tệp thực hiện <->

Tôi đang điều tra, không có may mắn, có 2 cách để làm điều này:

  1. Mở tệp thay thế trong cửa sổ hiện tại : Có nhiều cách để thực hiện việc này, tuy nhiên, tôi không thể tìm thấy cách ghi nhớ vị trí của mình trong tệp trước đó (tức là nhảy đến tiêu đề, nhảy trở lại, nhưng không đến cùng nơi tôi đã ở ).
  2. Mở tệp thay thế trong cửa sổ khác : Điều này được xác định rõ, vì tôi chỉ làm việc với 2 cửa sổ, tuy nhiên tôi thiếu kiến ​​thức vim để làm điều này.

1
Để biết gợi ý cho vấn đề thứ nhất, hãy xem phần cuối của :h line()(giải pháp chung): "Trình tự động tự động này nhảy đến vị trí đã biết cuối cùng trong một tệp ngay sau khi mở nó, nếu dấu '" được đặt :: au BufReadPost * if line ("' ' \ "")> 1 && dòng ("'\" ") <= dòng (" $ ") | exe "bình thường! g` \" "| endif
VanLaser

Bạn không thể sử dụng một danh sách nhảy và / hoặc đánh dấu tập tin chéo?
fruglemonkey


2
có lẽ bạn đang tìm kiếm A.vim
Christian Brabandt

Câu trả lời:


5

Có ba bước chính để thực hiện những gì bạn yêu cầu:

  • lấy tên tập tin thay thế
  • mở tệp đó trong cửa sổ hiện tại hoặc trong cửa sổ khác như mong muốn
  • Khôi phục vị trí con trỏ trong tệp đó

Để tìm tên tệp thay thế, bạn muốn ngắt tên tệp hiện tại thành "gốc" và "phần mở rộng". Một cách đơn giản để làm điều này là:

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

Nếu bạn biết bạn chỉ chuyển đổi giữa .h.cppcác tệp, bạn có thể dễ dàng thay đổi tiện ích mở rộng từ cái này sang cái khác:

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

Hoặc, tạo một ánh xạ từ điển các tiện ích mở rộng đã biết đến các tiện ích mở rộng thay thế có khả năng hợp lệ. Hoặc sử dụng globpath()để có được tất cả các lựa chọn thay thế có thể cho tệp hiện tại:

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

và chọn cái đầu tiên, hoặc bất cứ thứ gì. Tôi thích globpathcách tiếp cận, với một số thông minh thêm tôi sẽ mô tả sau. Khi bạn đã chọn tiện ích mở rộng mục tiêu, hãy tạo đường dẫn đích đầy đủ:

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

Bây giờ bạn có thể mở tệp thay thế trong cửa sổ hiện tại:

execute "edit " . target

Hoặc sử dụng winnr()để lấy số "cửa sổ khác" ( winnr("#")là cửa sổ <C-W>psẽ nhảy tới hoặc bạn có thể mã hóa nó nếu bạn biết nó sẽ luôn giống với thiết lập của bạn) và làm một cái gì đó như:

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

Điều này cung cấp cho bạn một giải pháp thực sự cơ bản để mở các tệp thay thế. Có một vài thiếu sót với cách tiếp cận ở trên, vì tôi đã viết nó đơn giản và nó hơi khó hiểu. Tôi đã viết một plugin thay thế tập tin chuyển đổi "theo cách tôi muốn" (đi qua tất cả các globpath()kết quả có sẵn ). Nó giải quyết một số vấn đề với sự đơn giản ở trên, bạn có thể kiểm tra việc thực hiện nếu bạn muốn khám phá thêm.

Cuối cùng, điểm "khôi phục vị trí con trỏ". Tôi đã lưu nó lần cuối vì nó trực giao với thứ chuyển đổi thay thế (ví dụ như plugin của tôi không xử lý nó), nhưng bạn có thể đặt nó vào chức năng của mình nếu bạn sẽ tự lăn. :help line()có một autocommand rất hữu ích cho việc khôi phục vị trí con trỏ về vị trí của nó khi tệp được mở lần cuối:

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

Tôi chỉ đặt điều đó, hoặc một cái gì đó rất giống nhau, .vimrcvì tôi thích hành vi mọi lúc. Bạn có thể dễ dàng đặt mã ở nơi khác.


2

Bạn có thể sử dụng plugin vim-fswitch cùng với cấu hình sau trong .vimrctệp của mình :

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>

Nếu bạn gõ <Leader>(đó là \theo mặc định) tiếp theo là strong một .hpphoặc .htập tin, các plugin sẽ kiểm tra xem một khớp .cpp, .cchoặc .ctập tin tồn tại:

  • bằng cách thay thế includebằng srctrong đường dẫn của tệp hiện tại
  • bằng cách tìm trong srcthư mục phía trên tập tin hiện tại
  • bằng cách tìm trong thư mục của tập tin hiện tại

Có nhiều lựa chọn hơn bạn có thể sử dụng để phù hợp với dự án của bạn hơn trong tài liệu . Bạn sẽ mất vài phút nhưng một khi bạn hiểu đúng, bạn nên yêu nó. Cá nhân tôi thấy nó rất linh hoạt và có thể mở rộng, cộng với nó cũng hoạt động tốt đối với nhiều loại tệp (.m, .h, .inl, v.v.).


1

Trong bạn .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>

Điều này cho phép bạn di chuyển nhanh chóng giữa các cửa sổ, chỉ bằng cách sử dụng các phím điều hướng Ctrl và VIM từ hàng chủ. Điều tuyệt vời của việc này là bạn có một cách phổ biến để nhảy tới bất kỳ cửa sổ nào, bao gồm cả cửa sổ quickfix.

Để nhanh chóng chuyển đổi giữa tiêu đề và nguồn tôi sử dụng vim-scripts/a.vimđược tìm thấy ở đây: https://github.com/vim-scripts/a.vim , sử dụng :Alệnh để chuyển đổi.

Lưu ý bên => Nếu bạn sử dụng tmux, bạn có thể sử dụng https://github.com/christoomey/vim-tmux-navigator để nhảy giữa các cửa sổ vim hoặc nvim và một thiết bị đầu cuối liền mạch.


1

Tôi sẽ chỉ chia sẻ phiên bản siêu nhanh và bẩn của tôi ...

Thiết lập bản đồ của tôi; alt-o mở tệp liên quan trong cùng một cửa sổ, alt-shift-o mở trong một tách ...

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

Sau đó, tôi có một chức năng có được danh sách các tập tin liên quan. Tôi đã có ý định tinh chỉnh nó để cắt tên tệp ở dấu chấm đầu tiên thay vì cuối cùng nhưng đó vẫn là một bài tập cho người đọc.

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

Thiết lập .vimrc của tôi đôi khi là chuyên biệt cho mỗi khách hàng; một số có nguồn và bao gồm trong hệ thống phân cấp thư mục riêng biệt, một số có chúng cùng nhau. Theo mặc định, tôi cho rằng tất cả đều ở gần nhưng nếu tôi cần săn, tôi sẽ cung cấp chức năng thay thế như thế này.

" 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

Sau đó, tôi xem qua danh sách các tệp đó để tìm tệp bộ đệm hiện tại và đi đến tệp tiếp theo trong danh sách. Nó không thường đơn giản như một cặp .cpp / .h, thường thì tôi sẽ có những thứ khác cần được xem xét.

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

Và cuối cùng, hai chức năng mở trong cửa sổ hiện tại hoặc phân tách ...

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

Phiên bản chia tách của tôi luôn đặt các tệp .cpp và .c ở phần tách bên dưới, nếu không thì chia mặc định (trong trường hợp của tôi là ở trên).

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
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.