2014-11-12 3 views
1

Ex 모드에서 실행 보통을 통해 프로그래밍 방식으로 정상 모드 명령을 수행 할 수 있습니다."정상 실행"후 삽입 모드에서 정상 모드로 돌아 가기

:execute "normal" "iNEWTEXT\<Esc>0" 

이 모드 (i)를 삽입하도록 스위치 "를 newText"을 기록한다 (> < Esc 키 \) 정상 모드로 탈출, 행 (0)의 선두로 이동한다.

그러나 상수가 아닌 문자열 인 레지스터 또는 변수를 사용하면 동작이 달라집니다. 그런 다음 "zy$를 통해 (여기서, Z) 어떤 레지스터에 텍스트를 복사하여 실행할 수 있습니다

iNEWTEXT\<Esc>0 

예를 들어, 어떤 파일의 라인 (A vim 스크립트 파일 반드시)에 저장된 위에 같은 명령이 있다고 가정 등록 번호는 @z입니다.

NEWTEXT\<Esc>0 

삽입 모드를 입력 한 후 탈출이 더 이상 특수 문자로 취급하고, 대신에 문자 그대로있다 : 이번에는하지만, 출력은 다르지 않습니다. \ e와 같은 다른 형식은 작동하지 않습니다. 이 문제를 해결할 방법이 있습니까?

EDIT : Ingo의 대답을 사용하여 다음과 같은 기능을 만들었습니다. 기본적으로 파일의 텍스트 안에 일반/삽입 명령 세트가 포함되어 있고이를 실행할 수 있습니다. 더 일반적으로 비슷한 것이 running Ex commands from a line of text에 사용되었지만 일반 모드와 삽입 모드에서 정확히 똑같은 것을 찾지 못했습니다.

jy10j10jpO\<Esc>jEll 

그 라인에, 당신은 함수 또는 다시 매핑을 호출 할 수 있고 명령이 예에서 (실행 것, 복사 :

그래서, 당신은 당신의 파일에 다음과 같은 텍스트가 줄 10 줄 붙여 넣기, 첫 번째 단어를지나 2 열 이동). Ingo의 대안은 심각한 사용법, 즉 .vimrc에 명령이 있거나 다른 파일에서 명령을 소싱하거나 파일 유형별 옵션을 사용하는 것이 좋습니다. 세션에 의해 저장된 매크로는 마찬가지로 잘 작동 할뿐 아니라 파일 전체에 명령을 분산시키는 것보다 더 실용적입니다. 필자의 경우, 여러 장치에 걸쳐 동기화하고 있었고 다른 특정 파일을 갖고 싶지 않거나이 특정 명령을 사용하여 vimrc를 복잡하게 만들지는 않았지만이 특정 파일 자체가 복잡하지는 않습니다. 이것을 휴대용 매크로처럼 생각하십시오.

" Execute current line as Vim normal mode commands. 
nnoremap <A-y> :call EvaluateLineAsNormalModeCmd()<CR> 

function! EvaluateLineAsNormalModeCmd() 
    let g:getCurrentLine = getline(".") 
    "have to :execute twice: once to get the contents of the 
    "register inserted into a double-quoted string, and then once for 
    "the :normal to evaluate the string. 
    execute 'execute "normal" "' . g:getCurrentLine . '"' 
endfunction 

EDIT2/3

: 여기에 기독교 Brabandt의 답변을 사용하여 두 함수입니다. 그들은 동일하게 작동하지만 끝에 삽입 모드로 사용자를 넣을 수 있습니다. (필자의 최소한의 정보를 기반로하면 다른 컨텍스트에서 'i'는 불완전한 명령으로 간주되어 실행되지 않으며 startinsert를 사용할 수 없습니다. 그 상황). PS : 당신이 정말이 (유스 케이스는 반신 반의) 필요하면 내가

function! EvaluateLineAsNormalModeCmd() 
    normal! 0y$ 
    execute ':call feedkeys("'[email protected]".'", "t")' 
endfunction 

function! EvaluateLineAsNormalModeCmd() 
    let g:getCurrentLine = getline(".") 
    execute ':call feedkeys("'.g:getCurrentLine.'", "t")' 
endfunction 
+0

'\ '시퀀스를'^ ['? (즉, '') –

+0

시도해 보았지만 똑같은 문제가 있습니다. 모든 것이 문자 그대로 취해진 것입니다. Ingo의 double execute 함수는 이것을 해결합니다. – traycerb

답변

4

