Bagaimana cara saya bergerak secara vertikal hingga mencapai karakter non-spasi putih?

27

Dalam file yang sangat panjang dengan kode indentasi (akurat-), mungkin berguna untuk memindahkan langsung ke baris teks di atas atau di bawah kursor yang membatasi indentasi.

(Salah satu cara melakukan ini bisa melalui metode indent, dengan melipat level indent saat ini, yang memecah garis yang membatasi level indent menjadi hanya satu jatau kjauh dari kursor. Namun, saya telah menemukan contoh di mana indent lipat belum bisa mengerjakan indent yang saya tertarik.)

Berikut ini sebuah contoh, dengan kursor ditandai dengan garis bawah _(pada kolom karakter kedua di antara definisi class Bazzdan class Qux), tetapi bayangkan bahwa jumlah paragraf atau garis dalam huruf modules tidak diketahui atau variabel:

module Foo
  # lots of code...
end

module Bar
  class Baz
    # ...
  end

  class Bazz
    # lots of code...
  end
 _
  class Qux
    # ...
  end

  class Quux
    # lots of code...
  end
end

... bagaimana bisa aku cepat menavigasi ke odari module Baratas kursor, atau ndari endbawah kursor pada baris yang terakhir? Perhatikan bahwa kolom vertikal berisi spasi putih, tetapi juga tidak ada karakter di kolom kedua di antara classdefinisi.

alxndr
sumber
2
terkait: "Pindah ke baris berikutnya / sebelumnya dengan lekukan yang sama" di Vim Tips Wiki vim.wikia.com/wiki/Move_to_next/…
alxndr
Menekan tombol g dan kemudian arah mungkin menghindari tab dan bergerak melintasi garis
SibiCoder
1
Solusi di tautan @ alxndr berfungsi dengan baik kecuali dalam kasus di mana spasi kosong tidak terpelihara (misalnya, ada garis acak yang hanya memiliki spasi putih) dan Anda ingin mengabaikan spasi putih tersebut. solusi superjer di bawah ini lebih baik jika ada yang peduli tentang kasus itu.
nukeguy

Jawaban:

9

Bagaimana dengan fungsi ini?

function FloatUp()
    while line(".") > 1
                \ && (strlen(getline(".")) < col(".")
                \ || getline(".")[col(".") - 1] =~ '\s')
        norm k
    endwhile
endfunction

Anda bisa nnoremap gU :call FloatUp()<CR>( gUuntuk "naik"), dan kemudian memohon gU.

Berikut penjelasannya:

  • Kode berulang kali bergerak ke atas kursor (dengan norm k) selama whilekondisi tersebut berlaku.
  • The whilekondisi berlaku jika ini bukan baris pertama ( line(".") > 1) dan baik
    • baris ini terlalu pendek (mungkin kosong); atau
    • karakter baris saat ini ( getline(".")) pada kolom saat ini ( [col(".") - 1]) adalah spasi putih ( =~ '\s'; yaitu, cocok dengan pola spasi putih).
wchargin
sumber
1
Ini tampaknya bekerja dengan sempurna (dan cepat), dan mudah dimodifikasi menjadi FloatDownfungsi juga. Ke dalam .vimrc saya, terima kasih! github.com/alxndr/dotfiles/commit/0e25a302
alxndr
1
Baru menemukan bahwa solusi ini tidak cukup berfungsi dalam mode visual (perilaku yang sedikit berbeda tergantung pada mode visual mana, itu akan tetap pada posisi yang sama atau bergerak hanya dengan satu baris). Adakah petunjuk tentang apa yang terjadi di sana?
alxndr
13

Saya suka menggunakan pencarian untuk hal-hal ini, karena regex Vim memiliki jumlah hal yang dapat Anda cari, seperti nomor kolom virtual tertentu, dalam hal ini:

nnoremap cd /\%<C-R>=virtcol(".")<CR>v\S<CR>

nnoremap cu ?\%<C-R>=virtcol(".")<CR>v\S<CR>

Gunakan cduntuk turun dan cunaik. Saya sedang berpikir "kolom atas" dan "kolom bawah" di sini. Saya hampir 100% yakin bahwa ini adalah no-ops secara default. Atau pilih pemetaan Anda sendiri.

Ini akan berfungsi baik jika Anda menggunakan tab atau spasi atau keduanya.

superjer
sumber
1
Saya mengalami masalah dalam menguraikan perintah-perintah itu. Maukah Anda memperluasnya sedikit?
davidlowryduda
1
/ atau ? untuk mencari ke bawah atau ke atas, \% xv membatasi untuk mencari ke nomor kolom virtual 'x', 'x' dalam hal ini adalah '<CR> = virtcol (".") <CR>' yang menjalankan perintah virtol dan memasukkan jumlah kolom virtual kursor masuk ke dalam ekspresi, \ S berarti karakter non-spasi putih.
Chad
1
Terima kasih telah menjelaskan Chad. Saya hanya akan menambahkan bahwa <CR> dalam mode Sisipkan atau mode baris perintah mengambil konten register. The =mendaftar adalah ekspresi mendaftar yang mengevaluasi ekspresi di tempat. Ini sangat berguna, jika tidak terlihat aneh.
superjer
1
Salah satu kelemahan dari pendekatan ini adalah jika Anda memiliki sorotan pencarian aktif, Anda akan menemukan bahwa semua karakter di kolom vertikal kursor sekarang disorot setelah "kolom naik" atau "kolom turun".
alxndr
3
Jika Anda ingin melindungi pencarian yang ada, Anda dapat menambahkan :let searchbak=@/<CR>dan menambahkan :let @/=searchbak<CR>. Tetapi pada titik ini menjadi agak panjang dan tidak dapat didekati dan mungkin hanya menjadi sebuah fungsi.
superjer
7

