انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


ارائه ۲۵٫۰۴ اوبونتو منتشر شد 🎉

نویسنده موضوع: vimrc  (دفعات بازدید: 404 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین learner:~$

  • Hero Member
  • *
  • ارسال: 823
  • جنسیت : پسر
  • روزی روز گاری در گنو/لینوکس
vimrc
« : 10 تیر 1404، 08:56 ب‌ظ »
درود!!
من مجبور شدم آرچ رو حذف کنم و دیبان نصب کنم در همین حین ادیتور مورد علاقه من یعنی زد روی دیبان پشتیبانی نمیشه:(
 از طرفی codium هم سرور های LSP ش نصب نمیشد.

بخاطر همین به سوی او بازگشتم! بازگشت همه به سوی اوست! یعنی ویم!!!!

تنظیمات خیلی اصولی و دقیقی رو برای زبان های سی پلاس پلاس  و پایتون نوشتم!!! اما بیشتر برای سی پلاس پلاس هست. توی این تنظیمات به یک نقطه خیلی توجه کردم؛ سرعت عمل و ابتکار. توی این فایل من پلاگین های زیادی رو نسبت به سری قبل نصب نکردم و زیاد به UI  توجه آنچنانی نکردم (  برخلاف تنظیمات پیشین من ) هرچند که یک تم ساده و عالی برای کسانی که میخوان از چشم هاشون محافظت کنند انتخاب کردم و تمام.

قبل از هرچیز باید این بسته ها رو نصب کنید:
sudo apt install clangd
sudo apt install clang-format
sudo apt install nodejs
البته به بسته های دیگه ایی هم نیاز دارید برای پایتون اما خب فعلا برای من سی پلاس پلاس و سی واجب تر هست!

پلاگین های لازم  برای ویم (  به vim-plug  هم نیاز دارید‌  ):


Plug 'arecarn/vim-fold-cycle'
Plug 'kshenoy/vim-signature'
Plug 'tpope/vim-sensible'
Plug 'vim-airline/vim-airline'
Plug 'dense-analysis/ale'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'dracula/vim'
Plug 'morhetz/gruvbox'
Plug 'preservim/nerdtree'
Plug 'raimondi/delimitmate'
Plug 'ap/vim-buftabline'

ما قراره ویم رو جوری تنظیم کنیم که سرعت عملمون از ۱۰ ه ۱۰۰۰۰۰۰ برسه باور کنید همچین چیزی شدنیه و من باور دارم که قراره بخاطر این تنظمات و شخصی سازی جایزه نوبل ویم رو تقدیم کنند! کم کم باید امسال یک تورینگ ببرم  :P
خب ما قرار چیکار کنیم و به چه چیز هایی نیاز داریم؟ :
فولد و آن فولد کردن؛ مارک کردن ؛ باز کردن تب  (‌به طور کلی همینه )


اول بزارید یکم هیجان زدتون کنم. فرض کنید توی یک فایل هستید که کم کم ۳۰۰ خط کد سی پلاس پلاس توشه و  لازمه که هر دقیقه بین خط ۹۰ و ۲۰۰ جابجا بشید. میتونید دو کار بکنید ۱: شماره خط رو هر دقیقه  تو ویم به این صورت بنویسید:200 یا میتونید یک کار عقلانی تر بکنید. از مارک کردن استفاده بکنید!!!!!!!
یا فرض کنید یک تابع نوشتید که ۶۰ خط و حجم زیادی رو اشغال میکنه شما اون رو به صورت خودکار نمیخواید فولد کنید پس دستی فولدش میکنید. میدونی چقدر سخته و زمان بر هست؟
برای تب هم که واضحه میخواید هم زمان روی چندتا فایل کار کنید و حرکت کنید.البته این یک خلاصه کوچیک بود.
پس بریم شروع کنیم:

let mapleader = " "
syntax on
set  foldenable
set foldmethod=syntax
set foldlevelstart=99     
set foldnestmax=3         
set foldcolumn=1
set fillchars=fold:\
set number
set relativenumber
set mouse=a
set cursorline
set ttyfast
set lazyredraw
set updatetime=300
set clipboard=unnamedplus
set background=dark
set hidden
set ignorecase
set smartcase
set completeopt=menuone,noinsert,noselect
set timeoutlen=3000
filetype plugin indent on
set viewoptions=folds,cursor,slash,unix
set tabstop=8
set shiftwidth=8
set softtabstop=8
set noexpandtab

اول از همه باید باید باید مپ لیدر ما ( دکمه ایی که قراره خیلی زیاد ازش استفاده بشه ) برابر اسپیس باشه که یک سرعب و انعطاف نجومی به ما میده. بعدش باید ویم رو برای شناسایی سینتکس آماده کنیم و چندتا دستور دیگه برای فولد کردن اضافه میکنیم تا بهره وری رو به ۱۰۰ برسونیم ( اگر سوال داشتید که اینها چی هستند و چی کار میکنند بپرسید چون جا نمیشه همش رو توی یک فرسته بنویسم ) بعدش ویم رو برای نشون دادن شماره خط و پشتیبانی از موس آماده میکنیم ( برای تاچ پد هم میشه چون من از موس متنفرم  ) بعدش کاری میکنیم که روی اون خطی که هستیم برجسته بشه و بک گراند رو تیره میکنیم برای تمی که قراره استفاده کنیم.
بعدش باید ویم رو برای افزایش سرعت بهینه کنیم بخاطر همین میگیم ttyfast هست و از ماکرو های غیر ضروری هم خود داری میکنیم. و زمان انتظار برای آپدیت تایم هم ۳۰۰ میلی ثانیه میزاریم و زمان برای انتظار هم ۳ ثانیه ( ۳۰۰۰ میلی ثانیه  چون برای نرمال مود نیاز داریم).
بعدش کاری میکنیم که ویم بتونه از کلیپ بورد هم استفاده بکنه مثلا کنرل +‌سی و بعدش کاری میکنیم که فایل ها بدون ذخیره شدن تو بافر بمونه.
بعد کاری میکنیم موقعیت فولد ها و نشانگر و ... اینجور چیز های ذخیره بشوند.
بعدش یک سری تنظیمات برای حساسیت ویم برای نوشتن رو تنظیم میکنیم. که هم به حروف بزرگ و کوچیک حساس نباشه و هم اگر از حروف بزرگ استفاده کردیم حساس بشه ( خوراک نینجا های  regex  ) بعدش چندتا چیز دیگه برای نمایش پیشنهادات فعال میکنیم ( تقریبا !‌ )‌

این قسمتش خیلی مهمه. من به طور پیش فرض هر تب رو برابر ۸ تا فاصله قرار دارم اینکار باعث میشه که کدم خوانا تر باشه ( از نظر خودم )‌ و اینکه از تب واقعی استفاده میکنم!

خب حالا بریم بخش بعدی:
function! CloseTabByName()
  let name = input("Enter tab path (partial, relative or full): ")
  for i in range(tabpagenr('$'))
    let bufnrs = tabpagebuflist(i + 1)
    for b in bufnrs
      let fullpath = fnamemodify(bufname(b), ':p:.') 
      if fullpath =~? name
        execute (i + 1) . "tabclose"
        echo "Closed tab containing: " . fullpath
        return
      endif
    endfor
  endfor
  echo "No tab found matching: " . name
endfunction
nnoremap <silent> <leader>T :call CloseTabByName()<CR>


بی نظیره بی نظیره واقعا این تابع بی نظیره  این تابع باعث میشه که اسم تبی که میخواید رو بنویسید و بعد ببندید خیلی راحت هم با space + T کار میکنه. هر چند که باید آدرس کامل و مطلق رو براش بنویسید.

nnoremap <silent> <leader>T :call CloseTabByName()<CR>
function! CloseCurrentTab()
  if tabpagenr('$') > 1
    tabclose
    echo "Closed current tab"
  else
    echo "Cannot close the last tab page"
  endif
endfunction

nnoremap <silent> <C-j> :call CloseCurrentTab()<CR>

خب حالا اگر نخواید یک ساعت آدرس به اون تابع ندید و میخواید مثل یک نینجا تب رو ببندید کافیه برید روی تب مورد نظر و crtl + j  رو فشار بدید.
nnoremap <leader>m :marks<CR>

با این دستور لیست مارک هایی که دارید بالا میاد یعنی  space + m  چون بعضی وقت ها یادتون میره چندتا مارک دارید و هرکدوم کجا هستند.
let g:buftabline_numbers = 2       
 nnoremap <silent> <leader>l :tabnext<CR>
 nnoremap <silent> <leader>h :tabprevious<CR>

  دستور اول میزاره که میتونید تبتون رو چک کنید که از ۰ تا ۲ میتونید مقدار دهی کنید ( خودتون بزنید ببینید چی میشه )
ولی دستور دوم و سوم خیلی مهم  با  space + l  به تب بعدی میرید و با  space + h  به تب قبلی ( خودم   اشتباهی  space + p  میزنم شاید تغیرش دادم :( )
autocmd BufWinLeave *.* mkview
autocmd BufWinEnter *.* silent! loadview
let g:fold_cycle_default_mapping = 0 "disable default mappings

خب اینجا هم یک سری تنظیمات عادیه ولی آخریش برای تنظیم فولد کردن که از تنظمات دیفالت عادی جلوگیری میکنه.
nnoremap <leader>u za
colorscheme gruvbox
این دو خط هم عالین خط اول میگه که با  space + u  یک تابع رو به صورت خودکار فولد و آن فولد کنی ( باید بری روی ابتدای کروشه اون تابع )  زیباست نه؟ خط بعدی هم تم مورد علاقه من هست که فوق العادست ( نمیدونم چرا وقتی اسمش رو میبینم یا میشنوم یا  rust  میفتم  ??? )
augroup CppFormat
  autocmd!
  autocmd BufWritePre *.cpp,*.h,*.c call CppFormatPreserveCursor()
augroup END

این تابع هم برای فرمت کردن کد سی پلاس پلاس و سی هست
function! CppFormatPreserveCursor()
  let l:save_cursor = getpos(".")
  silent! %!clang-format
  call setpos('.', l:save_cursor)
endfunction

  این هم برای اینه که وقتی فرمت میکنی نشانگر به ابتدای فایل نپره ‌(‌جا بجا نوشتم جای دو تابع  )
autocmd VimEnter * if argc() == 0 | NERDTree | endif
nnoremap <leader>n :NERDTreeToggle<CR>

خط اول باعث میشه که  وقتی دستور vim  خالی رو اجرا کردید nerdtree  باز بشه و  لیست فایل ها نمایش داده بشوند ( آیکون اضافه نکردم چون بیخوده و فقط حجم اضافه میکنه ) با دستور  space+ n  باز و بستش میکنید
inoremap <expr> <Tab>     pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab>   pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <silent><expr> <CR> pumvisible() ? coc#_select_confirm() : "\<CR>"
این خطوط باعث میشن که وقتی کاکا ویم ( coc-nvim )  برای  lsp  پیشنهاد میده  بتونید از تب و  arrow key  ها استفاده کنید.
let g:ale_linters = {
\   'cpp': ['clangd'],
\   'python': ['flake8'],
\}
let g:ale_fixers = {
\   'cpp':    ['clang-format'],
\   'python': ['black'],
\}

این خطوط هم حتما فعال کنید برای دریافت هشدار ها و اصلاحات
function! s:SafeBlack()
  let l:cmd = 'black --quiet ' . shellescape(expand('%:p'))
  call system(l:cmd)
  if v:shell_error == 0
    silent! edit!
  endif
endfunction

augroup PythonFormat
  autocmd!
  autocmd BufWritePre *.py call s:SafeBlack()
augroup END

فرمت پایتون

let g:airline_powerline_fonts = 1
"
let g:SignatureMarkTextHLDynamic = 1

let g:SignatureMarkText = '⚑'
let g:SignatureMarkerText = '✗'

let g:SignatureIncludeMarks = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

let g:SignaturePrioritizeMarks = 1

تنظیمات مارک کردن
let g:next_mark_idx = 0
let g:mark_list = []

function! s:NextDynamicMark()
  let idx = g:next_mark_idx % 26
  let letter = nr2char(char2nr('a') + idx)

  execute "normal! m" . letter

  if index(g:mark_list, letter) < 0
    call add(g:mark_list, letter)
  endif

  let g:next_mark_idx += 1

  echo ">> mark '" . letter . "' set"
endfunction

nnoremap <silent> ma :call <SID>NextDynamicMark()<CR>


بی نظیره! این تابع باعث میشه که شما بتونید به ترتیب حروف الفبا مارک کنید مثلا اگر روی یک خط هستید و space + ma زدید اولین مارکتون میشه  a  و به همین ترتیب تا آخر ادامه داره برای بقیه خط هااما اگر نمیخواید مشکلی نیست فقط space +m  رو فشار بدید و یکم مکث کنید و حرف دلخواهتون رو بنویسید.
et g:mark_cycle_idx = 0

function! s:JumpNextMark()
  if empty(g:mark_list)
    echo ">> no marks set"
    return
  endif
  let idx = g:mark_cycle_idx % len(g:mark_list)
  let letter = g:mark_list[idx]
  execute "normal! '" . letter
  let g:mark_cycle_idx += 1
endfunction

nnoremap <silent> <leader>j :call <SID>JumpNextMark()<CR>

این تابع باعث میشه که به ترتیب حرف الفبا روی مارک ها حرکت کنید و سراغ مارک بعدی برید یعنی space + j
function! s:JumpToTypedMark()
  let c = nr2char(getchar())
  if c =~# '[a-z]'
    execute "normal! '" . c
  else
    echohl ErrorMsg | echo ">> invalid mark: ".c | echohl None
  endif
endfunction

nnoremap <silent> <leader>v :call <SID>JumpToTypedMark()<CR>

دوست نداری به ترتیب حروف الفبا روی مارک های حرکت کنی و دوست داری بری مستقیم سراغ مارکی که میخوای؟ ایرادی نداره  space + v  بعدش اسم مارکت رو بزن ؛)  و بعد اینتر
function! DeleteMarkOnThisLine()
  let marks = split(execute('marks'), "\n")[1:]

  let currline = line('.')

  for line in marks
    let fields = split(line)
    if len(fields) >= 2
      let mark = fields[0]
      let lnum = str2nr(fields[1])
      if lnum == currline && mark =~# '^[a-zA-Z]$'
        execute 'delmarks ' . mark
call remove(g:mark_list, index(g:mark_list, mark))
        echo ">> Mark '" . mark . "' deleted from line " . lnum
        return
      endif
    endif
  endfor

  echo ">> No mark found on this line"
endfunction

nnoremap <leader>d :call DeleteMarkOnThisLine()<CR>

این تابع باعث میشه وقتی روی یک مارک هستید با زدن  space + d  اون مارک به صورت خودکار حذف بشه!
عالی بود نه؟‌
فایل کامل:‌
let mapleader = " "
syntax on
set  foldenable
set foldmethod=syntax
set foldlevelstart=99     
set foldnestmax=3         
set foldcolumn=1
set fillchars=fold:\
set number
set relativenumber
set mouse=a
set cursorline
set ttyfast
set lazyredraw
set updatetime=300
set clipboard=unnamedplus
set background=dark
set hidden
set ignorecase
set smartcase
set completeopt=menuone,noinsert,noselect
set timeoutlen=3000
filetype plugin indent on
set viewoptions=folds,cursor,slash,unix
set tabstop=8
set shiftwidth=8
set softtabstop=8
set noexpandtab

call plug#begin('~/.vim/plugged')
Plug 'arecarn/vim-fold-cycle'
Plug 'kshenoy/vim-signature'
Plug 'tpope/vim-sensible'
Plug 'vim-airline/vim-airline'
Plug 'dense-analysis/ale'
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'dracula/vim'
Plug 'morhetz/gruvbox'
Plug 'preservim/nerdtree'
Plug 'raimondi/delimitmate'
Plug 'ap/vim-buftabline'
call plug#end()


function! CloseTabByName()
  let name = input("Enter tab path (partial, relative or full): ")
  for i in range(tabpagenr('$'))
    let bufnrs = tabpagebuflist(i + 1)
    for b in bufnrs
      let fullpath = fnamemodify(bufname(b), ':p:.') 
      if fullpath =~? name
        execute (i + 1) . "tabclose"
        echo "Closed tab containing: " . fullpath
        return
      endif
    endfor
  endfor
  echo "No tab found matching: " . name
endfunction

nnoremap <silent> <leader>T :call CloseTabByName()<CR>
function! CloseCurrentTab()
  if tabpagenr('$') > 1
    tabclose
    echo "Closed current tab"
  else
    echo "Cannot close the last tab page"
  endif
endfunction

nnoremap <silent> <C-j> :call CloseCurrentTab()<CR>

nnoremap <leader>m :marks<CR>

let g:buftabline_numbers = 2       
 nnoremap <silent> <leader>l :tabnext<CR>
 nnoremap <silent> <leader>h :tabprevious<CR>

autocmd BufWinLeave *.* mkview
autocmd BufWinEnter *.* silent! loadview
let g:fold_cycle_default_mapping = 0 "disable default mappings
nnoremap <leader>u za




colorscheme gruvbox
function! CppFormatPreserveCursor()
  let l:save_cursor = getpos(".")
  silent! %!clang-format
  call setpos('.', l:save_cursor)
endfunction


augroup CppFormat
  autocmd!
  autocmd BufWritePre *.cpp,*.h,*.c call CppFormatPreserveCursor()
augroup END


autocmd VimEnter * if argc() == 0 | NERDTree | endif
nnoremap <leader>n :NERDTreeToggle<CR>


inoremap <expr> <Tab>     pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab>   pumvisible() ? "\<C-p>" : "\<S-Tab>"
inoremap <silent><expr> <CR> pumvisible() ? coc#_select_confirm() : "\<CR>"


let g:ale_linters = {
\   'cpp': ['clangd'],
\   'python': ['flake8'],
\}
let g:ale_fixers = {
\   'cpp':    ['clang-format'],
\   'python': ['black'],
\}

function! s:SafeBlack()
  let l:cmd = 'black --quiet ' . shellescape(expand('%:p'))
  call system(l:cmd)
  if v:shell_error == 0
    silent! edit!
  endif
endfunction

augroup PythonFormat
  autocmd!
  autocmd BufWritePre *.py call s:SafeBlack()
augroup END

let g:airline_powerline_fonts = 1
"
let g:SignatureMarkTextHLDynamic = 1

let g:SignatureMarkText = '⚑'
let g:SignatureMarkerText = '✗'

let g:SignatureIncludeMarks = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

let g:SignaturePrioritizeMarks = 1

"
"
let g:next_mark_idx = 0
let g:mark_list = []

function! s:NextDynamicMark()
  let idx = g:next_mark_idx % 26
  let letter = nr2char(char2nr('a') + idx)

  execute "normal! m" . letter

  if index(g:mark_list, letter) < 0
    call add(g:mark_list, letter)
  endif

  let g:next_mark_idx += 1

  echo ">> mark '" . letter . "' set"
endfunction

nnoremap <silent> ma :call <SID>NextDynamicMark()<CR>

let g:mark_cycle_idx = 0

function! s:JumpNextMark()
  if empty(g:mark_list)
    echo ">> no marks set"
    return
  endif
  let idx = g:mark_cycle_idx % len(g:mark_list)
  let letter = g:mark_list[idx]
  execute "normal! '" . letter
  let g:mark_cycle_idx += 1
endfunction

nnoremap <silent> <leader>j :call <SID>JumpNextMark()<CR>

function! s:JumpToTypedMark()
  let c = nr2char(getchar())
  if c =~# '[a-z]'
    execute "normal! '" . c
  else
    echohl ErrorMsg | echo ">> invalid mark: ".c | echohl None
  endif
endfunction

nnoremap <silent> <leader>v :call <SID>JumpToTypedMark()<CR>

function! DeleteMarkOnThisLine()
  let marks = split(execute('marks'), "\n")[1:]

  let currline = line('.')

  for line in marks
    let fields = split(line)
    if len(fields) >= 2
      let mark = fields[0]
      let lnum = str2nr(fields[1])
      if lnum == currline && mark =~# '^[a-zA-Z]$'
        execute 'delmarks ' . mark
call remove(g:mark_list, index(g:mark_list, mark))
        echo ">> Mark '" . mark . "' deleted from line " . lnum
        return
      endif
    endif
  endfor

  echo ">> No mark found on this line"
endfunction

nnoremap <leader>d :call DeleteMarkOnThisLine()<CR>

تنظیمات کاکا ویم رو در فرسته بعدی میفرستم اما قبلش باید black  رو برای پایتون نصب کنید.
هر سوالی داشتید در خدمتم!
 
مثل سمی کالونم( ; ).
خواستار پایان.
محکوم به کامپایل.

آفلاین دانیال بهزادی

  • ناظر انجمن
  • *
  • ارسال: 19805
  • جنسیت : پسر
  • Urahara Kiesuke
    • وبلاگ
پاسخ : vimrc
« پاسخ #1 : 12 تیر 1404، 03:44 ب‌ظ »
برای کار با چندین پرونده باید از میانگیر (buffer) استفاده کنی؛ نه زبانه (tab).
در ضمن افزونه‌های airline و ale توی مخازن دبیان هستن و با وجود netrw داخل ویم‌های جدید دیگه به nerdtree هم نیازی نیست.
« آخرین ویرایش: 12 تیر 1404، 03:47 ب‌ظ توسط دانیال بهزادی »
اگه این ارسال بهت کمک کرد، دنبال دکمهٔ تشکر نگرد. به جاش تو هم به جامعهٔ آزادت کمک کن

آفلاین abc

  • Full Member
  • *
  • ارسال: 210
  • جنسیت : پسر
پاسخ : vimrc
« پاسخ #2 : 12 تیر 1404، 10:29 ب‌ظ »
نقل‌قول
من مجبور شدم آرچ رو حذف کنم و دیبان نصب کنم در همین حین ادیتور مورد علاقه من یعنی زد روی دیبان پشتیبانی نمیشه:(
اگر شد بعدا تجربه‌ی کاربری‌ات را هم به اشتراک بگذار (آرچ‌لینوکس و دبیان)
~