2010-11-30 2 views
7

상황 # 1 : 방금 텍스트 블록을 선택했습니다. 그런 다음 ": Command"라고 입력하면 일부 기능이 호출됩니다.명령에 의해 호출 된 함수에서 Vim에 현재 활성화 된 시각적 선택이 있는지 확인하십시오.

상황 # 2 : 현재 시각적 선택이 없습니다 (편집 세션에서 이전에 그러한 선택을했을 수도 있음). 필자는 ": Command"를 입력합니다.이 명령은 (같은) 함수를 호출합니다.

함수 내에서 위의 두 가지 상황을 구분할 수있는 (견고한) 방법이 있습니까? 나는 mode()을 시도했다. 그러나 문제는 두 경우 모두 나는 명령 모드에있다. 첫 번째 경우에는 비주얼 모드에서 명령 모드로 들어간 반면 두 번째 모드에서는 정상 모드였다. 어쩌면 검사를 통해 a:firstline/a:lastline/v:count일까요?


업데이트 - 사용 사례 예 : ":Sum". 현재 시각적 선택 (예 : 숫자 열 (블록 선택) 또는 숫자 만 포함하는 범위)이있는 경우이 명령은 숫자 합을 표시합니다. 그렇지 않으면 공백으로 구분 된 숫자의 목록을 인수로 기대하며 그 숫자의 합을 에코합니다. 기본 프레임 워크 :

command! -nargs="*" -range Sum :call CalcSum(<f-args>) 
function! CalcSum(...) range 
    " 1. collect numbers from visual selection if there is a current active selection 
    " 2. otherwise, if len(args) > 0, collect numbers from args 
    " 3. other cases (i.e., no selection and no args or both selection and args) handled reasonably 
    " 4. sum collection of numbers 
    " 5. return/echo result 
endfunction 

단계 (2) - (5)는 간단합니다. 나는 (1)에 문제가있다. "<"/">"표시를 사용하여 시각적 인 선택에서 숫자를 수집합니다. 그러나 의 경우에만의 시각적 선택 이 현재 강조 표시/활성화되어 있습니다.

아마도 내 전체 논리가 잘못되어이 기능을 설계하는 더 좋은 방법이 있을까요? 당신이 명령을 사용해야하는 경우

답변

6

는, 내가 볼 수있는 유일한 방법은 a:firstline/a:lastline 검사하는 것입니다

" Assuming that you have passed -range=% when defining command 
if a:firstline==1 && a:lastline==line('$') 
    " Do something 
endif 

을하지만, 전체 버퍼를 선택하면 이러한 경우를 보유하지 않습니다. 난 당신이 표현 매핑을 사용하는 것이 좋습니다 :

function DoCommand() 
    if mode()!~#"^[vV\<C-v>]" 
     " Do something. For example, set global variable (and unset it in :Command) 
    endif 
    return ':Command' 
endfunction 
noremap <expr> {lhs} DoCommand() 

업데이트을 : 비주얼 모드는 명령 모드에서 결코 활성화됩니다. 못. 명령 모드가 비주얼 모드가 아니기 때문입니다. 매핑을 사용하면 원하는 것을 얻을 수있는 유일한 방법이며 두 가지 접근법이 있습니다. 모든 모드에 대해 정확히 같은 expr 매핑을 사용하고이 표현식 어딘가에 mode()을 확인하거나 다른 모드에 대해 서로 다른 매핑을 정의하고이 차이점을 사용하여 함수를 그것이 호출되는 모드.

+0

감사합니다. 이것은 가능한 유일한 접근 방법처럼 보입니다. – Jeet

관련 문제