Thursday, December 04, 2008

Some Features of "vi" and "vim"... #1

به نام دوست

ویرایشگر vi و vim (که نسخه گسترش داده شده vi) است جزو ویرایشگرهای محبوب در بین لینوکس کاران است. البته در رویارویی اولیه شاید ظاهر بدون منو کمی مشکل آفرین باشد اما آشنا شدن با دستورات این ویرایشگر قدرت زیادی به یک برنامه نویس میدهد.

vi سه وضعیت کاری (mode) دارد:
حالت فرمان: در ابتدای ورود به vi این ویرایشگر در این حالت قرار دارد. فشردن هر کلید به منزله صدور دستوری برای vi است. توجه داشته باشید که بزرگ و کوچیک بودن حروف در اجرای نوع دستور موثر است.
حالت ویرایش(درج): با فشردن کلید "i" در «حالت فرمان»، vi به مود ویرایش خواهد رفت. البته میتوان با زدن کلیدهای "o" و "O" نیز به این حالت رفت که اولی خطی جدید در پایین مکان فعلی و دومی خطی جدید در بالای مکان فعلی باز کده و به حالت ویرایش میرود. با زدن کلید «Esc» میتوان از «حالت ویرایش» خارج و به «حالت فرمان» رفت.
حالت خط فرمان: در این وضعیت که با زدن کلید «:» در «حالت فرمان» در آن قرار میگیریم، دستورات خط فرمان vi قابل تایپ هستند که در ادامه با آنها آشنا خواهیم شد. با دوبار فشردن «Esc» میتوان به «حالت فرمان» رفت.

توجه: در تمام مواردی که در پایین ذکر شده است مورد زیر صادق است:
۱- اگر ctrl+x ذکر شده به معنای فشردن کلید ctrl به همراه x است
۲- اگر حروفی پشت سر هم ذکر شده اند مانند dd به معنای فشردن دو بار حرف d است
۳- در تمام توضیحاتی که در زیر آمده است، از جدا کننده بین کلید(فرمان) و توضیح به جهت جلوگیری از اشتباه استفاده نشده است
۴- در تایپ عبارات انگلیسی سعی شده ترتیب حروف مطابق با ترتیب اعمال آنها به نظر رسد. با توجه به اینکه صفحه راستچین است کپی-پیست کردن این عبارت توصیه نمیشود.

جابه‌جایی مکان نما (حالت فرمان):
ctrl+d جابه‌جایی به میزان نصف صفحه به سمت پایین
ctrl+u جابه‌جایی به میزان نصف صفحه به سمت بالا
ctrl+f جابه‌جایی به میزان تمام صفحه به سمت پایین
ctrl+b جابه‌جایی به میزان تمام صفحه به سمت بالا
M جابه‌جایی مکان نما به وسط صفحه
H جابه‌جایی مکان نما به ابتدای صفحه
L جابه‌جایی مکان نما به انتهای صفحه
0 صفر، جابه‌جایی مکان نما به ابتدای خط
$ انتقال به انتهای خط
G انتقال به انتهای فایل
% انتقال به براکت متناظر.. با قرار گرفتن بر روی حروف {} [] () زده میشود. حاصل انتقال به براکت متناظر است. در برنامه نویسی برای اطمینان از صحت تناظر کاربرد خوبی دارد.

دستورات ویرایش (حالت فرمان):
u بازگرداندن آخرین ویرایش undo
U بازگرداندن تمامی تغییرات در خط جاری
dd حذف خط جاری
3dd حذف ۳ خط از مکان جاری
D حذف محتوای خط از محل مکان‌نما تا انتهای خط
C شبیه به D البته وارد حالت ویرایش میشود
x حذف کاراکتر زیر مکان نما
r جابه‌جایی replcae کاراکتر زیر مکان نما
s حذف کاراکتر فعلی و ورود به حالت ویرایش
S حذف خط فعلی و ورود به حالت ویرایش
~ تغییر case (بزرگ و کوچیک) کاراکتر در محل مکان نما
ctrl+a افزایش عدد زیر مکان نما به میزان یک واحد
ctrl+x کاهش عدد زیر مکان نما به میزان یک واحد
string/ جستجوی string به سمت انتهای فایل (بعد از تایپ باید کلید enter زده شود)
string? جستجوی string به سمت ابتدای فایل (بعد از تایپ باید کلید enter زده شود)
<\string>\/ جستجو برای یافتن string. در این جستجو کلماتی که string جزو آنها باشد تطابق محسوب نمیشوند.
n پیدا کردن رخداد بعدی کلمه مورد جستجو
N پیدا کردن رخداد قبلی کلمه مورد جستجو
. تکرار آخرین فرمان

