কার্সার অবস্থান থেকে শুরু করে চারপাশে মোড়ানো, ভিমে গ্লোবাল অনুসন্ধান এবং প্রতিস্থাপন


112

যখন আমি / নরমাল-মোড কমান্ডটি দিয়ে অনুসন্ধান করি :

/\vSEARCHTERM

ভিম কার্সার অবস্থান থেকে অনুসন্ধানটি শুরু করে এবং উপরের দিকে প্রায় মোড়ানো, নীচের দিকে অবিরত। যাইহোক, যখন আমি অনুসন্ধান এবং প্রতিস্থাপন :substituteকমান্ডটি ব্যবহার করে :

:%s/\vBEFORE/AFTER/gc

পরিবর্তে, ভিমের পরিবর্তে ফাইলের শীর্ষে শুরু হয়।

ভিম কী কার্সার অবস্থান থেকে শুরু করে এবং শেষের দিকে পৌঁছে একবারে শীর্ষে ppingেকে দেবার জন্য অনুসন্ধান সম্পাদন এবং প্রতিস্থাপন করার কোনও উপায় আছে ?


2
\vpattern- 'খুব ম্যাজিক' প্যাটার্ন: অ-অক্ষরীয় অক্ষরগুলি বিশেষ রেজেক্স প্রতীক হিসাবে ব্যাখ্যা করা হয় (কোনও পালানোর দরকার নেই)
কার্লোস আরায়া

এখনকার অবস্থান থেকে শুরু করে কেবলমাত্র ব্যবহার না করে ফাইলটির চারপাশে মোড় করার %কী আছে? আমি এর জন্য কোনও যুক্তিসঙ্গত ব্যবহার দেখতে পাচ্ছি না আপনি যেভাবেই পুরো ফাইলটি দিয়ে যাচ্ছেন।
tymik

@tymik উদ্দেশ্য ছিল কার্সার থেকে অনুসন্ধান শুরু করা, এবং প্রতিটি ফলাফল ধাপে ধাপে এগিয়ে যাওয়া। তবে আমি এখন বছরগুলিতে ভিম ব্যবহার করি নি।
বাসেলেন

উত্তর:


50

১.  দ্বি-পদক্ষেপের বিকল্প ব্যবহার করে আচরণ অর্জন করা কঠিন নয়:

:,$s/BEFORE/AFTER/gc|1,''-&&

প্রথমত, প্রতিস্থাপন কমান্ড বর্তমান লাইন থেকে শুরু করে ফাইলের শেষ অবধি প্রতিটি লাইনের জন্য চালিত হবে:

,$s/BEFORE/AFTER/gc

তারপরে, সেই :substituteআদেশটি একই অনুসন্ধান প্যাটার্ন, প্রতিস্থাপনের স্ট্রিং এবং পতাকাগুলি দিয়ে পুনরায় পুনরায় পুনরায় পুনরায় পুনরায় সাজানো হবে :& (কমান্ডটি দেখুন :help :&):

1,''-&&

