\ R ve \ n için mantık s komutunda farklı şeyler ifade ediyor mu?


13

Hepimiz biliyoruz ki, arama yaparken \nsatırsonu ve satır \rbaşı ( ^M) kullanılır, ancak yerine \rsatırsonu değiştirilirken \nbir boş bayt ( ^@) kullanılır.

Bu asimetrinin kökeni nedir? Bu davranışın ... en azından (ve ilk seferinde yanlış yaptığınızda oldukça verimsiz) söylenmesi tuhaf olduğu için, bazı tuhaf tarihsel nedenler olmasını bekliyorum.

(bu arada, bu davranışı "düzeltmenin" ve daha sezgisel bir şey edinmenin bir yolu var mı?)

Yanıtlar:


10

En temel düzeyde, arama ve değiştirme bölümleri arasında zaten bir asimetri vardır, :substituteçünkü birincisi düzenli bir ifade ve ikincisi metindir, belirli ek kaçış dizileriyle . Bu, ne \nanlama geldiğine dair sezgilerinizle vurgulanır .

Örneğin \n, aramada bir değişmez değerle eşleşmediğini düşünün \n. Bu olabilir hattı (EOL) bayt dizinin sonuna, eşleşen \r, \r\nya da sadece \nbağlı olarak 'fileformat'tampon.

Neden \r"EOL yerleştirmek" anlamında kullanıldığına göre, bunun arkasında bazı tarihler var. Vi'nin bir dosyada NUL baytını işlemesi mümkün değildi. Vim, NUL baytlarını dahili olarak bir NL baytı ile değiştirerek bunu geliştirdi (C dizeleri NUL sınırlandırılmış olduğundan).

Davranışlarıyla sızan Bu uygulama detay :substituteberi \nyerine basitçe bir boş karakter belirtmek için kullanılır bu hat, dahili temsiliyle içine yerleştirilir. \riç çizgiyi ikiye ayırarak bir EOL ekler. Vim aslında EOL baytlarını bellekte depolamaz, bunun yerine tamponu okurken / yazarken bunları serileştirir.

Birçok kullanıcının komut dosyalarını ve kas belleğini bozmadan değiştirilemez. Neyse ki, içinde belgelenmiştir :help sub-replace-special.


6

Bir NULbayt, C'de bir dize sonlandırıcıdır ve bu nedenle Vim, aşağıdaki kılavuzda açıklanan bu kuralı kullanır :h NL-used-for-Nul:

Dosyadaki <Nul> karakterler bellekte <NL> olarak depolanır. Ekranda "^ @" olarak gösterilir. Çeviri dosyaları okurken ve yazarken yapılır. Bir <Nul> öğesini bir arama modeliyle eşleştirmek için CTRL- @ veya "CTRL-V 000" girmeniz yeterlidir. Muhtemelen beklediğiniz budur. Dahili olarak karakter, arama düzeninde bir <NL> ile değiştirilir. Alışılmadık olan şey, CTRL-V CTRL-J yazmanın da bir <NL> eklemesi ve böylece dosyada bir <Nul> aramasıdır. {Vi, dosyadaki <Nul> karakteri hiç işleyemiyor}

Bu kural :s/.../.../komuta yayıldı, ancak substitute()işleve değil . \rve aramalardaki \nyedek dizelerde substitute()orijinal anlamlarını korurlar.

Her iki davranışın da daha derin nedenleri olduğunu düşünmüyorum. Vim basitçe orijinalinden organik olarak gelişti vi. Bunun için hiçbir zaman büyük bir plan yoktu, özellikler birbirinin üzerine yığıldı, onları organize tutmak için nispeten az çaba sarf edildi.


0

Diğer Vi klonları , ikame olarak desteklemez \rveya \n(gerçek ters eğik çizgi ve harf olarak), ancak çizgiyi iki satıra bölmek anlamına gelen real ^M( CTRL-V Enter) davranışı standart davranıştır :

Bir <taşıyıcı-dönüş> girme repl (bir kaçış <eğik çizgi> gerektirdiği ex açık veya modunda ve kaçan <kontrol> -V vi modu) düzenlemek tamponu içinde yeni bir çizgi oluşturarak, bu noktada satır bölünmüş eder . <aratıcı- dönüş> atılacaktır.

Unix Geçmiş arşivinde, BSD ex / vi'nin göründüğü ilk versiyonu 4.1cBSD'dir ( @(#)ex_re.c 7.2 10/16/81ve 4BSD'de yoktur) ( @(#)ex_re.c 6.2 10/23/80) [4.1a ve 4.1b arşivde mevcut değildir].

İlgili kod:

/* ^V <return> from vi to split lines */
if (c == '\r')
    c = '\n';

Bu haber dosyasında da belirtilmiştir :

Artık rh'deki ^ V <return> tuşunu kullanarak vi yerine ikame komutları olan satırları ayırmak mümkündür. Bu, ex komut modunu kullanmanın son iyi nedenini halleder.

Ex komut kipinde önceden desteklenen davranış ters eğik çizgi-enter (yani ters eğik çizgi ve ardından gerçek bir yeni satır) içindi.


0

Asimetrinin kökeni, tarihçeyi hesaplamanın bir yoluna gider.

Kısa versiyon:

<CR> & <LF>  (Carriage-Return and Linefeed) 
== 
\r & \n

Uzun versiyon:
İlk ekranlar temel olarak teletiplerin (TTY) dijital versiyonlarıydı ve yazıcılara benzer davranışlar yaratmak için kontrol kodlarını kullandı. Satır başı, imleci (veya baskı kafasını) başlangıç ​​sütununa götürdü. Satır besleme bir sonraki satıra (ekranda) ilerledi ve kağıdı bir satır ileriye besledi.

Yazıcılar için, bir eşleme yapmanız gerekiyordu <CR><LF>veya çıktınız doğru görünmüyordu. İlk ekranlarda, sorun hala geçerliydi.

DOS (ve sonra sorta-Windows) eski standardı izledi ve ile metni kaydeder <CRLF>.

* NIX metni (çoğu vi kullanıcısının bildiği gibi) yalnızca <LF>verimlilik için kullanılır.

Windows'ta sınamak için Word / Wordpad'i kullanın ve birkaç satırlık metni "tür: Metin - MS-DOS biçimi" olarak kaydedin. Ardından aynı dosyayı Not Defteri'nde açın. Normal görünmeli. Daha sonra aynı dosyayı Word / Wordpad'e "tür: Metin" olarak kaydedin. Not Defteri tüm yeni satırları yoksayar ve satırları birlikte çalıştırır. [Not Defteri'nin metin biçimi varsayılan olarak \r\nWord / Wordpad varsayılan olarak kullanılır \n.]

\ r kod eşdeğeri <CR>

\ n kod eşdeğeridir <LF>

Ve vi ile (çok sınırlı) deneyimlerime göre, <CRLF>DOS metin düzenleyiciden kombinasyonu "düzeltmeye" çalışır . vi, yerine bir karakteri kaldırarak sona erdi <NUL>. Nedeni büyük bir kısmı vi kullanmayı bıraktım.


2
Tüm bilgileriniz ilginç olsa da, sadece neden \rolduğunu <CR>ve \nolduğunu söyler <LF>. Farklı bağlamlarda neden farklı\n\r davrandığına dair asıl soruya değinmiyor.
Tumbler41

Teşekkür ederim! :-) Cevap verdiğinde ben değiştiriyordum. (Son paragraf eklendi.)
Robin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.