2012-08-06 17 views
6

Me gustaría saber cómo puedo activar una determinada acción cuando estoy dentro de un entorno determinado al escribir código/latex usando vim. Por ejemplo, supongamos que estoy escribiendo tex y dentro del entorno de alineación, y me gustaría que cada signo igual que ingrese se convierta a & =.Acción Vim dentro del entorno LaTeX

Lo que estoy pensando ahora es bastante engorroso. Esto es un pseudo código para lo que está en mi vimrc. Esto es lo que parece

Shortcut for environment opens start and end tag for align environment (Using imap) 
The above action also initiates a counter variable, sets it to 1 
If counter is 1, every equals sign I enter should be entered as an &=. 
Shortcut to force counter to zero when I move out of the environment. (Using imap) 

Me gustaría saber si hay una manera más fácil de evitar esto. Esto es solo un ejemplo. La idea principal aquí es que vim tenga conciencia ambiental.

Esperamos sus sugerencias.

+0

He editado el título para especificar LaTeX, de lo contrario, esta sería una pregunta muy amplia. El método para detectar un entorno de código diferirá dramáticamente de un idioma a otro. –

Respuesta

2

En general, me ocupo de este tipo de problema después de los hechos. Por ejemplo, lo escribo con los signos normales = y luego lo selecciono visualmente en el área y uso :s/=/\&=/g. Si desea hacer varias cosas en el "entorno" después del hecho, puede crear una función y activar una tecla para ejecutarla. Por ejemplo:

vnoremap <leader>la :call <SID>latexAlign()<cr> 

function! s:latexAlign() range 
    exe ":'<,'>s/=/\&=/g" 
    " add more stuff here... 
endfunction 

Sin embargo, creo que su solución es mejor en caso de que regrese y la edite posteriormente. El archivo en vim htmlcomplete maneja esta situación como esta:

let stylestart = searchpair('<style\>', '', '<\/style\>', "bnW") 
let styleend = searchpair('<style\>', '', '<\/style\>', "nW") 
if stylestart != 0 && styleend != 0 
    if stylestart <= curline && styleend >= curline 
     let start = col('.') - 1 
     let b:csscompl = 1 
     while start >= 0 && line[start - 1] =~ '\(\k\|-\)' 
     let start -= 1 
     endwhile 
    endif 
endif 

Usted puede ver cómo se utiliza searchpair para determinar si está dentro de los <style></style> etiquetas. Consulte :help searchpair() para obtener más información.

+0

Hola, perdón por la gran demora. Tenía mucho trabajo por hacer y me atraparon. Esto no es exactamente lo que estaba buscando. No quiero cambiar una vez que haya terminado con el código. Quiero que sepa mientras estoy dentro. Sin embargo, aprendí mucho de su respuesta, así que gracias. – WiFO215

0

Si está buscando "conciencia ambiental" y si con eso quiere decir "¿estoy en un archivo de látex?" podría habilitar comportamiento con un autocommand.

Vim reconoce una gran cantidad de tipos de archivo y se puede asegurar que el tipo de archivo que está editando es reconocida por defecto haciendo:

:echo &filetype 

Al editar un archivo de Python, me sale python como resultado. Si necesitas esto por sólo látex y se obtiene una respuesta satisfactoria de esa variable Vim, podría configurar un autocommand que utiliza que, de lo contrario puede especificar las extensiones en el mismo, que se vería así:

autocmd BufReadPost,BufNewFile,BufEnter *.tex, *.latex call MyFunction() 

Dónde la Redpost, NewFile y Enter son las posibles interacciones Vim que activarán su MyFunction cuando las extensiones de los archivos terminan en .text o .latex

Si lo que realmente necesita es un poco de ejemplo de código que va a hacer lo que su descripción estados, entonces tal vez la respuesta de Conner es más adecuado.

+2

Por "entorno", el cartel significa una región particular de un archivo LaTeX determinado por la sintaxis, no el tipo de archivo. –

2

Esta es una pregunta muy interesante, pero no estoy seguro de que su enfoque sugerido sea la mejor manera. He intentado una respuesta, pero esta primera iteración puede no ser perfecta. Estoy asumiendo que un entorno LaTeX está simplemente delimitado por los comandos \begin y \end (mi LaTeX está un poco oxidado).

Primero necesita una función para devolver el entorno de la posición del cursor.Mi función a continuación salta al comando anterior \begin, luego salta al comando correspondiente \end, calcula si el cursor está dentro de esta región y continúa el proceso hasta que se encuentra un entorno que lo contiene. Debe manejar entornos anidados. Si no está en un entorno LaTeX, se devuelve una cadena vacía.

function! GetTeXEnv() 
    let pos = getpos('.') 
    let win = winsaveview() 
    let env = '' 
    let carry_on = 1 
    let search_ops = 'bWc' 
    let b_start = line('.') 
    while carry_on 
     keepjumps let b_start = search('\\begin{',search_ops) 
     let search_ops = 'bW' 
     " Only accept a match at the cursor position on the 
     " first cycle, otherwise we wouldn't go anywhere! 
     let env = matchstr(getline('.'),'\\begin{\zs.\{-}\ze}') 
     let env_esc = escape(env,'*') 
     keepjumps let b_end = search('\\end{\s*' . env_esc . '\s*}','Wn') 
     if b_start == 0 
      " finished searching; stop 
      let carry_on = 0 
     elseif b_end > b_start && b_end < pos[1] 
      " not inside this env; carry on 
      let env = '' 
     elseif b_end > b_start && b_end >= pos[1] && b_start <= pos[1] 
      " found it; stop 
      let carry_on = 0 
     endif 
    endwhile 
    call setpos('.',pos) 
    call winrestview(win) 
    return env 
endfunction 

Ahora se puede investigar el entorno del cursor utilizando :echo GetTeXEnv().

Para cambiar el comportamiento de la tecla =, es necesario crear otra función que devuelve &= en el entorno de alineación, y = lo contrario:

function! TeXEquals() 
    return GetTeXEnv() =~ 'align\*\?' ? "&=" : "=" 
endfunction 

A continuación, puede volver a asignar = en modo de inserción (para archivos TeX solamente)

autocmd FileType tex inoremap <silent> = <c-r>=TeXEquals()<CR> 

Esto parece funcionar en mi ejemplo de archivo LaTeX. Avíseme si encuentra algún problema o si tiene alguna idea para mejorar.

Cuestiones relacionadas