পরেরটি তবে ফাইলের প্রথম লাইন থেকে রেখার রেঞ্জের বিস্তৃতিতে প্রতিস্থাপনটি করে যেখানে পূর্বের প্রসঙ্গ চিহ্নটি নির্ধারণ করা হয়েছে, বিয়োগ 1। যেহেতু প্রথম :substituteকমান্ডটি প্রকৃত প্রতিস্থাপন শুরু করার আগে কার্সারের অবস্থান সঞ্চয় করে,  ''রেখাটি যে লাইনটি চিহ্নিত করা হয়েছিল সেটি সেই প্রতিস্থাপন কমান্ড চালানোর আগে বর্তমান লাইন ছিল। ( '' ঠিকানাটি ' ছদ্ম চিহ্নকে বোঝায় ; দেখুন :help :rangeএবং :help ''বিশদগুলির জন্য))

মনে রাখবেন যে প্রথম কমান্ডে যখন প্যাটার্ন বা ফ্ল্যাগগুলি পরিবর্তন করা হয় তখন দ্বিতীয় কমান্ডের ( | কমান্ড বিভাজক-দেখুন পরে :help :bar) কোনও পরিবর্তন প্রয়োজন হয় না।

২.  কিছু টাইপিং সংরক্ষণ করতে, কমান্ড লাইনে উপরের সাবস্টিটিউশন কমান্ডের কঙ্কাল আনার জন্য, কেউ নরমাল-মোড ম্যাপিং সংজ্ঞায়িত করতে পারে, যেমন:

:noremap <leader>cs :,$s///gc\|1,''-&&<c-b><right><right><right><right>

<c-b><right><right><right><right>কমান্ড লাইন ( <c-b>) এর শুরুতে এবং তারপরে চারটি অক্ষর ডান দিকে ( move <right> 4) সরানোর জন্য পিছনের অংশটি প্রয়োজনীয় , সুতরাং এটি প্রথম দুটি স্ল্যাশ চিহ্নের মধ্যে রেখে, ব্যবহারকারী অনুসন্ধানের প্যাটার্নটি টাইপ করতে শুরু করে । একবার কাঙ্ক্ষিত প্যাটার্ন এবং প্রতিস্থাপন প্রস্তুত হয়ে গেলে ফলাফলটি কমান্ড টিপে চালানো যায় Enter

( উপরের ম্যাপিংয়ের //পরিবর্তে ///কেউ যদি বিবেচনা করতে পারে যে কেউ যদি প্যাটার্নটি টাইপ করতে পছন্দ করে তবে আলাদা করে স্ল্যাশ নিজেই টাইপ করুন, তারপরে প্রতিস্থাপনের স্ট্রিংয়ের পরিবর্তে ডান তীরটি ব্যবহার করার পরিবর্তে ইতিমধ্যে উপস্থিত পৃথক পৃথক স্ল্যাশ শুরুর উপরে কার্সারটি সরানো হবে প্রতিস্থাপন অংশ।)


1
এই সমাধানটির একমাত্র সমস্যাটি হ'ল বিকল্পগুলি শেষ (এল) এবং প্রস্থান (কি) দ্বিতীয় বিকল্প কমান্ডটি চালানো থেকে বিরত রাখবে না
স্টিভ ভার্মিউলেন

@eventualEntropy অন্য 'q' প্রেসের জন্য অনুরোধ জানাতে নীচে আমার সমাধানটি দেখুন।
q335r49

2
আপনি যদি কোনও কী ম্যাপিংয়ে রাখেন তবে পাইপটি থেকে বাঁচতে (যেমন আমি করেছি) ভুলে যাবেন না।
জাজাবানি

11
ওহে আমার ,শ্বর, এই সমস্ত নির্বিচার চরিত্রগুলি কী বোঝায় mean কীভাবে শিখলেন?
রকি রাকুন

2
@Tropilio: তারপর আপনি ভালো কিছু চেষ্টা করতে পারেন: :noremap <leader>R :,$s///gc\|1,''-&&<c-b><right><right><right><right>। এটি :,$s///gc|1,''-&&কমান্ড লাইনে প্রথম দুটি স্ল্যাশ চিহ্নের মধ্যে কার্সার দিয়ে রেখেছে। একবার আপনি পছন্দসই প্যাটার্ন এবং প্রতিস্থাপনটি টাইপ করুন, তারপরে আপনি এন্টার টিপে ফলাফল কমান্ড চালাতে পারেন ।
ইব।

174

আপনি ইতিমধ্যে একটি ব্যাপ্তি ব্যবহার করছেন %যা 1,$পুরো ফাইলটি অর্থের জন্য স্বল্প হাত । আপনি ব্যবহার করেন বর্তমান লাইন থেকে শেষ পর্যন্ত যেতে .,$। পিরিয়ডের অর্থ বর্তমান রেখা এবং $শেষ পংক্তির অর্থ। সুতরাং আদেশটি হবে:

:.,$s/\vBEFORE/AFTER/gc

তবে .বর্তমান বা বর্তমান লাইন ধরে নেওয়া যেতে পারে তাই এটি সরানো যেতে পারে:

:,$s/\vBEFORE/AFTER/gc

আরও সাহায্যের জন্য দেখুন

:h range

ধন্যবাদ, আমি ইতিমধ্যে এটি সম্পর্কে জানতাম। আমি অনুসন্ধানটি সন্ধান করতে চাই এবং দস্তাবেজের শেষে পৌঁছে একবারে মোড়কে প্রতিস্থাপন করতে চাই। সহ:।, It গুলি এটি করে না, এটি কেবল "প্যাটার্নটি পাওয়া যায় নি" বলে।
বাসটেলন

7
"পরবর্তী দশ লাইন" এর জন্য:10:s/pattern/replace/gc
এখানে

10
যদিও এটি ওপি যা খুঁজছিল তা নয়, এটি আমার পক্ষে খুব সহায়ক ছিল, ধন্যবাদ!
টোবিয়াস জ

51

%1,$
(ভিম সহায়তা => :help :%1, $ (সম্পূর্ণ ফাইল) এর সমান ) এর একটি শর্টকাট )

. এটি কর্সার পদক্ষেপ যা আপনি করতে পারেন

:.,$s/\vBEFORE/AFTER/gc

নথির শুরু থেকে কার্সার পর্যন্ত প্রতিস্থাপন করা

:1,.s/\vBEFORE/AFTER/gc

ইত্যাদি

আমি দৃ strongly়ভাবে আপনাকে পরামর্শ দিচ্ছি যে আপনি পরিসীমা সম্পর্কে ম্যানুয়ালটি পড়েন :help rangeযতই না সমস্ত কমান্ড একটি ব্যাপ্তির সাথে কাজ করে।


ধন্যবাদ, আমি ইতিমধ্যে এটি সম্পর্কে জানতাম। আমি অনুসন্ধানটি সন্ধান করতে চাই এবং দস্তাবেজের শেষে পৌঁছে একবারে মোড়কে প্রতিস্থাপন করতে চাই। সহ:।, It গুলি এটি করে না, এটি কেবল "প্যাটার্নটি পাওয়া যায় নি" বলে।
বাসটেলন

@ বাসটেলন: পোস্টে টাইপো ছিল // আপনি কপি করে পেস্ট করেছেন?
sehe

সুতরাং আপনি সমস্ত কিছু প্রতিস্থাপন করতে চান তবে আপনি যেমন নিশ্চিতকরণটি জানতে চান আপনি বর্তমান অবস্থান থেকে শুরু করতে চান। ঠিক তখনই দু'বার করুন।
এমবি 14

আপনি এন এবং এর পরিবর্তে ব্যবহার করতে পারেন।
এমবি 14

হুম, আমি অনুমান করি এবং এটি সর্বোত্তম সমাধান, যদিও এটি ঠিক কীভাবে হওয়া উচিত নয় (প্রতিটি ম্যাচে হ্যাঁ / কোনও প্রম্পট নেই)। তবে অবশ্যই যথেষ্ট ভাল, ধন্যবাদ! :)
বাসেলেন

