search – ¿Por qué un salto de línea se convierte en un carácter nulo dentro del registro de búsqueda y en un retorno de carro en la línea de comando?

Pregunta:

Si tengo el siguiente texto:

foo
bar

Lo selecciono visualmente y lo copio.
El texto ahora se almacena en el registro sin nombre " y aquí está su contenido (salida de :reg " ):

""   foo^Jbar^J

Según este gráfico , parece que ^J es la notación de intercalación para un avance de línea.

Si quiero duplicar el registro sin nombre en a registro escribiendo :let @a = @"
Aquí está su contenido (salida de :reg a ):

"a   foo^Jbar^J

No cambió.

Si ahora lo duplico en el registro de búsqueda escribiendo :let @/ = @" , aquí está su contenido (salida de :reg / ):

"/   foo^@bar^@

Según el gráfico anterior, parece que ^@ es la notación de intercalación para un carácter nulo.
¿Por qué es una línea de alimentación convierte automáticamente en un carácter nulo en el interior del registro de búsqueda (pero no el a registro)?

Si inserto el registro sin nombre en la línea de comando (o dentro de una búsqueda después de / ), escribiendo :<CR>" , esto es lo que se inserta:

:foo^Mbar^M

Nuevamente, de acuerdo con el último gráfico, ^M parece ser la notación de intercalación para un retorno de carro.
¿Por qué un salto de línea se convierte automáticamente en un retorno de carro en la línea de comando?

Editar :

Por lo general, puede insertar un carácter de control literal escribiendo:
<CV><C-{character in caret notation}>

Por ejemplo, puede insertar un <CR> literal escribiendo <CV><CR> .
Puedes hacerlo para aparentemente cualquier personaje de control.
Sin embargo, he notado que no puedo insertar un LF literal dentro de un búfer o en la línea de comando, porque si escribo: <CV><CJ> inserta ^@ , un carácter nulo, en lugar de ^J
¿Es por la misma razón que un LF se convierte en NUL dentro del registro de búsqueda?

Edición 2 :

En :h key-notation , podemos leer esto:

<Nul>       zero            CTRL-@    0 (stored as 10) <Nul>
<NL>        linefeed        CTRL-J   10 (used for <Nul>)

La parte stored as 10 en la primera línea y used for <Nul> en la segunda línea podría indicar que hay algún tipo de superposición entre un LF y un NUL, y que podrían interpretarse como lo mismo. Pero no pueden ser lo mismo, porque después de ejecutar el comando anterior :let @/ = @" , si escribo n en modo normal para llegar a la siguiente aparición de las 2 líneas foo y bar , en lugar de obtener un positivo Match, tengo el siguiente mensaje de error:

E486: Pattern not found: foo^@bar^@

Además, este enlace parece explicar que un NUL denota el final de una cadena, mientras que un LF denota el final de una línea en un archivo de texto.

Y si un NUL se stored as 10 como dice la ayuda, que es el mismo código que para un LF, ¿cómo puede Vim marcar la diferencia entre los 2?

Edición 3 :

Tal vez un LF y un NUL estén codificados con el mismo código decimal, 10 , como dice la ayuda. Y Vim marca la diferencia entre los 2 gracias al contexto. Si encuentra un carácter cuyo código decimal es 10 en un búfer o cualquier registro, excepto los registros de búsqueda y comando, lo interpreta como un LF.
Pero en el registro de búsqueda ( :reg / ) lo interpreta como un NUL porque en el contexto de una búsqueda, Vim solo busca una cadena donde el concepto de end of line in a file no tiene sentido porque una cadena no es un archivo (lo cual es extraño ya que todavía puede usar el átomo \n en un patrón de búsqueda, pero tal vez eso sea solo una característica del motor de expresiones regulares). Entonces interpreta automáticamente 10 como NUL porque es el concepto más cercano ( end of stringend of line ).

