আমি কীভাবে মিলিয়ে থাকা "%" নামগুলিকে হাইলাইট করতে পারি (উদাহরণস্বরূপ যদি / শেষ, জন্য / শেষ) সিলেকশনটিতে ম্যাচিটিট.ভিম দ্বারা সংজ্ঞায়িত করা হয়?


10

বর্তমানে আমার ভিম সায়ান ব্যাকগ্রাউন্ড এবং সাদা ফোরগ্রাউন্ডের সাথে ম্যাচিং বন্ধনী, বন্ধনী, কোটস ইত্যাদি হাইলাইট করে - কার্সার এর সাথে এগুলির মধ্যে সরানো যেতে পারে %। আমার ম্যাচিট.ভিমকে ধন্যবাদ, আমি %যদি / শেষ, জন্য / শেষ ইত্যাদির মধ্যেও স্যুইচ করতে পারি - তবে এগুলি নির্বাচনের ক্ষেত্রে হাইলাইট করা হয়নি।

নির্বাচিত হওয়ার পরে আমি কীভাবে স্বয়ংক্রিয়ভাবে এই ম্যাচিং জোড়গুলি হাইলাইট করতে পারি, যেমন বন্ধনীগুলির সাথে স্বয়ংক্রিয়ভাবে সম্পন্ন হয়?

তদুপরি, এই জোড়গুলি ব্যবহার করে আমি কীভাবে পটভূমি রঙটি পরিবর্তন করতে পারি :highlight?

আগাম ধন্যবাদ.


আমি নীচে @ টমি এ দ্বারা উত্তরটি আপডেট করেছি খারাপভাবে নির্দিষ্ট matchit.vimগোষ্ঠীগুলির জন্য অ্যাকাউন্ট করতে এবং অন্য পরিস্থিতিতে যেখানে %অপারেটর কার্সারটিকে মূল অবস্থানে ফিরে না দেয় ever "যখন" লুপের পার্থক্যগুলি পরীক্ষা করে দেখুন। এই থ্রেডটি পড়তে যে কাউকে অসীম লুপগুলি এড়াতে এই সংস্করণটি ব্যবহার করার পরামর্শ দেওয়া হচ্ছে:

function! s:get_match_lines(line) abort
  " Loop until `%` returns the original line number; abort if
  " (1) the % operator keeps us on the same line, or
  " (2) the % operator doesn't return us to the same line after some nubmer of jumps
  let a:tolerance=25
  let a:badbreak=1
  let a:linebefore=-1
  let lines = []
  while a:tolerance && a:linebefore != line('.')
    let a:linebefore=line('.')
    let a:tolerance-=1
    normal %
    if line('.') == a:line
      " Note that the current line number is never added to the `lines`
      " list. a:line is the input argument 'line'; a is the FUNCTION BUFFER
      let a:badbreak=0
      break
    endif
    call add(lines, line('.'))
  endwhile
  "Return to original line no matter what, return list of lines to highlight
  execute "normal ".a:line."gg"
  if a:badbreak==1
    return []
  else
    return lines
  endif
endfunction

function! s:hl_matching_lines() abort
  " `b:hl_last_line` prevents running the script again while the cursor is
  " moved on the same line.  Otherwise, the cursor won't move if the current
  " line has matching pairs of something.
  if exists('b:hl_last_line') && b:hl_last_line == line('.')
    return
  endif
  let b:hl_last_line = line('.')
  " Save the window's state.
  let view = winsaveview()
  " Delete a previous match highlight.  `12345` is used for the match ID.
  " It can be anything as long as it's unique.
  silent! call matchdelete(12345)
  " Try to get matching lines from the current cursor position.
  let lines = s:get_match_lines(view.lnum)
  if empty(lines)
    " It's possible that the line has another matching line, but can't be
    " matched at the current column.  Move the cursor to column 1 to try
    " one more time.
    call cursor(view.lnum, 1)
    let lines = s:get_match_lines(view.lnum)
  endif
  if len(lines)
    " Since the current line is not in the `lines` list, only the other
    " lines are highlighted.  If you want to highlight the current line as
    " well:
    " call add(lines, view.lnum)
    if exists('*matchaddpos')
      " If matchaddpos() is availble, use it to highlight the lines since it's
      " faster than using a pattern in matchadd().
      call matchaddpos('MatchLine', lines, 0, 12345)
    else
      " Highlight the matching lines using the \%l atom.  The `MatchLine`
      " highlight group is used.
      call matchadd('MatchLine', join(map(lines, '''\%''.v:val.''l'''), '\|'), 0, 12345)
    endif
  endif
  " Restore the window's state.
  call winrestview(view)