4

আমি চূড়ান্তভাবেই এই সমস্যার সমাধান নিয়ে এসেছি যে অনুসন্ধানের কাজটি প্রারম্ভিকভাবে ফাংশন না লিখে ফাইলটির শুরুতে গুটিয়ে যায় ...

এটি বিশ্বাস করতে আমাকে কতক্ষণ সময় নিয়েছিল আপনি বিশ্বাস করবেন না। মোড়ানোর জন্য কেবল একটি প্রম্পট যুক্ত করুন: ব্যবহারকারী যদি qআবার চাপা দেয় তবে মোড়ক করবেন না। সুতরাং মূলত, qqপরিবর্তে আলতো চাপ দিয়ে অনুসন্ধান ছেড়ে দিন q! (এবং যদি আপনি মোড়ানো করতে চান তবে কেবল টাইপ করুন y))

:,$s/BEFORE/AFTER/gce|echo 'Continue at beginning of file? (y/q)'|if getchar()!=113|1,''-&&|en

আমি আসলে এটি একটি হটকিতে ম্যাপ করেছি। সুতরাং, উদাহরণস্বরূপ, যদি আপনি বর্তমান অবস্থান থেকে শুরু করে কার্সারের অধীনে প্রতিটি শব্দ সন্ধান এবং প্রতিস্থাপন করতে চান তবে q*:

