2010-11-30 10 views
7

Situación n.º 1: Acabo de seleccionar un bloque de texto. Luego escribo ": Comando", que invoca alguna función.Comprueba si hay una selección visual activa actual en Vim desde una función invocada por un comando

Situación n.º 2: No hay una selección visual actual (aunque es posible que haya hecho una selección de este tipo previamente en la sesión de edición). Escribo ": Comando", que invoca (la misma) función.

¿Existe alguna forma (robusta) de distinguir las dos situaciones anteriores de la función? Intenté mode(), pero el problema es que en ambos casos estoy en modo comando, aunque en el primer caso ingresé al modo de comando desde el modo visual mientras que en el segundo estaba en el modo normal. Tal vez a través de la inspección de a:firstline/a:lastline/v:count?


actualización - Caso de Uso ejemplo: ":Sum". Si hay una selección visual actual, por ejemplo, una columna de números (selección de bloque) o un rango de líneas que contienen solo números, este comando hará eco de la suma de los números. De lo contrario, espera una lista de números separados por espacios como argumentos, y hará eco de la suma de esos números. Marco básico:

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 

Los pasos (2) - (5) son sencillos. Estoy teniendo problemas con (1). Utilizo los marcadores "<"/">" para recrear los números de una selección visual. Pero solo quiero hacer esto si hay una selección visual actualmente resaltada/activa.

Tal vez toda mi lógica es incorrecta y hay una mejor manera de diseñar esta funcionalidad?

Respuesta

6

Si necesita utilizar el comando, la única manera que veo es a inspeccionar a:firstline/a:lastline:

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

pero esto no se sostiene el caso cuando se ha seleccionado el búfer entero. Le sugiero que utilice asignaciones de expresión:

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() 

actualización: el modo visual es nunca se activa en el modo de comando. Nunca. Solo porque el modo comando no es el modo visual. El uso de asignaciones es la única forma de lograr lo que desea y aquí hay dos enfoques: utiliza exactamente el mismo mapeo expr para todos los modos y marca mode() en algún lugar de esta expresión o define diferentes mapeos para diferentes modos y usa estas diferencias para distinguir la función de qué modo se llama

+0

Gracias. Este parece el único enfoque posible. – Jeet

Cuestiones relacionadas