Anda dapat menggunakan plugin JumpToVerticalOccurrence (default dipetakan ke ]|dan [|). Ada beberapa yang lain ]V{char}yang berfungsi seperti itu f, tetapi secara vertikal. Anda tentu saja dapat memetakannya kembali seperti yang diminta.


Jika Anda tidak ingin menggunakan plugin, Anda dapat mencoba menggunakan :searchdengan virtcol(.), misalnya:

:call search('\%' . virtcol('.') . 'v\S', 'bW')

dimana:

  • virtcol('.') memberi Anda kolom saat ini,
  • \S singkatan dari non-whitespace
  • bW adalah untuk pencarian mundur

Periksa :help searchuntuk mempelajari lebih lanjut.

Untuk membuatnya lebih mudah digunakan, Anda dapat memetakannya, misalnya:

:map <C-k> :call search('\%' . virtcol('.') . 'v\S', 'bW')<CR>
:map <C-j> :call search('\%' . virtcol('.') . 'v\S', 'W')<CR>

Atau, jika kode Anda berisi tanda kurung, gunakan %untuk melompat antara pencocokan mereka (misalnya {, }, [, ], dll) atau menggunakan seluruh ayat melompat ( {, }dengan Shiftjika perlu).


Tautan / sumber:

kenorb
sumber
Dari :h search(): wsarana wrap around the end of the filedan Wsarana don't wrap around the end of the file. Tapi mengapa Anda menempatkan mereka pada yang kedua :map?
Jair López
@JairLopez Benar, wseharusnya tidak ada di sana, jadi saya sudah menghapusnya, terima kasih. Mungkin saya bingung dengan makna tombol gerak.
kenorb
3

Saya menggunakan versi modifikasi dari vim-indent-object plugin untuk memberikan perilaku ini. Modifikasi saya dapat dilihat di sini .

Ini memungkinkan saya memetakan [iuntuk pergi ke awal level indentasi saat ini dan ]imenuju akhir.

Steve Vermeulen
sumber
2

Ini bukan apa yang Anda minta karena itu bukan gerakan vertikal, tetapi sesuatu yang mirip, cepat, dan mungkin cukup baik untuk Anda bergerak mundur 2 paragraf: {{. Ini akan membawa Anda ke garis tepat sebelumnya module Bar.

Hentikan bahaya yang berkelanjutan pada Monica
sumber
2
Bayangkan ada sejumlah garis dan / atau paragraf yang tidak diketahui antara kursor dan modulegaris level atasnya . (Secara khusus, situasi ini muncul ketika saya baru-baru ini menavigasi kode pihak ketiga beberapa ribu baris, dengan lekukan yang akurat tetapi tidak ada baris kosong, dan mencoba untuk menemukan konteks luar dari definisi modul.)
alxndr
Melompati paragraf adalah cara yang saya sukai untuk bergerak, tetapi itu bukan pilihan: seluruh file adalah satu "paragraf".
alxndr
2

jeetsukumaran / vim-indentwise bekerja dengan baik untuk gerakan relatif, absolut, atau blok-lingkup di seluruh blok indentasi.

Harry
sumber
1

Saya menggunakan plugin saya sendiri move_until_char_changes.vim untuk itu.

Saya memetakannya ke gKdan gJ.

Ini akan melompati banyak baris dengan karakter yang sama di kolom saat ini (bukan hanya spasi), yang dapat berguna dalam logfiles atau SQL dumps dengan string berulang.

Secara default, pertama-tama bergerak satu baris, sebelum mengambil karakter "pencarian".

Ini berfungsi dalam mode Visual asalkan Anda tidak mencoba menggunakannya dua kali, dan Anda tidak berada dalam mode Visual yang berbaris atau blockwise ... (selamat datang perbaikan!)

joeytwiddle
sumber
1

Karena saya tidak melihatnya di sini sebagai jawaban ( edit hanya memperhatikan bahwa superjer menyebutkan sesuatu yang sangat mirip). Anda bisa dengan sederhana menggunakan / atau? pencarian.

Misalnya, Anda bisa mencari karakter non whitespace ke bawah di kolom ke-2 seperti ini:

/\%2v\S

Rinciannya adalah:

/    "search downward (use ? for upward movement)
\%2v "for the following char in the 2nd virtual column
\S   "any non white space character

Kemudian Anda dapat menggunakan operator normal untuk mengulang pencarian.

Untuk info lebih lanjut tentang subjek, lihat :help \%cdan :help \%v.

Eric
sumber