endfunction
function! s:hl_matching_lines_clear() abort
  silent! call matchdelete(12345)
  unlet! b:hl_last_line
endfunction

" The highlight group that's used for highlighting matched lines.  By
" default, it will be the same as the `MatchParen` group.
highlight default link MatchLine MatchParen
augroup matching_lines
  autocmd!
  " Highlight lines as the cursor moves.
  autocmd CursorMoved * call s:hl_matching_lines()
  " Remove the highlight while in insert mode.
  autocmd InsertEnter * call s:hl_matching_lines_clear()
  " Remove the highlight after TextChanged.
  autocmd TextChanged,TextChangedI * call s:hl_matching_lines_clear()
augroup END

2
আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমি কেবল মুহূর্তের আগে এটি প্রথম পৃষ্ঠায় পপ আপ করতে দেখেছি। কেবলমাত্র আমার নতুন প্লাগইন ম্যাচ-আপটি আরও শক্তিশালী উপায়ে এটি করার জন্য ডিজাইন করা হয়েছে উল্লেখ করতে চাই: github.com/andymass/vim-matchup ( ম্যাচিটের ওপরে আরও অনেক উন্নতি সহ)।
মাস

সত্যিই দরকারী মনে হচ্ছে, এটি তৈরি করার জন্য ধন্যবাদ! আমি এটি চেষ্টা করে দেখুন।
লুক ডেভিস

উত্তর:


12

আমি ভাবলাম এই ধারণাটি আকর্ষণীয়, তাই আমি এটিকে একটি শট দিয়েছি। এটি HTML হিসাবে ঘন ফাইলগুলিতে বিশেষভাবে কার্যকর হবে।

ম্যাচ লাইন

নিম্নলিখিত স্ক্রিপ্টটি কেবল matchit.vimলাইন সংখ্যা রেকর্ড করার সময় যা কিছু করে তা করতে দেয়। ব্যাখ্যা স্ক্রিপ্টের মন্তব্যে রয়েছে।

matchlines.vim

function! s:get_match_lines(line) abort
  let lines = []

  " Loop until `%` returns the original line number
  while 1
    normal %
    if line('.') == a:line
      " Note that the current line number is never added to the `lines`
      " list.
      break
    endif
    call add(lines, line('.'))
  endwhile

  return lines
endfunction

function! s:hl_matching_lines() abort
  " `b:hl_last_line` prevents running the script again while the cursor is
  " moved on the same line.  Otherwise, the cursor won't move if the current
  " line has matching pairs of something.
  if exists('b:hl_last_line') && b:hl_last_line == line('.')
    return
  endif

  let b:hl_last_line = line('.')

  " Save the window's state.
  let view = winsaveview()

  " Delete a previous match highlight.  `12345` is used for the match ID.
  " It can be anything as long as it's unique.
  silent! call matchdelete(12345)

  " Try to get matching lines from the current cursor position.
  let lines = s:get_match_lines(view.lnum)

  if empty(lines)
    " It's possible that the line has another matching line, but can't be
    " matched at the current column.  Move the cursor to column 1 to try
    " one more time.
    call cursor(view.lnum, 1)
    let lines = s:get_match_lines(view.lnum)
  endif

  if len(lines)
    " Since the current line is not in the `lines` list, only the other
    " lines are highlighted.  If you want to highlight the current line as
    " well:
    " call add(lines, view.lnum)
    if exists('*matchaddpos')
      " If matchaddpos() is availble, use it to highlight the lines since it's
      " faster than using a pattern in matchadd().
      call matchaddpos('MatchLine', lines, 0, 12345)
    else
      " Highlight the matching lines using the \%l atom.  The `MatchLine`
      " highlight group is used.
      call matchadd('MatchLine', join(map(lines, '''\%''.v:val.''l'''), '\|'), 0, 12345)
    endif
  endif

  " Restore the window's state.
  call winrestview(view)
