VIM - هذا ليس محررًا فحسب ، بل هو تكامل مع جميع بيئة العمل الخاصة بك

لماذا Vim / Neovim جيدة بشكل خاص؟ حقيقة أن مجموعة الأدوات الخاصة بك ليست مجرد محرر (وهو في حد ذاته قابلاً للتوسعة مع الإضافات ولديه وظائف أساسية غنية ومرنة للغاية في مجال التخصيص) ، ولكن أيضًا بيئة العمل الخاصة بك بأكملها ، مع تضمين مجموعة الأدوات أحادية الاتجاه من gnu / coreutils و ليس فقط يمكنك أخذ أي برنامج أو مترجم فوري دون مغادرة المحرر واستخدامه مباشرة في المحرر.


مقدمة


كُتب هذا المنشور على عجل لدائرة خاصة من الأشخاص ، لكنني قررت أنه من الممكن نشره على موقع Habr. بالنسبة للبعض ، يمكن أن يصبح مصدر إلهام ، وسيساعد شخص ما على فهم فلسفة Vim بشكل أفضل ، وسيأخذ شخص ما بعض الحيل لأنفسهم. فقط في حالة ، سأبدي تحفظًا لا ينبغي أن أتوقع أنني سأبدأ في إثبات شيء لشخص ما في التعليقات ، على سبيل المثال ، لإقناعك أنك بحاجة بالتأكيد إلى التخلي عن IDE الخاص بك السمين والبدء في استخدام Vim ، لست مهتمًا بهذا على الإطلاق.


لرجال الأعمال


هنا ، على سبيل المثال ، خذ هذه الشفرة (من تهيئة مشروع Haskell) ، قائمة بتبعيات الحزمة (مثال في فراغ):


build-depends: X11 , base , directory , extra , GLFW-b , safe , aeson , containers , data-default , text , process , time , dbus 

ماذا نريد؟


  1. ترتيب التبعيات أبجديا
  2. فرز غير GLFW-b لحالة الأحرف ( X11 و GLFW-b يجب ألا GLFW-b فوق كل شيء)
  3. قم باستعادة الفواصل ( aeson إلى القمة ويجب ألا تحتوي على فاصلة على اليسار ، ولكن X11 يجب أن تحتوي على فاصلة على اليسار)
  4. استعادة المسافة البادئة (بحيث يمكنك أيضًا الحصول على الأمر من السجل وإعادة استخدامه في تهيئة أخرى بمستوى تداخل مختلف ، أو حتى ربط أمر hotkey في تهيئة Vim)

قرار


أولاً وقبل كل شيء ، حدد (عن طريق التمييز المرئي) قائمة التبعيات باستثناء السطر الأول من build-depends . بالطبع يمكنك فقط الضغط على V (الوضع المرئي مع تحديد سطر بسطر) وتحديد الخطوط الضرورية من خلال أسهم jk أو لأعلى ولأسفل. في حالتي ، أفعل ذلك بموجة واحدة من يدي باستخدام مفتاح الاختصار المخصص للوضع المرئي:


 xn iz <esc>[zV]z 

على سبيل المثال ، في منتصف قائمة التبعيات ، أقوم فقط بالضغط على viz وسيتم تمييز كل التبعيات بسبب ذلك يتم تمييز الطية بأكملها ، والتي بدورها هي كتلة التعشيش الحالية (حيث قمت بتعريف foldmethod أنها indent ). لكن يمكنك أيضًا كتابة [zV]z بالتتابع دون وجود مفتاح [zV]z مخصص ( [z ينتقل إلى بداية الطية ، a ]z إلى النهاية) ، لكن منذ بالنسبة لي غالبًا ما يتم استخدام مثل هذه العملية ، ثم أقصرها على viz - لا توجد معدلات مثل التحول وتضغط على ردود الفعل في لحظة (أقرب تناظرية قياسية هي vip لتحديد كتلة لأقرب الخطوط الفارغة).


ثم اضغط على : (نقطتين) للدخول في وضع الأوامر لتنفيذ أمر يتعلق بالتمييز المرئي الحالي. في الواقع ، فإن وضع القيادة المعتاد ، ولكن مع علامات الاختيار المضافة على الفور ، أي سيبدو :'<,'> حيث '<,'> هو نطاق التحديد ، حيث '< هو السطر الأول من التحديد المرئي ، و '> هو الأخير.


