Apakah mungkin untuk menggabungkan:% s / \ = dan | dalam vim?


3

Berikut ini kira-kira apa yang saya coba lakukan di vim

:let g:ID = 1
:%s/^/\= g:ID | let g:ID = g:ID * 1.2/

Sekarang, sepertinya vim tidak menyetujui semuanya setelah bilah (itu adalah let g:ID = g:ID * 1.2bagiannya.

Tentu saja saya bisa menulis fungsi yang mengalikan g: ID dengan 1.2 dan mengembalikan nilai g: ID, tetapi saya ingin melupakannya.

Terima kasih Rene

edit untuk kejelasan:

Dalam vim-script, saya bisa menulis banyak pernyataan dalam satu baris jika saya menggunakan bilah (|) untuk membuat rantai. Jadi, bukannya

let g:ID = 20
let g:ID = g:ID * 1.2
let g:ID = g:ID * 1.2

Saya juga bisa menulis

  let g:ID = 20 | let g:ID = g:ID * 1.2 | let g:ID = g:ID * 1.2

Sekarang, \ = thingy memungkinkan saya untuk mengganti ekspresi reguler dengan ekspresi skrip vim. Sebagai contoh, saya bisa melakukan

:%s/ABC/\=line(".")/

yang akan menggantikan setiap kemunculan ABC di buffer saya saat ini dengan nomor baris yang ditemukan.

Demikian pula a

:%s/^/\=g:ID/

akan menulis nilai g: ID di awal setiap baris di buffer saya.

Itu semua bagus dan keren, tetapi saya ingin memiliki lebih dari satu ekspresi di bagian pengganti dan bertanya-tanya apakah saya bisa mencapainya dengan merantai ekspresi seperti itu dengan bilah. Dalam kasus saya, saya ingin memanipulasi g: ID setelah setiap panggilan substitusi, karenanya

:let g:ID=20
:s/^/\=g:ID|let g:ID=g:ID * 1.2/

akan menghasilkan tulisan 20 di awal baris pertama di buffer saya, 24 di awal baris kedua di buffer saya, 28,8 di awal baris ketiga di buffer saya dan seterusnya.

Saya harap saya membuat diri saya lebih jelas sekarang.


1
tidak jelas apa yang ingin Anda capai ...
akira

Saya ingin rantai dua "perintah" di bagian pengganti dari pencocokan pola pencarian-repacle.
René Nyffenegger

jelas aku Bukankah jelas tentang apa yang saya coba katakan: mengedit pertanyaan Anda sehingga menjadi lebih jelas tanpa komentar :)
akira

Hanya ekspresi yang diizinkan setelahnya \=. Atau tepat satu ungkapan. |adalah pembatas perintah, dan jika Anda perlu menggunakan letAnda juga memerlukan fungsi (misalnya jika Anda perlu menggunakannya s/RE/\=EXPRESSION/g) atau :gseperti yang disarankan @peth. Apakah ini pertanyaan golf vim? ;-)
Mars

Jawaban:


3

Anda dapat menggunakan :globalkarena perintahnya dijalankan untuk setiap baris.

:let g:ID = 1
:g//s//\=g:ID/ | let g:ID = g:ID + 1

Jika Anda ingin membatasi penggantian, baik dibatasi oleh :globalpola, atau awalan :globaldengan rentang, atau keduanya.

:10,20g/foo/s/^/\=g:ID/ | let g:ID = g:ID + 1

Itu harus menambahkan pertambahan g:IDuntuk setiap baris yang cocok foodari baris 10 hingga 20 (inklusif).


Terima kasih. Meskipun saya berharap akan ada cara "lebih langsung", jawaban Anda paling dekat dengan apa yang saya inginkan.
René Nyffenegger

1

Anda mungkin perlu mendefinisikan suatu fungsi:

function! Accu(varname, mult)
  let old = {a:varname}
  let {a:varname} = {a:varname} * a:mult
  return old
endfunction

dan gunakan seperti ini:

:let g:ID = 1
:%s/^/\=Accu('g:ID', 1.2)/

Ya, saya tahu itu mungkin dengan suatu fungsi. Tapi kadang-kadang saya merasa itu hanya tidak layak menulis fungsi ... yaitu, jika saya bisa pergi tanpa ...
René Nyffenegger

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.