Y de la misma manera, en la línea de comando / registro de comando ( :reg : interpreta el código 10 como un CR, porque el concepto de end of line in a file no tiene sentido aquí. El concepto más cercano es el end of command por lo que Vim interpreta 10 como un CR, porque presionar Enter es la forma de finalizar / ejecutar un comando y un CR es lo mismo que presionar Enter , ya que cuando inserta uno literal con <CV><Enter> , Se muestra ^M

Quizás la interpretación del personaje cuyo código es 10 cambia según el contexto:

  • fin de línea en un búfer ( ^J )
  • fin de cadena en una búsqueda ( ^@ )
  • fin del comando en la línea de comando ( ^M )

Respuesta:

Primero, gracias por esta publicación tan completa y reflexiva.

Después de algunas pruebas, he llegado a esta conclusión:

  1. Los caracteres de control se muestran usando la notación de intercalación: ^M para <CR> (retorno de carro) y ^J para <LF> (salto de línea). En los búferes, <EOL> (fin de línea) se muestran como nuevas líneas de pantalla y se ingresan con la tecla enter. <EOL> depende del formato de archivo del búfer: <EOL> = <CR>|<LF>|<CR><LF> para mac|unix|dos respectivamente.

  2. Al editar un búfer, siempre se establece el formato de archivo. Para cambiar el formato de archivo de un búfer abierto, puede usar el siguiente comando que convierte <EOL> :

     :set f[ile]f[ormat]=mac|unix|dos

    Además de convertir <EOL> , este comando convierte <LF> a <CR> cuando se cambia el formato de archivo de mac a unix|dos , y viceversa, <CR> a <LF> cuando se cambia el formato de archivo de unix|dos a mac . Para ver los bytes reales del búfer, puede usar el siguiente comando que transforma la representación textual del búfer en su representación hexadecimal usando el conveniente editor hexadecimal xxd:

     :%!xxd
  3. En los registros (mostrados con el comando :reg[isters] o :di[splay] ), <EOL> siempre se muestran como ^J (pero no todos los ^J son <EOL> ), independientemente del formato de archivo del búfer. Sin embargo, <EOL> se almacenan como deberían. Para poder distinguir ^J visualmente real (es decir <LF> ) de los demás ^J (es decir <EOL> ) en los registros, puede utilizar el siguiente comando que muestra los valores hexadecimales en lugar de la notación de intercalación de los caracteres de control diferente de <EOL> :

     :set d[ispla]y=uhex
  4. En patrones de búsqueda y cadenas de sustitución:

     \r = newline different from <EOL> (<CR> if <EOL> = <CR><LF>|<LF>, <LF> if <EOL> = <CR>) \n = <EOL>
  5. En todos lados:

     <CV><CM>|<CV><EOL> = newline different from <EOL> <CV><CJ> = <NUL>

    Esto muestra que cuando el formato de archivo es dos , es imposible ingresar <LF> , ya que <EOL> = <CR><LF> y <CV><CM>|<CV><EOL> = <CR> .

  6. En cadenas de sustitución:

    • las nuevas líneas distintas de <EOL> se interpretan como <EOL> ;

    • <EOL> se interpretan como <NUL> .

    Entonces, de acuerdo con 4., :%s[ubstitute]/\r/\r/g reemplaza cada nueva línea diferente de <EOL> en el búfer con <EOL> , mientras que :%s[ubstitute]/\n/\n/g reemplaza cada <EOL> en el búfer con <NUL> .

  7. En el registro de búsqueda / y el registro de comando : <EOL> se convierten a

    • nueva línea diferente de <EOL> cuando se inserta desde un registro con /<CR>{register} o :<CR>{register} respectivamente;

    • <NUL> cuando se inserta desde un registro con :let @/=@{register} o :let @:=@{register} respectivamente.

  8. En los búferes, las nuevas líneas diferentes de <EOL> se convierten a <EOL> cuando se insertan desde un registro usando i<CR>{register} .

¿Por qué un salto de línea se convierte en un carácter nulo dentro del registro de búsqueda y en un retorno de carro en la línea de comando?

Antes de copiar <LF> del registro sin nombre " a otros registros, debe ingresar <LF> y ponerlo en el registro " . Si el formato de archivo es unix , puede hacerlo usando yy en una línea vacía; si el formato de archivo es mac , puede hacerlo usando i<CV><CM><Esc>yl ; si el formato de archivo es dos , no puede ingresar <LF> (véase 5.).

Ahora tu afirmación es parcialmente incorrecta, ya que

  • no usa el mismo método para copiar <LF> desde el registro " al registro de búsqueda / y al registro de comando : Usa :let @/=@" para copiar en el registro / y :<CR>" para copiar en el registro : uso de /<CR>" y :<CR>" respectivamente le dará el mismo resultado ( <CR> ) en ambos casos;

  • las conversiones de <LF> que tienen lugar con sus dos métodos de copia diferentes ocurren solo cuando el formato de archivo es unix . Si es mac , <LF> no se convierte cuando se copia al registro / o al registro : y si es dos , ni siquiera puede ingresar <LF> .

La afirmación correcta viene dada por 7. Pero realmente no sé las razones detrás de esto.

Leave a Comment

Your email address will not be published.

Scroll to Top

istanbul avukat

-

web tasarım