खोज रजिस्टर के अंदर और कमांड लाइन पर कैरिज रिटर्न में एक लाइन फीड को नल वर्ण में क्यों बदल दिया जाता है?


12

यदि मेरे पास निम्न पाठ है:

foo
bar

मैं नेत्रहीन इसे चुनता हूं और इसे कॉपी करता हूं।
पाठ अब अनाम रजिस्टर में संग्रहीत है "और यहां इसकी सामग्री (आउटपुट :reg ") है:

""   foo^Jbar^J

इस चार्ट के अनुसार , ऐसा लगता ^Jहै कि एक लाइन फ़ीड के लिए कैरेट नोटेशन है।

यदि मैं रजिस्टर में अनाम कोड को डुप्लिकेट करना चाहता हूं a: :let @a = @"
यहां इसकी सामग्री (आउटपुट :reg a) है:

"a   foo^Jbar^J

यह नहीं बदला।

यदि मैं अब इसे टाइप करके खोज रजिस्टर में डुप्लिकेट करता हूं :let @/ = @", तो यहां इसकी सामग्री (आउटपुट :reg /) है:

"/   foo^@bar^@

पिछले चार्ट के अनुसार, ऐसा लगता ^@है कि यह अशक्त चरित्र के लिए सबसे महत्वपूर्ण संकेत है।
खोज रजिस्टर (लेकिन aरजिस्टर नहीं ) के अंदर एक पंक्ति फ़ीड स्वचालित रूप से एक अशक्त चरित्र में क्यों बदल जाती है ?

यदि मैं कमांड लाइन पर (या बाद में एक खोज के अंदर /) अनाम कोड सम्मिलित करता हूं :<C-R>", तो यहां यह लिखा है:

:foo^Mbar^M

अंतिम चार्ट के अनुसार, ^Mकैरिज रिटर्न के लिए कैरेट नोटेशन प्रतीत होता है।
एक पंक्ति फ़ीड स्वचालित रूप से कैरिज रिटर्न में कमांड लाइन में क्यों परिवर्तित हो जाती है?

संपादित करें :

आमतौर पर आप टाइप करके शाब्दिक नियंत्रण वर्ण सम्मिलित कर सकते हैं:
<C-V><C-{character in caret notation}>

उदाहरण के लिए, आप <C-R>टाइप करके एक शाब्दिक सम्मिलित कर सकते हैं <C-V><C-R>
आप इसे किसी भी नियंत्रण चरित्र के लिए कर सकते हैं।
हालाँकि मैंने देखा है कि मैं एक बफर के अंदर या कमांड लाइन पर शाब्दिक LF सम्मिलित करने में असमर्थ हूँ, क्योंकि अगर मैं टाइप <C-V><C-J>करता हूँ: तो यह सम्मिलित करता है ^@, इसके बजाय एक अशक्त वर्ण ^J
क्या यह उसी कारण से है, जिससे LF सर्च रजिस्टर के अंदर NUL में बदल जाता है?

2 संपादित करें :

में :h key-notation, हम इसे पढ़ सकते हैं:

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

stored as 10पहली पंक्ति पर और भाग used for <Nul>दूसरी पंक्ति पर संकेत दे सकती हैं कि वहाँ एक वामो और एक NUL के बीच ओवरलैप के कुछ प्रकार है कि, और वे एक ही बात के रूप में व्याख्या की जा सकती है। लेकिन वे एक ही चीज नहीं हो सकते हैं, क्योंकि पिछली कमांड को निष्पादित करने के बाद :let @/ = @", अगर मैं n2 लाइनों की अगली घटना के लिए सामान्य मोड में टाइप करता हूं fooऔर bar, सकारात्मक मिलान प्राप्त करने के बजाय, मेरे पास निम्न त्रुटि संदेश है:

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

इस लिंक के अलावा एक एनयूएल एक स्ट्रिंग के अंत को दर्शाता है, जबकि एक एलएफ एक पाठ फ़ाइल में एक पंक्ति के अंत को दर्शाता है।

और अगर एक एनयूएल stored as 10मदद के रूप में कहता है, जो कि एलएफ के लिए समान कोड है, तो विम 2 के बीच अंतर कैसे कर सकता है?

संपादित करें 3 :

शायद LF और NUL को एक ही दशमलव कोड के साथ कोडित किया जाता है 10, जैसा कि सहायता कहती है। और विम संदर्भ के लिए 2 धन्यवाद के बीच अंतर करता है। यदि यह एक ऐसे पात्र से मिलता है, जिसका दशमलव कोड 10बफर या किसी रजिस्टर में है, तो खोज और कमांड रजिस्टर के अलावा, यह इसे LF के रूप में व्याख्या करता है।
लेकिन खोज रजिस्टर में ( :reg /) इसे एनयूएल के रूप में व्याख्या करता है क्योंकि एक खोज के संदर्भ में, विम केवल एक स्ट्रिंग की खोज करता है, जहां की अवधारणा का end of line in a fileकोई मतलब नहीं है क्योंकि एक स्ट्रिंग एक फ़ाइल नहीं है (जो कि अजीब है क्योंकि आप कर सकते हैं अभी भी \nखोजे गए पैटर्न में परमाणु का उपयोग करें , लेकिन शायद यह केवल रेगेक्स इंजन की एक विशेषता है?)। तो यह स्वतः 10एनयूएल के रूप में व्याख्या करता है क्योंकि यह निकटतम अवधारणा ( end of stringts end of line) है।