O_O 주변에 내 머리를 정리 할 수 ​​없기 때문에, 모든 단일 및 이중 따옴표가 무엇을하고 있는지 묻지 마십시오, 당신을 :execute 두 번 : 두 번 인용 문자열에 삽입 된 레지스터의 내용을 얻으려면 한 번 다음 문자열을 평가하려면 :normal 한 번.

:execute 'execute "normal" "' . @z . '"' 

추신 : 자세한 배경을 알려주세요; 최종 목표는 무엇입니까? 질문이 기술적 인 단계에 불과할 때 좋은 대답을 제시하기가 어렵습니다.이유를으로 말하지 않으면 XY problem으로 쉽게 넘어갈 수 있습니다.

+0

불투명하다는 의미는 아닙니다. 너무 많은 정보를 포함하는 라인이 어디에 있는지를 아는 것은 어렵습니다. 어쨌든, 여러 컴퓨터에서 공유되는 파일이 있습니다 (즉, 앱 동기화, 즉 BTSync를 통해). 나는 일련의 명령을 일상적으로 수행한다. 텍스트의 특정 부분을 복사하여 붙여 넣기. 명령을 매크로에 저장하면 (세션에서 복원하는 경우) 작동하지만 각기 다른 컴퓨터에서 수행해야합니다. 명령을 파일 내에 텍스트로 저장하고 거기에서 간단하게 실행한다고 생각했습니다. 나의 유스 케이스의 어리 석음은 이것에 갈 더 좋은 방법이 있다는 것을 의미합니까? 나는 아이디어에 열중하고 있습니다. – traycerb

+1

설명해 주셔서 감사합니다. 명령을 실제 파일 옆의'command.vim' Vimscript 파일과 동기화하고': source' 할 수 있습니다. 또는'.vimrc' (아마도 다른 수단을 통해)를 동기화한다면, 거기에 커맨드를 정의 할 수도 있고 커스텀 파일 타입 (buffer-local 커맨드가있는 플러그인)을 정의 할 수도 있습니다. –

+0

감사합니다. 이것은 잘 작동합니다. 이 솔루션이 나에게 일어 났을 지 확신하지 못합니다. 큰 따옴표 붙이기에 대해 더 많이 배워야합니다.': source' 옵션은 작동하지만, 단지 하나의 명령 이었기 때문에 조금 무거워 보였습니다. 명령 자체는 약간 휘발성이며 (작은 조정이 쉽다) 특정 적이기 때문에 .vimrc에있는 것으로 생각하지 않았습니다. 어느 쪽도 완벽했다. 이제 내 파일에'jv10jy10jpO \ jEll'과 같은 줄이 있는데 거기에서 실행합니다. 그러한 행을 갖는 것은별로 실용적이지 않거나 모든 경우에 가능하지는 않지만, 텍스트를 신경 쓰지 않고 vimrc에서 재 매핑을 동기화 할 수 있기 때문에 여기서는 저에게 큰 도움이됩니다. – traycerb

1

나는 feedkeys() 함수를 사용하고 싶습니다. 예 : (당신이 이름이 레지스터로 라인을 빠지게되면 다른, 그에 따라 레지스터 이름을 조정)

exe ':call feedkeys("'[email protected]".'", "t")' 

을 : 당신의 샘플이 작동합니다. 참고로 인용문이 추락 할 수 있습니다.

exe ':call feedkeys('   - First part of the feedkeys() function call 
    "       - Start of Quote for the first argument 
    .       - String concatenation 
    @"       - content of the unnamed register 
    .       - String concatenation 
    '       - Start of second part of the feedkeys function call 
    "       - End of Quote for the first argument 
    , "t")'      - Second argument of feedkeys() function call 

또한 다음과 같이 2 단계에서 그것을 할 수 :

는이 작업이 무엇이며, 무슨 일이 일어나고 있는지 이해하기 쉽게 이해할 수 있어야한다

exe ':let a="'. @". '"'  - Also needs to quote @" correctly. 
    call feedkeys(a, 't') 

. exe 호출은 정규화 된 키 표기법을 리터럴 키로 변환하는 것입니다.

+0

추악한가요? 나는이 용어가 '마음이 우글 거리다'고 생각한다. 이중 따옴표와 단일 따옴표를 읽으면 알 수있을 것입니다 : h expr-quote,하지만 무명의 레지스터 (@ ")를 대괄호로 묶는 것은 무엇을합니까? 그들은 문자열 연결 연산자처럼 보이지 않습니다. – traycerb

+1

기본적으로 feedkeys 호출이며, 키 표기법이 올바르게 변환되도록'exe'에 의해 평가되어야합니다 (그에 따라 응답을 업데이트하므로 읽기가 더 쉽습니다.)) –

관련 문제