Program Club

열에 항목을 정렬하기 위해 열 X까지 공백을 삽입하는 방법은 무엇입니까?

proclub 2020. 11. 29. 12:30
반응형

열에 항목을 정렬하기 위해 열 X까지 공백을 삽입하는 방법은 무엇입니까?


다음과 같이 작성된 복사 연산자에 대한 소스 코드가 있습니다.

foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;

나는 다음과 같이 정렬하고 싶습니다 (더 인간이 읽을 수 있지 않습니까?).

foo    = rhs.foo;
foobar = rhs.foobar;
bar    = rhs.bar;
toto   = rhs.toto;

VIM 매직 삽입 -N 열에 또는 한 줄에 몇 번의 키 입력을 사용하여 항목을 정렬 할 수있는 것과 비슷한 것이 있습니까?


Align.vim 이라는 멋진 플러그인이 있습니다.

이 경우 표현식을 선택한 다음을 입력해야 :Align =합니다. =구분 기호 및 참조로 사용하여 모든 것을 정렬 합니다.

(정렬, 왼쪽, 오른쪽, 순환 등 많은 옵션이 있습니다)

유사한 기능을 제공하는 Tabular.vim확인할 수도 있습니다. 스크린 캐스트를 참조하십시오 데모를 위해.


여기에있는 다른 답변은 훌륭합니다. 특히 Tabular.vim에 대한 @nelstrom의 의견과 그의 훌륭한 스크린 캐스트입니다.

그러나 Vim 플러그인을 설치하기에는 너무 게으르지 만 어떻게 든 Vim 매크로를 사용할 의향이 있다면 매크로를 사용합니다.

알고리즘 :

For each line,
    Add tons of spaces before the symbol =
    Go to the column you want to align to
    Delete all text up to =, thereby shifting the = into the spot you want.

예를 들어,

foo = rhs.foo;
foobar = rhs.foobar;
bar = rhs.bar;
toto = rhs.toto;

첫 번째 줄의 아무 곳에 나 커서를 놓고 일반 모드에서 다음을 입력하여 해당 줄의 매크로를 기록합니다.

qa0f=100i <Esc>8|dwjq

다음으로 번역됩니다.

  1. qa -핫키에 매크로 기록 a
  2. 0 -줄의 시작으로 이동
  3. f= -첫 번째 등호로 이동
  4. 100i <Esc>-(뒤에 공백이 하나 i있고 <Esc>"<Esc>"를 입력하지 마십시오.) 공백을 100 개 삽입하십시오.
  5. 8| -8 번째 열로 이동합니다 (죄송합니다. 정렬 할 열을 수동으로 파악해야합니다).
  6. dw -공백이 아닌 다음 문자까지 삭제
  7. j -다음 줄로 이동
  8. q -녹음을 중지합니다.

그런 다음 a두 번째 줄에 커서를 놓고 다음을 눌러 hotkey에 저장된 매크로를 3 번 (나머지 3 줄에 대해) 실행합니다 .

3@a

유닉스 계열 환경을 사용하는 경우 명령 줄 도구를 사용할 수 있습니다 column. 시각적 모드를 사용하여 선을 표시 한 다음 :

:'<,'>!column -t

그러면 선택한 텍스트가 '<,'>!. '<,'>!당신이 명중 할 때 자동으로 삽입됩니다 :비주얼 모드.


진행하는 빠르고 간단한 방법은 X 공백을 추가 한 다음 X 열을 다시 삭제하는 것입니다. 예를 들어 X = 40이면 다음을 입력합니다.

40a<Space><Esc>d40|

동일한 시나리오에 대해 아래 경로에서 설명한 다음 두 기능을 사용할 수 있습니다. https://stackoverflow.com/a/32478708/3146151

이 두 함수를 .vimrc 또는 .gvimrc에 넣고 원할 때마다 편집기에서 일반 함수 호출로 함수를 호출하면됩니다.

내가 게시 한 기능 : https://github.com/imbichie/vim-vimrc-/blob/master/MCCB_MCCE.vim

vim 편집기에서이 함수를 호출하고 이동하려는 문자 또는 공간의 발생 횟수와 ''안의 문자 및 열 번호를 제공해야합니다.