endfunction

function! s:hl_matching_lines_clear() abort
  silent! call matchdelete(12345)
  unlet! b:hl_last_line
endfunction


" The highlight group that's used for highlighting matched lines.  By
" default, it will be the same as the `MatchParen` group.
highlight default link MatchLine MatchParen

augroup matching_lines
  autocmd!
  " Highlight lines as the cursor moves.
  autocmd CursorMoved * call s:hl_matching_lines()
  " Remove the highlight while in insert mode.
  autocmd InsertEnter * call s:hl_matching_lines_clear()
  " Remove the highlight after TextChanged.
  autocmd TextChanged,TextChangedI * call s:hl_matching_lines_clear()
augroup END

CursorMovedযদিও আমি সত্যিই এটি ঘটতে পছন্দ করি না । আমি মনে করি এটি একটি মূল মানচিত্র হিসাবে ভাল যা আমার প্রয়োজন হলে ব্যবহার করা যেতে পারে:

nnoremap <silent> <leader>l :<c-u>call <sid>hl_matching_lines()<cr>

matchaddposপরিবর্তে আপনি ফাংশনটি ব্যবহার করতে পারেন । এটি সামান্য দ্রুত এবং যদি আপনি যাইহোক পুরো লাইনটি হাইলাইট করেন তবে এটি জিনিসগুলিকে কিছুটা সহজ করবে।
কার্ল ইংভে লার্ভাগ

1
@ কার্লইংভেলেভের্গ ভাল পয়েন্ট আমি অবচেতনভাবে এটিকে এড়িয়ে চলেছি কারণ এটি এখনও একটি তুলনামূলকভাবে নতুন ফাংশন (v7.4.330 আমি মনে করি) এবং এটি আমাকে একবার পাছায় বিট দেয়। আমি উত্তরটি ব্যবহার করার জন্য আপডেট করব।
টমি এ

এটি একেবারে নিখুঁত, অনেক ধন্যবাদ! ভাল ভিমস্ক্রিপ্ট অনুশীলনও; প্রতিটি লাইন বুঝতে চেষ্টা করবে। আমি ধারণা করি আপনি যদি এই ধরণের ইউটিলিটি লেখেন প্রথম হন তবে এটি বেশ জনপ্রিয় হতে পারে।
লুক ডেভিস

@ লুকডাভিস এর মধ্যে একটি অনাকাঙ্ক্ষিত প্রভাব রয়েছে যা আমি লক্ষ্য করেছি: এটি লাফের তালিকাটি সরিয়ে ফেলবে। আমি <c-o>কোন মিল খুঁজে পেয়েছি এবং এটি একরকমভাবে কার্যকর হয় তার সংখ্যার জন্য ব্যবহার করে এটি ঠিক করার একটি উপায় নিয়ে এসেছি । সমস্যাটি হ'ল ম্যাচিট.ভিমে একটি বাগ রয়েছে যা উইন্ডোটির শীর্ষ লাইনটি জাম্প তালিকায় যুক্ত করে। এটি স্বীকৃত হয়েছে , তবে এটি সংশোধন করার জন্য কোনও তাড়াহুড়া বলে মনে হচ্ছে না।
টমি এ

@ টমমিএ আরে, এই ইউটিলিটির জন্য আবার ধন্যবাদ। আমি প্রকৃতপক্ষে আমার কম্পিউটারে সন্ধান করি যে কর্সারমোভ অটোক্যামডির সাথে বিলম্ব বেশ নগণ্য। s:get_match_lines(line)অসীম লুপগুলি রক্ষা করতে আপনার ফাংশন আপডেট করেছি , যা কিছু অদ্ভুত প্রসঙ্গে আমার জন্য একটি বড় সমস্যা হয়ে উঠছিল। দুর্ভাগ্যক্রমে matchit.vimত্রুটি পূর্ণ। আমার সম্পাদনা উপরে দেখুন এবং আপনার কোনও পরামর্শ থাকলে আমাকে জানান; আমি একটি প্রতিলিপি শিক্ষানবিশ।
লুক ডেভিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.