Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 可以在vim中对一组行进行排序吗?_Sorting_Vim - Fatal编程技术网

Sorting 可以在vim中对一组行进行排序吗?

Sorting 可以在vim中对一组行进行排序吗?,sorting,vim,Sorting,Vim,据我所知,vim的:sort方法将对每一行进行排序。我有一些代码是三行一组的。我该怎么分类呢?请忽略这个糟糕的代码,这是一个遗留应用程序:'( 我想按案例“AF”行进行排序,但忽略(分组)国家和中断行 case 'AF': country = 'Afghanistan'; break;, case 'AL': country = 'Albania'; break;, case 'DZ': country = 'Algeria'; break;, case 'AS':

据我所知,vim的:sort方法将对每一行进行排序。我有一些代码是三行一组的。我该怎么分类呢?请忽略这个糟糕的代码,这是一个遗留应用程序:'(

我想按案例“AF”行进行排序,但忽略(分组)国家和中断行

case 'AF':
  country = 'Afghanistan';
  break;,
case 'AL':
  country = 'Albania';
  break;,
case 'DZ':
  country = 'Algeria';
  break;,
case 'AS':
  country = 'American Samoa';
  break;,
case 'AD':
  country = 'Andorra';
  break;,
case 'AO':
  country = 'Angola';
  break;,
case 'AI':
  country = 'Anguilla';
  break;,
case 'AQ':
  country = 'Antarctica';
  break;,
case 'AG':
  country = 'Antigua And Barbuda';
  break;,
case 'AR':
  country = 'Argentina';
  break;,
case 'AM':
  country = 'Armenia';
  break;,
case 'AW':
  country = 'Aruba';
  break;,
case 'AU':
  country = 'Australia';
  break;,
case 'AT':
  country = 'Austria';
  break;,
case 'AZ':
  country = 'Azerbaijan';
  break;,
case 'BS':
  country = 'Bahamas';
  break;,
case 'BH':
  country = 'Bahrain';
  break;,
case 'BD':
  country = 'Bangladesh';
  break;,
case 'BB':
  country = 'Barbados';
  break;,
case 'BY':
  country = 'Belarus';
  break;

一种方法是将语句折叠成一行,如下所示:

case 'AG': country = 'Antigua And Barbuda'; break;
通过执行可视选择并将换行+缩进替换为空格:

:'<,'>s/\n  / /g


这是采用机器格式代码的一个优点,您可以运行一个混乱的转换(例如正则表达式),然后自动将其修复。

由@Halst建议的与流行语兼容的解决方案版本:

  • 划线
  • 在代码中未显示的字符上加入它们:

    :'<,'>s/[:;]\zs\n/@/
    
您需要手动修复最后一个术语。无需使用
缩进
排序
或任何其他外部程序

如果将相关代码移动到报废缓冲区并在那里重新格式化,也可以避免划线。

My将@Halst和@SatoKatsura(连接、排序,然后取消连接)建议的算法作为一个简单的自定义命令来实现:

:SortRangesByHeader /^case/

该插件实现了各种其他排序方法,例如按折叠、范围等进行排序。

我为此创建了一个命令

这意味着您可以执行
:SortGroup/case/

实施情况如下:

function! s:sort_by_header(bang, pat) range
  let pat = a:pat
  let opts = ""
  if pat =~ '^\s*[nfxbo]\s'
    let opts = matchstr(pat, '^\s*\zs[nfxbo]')
    let pat = matchstr(pat, '^\s*[nfxbo]\s*\zs.*')
  endif
  let pat = substitute(pat, '^\s*', '', '')
  let pat = substitute(pat, '\s*$', '', '')
  let sep = '/'
  if len(pat) > 0 && pat[0] == matchstr(pat, '.$') && pat[0] =~ '\W'
    let [sep, pat] = [pat[0], pat[1:-2]]
  endif
  if pat == ''
    let pat = @/
  endif

  let ranges = []
  execute a:firstline . ',' . a:lastline . 'g' . sep . pat . sep . 'call add(ranges, line("."))'

  let converters = {
        \ 'n': {s-> str2nr(matchstr(s, '-\?\d\+.*'))},
        \ 'x': {s-> str2nr(matchstr(s, '-\?\%(0[xX]\)\?\x\+.*'), 16)},
        \ 'o': {s-> str2nr(matchstr(s, '-\?\%(0\)\?\x\+.*'), 8)},
        \ 'b': {s-> str2nr(matchstr(s, '-\?\%(0[bB]\)\?\x\+.*'), 2)},
        \ 'f': {s-> str2float(matchstr(s, '-\?\d\+.*'))},
        \ }
  let arr = []
  for i in range(len(ranges))
    let end = max([get(ranges, i+1, a:lastline+1) - 1, ranges[i]])
    let line = getline(ranges[i])
    let d = {}
    let d.key = call(get(converters, opts, {s->s}), [strpart(line, match(line, pat))])
    let d.group = getline(ranges[i], end)
    call add(arr, d)
  endfor
  call sort(arr, {a,b -> a.key == b.key ? 0 : (a.key < b.key ? -1 : 1)})
  if a:bang
    call reverse(arr)
  endif
  let lines = []
  call map(arr, 'extend(lines, v:val.group)')
  let start = max([a:firstline, get(ranges, 0, 0)])
  call setline(start, lines)
  call setpos("'[", start)
  call setpos("']", start+len(lines)-1)