exe 'nno q* :,$s/\<<c-r>=expand("<cword>")<cr>\>//gce\|echo "Continue at beginning of file? (y/q)"\|if getchar()==121\|1,''''-&&\|en'.repeat('<left>',77)

আমার মতে, এই পদ্ধতির - আমার উত্তরে প্রস্তাবিত দুটি আদেশের মধ্যে অতিরিক্ত প্রম্পট সন্নিবেশ করানো - ব্যবহারযোগ্যতার উন্নতি না করে অপ্রয়োজনীয় জটিলতা যুক্ত করে। ইন মূল সংস্করণ , যদি আপনি প্রথম প্রতিকল্পন কমান্ড (সঙ্গে প্রস্থান q, lবা Esc চাপুন ) এবং উপর থেকে অবিরত করতে চান না, আপনি ইতিমধ্যে টিপতে পারেন qঅথবা Esc চাপুন আবার দ্বিতীয় কমান্ড সরাসরি প্রস্থান করার জন্য। এটি হ'ল, প্রম্পটের প্রস্তাবিত সংযোজনটি ইতিমধ্যে উপস্থিত কার্যকারিতা কার্যকরভাবে সদৃশ করেছে।
ইব।

বাবু ... তুমি কি তোমার পদ্ধতির চেষ্টা করেছ? ধরা যাক আমি "লেট" এর পরবর্তী 3 টি ঘটনাকে "আনলেট" দিয়ে প্রতিস্থাপন করতে চাই এবং তারপরে - এটিই কী - অনুচ্ছেদে সম্পাদনা চালিয়ে যান । আপনার পদ্ধতির "y, y, y টিপুন, এখন q টিপুন Now এখন আপনি অনুচ্ছেদের প্রথম লাইনে সন্ধান শুরু করুন quit প্রস্থান করতে আবার Q টিপুন editing সুতরাং, মূলত: yyyqq ... বিভ্রান্ত হয়ে উঠুন ... g; (বা আপনি ^ আর) আমার পদ্ধতি: yyyqq
q335r49

আদর্শ পদ্ধতিটি অবশ্যই yyyqসম্পাদনা চালিয়ে যাওয়া, কোনও বিভ্রান্তিকর জাম্প ছাড়াই। তবে yyyqqপ্রায় হিসাবে ভাল, আপনি যদি ব্যবহারের স্বাচ্ছন্দ্যের দিক থেকে একটি ডাবল ট্যাপকে প্রায় একক ট্যাপ মনে করেন।
q335r49

প্রম্পট সহ মূল কমান্ড বা এর সংস্করণ উভয়ই সেই দৃশ্যে কার্সারটিকে তার পূর্ববর্তী অবস্থানে ফিরিয়ে দেয়। প্রাক্তন শীর্ষস্থান থেকে প্যাটার্নটির প্রথম ঘটনায় ব্যবহারকারীকে ছেড়ে যায় (যেখানে এটি qদ্বিতীয়বার টিপানোর মুহূর্তে ছিল )। দ্বিতীয়টি কার্সারটিকে সর্বশেষ ইভেন্টে ছেড়ে দেয় যা প্রতিস্থাপন করা হয়েছিল (প্রথমটি qচাপ দেওয়ার ঠিক আগে )।
ইব।

1
ইন মূল সংস্করণ , যদি বাঞ্ছনীয় স্বয়ংক্রিয়ভাবে তার পূর্বে অবস্থানে কার্সার ফিরে যাওয়ার (ব্যবহারকারী টাইপ করা ছাড়াই জন্য Ctrl + + হে ), একটি মাত্র সংযুক্ত করতে পারবেন norm!``কমান্ড প্রয়োগ করুন: :,$s/BEFORE/AFTER/gc|1,''-&&|norm!``
ইব।

3

এখানে খুব রুক্ষ কিছু যা দ্বি-পদক্ষেপের পদ্ধতির ( :,$s/BEFORE/AFTER/gc|1,''-&&) দ্বারা বা একটি মধ্যবর্তী "অনুসন্ধানের পরে ফাইলটি শুরু করার জন্য চালিয়ে যাওয়ার বিষয়ে উদ্বেগকে সম্বোধন করে ?" দৃষ্টীকোণ:

" Define a mapping that calls a command.
nnoremap <Leader>e :Substitute/\v<<C-R>=expand('<cword>')<CR>>//<Left>

" And that command calls a script-local function.
command! -nargs=1 Substitute call s:Substitute(<q-args>)

function! s:Substitute(patterns)
  if getregtype('s') != ''
    let l:register=getreg('s')
  endif
  normal! qs
  redir => l:replacements
  try
    execute ',$s' . a:patterns . 'gce#'
  catch /^Vim:Interrupt$/
    return
  finally
    normal! q
    let l:transcript=getreg('s')
    if exists('l:register')
      call setreg('s', l:register)
    endif
  endtry
  redir END
  if len(l:replacements) > 0
    " At least one instance of pattern was found.
    let l:last=strpart(l:transcript, len(l:transcript) - 1)
    " Note: type the literal <Esc> (^[) here with <C-v><Esc>:
    if l:last ==# 'l' || l:last ==# 'q' || l:last ==# '^['
      " User bailed.
      return
    endif
  endif

  " Loop around to top of file and continue.
  " Avoid unwanted "Backwards range given, OK to swap (y/n)?" messages.
  if line("''") > 1
    1,''-&&"
  endif
endfunction

আমাদের শীর্ষে প্রায় গুটিয়ে রাখা উচিত কিনা তা পরীক্ষা করতে এই ফাংশনটি কয়েকটি হ্যাক ব্যবহার করে:

  • ব্যবহারকারী "l", "কিউ" বা "ইস্ক" চাপলে কোনও মোড়ক নেই, যার মধ্যে কোনওটি বাতিল করার ইচ্ছাকে নির্দেশ করে।
  • "S" রেজিস্ট্রারে একটি ম্যাক্রো রেকর্ড করে এবং এর শেষ চরিত্রটি পরীক্ষা করে সেই চূড়ান্ত কী প্রেসটি সনাক্ত করুন।
  • "S" রেজিস্টার সংরক্ষণ / পুনরুদ্ধার করে বিদ্যমান ম্যাক্রোটিকে ওভাররাইট করা এড়িয়ে চলুন।
  • কমান্ডটি ব্যবহার করার সময় আপনি যদি ইতিমধ্যে ম্যাক্রো রেকর্ড করছেন তবে সমস্ত বেট বন্ধ রয়েছে।
  • বাধা দিয়ে সঠিক জিনিস করার চেষ্টা করে।
  • সুস্পষ্ট গার্ডের সাথে "পিছনের সীমার" সতর্কতাগুলি এড়িয়ে চলে।

1
আমি একটি ক্ষুদ্র প্লাগ-ইন এই নিষ্কাশিত এবং GitHub থেকে এটিকে এখানে রেখেছেন
15

স্রেফ আপনার প্লাগইন ইনস্টল করেছেন, এটি কবজির মতো কাজ করে !! এটি করার জন্য আপনাকে অনেক ধন্যবাদ!
ট্রপিলিও

1

আমি পার্টিতে দেরি করে ফেলেছি, তবে আমি এটি না করার জন্য এই জাতীয় দেরী স্ট্যাকওভারফ্লো উত্তরদাতাদের উপর প্রায়শই নির্ভর করেছি। আমি রেডডিট এবং স্ট্যাকওভারফ্লোতে ইঙ্গিত সংগ্রহ করেছি এবং \%>...cঅনুসন্ধানে প্যাটার্নটি ব্যবহার করা সবচেয়ে ভাল বিকল্প , যা কেবলমাত্র আপনার কার্সারের পরে মেলে।

এটি বলেছিল, এটি পরবর্তী প্রতিস্থাপনের ধাপের জন্য প্যাটার্নটিও গণ্ডগোল করে এবং এটি টাইপ করা শক্ত। এই প্রভাবগুলির বিরুদ্ধে লড়াই করতে, একটি কাস্টম ফাংশন অবশ্যই অনুসন্ধানের প্যাটার্নটি পরে ফিল্টার করবে, এটি পুনরায় সেট করে। নিচে দেখ.

আমি নিজেকে একটি ম্যাপিং দিয়ে নিজেকে যুক্তি দিয়েছি যা পরের ঘটনাটি প্রতিস্থাপন করে এবং নিম্নলিখিতটির সাথে লাফ দেয় এবং তার চেয়ে বেশি নয় (যাইহোক আমার লক্ষ্য ছিল)। আমি নিশ্চিত, এর ভিত্তিতে একটি বৈশ্বিক প্রতিস্থাপন কাজ করা যেতে পারে can কোনও সমাধানের উপর লক্ষ্য রেখে কাজ করার সময় মনে রাখবেন :%s/.../.../gযে নীচের প্যাটার্নটি কার্সার অবস্থানে রেখে যাওয়া সমস্ত লাইনে মেলে ফিল্টার করে - তবে একক প্রতিস্থাপন শেষ হওয়ার পরে এটি পরিষ্কার হয়ে যায়, সুতরাং এটি সরাসরি প্রভাব হারিয়ে ফেলে, লাফিয়ে লাফিয়ে লাফিয়ে লাফিয়ে যায় পরবর্তী ম্যাচ এবং এভাবে একের পর এক সমস্ত ম্যাচ চালাতে সক্ষম হয়।

fun! g:CleanColFromPattern(prevPattern) return substitute(a:prevPattern, '\V\^\\%>\[0-9]\+c', '', '') endf nmap <F3>n m`:s/\%><C-r>=col(".")-1<CR>c<C-.r>=g:CleanColFromPattern(getreg("/"))<CR>/~/&<CR>:call setreg("/", g:CleanColFromPattern(getreg("/")))<CR>``n


ধন্যবাদ, আমি একমত যে দেরিতে উত্তর প্রায়শই সহায়ক। আমি ব্যক্তিগতভাবে ভিমকে দীর্ঘকাল থেকে আর ব্যবহার করি না (যেমন কারণের জন্য) তবে আমি নিশ্চিত যে আরও অনেক লোক এটিকে সহায়ক বলে মনে করবে।
বাসেলেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.