بعد أن نقر ! (علامة تعجب) على لوحة المفاتيح ، سيعني هذا أن كل شيء يذهب أبعد من ذلك هو أمر shell / bash (حسب الإعدادات). سيبدو مثل :'<,'>! . في الواقع ، بعد تسليط الضوء ، يمكنك النقر على الفور ! واحصل على نفس النتيجة - :'<,'>! .


ستعيد هذه العملية توجيه الخطوط المميزة إلى أمر STDIN واستبدال الخطوط المميزة بـ STDOUT العادم من هذا الأمر. على سبيل المثال ، يمكنك استخدام الأمر sort ، لمجرد التحقق ، والنتيجة ليست هي ما نحتاج إليه - '<,'>!sort ثم اضغط على Enter ، نحصل على:


  build-depends: , aeson , base , containers , data-default , dbus , directory , extra , GLFW-b , process , safe , text , time X11 

الموضة مع coreutils والبرج العام


استعادة التحديد السابق (يمكنك الضغط على gv لاستعادة الاختيار الأخير) واضغط ! وبعد ذلك السهم للأعلى - سيعيد هذا الأمر إلى آخر أمر من السجل ، لذلك لا نحتاج إلى الكتابة مرة أخرى ، بل نستخلص الأمر السابق من السجل ونغيره. لمزيد من الراحة عند تحرير الأمر ، يمكنك الضغط على Ctrl + f - هذا سيفتح إضافية. نافذة مع التحرير القياسي العادي للأمر ، مع كل إمكانيات Vim ، بالمناسبة ، ستكون جميع الفرق السابقة من السجل مرئية هناك كخطوط منفصلة ، والتي يمكن تحديدها وتحريرها وتنفيذها أيضًا.


ما هو الشيء الصحيح الذي يجب القيام به - يمكنك التفكير في اكتشاف ما ، النقطة التي لدي هي: أولاً ، نزيل الفواصل ، نفرزها بدونها (غير متحسسة لحالة الأحرف) ، ثم نعيد الفواصل ، باستثناء السطر الأول.


أولاً ، نزيل الفواصل (ويحتوي السطر الأول على مسافة بادئة إضافية بحيث تكون جميع الخطوط لها نفس المسافة البادئة) باستخدام الأمر sed مع تعبير منتظم ( [, ] - فاصلة أو مسافة ، ثم مسافة أخرى ، \(\w\) أقواس نجحت في إبرازها حظر الاستبدال ، بحيث يكون متاحًا بعد ذلك \1 ، \w هو أول حرف أبجدي ، في الاستبدال سنقوم باستعادة الحرف الأبجدي عن طريق الاستبدال \1 ):


 :'<,'>!sed 's/[, ] \(\w\)/\1/' 

نحصل على ما يلي:


  build-depends: X11 base directory extra GLFW-b safe aeson containers data-default text process time dbus 

بعد ذلك ، نمرر (من خلال الرمز | هو سمة من سمات bash) إلى أمر sort ، ويمر -f لعدم حساسية الحالة:


 :'<,'>!sed 's/[, ] \(\w\)/\1/' | sort -f 

نحصل على:


  build-depends: aeson base containers data-default dbus directory extra GLFW-b process safe text time X11 

انتهى تقريبا! يبقى فقط لإضافة فواصل ، والسطر الأول - بضع مسافات. نستخدم نفس sed ، في بناء جملة عملياتها ، يمكنك تحديد سلاسل ونطاقات سلاسل (كما في Vim نفسه ، يكون بناء الجملة هو نفسه ، جيدًا ، أو مماثلًا تقريبًا). تعني البادئة 1 السطر الأول ، 2,$ يعني النطاق من السطر الثاني إلى النهاية ( $ ، مثل ^ يعني بداية الملف ، بالقياس مع الأحرف نفسها في التعبيرات العادية التي تعني نهاية السطر وبدايةه). سنستخدم \w لتخطي المسافة البادئة وتحديد الحرف الأبجدي الأول على الفور: 1s/\w/ &/ - هنا نقوم باستبدال السطر الأول ، واستعادة أول حرف أبجدي عبر & (مشابه لـ \1 ، فقط ويعني كل شيء تحت regex بالكامل ، بينما يشير \1 إلى أول كتلة ملفوفة بين قوسين) ، تضيف بضعة مسافات أمامها. بالنسبة للسطور المتبقية ، بدلاً من مسافتين ، أضف مسافة فاصلة + متبوعة: 2,$s/\w/, &/ ، الأمر بأكمله سيكون sed -e '1s/\w/ &/' -e '2,$s/\w/, &/' : sed -e '1s/\w/ &/' -e '2,$s/\w/, &/' ، - -e نستخدم لفصل عمليتين عن بعضها البعض. في Vim ، ستبدو العملية بأكملها كما يلي:


 :'<,'>!sed 's/[, ] \([^, ]\)/\1/' | sort -f | sed -e '1s/\w/ &/' -e '2,$s/\w/, &/' 