और इसी तरह, कमांड लाइन / कमांड रजिस्टर पर ( :reg :) यह 10एक सीआर के रूप में कोड की व्याख्या करता है , क्योंकि यहां अवधारणा की end of line in a fileभावना नहीं है। निकटतम अवधारणा end of commandइसलिए है कि विम 10एक सीआर के रूप में व्याख्या करता है, क्योंकि हिटिंग Enterएक कमांड को समाप्त / निष्पादित करने का तरीका है और सीआर एक हिटिंग के समान है Enter, जब आप एक शाब्दिक के साथ सम्मिलित करते हैं <C-V><Enter>, ^Mतो प्रदर्शित किया जाता है।

हो सकता है कि चरित्र की व्याख्या जिसका कोड 10संदर्भ के अनुसार परिवर्तन हो:

  • एक बफर में लाइन का अंत ( ^J)
  • एक खोज में स्ट्रिंग का अंत ( ^@)
  • कमांड लाइन पर कमांड का अंत ( ^M)

2
कभी-कभी अप्रत्याशित NULL वर्णों की घटना अंतर्निहित सी फ़ंक्शन के कारण होती है जो तारों को संभाल रही है। यह इस बात की व्याख्या करता है कि आप कैसे सी प्रक्रियाओं को तार से जोड़ते हैं, जो यह बताता है कि आंतरिक रूप से सी एक के साथ तार का परिसीमन करता है NULLNULLपाठ में शायद ही कभी पर्याप्त होता है कि यह इस उद्देश्य के लिए एक अच्छा चरित्र बनाता है। इसका एक परिणाम यह है कि यदि C प्रोग्राम (vim) ने "खाली" स्ट्रिंग को आंतरिक C फ़ंक्शन में पास करने की कोशिश की
The_velour_fog

2
उदाहरण के लिए someFunction(arg1, "")जहाँ arg 2 था, "" अर्थात "उद्धरण के बीच की वस्तु, जो कि शाब्दिक रूप से कुछ भी नहीं है - एक" खाली "। एक NULL दिखाई दे सकता है, क्योंकि यह अंतर्निहित सी कार्यान्वयन द्वारा" जोड़ा गया "था क्योंकि यह स्ट्रिंग को सीमांकित करता है। मुझे नहीं पता। आप इसके लिए कैसे जाँच करेंगे - लेकिन यह एक संभावित कारण के रूप में ध्यान में आता है।
the_velour_fog

1
इस पर चर्चा \rऔर \nअंतर:substitute भी देखें ।
जामसेन

जवाबों:


4

सबसे पहले, इस बहुत व्यापक और विचारशील पोस्ट के लिए धन्यवाद।

