Si j'ai le texte suivant:
foo
bar
Je le sélectionne visuellement et le copie.
Le texte est maintenant stocké dans le registre sans nom "
et voici son contenu (sortie de :reg "
):
"" foo^Jbar^J
Selon ce graphique , il semble que ce ^J
soit la notation caret pour un saut de ligne.
Si je veux dupliquer le registre sans nom dans le a
registre en tapant: :let @a = @"
Voici son contenu (sortie de :reg a
):
"a foo^Jbar^J
Cela n'a pas changé.
Si je le copie maintenant dans le registre de recherche en tapant :let @/ = @"
, voici son contenu (sortie de :reg /
):
"/ foo^@bar^@
Selon le tableau précédent, il semble que ce ^@
soit la notation caret pour un caractère nul.
Pourquoi un saut de ligne est-il automatiquement converti en caractère nul dans le registre de recherche (mais pas dans le a
registre)?
Si j'insère le registre sans nom sur la ligne de commande (ou dans une recherche après /
), en tapant :<C-R>"
, voici ce qui est inséré:
:foo^Mbar^M
Encore une fois, selon le dernier tableau, ^M
semble être la notation caret pour un retour chariot.
Pourquoi un saut de ligne est-il automatiquement converti en retour chariot sur la ligne de commande?
Modifier :
Habituellement, vous pouvez insérer un caractère de contrôle littéral en tapant:
<C-V><C-{character in caret notation}>
Par exemple, vous pouvez insérer un littéral <C-R>
en tapant <C-V><C-R>
.
Vous pouvez le faire pour apparemment n'importe quel personnage de contrôle.
Cependant, j'ai remarqué que je ne peux pas insérer un LF littéral dans un tampon ou sur la ligne de commande, car si je tape: <C-V><C-J>
il insère ^@
, un caractère nul, au lieu de ^J
.
Est-ce pour la même raison qu'un LF est converti en NUL dans le registre de recherche?
Modifier 2 :
Dans :h key-notation
, nous pouvons lire ceci:
<Nul> zero CTRL-@ 0 (stored as 10) <Nul>
<NL> linefeed CTRL-J 10 (used for <Nul>)
La stored as 10
partie sur la première ligne et used for <Nul>
sur la deuxième ligne pourrait indiquer qu'il y a une sorte de chevauchement entre un LF et un NUL, et qu'ils pourraient être interprétés comme la même chose. Mais ils ne peuvent pas être la même chose, car après avoir exécuté la commande précédente :let @/ = @"
, si je tape n
en mode normal pour arriver à la prochaine occurrence des 2 lignes foo
et bar
, au lieu d'obtenir une correspondance positive, j'ai le message d'erreur suivant:
E486: Pattern not found: foo^@bar^@
En outre, ce lien semble expliquer qu'un NUL désigne la fin d'une chaîne, tandis qu'un LF désigne la fin d'une ligne dans un fichier texte.
Et si un NUL est stored as 10
comme l'indique l'aide, qui est le même code que pour un LF, comment Vim est-il capable de faire la différence entre les 2?
Modifier 3 :
Peut-être qu'un LF et un NUL sont codés avec le même code décimal 10
, comme le dit l'aide. Et Vim fait la différence entre les 2 grâce au contexte. S'il rencontre un caractère dont le code décimal est 10
dans un tampon ou n'importe quel registre, à l'exception des registres de recherche et de commande, il l'interprète comme un LF.
Mais dans le registre de recherche ( :reg /
) il l'interprète comme un NUL car dans le contexte d'une recherche, Vim ne recherche qu'une chaîne où le concept de end of line in a file
n'a pas de sens car une chaîne n'est pas un fichier (ce qui est bizarre puisque vous pouvez utilise toujours l'atome \n
dans un motif recherché, mais ce n'est peut-être qu'une caractéristique du moteur d'expression régulière?). Il est donc automatiquement interprété 10
comme un NUL car c'est le concept le plus proche ( end of string
≈ end of line
).
Et de la même manière, sur la ligne de commande / registre de commande ( :reg :
), il interprète le code 10
comme un CR, car le concept de end of line in a file
n'a pas de sens ici. Le concept le plus proche est end of command
que Vim interprète 10
comme un CR, car frapper Enter
est le moyen de terminer / exécuter une commande et un CR est le même que frapper Enter
, car lorsque vous insérez un littéral avec <C-V><Enter>
, ^M
s'affiche.
Peut-être que l'interprétation du caractère dont le code est 10
change en fonction du contexte:
- fin de ligne dans un buffer (
^J
) - fin de chaîne dans une recherche (
^@
) - fin de commande sur la ligne de commande (
^M
)
someFunction(arg1, "")
où arg 2 était ""
ie "l'élément entre les guillemets, qui est littéralement rien - un" vide ". un NULL peut apparaître, car il a été" ajouté "par l'implémentation C sous-jacente car il délimitait la chaîne. Je ne sais pas comment vous vérifieriez cela - mais cela vient à l'esprit comme une cause possible
\r
et la \n
différence:substitute
.
NULL
caractères inattendus est provoquée par la fonction C sous-jacente qui gère les chaînes. Cette explication de la façon dont C traite les chaînes auxquelles vous avez lié explique qu'en C interne délimite les chaînes avec aNULL
.NULL
s apparaissent assez rarement dans le texte pour en faire un bon caractère à cet effet. Une conséquence de cela est que si le programme C (vim) essayait de passer une chaîne "vide" dans une fonction C interne