نحن نطبق ونحصل على:


  build-depends: aeson , base , containers , data-default , dbus , directory , extra , GLFW-b , process , safe , text , time , X11 

القيام به! لم يعد من الضروري كتابة مرة ثانية ، فقط اكتب الأحرف القليلة الأولى ، على سبيل المثال :: :'<,'>!se (في الواقع ، ما عليك سوى الضغط على !se ) ، واستخدام السهم لأعلى للحصول على الأمر المطلوب من السجل. بطريقة أو بأخرى ، أوصي دائمًا بممارسة كتابة مثل هذه الأشياء على الفور . وبالتالي ، سوف تضخ كل من مهارات العمل اليومية في باش وفي فيم نفسه ، كما أساسا أنت تفعل الشيء نفسه.


في النهاية ، يمكن تعيين هذا الأمر برمته إلى مفتاح سريع ، أو تجريده في دالة ، وإعادة استخدامه في كل مكان لواحد أو اثنين.


باستخدام طرف ثالث PL


بدلاً من إطلاق شيء ما من coreutils ، يمكنك تشغيل مترجم من نوع ما من اللغة المناسبة لك ، أحب القيام بهذه الأشياء من خلال Perl6 (تمت إعادة تسميته مؤخراً إلى Raku ):


 :'<,'>!perl6 -e 'my @x=lines.map(*.subst(/<[,\s]>\s(\w)/,{$0})).sort(*.lc); @x.shift.subst(/\w/,{q/ /~$_}).say; .subst(/\w/,{q/, /~$_}).say for @x' 

نعم ، على الأقل في zoskoscript (node.js):


 :'<,'>!node -e 'let fs=require("fs"), x=fs.readFileSync(process.stdin.fd).toString().replace(/\n$/,'').split(/\n/).map(x=>x.replace(/[, ] (\w)/,"$1")).sort((a,b)=>a.toLowerCase().localeCompare(b.toLowerCase())); console.log(x.shift().replace(/(\w)/," $1")); process.stdout.write(x.map(x=>x.replace(/(\w)/,", $1")).join("\n"))' 

يمكن القيام بذلك أيضًا على VimL / Vimscript داخل Vim نفسه ، دون استدعاء الأوامر الخارجية. ولكن هذا المنصب لا يتعلق بذلك.


بطبيعة الحال ، كما كنت قد خمنت ، يمكنك بسهولة حفظ البرنامج النصي الخاص بك في ملف منفصل ، أو حتى تجميع البرنامج الخاص بك الذي يأخذ شيئا لدخول STDIN وإخراج شيء معالج في STDOUT واستخدامه في Vim ببساطة عن طريق الاتصال (والذي ، مرة أخرى ، يمكن تعيينه إلى مفتاح الاختصار):


 :'<,'>!~/my-program-or-script 

وبالتالي ، عند كتابة التعليمات البرمجية في Vim ، ليس فقط Vim نفسه تحت تصرفك ، ولكن أيضًا بيئة العمل بأكملها.


أحد أبسط الأمثلة هو رفض ملف JSON:


 :%!jq 

فقط عدد قليل من ضغطات المفاتيح ، لماذا تقوم بإعادة اختراع محلل AST و prettifayer لـ JSON لأي محرر جديد / IDE / أيا كان ، عندما يمكنك فقط أخذ وتشغيل ملف من خلال jq دون ترك Vim؟ أنا لا أتحدث عن حقيقة أنه من خلال jq يمكنك معالجة ملف JSON الكبير الخاص بك دون مغادرة Vim ، ابحث على سبيل المثال عن المفتاح المطلوب في الشجرة ، وفرزها ، وترك البيانات الضرورية فقط ، إلخ.

Source: https://habr.com/ru/post/ar483580/


All Articles