발생 횟수는 각 줄의 시작 (MCCB 기능) 또는 각 줄의 끝 (MCCE 기능) 일 수 있습니다.

질문에서 언급 한 위의 예에서는 MCCB 함수를 사용할 수 있고 '='를 사용할 수있는 문자를 사용할 수 있으므로 vim 편집기에서 사용법은 다음과 같습니다.

:1,4call MCCB(1,'=',8)

따라서 이것은 첫 번째 =기호를 줄 번호 1에서 4로 8 번째 열로 이동합니다 .

다음은 기능입니다.

" MCCB - Move the Character to the Column from the Begin of line
" This is a function for Moving the specified Character 
" in a given range of lines to a the specified Column from the Begin of the line
" NOTE 1 :- If the specified character and the first character of the line are same
"           then the number of Occurance (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range 
"           of lines should be less than or equal to 80, if we need more than 80
"           then we need to insert more spaces by increasing the value 80 in the 
"           "nmap s 80i <ESC>" line inside the function
" Usage :-  in command mode do it like below
" Eg 1:-    :5,11call MCCB(1, '=', 8)
"           The above command will move the 1st Occurance from the begin of Character =
"           to the 8th Column of the lines from 5 to 11
" Eg 2 :-   :7,10call MCCB(2, '+', 12)
"           The above command will move the 2nd Occurance of Character = to the 12th
"           Column of the lines from 7 to 10
    function! MCCB (num_occr, mv_char, col_num) range
        if (a:firstline <= a:lastline)
            nmap s 80i <ESC>
            let line_num = a:firstline
            while line_num <= a:lastline
                execute "normal " . line_num . "G0" . a:num_occr . "f" . a:mv_char . "s" . a:col_num . "|dw"
                let line_num = line_num + 1
            endwhile
            nunmap s
        else
            execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
        endif
    endfunction

" MCCE - Move the Character to the Column from the End of line
" This is a function for Moving the specified Character 
" in a given range of lines to a the specified Column from the End of the line
" NOTE 1 :- If the specified character and the last character of the line are same
"           then the number of Occurance (num_occr) will be one less than the actual
" NOTE 2 :- Maximum space between the specified character with in the range 
"           of lines should be less than or equal to 80, if we need more than 80
"           then we need to insert more spaces by increasing the value 80 in the 
"           "nmap s 80i <ESC>" line inside the function
" Usage :-  in command mode do it like below
" Eg 1:-    :5,11call MCCE(1, ';', 20)
"           The above command will move the 1st Occurance from the End of Character ;
"           to the 20th Column of the lines from 5 to 11
" Eg 2 :-   :7,10call MCCE(5, 'i', 26)
"           The above command will move the 5th Occurance from the End of Character i
"           to the 26th Column of the lines from 7 to 10
    function! MCCE (num_occr, mv_char, col_num) range
        if (a:firstline <= a:lastline)
            nmap s 80i <ESC>
            let line_num = a:firstline
            while line_num <= a:lastline
                execute "normal " . line_num . "G$" . a:num_occr . "F" . a:mv_char . "s" . a:col_num . "|dw"
                let line_num = line_num + 1
            endwhile
            nunmap s
        else
            execute printf('ERROR : Start line %d is higher thatn End line %d, a:firstline, a:lastline)
        endif
    endfunction

대체 솔루션은 두 개의 연속 대체를 수행하는 것입니다.

%s/=/     =/
%s/\%>7c *//

트릭은 7 번째 열 이후에만 \%>7c공백과 일치 하는 열 패턴 입니다 *. 다음 foobar정규식에 6필요하므로 문자 가있는 가장 긴 변수 이름입니다 7.


나는 이것이 오래되었다는 것을 알고 있지만 @talklittle이 올바른 아이디어를 가지고 있다고 생각했으며 대답은 장황했습니다. 더 빠른 방법은 = 뒤에 공백을 삽입 한 다음 다음과 같이 10 번째 열 뒤에있는 모든 공백을 제거하는 것입니다.

   :1,4 s/^\(.*=\) *\(.*\)$/\1                           \2/
   :1,4 s/^\(.\{10\}\) *\(.*\)$/\1\2/

참고 URL : https://stackoverflow.com/questions/6154306/how-to-insert-spaces-up-to-column-x-to-line-up-things-in-columns

반응형