कुछ परीक्षण के बाद, मैं इस निष्कर्ष पर पहुंचा हूं:

  1. : नियंत्रण वर्ण कैरट अंकन का उपयोग प्रदर्शित किए जाते हैं ^Mके लिए <CR>(गाड़ी वापसी) और ^Jके लिए <LF>(लाइन फ़ीड)। बफ़र में, <EOL>(एंड-ऑफ़-लाइन) नई स्क्रीन लाइनों के रूप में प्रदर्शित होते हैं और एंटर कुंजी के साथ इनपुट होते हैं। <EOL>बफर के फ़ाइल स्वरूप पर निर्भर करते हैं: <EOL> = <CR>|<LF>|<CR><LF>के लिए mac|unix|dosक्रमशः।

  2. एक बफर को संपादित करते समय, फ़ाइल प्रारूप हमेशा सेट होता है। किसी खुले बफर के फ़ाइल प्रारूप को बदलने के लिए, आप निम्नलिखित कमांड का उपयोग कर सकते हैं जो परिवर्तित करता है <EOL>:

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

    परिवर्तित करने के अलावा <EOL>, इस आदेश को धर्मान्तरित <LF>करने के लिए <CR>जब से फ़ाइल स्वरूप बदल रहा है macकरने के लिए unix|dos, और इसके विपरीत, <CR>को <LF>जब से फ़ाइल स्वरूप बदल रहा है unix|dosकरने के लिए mac। बफर के वास्तविक बाइट्स को देखने के लिए, आप निम्न कमांड का उपयोग कर सकते हैं जो बफर के शाब्दिक प्रतिनिधित्व को सुविधाजनक हेक्साडेसिमल संपादक xxd का उपयोग करके अपने हेक्साडेसिमल प्रतिनिधित्व में बदल देता है:

    :%!xxd
    
  3. रजिस्टरों में (कमांड :reg[isters]या के साथ दिखाया गया है :di[splay]), <EOL>हमेशा बफर के फ़ाइल प्रारूप की परवाह किए बिना (लेकिन सभी नहीं हैं ) के रूप में प्रदर्शित किया जाता है । हालांकि रहे हैं संग्रहीत जैसे दिखने चाहिए। नेत्रहीन असली भेद करने में सक्षम होना करने के लिए (यह है कि ) दूसरों से (है कि ) रजिस्टरों में, आप निम्न आदेश का उपयोग कर सकते हैं कि से अलग नियंत्रण केरेक्टर कैरट अंकन के बजाय प्रदर्शित करता है हेक्साडेसिमल मान :^J^J<EOL><EOL>^J<LF>^J<EOL><EOL>

    :set d[ispla]y=uhex
    
  4. खोज पैटर्न और प्रतिस्थापन स्ट्रिंग में:

    \r = newline different from <EOL> (<CR> if <EOL> = <CR><LF>|<LF>, <LF> if <EOL> = <CR>)
    \n = <EOL>
    
  5. हर जगह:

    <C-V><C-M>|<C-V><EOL> = newline different from <EOL>
    <C-V><C-J> = <NUL>
    

    इससे पता चलता है कि जब फ़ाइल स्वरूप है dos, तब से इनपुट करना असंभव है <LF>, <EOL> = <CR><LF>और <C-V><C-M>|<C-V><EOL> = <CR>

  6. प्रतिस्थापन स्ट्रिंग में:

    • से अलग न्यू लाइन <EOL>कर रहे हैं व्याख्या के रूप में <EOL>;

    • <EOL>के रूप में व्याख्या कर रहे हैं <NUL>

    तो, 4. के अनुसार, :%s[ubstitute]/\r/\r/gहर न्यू लाइन अलग से बदल देता है <EOL>साथ बफर में <EOL>है, जबकि :%s[ubstitute]/\n/\n/gजगह हर <EOL>साथ बफर में <NUL>

  7. खोज रजिस्टर में /और आदेश रजिस्टर :, <EOL>कर रहे हैं परिवर्तित करने के लिए

    • के <EOL>साथ /<C-R>{register}या :<C-R>{register}क्रमशः एक रजिस्टर से डाला जब से अलग newline ;

    • <NUL>जब क्रमशः :let @/=@{register}या :let @:=@{register}क्रमशः एक रजिस्टर से डाला जाता है ।

  8. बफ़र्स में, से न्यू लाइन अलग <EOL>कर रहे हैं परिवर्तित करने के लिए <EOL>जब एक रजिस्टर का उपयोग करने से डाला i<C-R>{register}

खोज रजिस्टर के अंदर और कमांड लाइन पर कैरिज रिटर्न में एक लाइन फीड को नल वर्ण में क्यों बदल दिया जाता है?

<LF>अनाम रजिस्टर "से दूसरे रजिस्टरों में कॉपी करने से पहले , आपको इनपुट <LF>और रजिस्टर में डालना होगा "। यदि फ़ाइल प्रारूप है unix, तो आप yyएक खाली लाइन का उपयोग करके ऐसा कर सकते हैं ; यदि फ़ाइल प्रारूप है mac, तो आप इसका उपयोग करके कर सकते हैं i<C-V><C-M><Esc>yl; यदि फ़ाइल प्रारूप है dos, तो आप इनपुट नहीं कर सकते <LF>(cf. 5.)।

अब आपका बयान आंशिक रूप से गलत है

  • आप <LF>रजिस्टर से कॉपी करने के लिए समान विधि का उपयोग "खोज रजिस्टर /और कमांड रजिस्टर में नहीं करते हैं :। आप का उपयोग :let @/=@"रजिस्टर में कॉपी करने के लिए /और :<C-R>"रजिस्टर में कॉपी करने के लिए :। उपयोग करना /<C-R>"और :<C-R>"क्रमशः आपको <CR>दोनों मामलों में एक ही परिणाम ( ) देगा;

  • उस के रूपांतरण <LF>आपके दो अलग-अलग कॉपी तरीकों से होते हैं, जब फ़ाइल प्रारूप होता है unix। अगर ऐसा है mac, <LF>है जब रजिस्टर में कॉपी किया परिवर्तित /या रजिस्टर :, और अगर यह है dosतुम भी इनपुट नहीं कर सकते हैं <LF>

सही बयान 7 द्वारा दिया गया है। लेकिन मैं वास्तव में इसके पीछे के कारणों को नहीं जानता।


यह समझना इतना मुश्किल क्यों है ... मैंने एसओ और विम-एसई और विम मदद पर कई पोस्टों के माध्यम से शोध किया है, लेकिन पूरी तरह से सुसंगत नहीं है, और अभी भी भ्रमित है।
वायलिन्टेरिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.