نکته: این مقاله برای کاربران لینوکس طراحی شده است و ممکن است از مفاهیم برنامه نویسی در آن استفاده شود بنابراین برای افراد مبتدی طراحی نشده است. همچنین اصل یادگیری Vim روی تمرین است درنتیجه برای یادگیری کامل باید تک تک این دستورات را خودتان به صورت دستی تست و تمرین کنید.
Vim یکی از ویرایشگر های متنی بسیار مشهور برای سیستم عامل های Unix مانند لینوکس بود اما امروزه می توانید آن را روی ویندوز نیز نصب کنید. از آنجایی که Vim بسیار مشهور است و بسیاری از توسعه دهندگان حرفه ای با آن کار می کنند، تصمیم گرفته ام که آموزش آن را برایتان آماده کنم.
معمولا سه دلیل اصلی برای استفاده از Vim وجود دارد:
بعضی از افراد مانند Kana The Wizard سطوح یادگیری Vim را به قسمت های زیر تقسیم می کنند:
این آموزش بر این اساس نیست چرا که من خیلی با آن موافق نیستم. آموزش ما چند سرفصل زیر را خواهد داشت:
اگر از Ubuntu یا سیستم های لینوکسی مانند آن استفاده می کنید باید به نکته ای مهم توجه کنید. Vim و Vi دو ویرایشگر متفاوت هستند. Vi به صورت پیش فرض در Ubuntu و اکثر سیستم های عامل نصب شده است اما Vim نسخه تکامل یافته تر Vi است که به صورت پیش فرض نصب نشده است. Vim قابلیت های جدیدی را به Vi اضافه می کند بنابراین هر چیزی که در Vi باشد در Vim نیز هست و من پیشنهاد می دهم Vim را نصب کنید. برای انجام این کار دستور زیر را در ترمینال خود اجرا کنید:
sudo apt install vim
کاربران ویندوز نیز باید به وب سایت Vim Editor مراجعه کرده و installer آن را نصب کنند. به هر صورت از این به بعد برای باز کردن یک فایل به نام text.txt می توانید از دستور vim text.txt استفاده نمایید.
راه های مختلفی برای پیکربندی Vim وجود دارد اما من از روش vimrc استفاده می کنم. یعنی یک فایل به نام vimrc. را در مسیر Home سیستم خودم ایجاد می کنم:
touch ~/.vimrc
حالا با دستور زیر، فایل مورد نظر را در vim باز می کنیم:
vim ~/.vimrc
حالا می توانیم در این فایل، دستورات پیکربندی خود را بنویسیم. قبل از ادامه این بحث باید بدانید که Vim چند حالت یا mode مختلف دارد:
حالت های دیگری نیز در Vim وجود دارد اما ما فعلا با آن ها کاری نداریم. تصویر زیر جابجایی بین این حالت ها را به خوبی نشان می دهد.
در حالت پیش فرض از کلید ESC در کیبورد شما، برای خروج از حالت insert استفاده می شود اما معمولا تمام کاربران Vim آن را تغییر می دهند بنابراین من هم آن را به کلیدهای jk تغییر می دهم:
inoremap jk <ESC>
در مرحله بعدی کلیدی به نام leader key وجود دارد که مسئول فعال کردن دستورات میانبر در Vim است. مثلا اگر در تنظیمات خود کلید C را به عنوان میانبر خاصی برای انجام کاری تعریف کرده باشید برای فعال کردن آن باید از کلید leader key خود به همراه C استفاده کنید. کلید leader به صورت پیش فرض / است اما برخی از افراد این موضوع را دوست ندارند. اگر شما نیز از این افراد هستید می توانید آن را به شکل زیر تغییر بدهید:
let mapleader = "'"
با این کار کلید leader key از / به ' (دکمه بین Enter و علامت ; روی کیبورد) تغییر پیدا می کند. من شخصا این کار را انجام نمی دهم. در مرحله بعدی چند دستور دیگر را نیز داریم که به ظاهر vim کمک می کنند:
inoremap jk <ESC> syntax on # highlight syntax set number # show line numbers set noswapfile # disable the swapfile set hlsearch # highlight all results set ignorecase # ignore case in search set incsearch # show search results as you type
syntax on قابلیت syntax highlighting را برای برخی از زبان های برنامه نویسی اضافه می کند. دستور noswapfile ایجاد فایل های swap را غیر فعال می کند. زمانی که در حال ویرایش یک فایل هستید، این ویرایش ها تا لحظه ثبت نهایی و خروج از فایل هنوز اعمال نشده اند بنابراین در یک buffer ذخیره می شوند تا زمانی که شما فایل را ذخیره کنید. حالا اگر در حین ویرایش یک فایل سیستم شما خاموش شود یا اتفاق بدی بیفتد این تغییرات در یک فایل swap ذخیره می شوند تا بعدا بازیابی شوند. من شخصا این قابلیت را دوست ندارد چرا که فایل های ریز و درشتی را می سازد و سیستم را شلوغ می کند بنابراین آن را غیر فعال کرده ام اما شما می توانید با حذف این دستور، آن را فعال نگه دارید. hlsearch باعث پررنگ شدن نتایج جستجوهای شما در یک فایل می شود بنابراین فعال کردنش بسیار بهتر است. ignorecase باعث غیر حساس بودن جستجوهای شما نسبت به بزرگی و کوچکی حروف انگلیسی می شود که قابلیت خوبی است. incsearch نیز در لحظه و همگام با تایپ کرند شما نتایج جستجو را نمایش می دهد.
مسئله اینجاست که برای کپی کردن کد های بالا درون فایل vimrc. چه کار کنیم؟ اول از همه همانطور که گفتم باید با دستور vim .vimrc فایل vimrc. را در ترمینال باز کرده باشید. حالا تنظیمات پیکربندی بالا را کپی کرده و به ترمینال برگردید. ابتدا با فشردن یک کلید مانند i باید وارد insert mode شوید. زمانی که این کلید را یک بار فشار دهید در سمت چپ و پایین صفحه کلمه INSERT ظاهر خواهد شد بنابراین می دانیم که وارد Insert Mode شده ایم. حالا با فشردن کلیدهای shift + Insert می توانید داده های کپی شده در کلیپ بورد سیستم خود را در این قسمت paste کنید:
نکته: کپی و paste کردن داده ها در Vim داستانی طولانی دارد که به وقت خودش در مورد آن صحبت می کنیم.
زمانی که مانند عکس بالا همه چیز را در فایل vimrc. کپی کردید (من کامنت ها را که با # نوشته شده بودند پاک کرده ام) باید کلید ESC را بزنید تا از حالت insert mode خارج شوید. با انجام این کار کلمه INSERT از قسمت سمت چپ و پایین ترمینال حذف می شود. در مرحله بعدی کلید shift را نگه داشته و روی کلید ; کلیک کنید (کلیدی که در سمت راست حرف L روی کیبورد است). همانطور که می دانید با فشردن این دو کلید در حالت عادی علامت دو نقطه (:) تایپ می شود اما در Vim با فشردن این دو کلید وارد حالت Ex یا همان prompt می شویم (به شرطی که در insert mode نباشید). حالا حرف x را تایپ کنید و Enter بزنید. با این کار تمام تغییرات ذخیره شده اند. برای مطمئن شدن از این موضوع یک بار دیگر این فایل را در Vim باز کنید:
vim .vimrc
با باز کردن این فایل باید تغییرات قبلی را مشاهده کنید. از این به بعد برای خارج شدن از insert mode به جای فشردن ESC از کلیدهای J + K استفاده می کنیم. همچنین باید مثل عکسی که بالاتر برایتان گذاشته ام شماره خطوط و دیگر قابلیت ها فعال شده باشند.
نکته: در صورتی که فایل را خراب کردید می توانید این مراحل را دوباره انجام بدهید. همچنین باید بدانید که برای خارج شدن از فایل بدون ذخیره کردن آن، در حالت Ex به جای تایپ کردن X باید !q را تایپ کرده و enter بزنید.
Vim شباهت بسیار زیادی به زبان انگلیسی دارد، یعنی دارای مفعول، فعل و قید و امثال آن است. ما اگر بدین شکل به Vim نگاه کنیم درک آن را ساده تر کرده ایم بنابراین بیایید بر اساس همین قیاس ساده، دستورات اصلی Vim را توضیح بدهیم.
منظور ما از فعل عملیات هایی است که روی اسم ها انجام می دهیم. چند نمونه از این فعل ها را در لیست زیر می بینید:
قیدها نحوه انجام فعل روی اسم را توضیح می دهند. باز هم لیستی از قیدها در Vim را برایتان آماده کرده ام:
مفعول ها در Vim همان چیز هایی هستند که فعل روی آن ها انجام می شود. لیست زیر تعدادی از این مفعول ها را نشان می دهد:
اگر این دستورات برایتان گیج کننده است نگران نباشید، در ادامه به صورت عملی با آن ها آشنا می شویم.
حالا که با فعل و مفعول و قید در Vim آشنا شدیم می توانیم از آن برای ساخت دستورات مختلف استفاده کنیم. به طور مثال برای حذف دو کلمه دستورات زیر را تایپ می کنیم:
d2w
d یعنی delete و 2 هم به معنی عدد ۲ و w به معنی word است بنابراین گفته ایم delete 2 words (دو کلمه را حذف کن). برای حذف جمله ای که در آن هستیم و سپس ورود به حالت insert mode دستور زیر را تایپ می کنیم:
cis
c برای change و i برای inside و s برای sentence که می شود change inside sentence (داخل جمله را تغییر بده). تغییر دادن «داخل» جمله، یعنی جمله ای که در حال حاضر روی آن قرار داریم. در Vim کلمه داخل به این معنی است. برای کپی کردن پاراگراف فعلی از دستور زیر استفاده می کنیم:
yip
y برای yank و i برای inside و p برای paragraph است. البته همانطور که گفتم بحث کپی و paste کردن در Vim مسئله خاص خودش را دارد که در ادامه توضیح خواهیم داد. برای تغییر متن تا علامت > از دستور زیر استفاده می کنیم:
ct<
c برای change و t برای to و > هم خود علامت > است. با این کار تمام متن، از جایی که شما هستید تا جایی که به اولین علامت > برسیم تغییر خواهد کرد. ما می توانستیم به جای c از d استفاده کنیم تا دستور بالا به >dt تبدیل شود (یعنی از جایی که هستیم تا > حذف شود). آیا حالا متوجه منظور من می شوید؟ Vim می تواند مانند زبان انگلیسی و به صورت عادی صحبت کند! همانطور که می بینید یادگیری Vim شاید کمی زحمت داشته باشد اما قدرت زیادی را نیز به شما می دهد.
در این بخش می خواهیم با انجام انواع عملیات های ضروری آشنا شویم که همه افراد باید بدانند. این عملیات ها شامل جستجوی متن در یک فایل و دستورات کار با فایل ها هستند.
دستورات مختلفی برای کار کردن با فایل ها در Vim وجود دارد اما مهم ترین آن ها از قرار زیر هستند:
نکته: در طول این مقاله باید به بزرگی و کوچکی حروف توجه داشته باشید. دستور ZZ با zz یکی نیست چرا که برای تایپ Z بزرگ باید کلید shift را نگه داشته و حرف z را تایپ کنید.
توجه داشته باشید که برخی از این دستورات در کنار خود یک علامت دو نقطه (:) دارند. این دستورات در حالت Ex تایپ و اجرا می شوند. یعنی چه؟ در همین مقاله برایتان توضیح دادم که اگر در حالت insert mode نباشید (با فشردن کلیدهای J + K می توانید از این حالت خارج شوید)، می توانید کلید Shift را نگه دارید و کلید ; را فشار دهید (کلیدی که کنار Enter است و حرف «ک» فارسی را تایپ می کند) تا وارد حالت Ex شوید. در این مرحله می توانید یکی از دستورات بالا را که در کنار خود علامت دو نقطه دارد تایپ کنید و Enter بزنید. توجه داشته باشید که با فشردن کلیدهای ; + Shift علامت دو نقطه تایپ می شود بنابراین نباید دوباره آن را تایپ کنید. مثلا برای ذخیره کردن یک فایل باید وارد حالت Ex شده و فقط حرف w را تایپ کرده و Enter بزنید.
یکی از ضروری ترین کارهایی که با ویرایشگرها انجام می دهیم، جستجو برای رشته خاصی در یک فایل است. یک مثال بسیار رایج، جستجو در فایل های پیکربندی پایگاه های داده ای مانند Redis است که بسیار طولانی هستند و هر قسمت مکانیسم خاصی از Redis را مدیریت می کنند.
برای جستجوی یک رشته باید کلید / را در حالت عادی فشار دهید. با انجام این کار به انتهای صفحه برده می شوید و می توانید رشته مورد نظر خود برای جستجو را تایپ نمایید و در نهایت Enter بزنید. با انجام این کار تمام رشته هایی که با رشته جستجو شده برابر باشند با رنگ خاصی پررنگ و هایلایت می شوند. حالا با فشردن کلید n به نتیجه بعدی منتقل می شوید تا جایی که به انتهای فایل برسید. همچنین با فشردن کلیدهای Shift + n (یعنی N بزرگ) به نتیجه قبلی منتقل می شوید.
در صورتی که می خواهید نتایج هایلایت شده مخفی شوند دستور noh: را اجرا کنید (توجه کنید که این دستور کنارش دو نقطه دارد بنابراین باید در حالت Ex اجرا شود). همچنین می توانید از علامت ؟ به جای علامت / برای جستجو استفاده کنید. تفاوت اینجاست که علامت ؟ (کلیدهای / + Shift) جستجو را به صورت برعکس انجام می دهد؛ یعنی از نتیجه آخر به نتیجه اول می رود.
در Vim قابلیت خاصی وجود دارد که به شما اجازه می دهد به کاراکتر خاصی جهش کنید. به طور مثال پاراگراف تصادفی و تمرینی زیر را در نظر بگیرید:
remember, the "to" here was an open bracket, but it could have been anything. And the syntax for "to" was simply t, so I could have said dt. or yt; for "delete to the next period", or "copy to the next semicolon"
دستور fC به طوری که C کاراکتر مورد نظر شما باشد، مکان نمای شما را به آن کاراکتر منتقل می کند. به طور مثال اگر کلید f را نگه داشته و کلید , (ویرگول انگلیسی) را فشار دهیم به اولین ویرگول انگلیسی در پاراگراف بالا منتقل می شویم (اولین ویرگول در خط اول و بعد از کلمه remember است). حالا اگر بخواهیم به نتیجه بعدی برویم باید کلید ; (کاراکتر نقطه ویرگول در انگلیسی - کلیدی که حرف «ک» در فارسی را تایپ می کند) را فشار بدهیم. هر بار که ; را فشار بدهید به نتیجه بعدی منتقل می شوید (در این مثال ویرگول بعد از کلمه bracket) اما یادتان باشد که این روش فقط برای خطی است که روی آن هستید و در کل متن جستجو نمی کند. همچنین این دستور علاوه بر خط فعلی فقط در جهت روبرو جستجو را انجام می دهد و به عقب نگاه نمی کند.
نکته: دستور دیگری به نام tC وجود دارد که دقیقا مانند fC عمل می کند اما به جای آنکه مکان نما (cursor) شما را روی کاراکتر مورد نظر ببرد، آن را قبل از کاراکتر مورد نظر نگه می دارد.
مسئله جالب اینجاست که ما می توانیم از همین الگو در دستورات خودمان نیز استفاده کنیم. به طور مثال دستور زیر می تواند تمام نوشته های یک خط را از جایی که در آن هستید (محل مکان نما) تا کاراکتر ویرگول تغییر بدهد:
ct,
تغییر دادن یا change کردن یعنی حذف آن قسمت، تا شما بتوانید تغییرات را بنویسید. با این حساب مهم ترین کاراکترها در این بخش به شرح زیر هستند:
جابجایی در یک فایل متنی برای خواندن محتویات آن از ساده ترین و در عین حال مهم ترین مهارت های ممکن در Vim است. من ابتدا لیستی از دستورات مهم برای جابجایی در فایل ها را برایتان قرار می دهم:
تمامی این دستورات فقط در حالت عادی و خارج از insert mode اجرا می شوند و طبیعتا کارشان جابجایی مکان نما (cursor) شما است.
اگر در یک از یک فایل متنی باشید، دستور هایی در اختیار شما گذاشته می شود که برای فقط برای حرکت در همان خط هستند. این دستورات به شکل زیر هستند:
همچنین اگر می خواهید در یک کلمه خاص جا به جا شوید باید از کاراکترهای زیر استفاده کنید:
Vim برای جابجایی در واحد جمله، پاراگراف و صفحه نمایش نیز دستورات مختلفی دارد:
همچنین برای جابجایی در صفحات مختلف نیز از دستورات زیر استفاده می کنیم:
دو نکته بسیار مهم در مورد این دستورات وجود دارد. نکته اول تفاوت بین صفحه (screen) و فایل (file) می باشد. «صفحه» چیزی است که شما در ترمینال می بینید که فقط قسمتی از فایل می باشد اما «فایل» تمام محتوای باز شده در ترمینال است. زمانی که از دستور H استفاده می کنید، محتوای درون ترمینال به بالا یا پایین اسکرول نمی شوند بلکه مکان نما به بالای همان صفحه می رود. این در حالی است که اگر از دستور gg استفاده کنیم تمام محتوا به بالا اسکرول شده و به ابتدای فایل می رویم. با چند با تست این دستورات در یک فایل متنی طولانی می توانید به راحتی متوجه منظور من بشوید.
نکته دوم این است که در Vim (و حتی ویرایشگر هایی مانند nano) برخی اوقات ^ به معنای کلید Ctrl است و به کاراکتر ^ (کلید shift و عدد ۶) ربطی ندارد. دستوراتی که در این بخش ذکر شد (دستورات U^ و D^ و F^ و B^) همگی شامل این موضوع می شوند بنابراین U^ به معنی Ctrl + U است، نه اینکه shift و 6 را نگه داشته و سپس U را تایپ کنید.
همچنین در Vim اجازه دارید که با استفاده از دو دستور زیر بین مکان هایی که بودید منتقل شوید:
و در نهایت چند دستور باقی مانده را نیز بررسی می کنیم:
در ابتدای این مقاله mode های مختلف Vim را توضیح دادم و اولین آن ها Command mode بود که به Normal Mode نیز مشهور است. در این حالت هر کدام از کلیدها معنی خاصی دارند بنابراین می خواهم به صورت جزئی تری وارد مبحث آن شده و برخی از آن ها را بررسی کنیم. من مستقیما به سراغ دستورات می روم. توجه داشته باشید که بزرگی و کوچکی حروف در این دستورات مهم است چرا که حروف بزرگ با نگه داشتن کلید Shift نوشته می شوند. همچنین تمام دستورات زیر در حالت command mode جرا می شوند و علامت دو نقطه جزئی از دستور نیست.
دستور i: باعث ورود به حالت insert می شود اما این کار را دقیقا قبل از محل cursor شما انجام می دهد. به طور مثال اگر cursor شما روی حرف b از کلمه beautiful باشد با فشردن i وارد حالت insert mode می شوید و هر چیزی که تایپ کنید قبل از حرف b از کلمه beautiful تایپ می شود.
دستور a: این دستور مانند دستور i شما را وارد insert mode می کند با این تفاوت که به جای نوشتن کاراکترها قبل از cursor، آن ها را بعد از cursor می نویسد. باز هم از همان مثال قبلی استفاده می کنم و می گویم اگر cursor شما روی حرف b از کلمه beautiful باشد با فشردن a وارد حالت insert mode می شوید و هر چیزی که تایپ کنید بعد از حرف b از کلمه beautiful تایپ می شود.
دستور I: این دستور با نگه داشتن کلید shift و نوشتن i اجرا می شود. این دستور مانند i شما را وارد insert mode می کند با این تفاوت که نوشتن را از ابتدای خط شروع می کند و با کلمات کاری ندارد.
دستور A: این دستور با نگه داشتن کلید shift و نوشتن a اجرا می شود. این دستور مانند a شما را وارد insert mode می کند با این تفاوت که نوشتن را از انتهای خط شروع می کند و با کلمات کاری ندارد.
دستور o: این دستور ابتدا به خط جدید می رود و سپس شما را وارد حالت insert mode می کند.
دستور O: این دستور ابتدا یک خط جدید را قبل از خط فعلی ایجاد کرده و شما را وارد insert mode می کند.
دستور r: کاراکتری که مکان نمای شما روی آن است را جایگزین می کند. برای این کار ابتدا روی کاراکتر مورد نظر بروید و سپس کلید r را یک بار فشار دهید. حالا هر کلیدی از کیبورد را که فشار بدهید، جایگزین حرف مورد نظر خواهد شد.
دستور R: کاراکتری که مکان نمای شما روی آن است را جایگزین می کند اما پس از جایگزینی به شما اجازه تایپ کردن می دهد تا کاراکترهای بعدی را نیز جایگزین کنید. در واقع این دستور شما را وارد حالت replace mode می کند و برای خروج از آن باید کلیدهای J + K را فشار دهید.
دستور C: این دستور خط مورد نظر را از محل cursor شما تا انتهای خط حذف می کند تا به جایش چیزی بنویسید.
دستور S: کل خط فعلی را حذف می کند.
دستور ~: علامت tilde یا ~ (کلید shift را گرفته و کلید بالای tab را فشار دهید) باعث تغییر casing حروف می شود. به طور مثال اگر مکان نما یا cursor خود را روی حرف b از کلمه beautiful برده و دستور ~ را اجرا کنیم، حرف b به B تبدیل می شود. بنابراین این دستور حروف بزرگ را به کوچک و حروف کوچک را به بزرگ تبدیل می کند.
دستور gq ap: این دستور برای فرمت کردن و ترازبندی متن استفاده می شود و بر اساس تنظیمات textwidth سیستم شما اعمال می شود. این دستور برای زمانی است که با فایل های بسیار شلوغ سر و کار دارید و می خواهید جمله یا پاگراف خاصی را کمی مرتب تر کنید تا خوانا تر شود.
حالا که با ویرایش متون در Vim آشنا شدید باید با دستورات مربوط به حذف نیز صحبت کنیم. دستوراتی که در قسمت قبل به شما معرفی کردیم و کارشان حذف کردن یک قسمت خاص بود (مانند دستور C) در Vim به دستور های sustitute معروف هستند چرا که به شما اجازه می دهند پس از حذف، شروع به نوشتن کنید بنابراین در اصل برای جایگزین کردن یک خط استفاده می شوند اما دستوراتی که در این بخش معرفی خواهیم کرد فقط برای حذف کردن یک متن می باشند.
دستور x: این دستور کاراکتری را حذف می کند که cursor شما روی آن باشد.
دستور X: این دستور کاراکتری را حذف می کند که قبل از cursor شما باشد.
دستور dd: این دستور خط فعلی را حذف می کند. منظور از خط فعلی همان خطی است که مکان نمای شما در آن قرار دارد.
دستور dt: این دستور تمام کاراکترها از محل مکان نما تا کاراکتر خاصی را حذف می کند. به طور مثال dta تمام رشته از محل مکان نما تا اولین حرف a را حذف می کند. دستور .dt نیز تمام رشته از مکان نما تا اولین علامت نقطه را حذف خواهد کرد.
دستور D: این دستور رشته را از محل مکان نما تا انتهای خط حذف می کند.
دستور J: این دستور خط فعلی را به خط بعدی متصل می کند.
فرض کنید یکی از دستورات بالا را به اشتباه وارد کرده باشید و خطی که نباید حذف می شده است، حالا از بین رفته است. چطور می توانیم این اشتباه را به عقب برگردانده و خط را بازگردانی کنیم؟ در نرم افزار هایی مثل Microsoft Office Word از کلیدهایی مانند Ctrl + Z استفاده می شود اما در Vim از کاراکتر u استفاده می کنیم. u شما را یک مرحله به عقب برمی گرداند بنابراین اگر آن را دوباره بزنید دو بار به عقب برمی گردید و الی آخر تا زمانی که به آخرین تغییر ثبت شده در آن فایل برسید.
حالا اگر یک بار undo را انجام دادید (به عقب برگشتید) اما پشیمان شدید و خواستید دوباره به جلو برگردید چطور؟ به این عملیات redo یا بازانجام می گوییم که با کلیدهای Ctrl + r انجام می شود. توجه داشته باشید که redo (کلیدهای Ctrl + r) فقط در مقابل Undo (کلید u) معنی دارند؛ یعنی با استفاده از این دو دستور فقط می توانید در تاریخچه عملیات ها جلو و عقب بروید نه اینکه یکی از این کار ها را دوباره انجام بدهید. مثلا اگر من کلید i را فشار داده و وارد حالت insert mode شوم و سپس کلمه roxo را در فایل خودم بنویسم و با کلیدهای j + k به حالت command mode بازگردم، با فشردن کلیدهای Ctrl + r دوباره این کلمه نوشته نمی شود. چرا؟ به دلیل اینکه کلیدهای Ctrl + r فقط در تاریخچه جا به جا می شوند و نوشتن کلمه roxo آخرین تاریخچه عملیات ما است بنابراین عملیات جدیدتری در این تاریخچه ثبت نشده است که بخواهیم به آن برویم (دقیقا مانند زمانی که مرورگر را باز کرده اید و به roxo.ir می روید. در این حالت کلید forward یا next در مرورگر غیر فعال است چرا که در آخرین صفحه از تاریخچه مرورگر خود هستید).
در صورتی که می خواهید آخرین عملیات انجام شده را دوباره انجام بدهید باید کلید . (علامت نقطه) را در کیبورد فشار بدهید. مثلا من وارد insert mode شده و کلمه roxo را تایپ می کنم و سپس به حالت command mode برمی گردم. حالا اگر کلید . را فشار بدهید یک بار دیگر کلمه roxo برایتان تایپ می شود. اگر دوباره . را فشار دهید، یک بار دیگر roxo تایپ می شود و می توانید این کار را تا ابد انجام بدهید. بگذارید یک مثال دیگر بزنم. ما می توانیم با اجرای دستور dw یک کلمه را حذف کنیم (d برای delete و w برای word). حالا اگر دستور .5 را اجرا کنیم چه می شود؟ همان عملیات 5 بار تکرار می شود که یعنی 5 کلمه دیگر نیز حذف می شوند! خیلی کاربردی است، مگر نه؟
اگر یادتان باشد برایتان توضیح دادم که عملیات کپی و پیست کردن در Vim مسئله ای پیچیده تر از فشردن کلیدهای Ctrl + C و Ctrl + V است اما چرا؟ به دلیل اینکه Vim محیط خودش را از کلیپ بورد سیستم عامل شما جدا می کند. مثلا اگر یک قطعه متن را از Vim کپی کنید و سپس مرورگر خود را باز کرده و Ctrl + V را بزنید، آن متن کپی شده برایتان paste نمی شود! محیط Vim از سیستم عامل شما جداست. راه حل چیست؟ در این بخش برایتان توضیح خواهیم داد.
دستور y (مخفف yank) برای کپی کردن رشته های انتخاب شده در Vim طراحی شده است اما دستور yy کل خط فعلی را کپی می کند. منظور ما از خط فعلی همان خطی است که cursor یا مکان نمای شما در آن قرار دارد. شاید بپرسید برای کات کردن از چه دستوری استفاده کنیم؟ کات کردن بسیار ساده است؛ هر زمانی که متنی را حذف کرده باشید در واقع آن را کات کرده اید (چه دستور dd باشد و چه دستور C و چه دستورات دیگر شبیه به آن ها)! یعنی چه؟ یعنی دستور خاصی برای کات کردن در Vim نیست بلکه تمام دستورات delete در واقع یک نوع کات هستند. برای paste کردن نیز از دستور p استفاده می کنیم که متن را پس از مکان نمای شما paste می کند اما دستور P متن را قبل از مکان نما paste خواهد کرد.
یک ترفند جالب برای جا به جا کردن محل دو خط با یکدیگر استفاده از دستور ddp است. قسمت dd ابتدا خط اول را حذف می کند و مکان نمای شما را پس از خط بعدی می گذارد بنابراین قسمت p آن را دوباره paste می کند و حالا جای خط ها جا به جا شده است. مسائلی که تا این بخش توضیح داده ام همگی درون خود Vim کار می کنند اما اگر بخواهیم متنی را خارج از ترمینال و Vim کپی کنیم و سپس درون Vim قرار بدهیم (paste کنیم) چطور؟
ابتدا با کپی کردن از Vim به درون کلیپ بورد سیستم عامل صحبت می کنیم. روش اول این است که با موس خود قسمتی از متن درون ترمینال را انتخاب کرده و سپس کلیک راست کرده و گزینه Copy را بزنید! شاید بگویید این کار که خیلی راحت است! حرفتان صحیح است اما دو مسئله وجود دارد: اولا افرادی که با Vim کار می کنند حرفه ای تر هستند بنابراین دوست ندارند از موس استفاده کنند، دوما در اتصال به سرور با SSH استفاده از موس بعضا باعث اذیت خودتان خواهد بود بنابراین راه حل چیست؟
ابتدا از Vim خارج شده و در ترمینال عادی خود دستور زیر را اجرا کنید:
vim --version | grep clipboard
با اجرای این دستور احتمالا نتیجه ای شبیه به نتیجه زیر می گیرید:
-clipboard +jumplist +popupwin +user_commands +ex_extra -mouse_jsbterm -sun_workshop -xterm_clipboard
همانطور که می بینید در کنار clipboard و xterm_clipboard علامت های منفی (-) را داریم بنابراین نسخه ای که برای ما نصب است قابلیت استفاده از کلیپ بورد را ندارد. راه حل چیست؟ برای کاربران ubuntu راه حل نصب پکیج vim-gtk یا vim-gnome است. برای نصب آن می گوییم:
sudo apt install vim-gtk
از این به بعد می توانیم فایل ها را به شکل زیر باز کنیم:
vim.gtk3 sample.txt
به جای sample.txt نام فایل خودتان را در نظر بگیرید. حالا می توانیم دستور زیر را اجرا کنیم:
vim.gtk3 --version
با اجرای این دستور نتیجه ای مانند نتیجه زیر را دریافت می کنیم:
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Aug 11 2020 17:00:59) Included patches: 1-716 Modified by team+vim@tracker.debian.org Compiled by team+vim@tracker.debian.org Huge version with GTK3 GUI. Features included (+) or not (-): +acl -farsi +mouse_sgr +tag_binary +arabic +file_in_path -mouse_sysmouse -tag_old_static +autocmd +find_in_path +mouse_urxvt -tag_any_white +autochdir +float +mouse_xterm +tcl -autoservername +folding +multi_byte +termguicolors +balloon_eval -footer +multi_lang +terminal +balloon_eval_term +fork() -mzscheme +terminfo +browse +gettext +netbeans_intg +termresponse ++builtin_terms -hangul_input +num64 +textobjects +byte_offset +iconv +packages +textprop +channel +insert_expand +path_extra +timers +cindent +ipv6 +perl +title +clientserver +job +persistent_undo +toolbar +clipboard +jumplist +popupwin +user_commands +cmdline_compl +keymap +postscript +vartabs +cmdline_hist +lambda +printer +vertsplit +cmdline_info +langmap +profile +virtualedit +comments +libcall -python +visual +conceal +linebreak +python3 +visualextra +cryptv +lispindent +quickfix +viminfo +cscope +listcmds +reltime +vreplace +cursorbind +localmap +rightleft +wildignore +cursorshape +lua -ruby +wildmenu +dialog_con_gui +menu +scrollbind +windows +diff +mksession +signs +writebackup +digraphs +modify_fname +smartindent +X11 +dnd +mouse +sound -xfontset -ebcdic +mouseshape +spell +xim +emacs_tags +mouse_dec +startuptime +xpm +eval +mouse_gpm +statusline +xsmp_interact +ex_extra -mouse_jsbterm -sun_workshop +xterm_clipboard +extra_search +mouse_netterm +syntax -xterm_save system vimrc file: "$VIM/vimrc" user vimrc file: "$HOME/.vimrc" 2nd user vimrc file: "~/.vim/vimrc" user exrc file: "$HOME/.exrc" system gvimrc file: "$VIM/gvimrc" user gvimrc file: "$HOME/.gvimrc" 2nd user gvimrc file: "~/.vim/gvimrc" defaults file: "$VIMRUNTIME/defaults.vim" system menu file: "$VIMRUNTIME/menu.vim" fall-back for $VIM: "/usr/share/vim" Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/include/gio-unix-2.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/fribidi -I/usr/include/harfbuzz -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -Wdate-time -g -O2 -fdebug-prefix-map=/build/vim-It0QT5/vim-8.2.0716=. -fstack-protector-strong -Wformat -Werror=format-security -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 Linking: gcc -Wl,-E -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -o vim -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE -lm -ltinfo -lselinux -lcanberra -lacl -lattr -lgpm -ldl -L/usr/lib -llua5.2 -Wl,-E -fstack-protector-strong -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/perl/5.30/CORE -lperl -ldl -lm -lpthread -lcrypt -L/usr/lib/python3.8/config-3.8-x86_64-linux-gnu -lpython3.8 -lcrypt -lpthread -ldl -lutil -lm -lm -L/usr/lib/x86_64-linux-gnu -ltcl8.6 -ldl -lz -lpthread -lm
همانطور که در گزارش بالا می بینید حالا در کنار xterm_clipboard علامت + را داریم که یعنی می توانیم از کلیپ بورد استفاده کنیم. چطور؟ ابتدا فایل خود را در vim باز کنید و سپس با فشردن کلید v وارد حالت visual mode شوید. حالا با حرکت دادن مکان نما (با کلیدهای فلش دار یا دستوراتی مانند j و k و l و h) متوجه می شوید که در حال هایلایت کردن نوشته ها هستید. نوشته مورد نظر خود برای کپی را هایلایت کنید و حالا دستور y+" را تایپ کنید (ابتدا " و سپس + و سپس y). با انجام این کار مقدار مورد نظر شما در کلیپ بورد سیستم عامل کپی می شود.
برای paste کردن چطور؟ همانطور که گفتم دستور p محتوای درون حافظه Vim را paste می کند و با سیستم عامل کاری ندارد. اگر بخواهید محتوای درون کلیپ بورد سیستم عامل را درون Vim قرار بدهید (paste کنید) باید از همان +" کمک گرفته و دستور p+" را اجرا کنید. دستور +" به یک register خاص دسترسی پیدا می کند که به کلیپ بورد سیستم عامل دسترسی دارد بنابراین قرار دادن دستورات p و y در کنارشان باعث استفاده از این register خاص می شود.
substitution در انگلیسی به معنای تعویض یا جایگزینی است. شما در Vim می توانید رشته خاصی را مشخص کنید، سپس بگویید که آن رشته باید به چه چیزی تغییر کند و در نهایت مشخص کنید که این عملیات در چه سطحی انجام شود. این قابلیت در اصل همان regex است. به مثال زیر توجه کنید:
:s /foo/bar/g
وجود علامت: یعنی باید به حالت Ex Mode یا همان prompt برویم بنابراین ابتدا : را تایپ می کنید تا وارد این حالت شویم. در مرحله بعد حرف s را تایپ می کنید که مخفف substitute است (یعنی می خواهید رشته ای را پیدا کرده و سپس جایگزین کنید). حالا اولین قسمتی که بین علامت های / می آید، قسمت جستجو شده است و دومین قسمتی که بین علامت های / می آید داده جایگزین است. دستور بالا می گوید رشته foo را در خط فعلی پیدا کن و به جایش رشته bar را قرار بده! توجه کنید که این دستور عملیات جایگزینی را فقط روی خط فعلی انجام می دهد.
اگر بخواهیم عملیات جایگزینی در تمام خطوط انجام شود باید علامت % را نیز به آن اضافه کنیم:
:%s/foo/bar/g
این دستور رشته foo در تمام خطوط متن را پیدا کرده و آن ها را با bar جایگزین می کند. اگر مطمئن نیستید که می خواهید تمام foo ها را در متن حذف کنید می توانید C را نیز به انتهای دستور اضافه کنید تا قبل از حذف هر مورد از شما سوال پرسیده شود و مجبور شوید آن را به صورت دستی تایید کنید:
:%s/foo/bar/gc
بین رشته foo و کلمه foo یک تفاوت بزرگ وجود دارد. دستور بالا رشته های foo را به bar تغییر می دهد. یعنی چه؟ یعنی تمام خطوط زیر تغییر می کنند:
exampe of foo
foostring example
this is a foo word
رشته یعنی کاراکترهای foo در هر جایی از متن باشند اما کلمه یعنی foo قبل و بعد از خودش دارای اسپیس باشد و جزئی از یک رشته یا کلمه دیگر نباشد. در سه خط بالا، خط اول و سوم کلمه foo را دارند درحالی که خط دوم رشته foo و کلمه foostring را دارد. دستوراتی که تا به حال به شما دادم وظیفه تغییر رشته foo را دارند بنابراین هر سه خط بالا را تغییر می دهند.
در صورتی که می خواهید فقط کلمات foo را تغییر بدهید باید از روش زیر استفاده کنید:
:%s/\<foo\>/bar/gc
همچنین اگر می خواهید جستجو case-insensitive باشد (نسبت به بزرگی و کوچکی حروف حساس نباشد) باید i را نیز به انتهای دستور اضافه کنید:
:%s/foo/bar/gci
اطلاعات و جزئیات بیشتر در مورد substitution در صفحه vim fandom موجود می باشد. امیدوارم این مقاله به شما در درک Vim و شروع کار با آن کمک کرده باشد. به یاد داشته باشید که Vim قابلیت های بسیار زیادی دارد بنابراین هنوز مباحث زیادی وجود دارد که در این مقاله بررسی نکرده ایم. جستجو و یادگیری بیشتر بر عهده شما است.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.