نشانه دار کردن یک خط (mark) (در حالت فرمان): برای نشانه دار کردن یک خط کافی است کلید m را بزنید و به دنبال آن یک حرف به عنوان یک نشانه برای آن خط. جهت رجوع به آن خط باید ابتدای کاراکتر «'» را و به دنبال آن حرفی که به عنوان نشانه در نظر گرفته شده زد.

کپی-پیست کردن (copy-paste):
برای کپی کردن (انتقال متن به حافظه):
yy خط جاری را کپی خواهد کرد
3yy از خط جاری ۳ خط را کپی خواهد کرد (با خط جاری دو خط دیگر)
y't از خط جاری تا خطی را که با حرف t نشانه‌دار شده است کپی خواهد کرد
برای پیست کردن (انتقال متن از حافظه):
p متن درون حافظه را بعد از خط جاری پیست خواهد کرد.

انتقال متن به چپ یا راست (شبیه به فشردن tab):
>> انتقال به سمت چپ
<< انتقال به سمت راست
اما انتقال یک بلاک مختص vim است که نیاز به آشنایی مختصری با حالت ویژوال دارد... در حالت ویژوال این امکان وجود دارد که قسمتی از متن انتخاب (high light) شود. در این صورت مواردی که به صورت تکی بر روی کاراکتر یا خط قابل اعمال بوده به صورت گروهی بر روی تمام متن انتخاب شده قابل اجرا است (مانند کپی-پیست کردن)

حالت ویژوال:
ورود به حالت ویژوال از حالت فرمان به سه طریق امکان پذیر است:
v که اصطلاحا حالت ویژوال کاراکتری است. انتخاب کاراکتر به کاراکتر خواهد بود. با زدن این حرف میتوانید با حرکت با کلیدهای جهت نما گستره انتخاب خود را تعیین کنید
V باعث ورود به حالت ویژوال خطی میشود. در این حالت کوچکترین واحد انتخابی خط خواهد بود.
ctrl+v حالت ویژوال بلاکی. میتوانید یک مستطیل از فایل را انتخاب کنید.
برای خروج از حالت ویژوال نیز میتوان از Esc استفاده کرد. البته در هر حالت ویژوال با فشردن مجدد کلید فرمان مربوط به همان حالت ویژوال از حالت ویژوال خارج خواهید شد.
با فشردن gv به حالت ویژوال قبلی خواهید رفت و همچنین متن انتخاب شده(در حالت قبل) نیز مجددا ظاهر خواهد شد. همچنین فشردن کلید o (او) در حالت ویژوال باعث جابه‌جایی بین ابتدا و انتهای بلاک انتخاب شده خواهد شد.

حالت دیگری هم به نام حالت انتخاب (select mode) وجود دارد که شبیه به ویژوال است. برای ورود به این حالت باید gh را بزنید. در این حالت میتوانید متنی را انتخاب کنید در صورتیکه شروع به فشردن حروف کنید متن انتخاب شده حذف و مواردی که شما تایپ میکنید جایگزین آن خواهد شد.
کلید h به معنای انتخاب کاراکتری است و همچنین H حالت انتخاب خطی و ctrl+h انتخاب بلاکی (مستطیلی) است.

حالت خط فرمان:
در این حالت که بازدن «:» (دو نقطه) از حالت فرمان به آن وارد میشویم دستورات خط فرمان vi صادر میشود.

help topic: متن کمک در مورد topic ظاهر خواهد شد. در صورتیکه متن کامل topic مجهول باشد میتوان با زدن tab بین کلمات محتمل چرخی زد. همچنین اگر بعد از تایپ help کلید ctrl+d را بزنید تمامی تاپیکها ظاهر میشوند.

set all: تمامی تنظیمات vi نمایش داده خواهد شد.
set SET_COMMAND: بر اساس SET_COMMAND پارامتری از vi ست میشود. به عنوان مثال set ic: باعث میشود که بزرگ و کوچیک بودن حروف در جستجو در نظر گرفته نشود (case Insensitive) . بعضی از تنظیمات به شرح زیر هستند:

حالت کامل
متناظر کوتاه
توصیف
autoindent/noautoindent ai/noai با زدن enter در انتهای خط، مکان نما در محل indent خط قبل قرار میگیرد. این تنظیم در هنگام برنامه نویسی خیلی مفید است
autowrite/noautowrite aw/noaw در قسمت tag توضیح داده شده
errorbells/noerrorbells eb/noeb حذف beep (صدای کوتاه خطا) در هنگام بروز خطا
flash/noflash fl/nofl در هنگام بروز خطا صفحه flash میشود.
tabstop=8 ts تعداد فضای خالی tab را مشخص میکند
ignorecase/noignorecase ic/noic در نظر نگرفتن بزرگ و کوچیک بودن حروف در جستجو
number/nonumber nu/nonu نشان دادن شماره خطها
showmatch/noshowmatch no abbreviations براکت متناظر را نشان میدهد
showmode/noshowmode no abbreviations نشان دادن وضعیت کاری ویرایشگر
taglength tl تعداد کاراکتر موثر در نشان دادن تگ، به صورت پیش فرض صفر است.
closepunct='".,;)]}
کارکترهایی که کارکاتر متناظر آنها با زدن % نشان داده میشود
linelimit=1048560
حداکثر طول فایل
wrapscan/nowrapscan ws/nows شکستن خطوط در صورتیکه خیلی طولانی باشند
wrapmargin=0/nowrapmargin wm/nowm فضای قبل از خط شکسته شده را مشخص میکند
list/nolist
انتهای خط و همچنین تبها را به صورت مشخص نشان میدهد
bg=dark
bg=light

شیوه رنگ صفحه را مشخص میکند. سفید روی سیاه و یا سیاه روی سفید

چنانچه خواستار انجام تنظیمات برای تمام فعالیتهای ویرایشی خود باشید میتوانید از فایل vimrc. در home folder خود استفاده کنید. چنانچه این فایل موجود نیست میتوانید فایلی با این نام بسازید. هر مرتبه که vi اجرا میشود ابتدا دستورات موجود دراین فایل اجرا خواهد شد. به عنوان مثال عبارات زیر را به عنوان محتوای فایل vimrc. در نظر بگیرید:
" set auto indent
:set ai
باعث میشود که auto indent به صورت پیش فرض تنظیم شود.
توجه: کامنتها در این فایل با " شروع میشوند.

جستجو(Find) و جابه‌جایی(Replace):
معمولا از رایج‌ترین نیازهای استفاده‌کننده از ویرایشگرها جستجو در متن میباشد. چگونگی انجام جستجو قبلا توضیح داده شده است. اما جابه‌جایی در vi در حالت خط فرمان انجام میشود. مثالهایی جهت روشن شدن موضوع:
/s/ffff/rrrr: اولین رخداد از ffff را در یک خط با rrrr جایگزین میکند
/s/ffff/rrrr%: و یا s/ffff/rrrr/g%: تمام رخدادهای ffff را در یک فایل با rrrr جایگزین خواهد کرد.
s/ffff/rrrr/gc%: تمام رخدادهای ffff با rrrr جایگزین خواهد شد اما با سوالی هر جایگزینی از طرف کاربر تایید خواهد شد.
s/ffff/rrrr/i: اولین رخداد از ffff را با rrrr جایگزین میشود البته بدن احتساب کوچیک یا بزرگ بودن حروف.
توجه: ترکیب i با دستورات قبلی نیز مجاز و موجب جستجوی case insensitive میشود.

تعیین محدوده جستجو (تعیین محدوده):
نکته: کارکتر % قبل از s به معنای تمام فایل میباشد. به عبارتی قبل از s محدوده مورد جستجو مشخص میشود. به عنوان مثال از آن جهت که آخرین خط یک فایل در vi با $ مشخص میشود، میتوان به جای % از عبارت $,1 استفاده که همان مفهوم % را خواهد رساند.
همچنین کارکتر نقطه «.» به معنای خط جاری است. بنابراین واژه .,t' محدوده خط نشانه‌دار شده با حرف t تا خط جاری را مشخص میکند.
همچنین جهت تعیین یک بلاک برای جستجو هم میتوان از شماره خطوط استفاده کرد: مثلا 5,23 که محدوده خطوط ۵ تا ۲۳ مورد جستجو قرار میگیرد و همچنین چنانچه خطوطی نشانه‌دار(mark) شده باشند میتوان از نشانه‌ها بدینصورت استفاده کرد: a,‍'b' (کاراکتر قبل از a و b تک کوتیشن است)که حدفاصل خطوطی که با a و b نشانه‌دار شده‌اند مورد جستجو قرار میگیرد.