endfunction
command! -range=% -bang -nargs=+ SortGroup <line1>,<line2>call <SID>sort_by_header(<bang>0, <q-args>)
function!s:按页眉排序(bang,pat)范围
让帕特
let opts=“”
如果pat=~'^\s*[nfxbo]\s'
让opts=matchstr(pat,“^\s*\zs[nfxbo]”)
让pat=matchstr(pat,'^\s*[nfxbo]\s*\zs.')
恩迪夫
让pat=替换(pat,“^\s*”,“,”)
设pat=替换(pat,'\s*$','','')
设sep='/'
如果len(pat)>0&&pat[0]==matchstr(pat,'.$')&&pat[0]=~'\W'
让[sep,pat]=[pat[0],pat[1:-2]]
恩迪夫
如果pat=''
让帕特=@/
恩迪夫
让范围=[]
执行a:firstline.,'.a:lastline.'g'.sep.pat.sep.'调用add(范围,行(“.”)'
设转换器={
\'n':{s->str2nr(matchstr(s,'-\?\d\+.')),
\'x':{s->str2nr(matchstr(s),-\?\%(0[xX]\)\?\x\+.'),16)},
\'o':{s->str2nr(matchstr(s,'-\?\%(0\)\?\x\+.'),8)},
\“b”:{s->str2nr(matchstr(s),-\?\%(0[bB]\)\?\x\+.'),2)},
\'f':{s->str2float(matchstr(s,'-\?\d\+.')),
\ }
设arr=[]
对于范围内的i(len(范围))
让end=max([get(ranges,i+1,a:lastline+1)-1,ranges[i]]))
let line=getline(范围[i])
设d={}
让d.key=call(get(转换器,opts,{s->s}),[strpart(line,match(line,pat)))
设d.group=getline(范围[i],结束)
呼叫添加(arr,d)
外循环
调用排序(arr,{a,b->a.key==b.key?0:(a.key

注意:这需要Vim 8+,因为使用lambdas

为什么不将其重构为
var COUNTRIES={AF:'阿富汗',…};country=国家[…];
同时?(或
['AF'=>'阿富汗',…]
等)事实上,我在结尾做了谢谢sato。这是一个很好的小技巧。我喜欢漂亮打印的想法,以获得更干净的结果。谢谢链接。我给你答案只是因为插件添加了比我要求的多得多的东西。我爱它!它的大部分功能都来自像你这样的问题。它是一个vimball。从未使用过vimball以前。我如何安装这个东西。如果有帮助的话,我目前使用病原体和janus来安装我的插件。任何帮助都将非常感激。只是
:编辑AdvancedSorters-1.21.vmb.gz
,然后
:so%
。或者,你可以使用GitHub镜像;我也在慢慢地将脚本开发转移到GitHub。是的,我刚刚使用了谢谢
:'<,'>sort
:'<,'>s/@/\r/g
:SortRangesByHeader /^case/
" :[range]SortGroup[!] [n|f|o|b|x] /{pattern}/
" e.g. :SortGroup /^header/
" e.g. :SortGroup n /^header/
" See :h :sort for details
function! s:sort_by_header(bang, pat) range
  let pat = a:pat
  let opts = ""
  if pat =~ '^\s*[nfxbo]\s'
    let opts = matchstr(pat, '^\s*\zs[nfxbo]')
    let pat = matchstr(pat, '^\s*[nfxbo]\s*\zs.*')
  endif
  let pat = substitute(pat, '^\s*', '', '')
  let pat = substitute(pat, '\s*$', '', '')
  let sep = '/'
  if len(pat) > 0 && pat[0] == matchstr(pat, '.$') && pat[0] =~ '\W'
    let [sep, pat] = [pat[0], pat[1:-2]]
  endif
  if pat == ''
    let pat = @/
  endif

  let ranges = []
  execute a:firstline . ',' . a:lastline . 'g' . sep . pat . sep . 'call add(ranges, line("."))'

  let converters = {
        \ 'n': {s-> str2nr(matchstr(s, '-\?\d\+.*'))},
        \ 'x': {s-> str2nr(matchstr(s, '-\?\%(0[xX]\)\?\x\+.*'), 16)},
        \ 'o': {s-> str2nr(matchstr(s, '-\?\%(0\)\?\x\+.*'), 8)},
        \ 'b': {s-> str2nr(matchstr(s, '-\?\%(0[bB]\)\?\x\+.*'), 2)},
        \ 'f': {s-> str2float(matchstr(s, '-\?\d\+.*'))},
        \ }
  let arr = []
  for i in range(len(ranges))
    let end = max([get(ranges, i+1, a:lastline+1) - 1, ranges[i]])
    let line = getline(ranges[i])
    let d = {}
    let d.key = call(get(converters, opts, {s->s}), [strpart(line, match(line, pat))])
    let d.group = getline(ranges[i], end)
    call add(arr, d)
  endfor
  call sort(arr, {a,b -> a.key == b.key ? 0 : (a.key < b.key ? -1 : 1)})
  if a:bang
    call reverse(arr)
  endif
  let lines = []
  call map(arr, 'extend(lines, v:val.group)')
  let start = max([a:firstline, get(ranges, 0, 0)])
  call setline(start, lines)
  call setpos("'[", start)
  call setpos("']", start+len(lines)-1)
endfunction
command! -range=% -bang -nargs=+ SortGroup <line1>,<line2>call <SID>sort_by_header(<bang>0, <q-args>)