اجرای دستورات unix در vi و تعامل با آنها:
command!: دستور command اجرا خواهد شد. به عنوان مثال pwd!: باعث اجرای pwd (چاپ شاخه جاری) خواهد شد.
r !command: موجب میشود که خروجی در یک خط جدید در پایین مکان‌نما قرار گیرد. به عنوان مثال r !date: باعث چاپ تاریخ در خط جدید در زیر مکان فعلی میشود.

همچنین این امکان وجود دارد که خطوطی به عنوان ورودی به دستورات داده شود و خروجی آن دستور جای آنها را بگیرد. به عنوان مثال؛
:1,$ !sort
باعث مرتب شدن تمامی خطوط فایل میشود (تعیین محدوده میتواند به طرقی که در قبل آمد انجام شود)
و همچنین مثال دیگر که اندکی جالب است:
:'a,'b !awk '{ $1 " " $2 " " $3 " " }'
اتفاقی به شرح زیر رخ خواهد داد






aaa bbb ccc
ccc bbb aaa
ddd eee fff تبدیل میشود به: > fff eee ddd
ggg hhh iii
iii hhh ggg
با استفاده از awk توانسته‌ایم جای ستونها را عوض کنیم.

پرش به فایل include شده:
در بسیاری از موارد هنگامی که در حال برنامه‌نویسی هستید شاید نیاز به چک محتوای فایل include شده داشته باشید. در vi میتوانید مکان نما را بر روی فایل داخل عبارت include قرار بدهید و کلیدهای gf که کوتاه شده go to file است را فشار دهید. فایل مورد نظر باز خواهد شد.
البته استفاده از gf عام است. یعنی هر جا که مسیر فایلی در متن تایپ شده باشد و gf فشار داده شود فایل باز خواهد شد. جستجو در مسیرهایی که توسط path مشخص شده‌اند انجام خواهد شد. دستور زیر را امتخان کنید:
:set path

محتوای path نمایش داده خواهد شد. جهت تغییر آن میتوانید به عنوان مثال به این صورت عمل کنید:
set path=/home,/,,

همچنین میتوانید درون فایل vimrc. نیز آن را تنظیم کنید. به عنوان مثال:
set path=$PWD/**

باعث میشود که مسیر جاری و تمام زیرشاخه‌ها برای جستجو مد نظر قرار گیرند.

کار با فایلهای متعددی که به صورت همزمان باز شده‌اند:
در بعضی مواقع ممکن است شما چند فایل به صورت همزمان باز کرده باشید. این اتفاق ممکن است به روشهای گوناگون رخ دهد: یکی از آنها در قسمت قبلی توضیح داده شد که همان gf‌ است.
روش دیگر این است که شما از دستور open استفاده کنید (در حالت خط فرمان):
:open /my/path/example.c
و همچنین ممکن است در هنگام اجرای دستور vi چند فایل را به عنوان پارامتر مشخص کرده باشید:
vi file1 file2 file3
به هر حال دستورات زیر در حالت خط فرمان میتواند به شما کمک کند:
buffers: تمام فایلهای باز را نشان خواهد داد. هر کدام با یک شماره مشخص میشوند.
# buffer: باید به جای # شماره فایل باز را که از دستور قبل بدست آورده‌اید قرار بدید. در این صورت فایل مورد نظرتان نمایش داده خواهد شد.

خروج از vi :
به هر حال در پایان کار شما نیاز به خروج از vi دارید. به روشهای زیر میتوانید این کار را انجام دهید:
فشردن ZZ (در حالت فرمان)که باعث ذخیره شده تغییرات و خروج میشود.
wq: در حالت خط فرمان باعث ذخیره و خروج میشود
w: در حالت خط فرمان باعث ذخیره تغییرات میشود
!q: خروج بدون ذخیره تغییرات
qa: خروج از تمامی فایلهای باز

منبع: اینجا

2 comments:

mona said...

Hi,
good work!
Interesting topic: kernel hacking.
do you want to write other linux topics like vim and ... ?
Would you write some tips about what a normal Linux user could do with kernel programming and then how to start it?

hamid jafarian said...

hi and thanks "mona"

about "vi" their my needs and interests.. "note one time, use every time"

about normal users: good idea,, thanks.

best regards