patch -p0 < /path/to/c.vim.patch1. Поддержка директорий проектов в c.vim. Под поддержкой проекта будем понимать возможность использования различных шаблонов c.vim в зависимости от того, какому проекту принадлежит редактируемый файл. Как правило, файлы проекта расположены в отдельной директории, а сами проекты могут предъявлять разные требования к оформлению элементов, таких как заголовки файлов. В c.vim имеется поддержка отдельных проектов с помощью макроса STYLE (см. документацию c.vim), однако ее реализация имеет недостатки. В частности, этот подход подразумевает централизованное хранение всех шаблонов в директории ~/.vim/c-support/templates/. Нормальная поддержка проектов должна предполагать возможность хранения независимого набора шаблонов в директории проекта - это более гибкий и естественный подход.
Следующий патч (относительно c.vim версии 5.13) реализует возможность хранения шаблонов c.vim в директории проекта:
--- c.vim 2011-01-26 00:12:31.000000000 +0300
+++ c.vim.new 2011-06-26 13:07:16.000000000 +0400
@@ -327,6 +327,10 @@
let s:C_SourceCodeExtensionsList = split( s:C_SourceCodeExtensions, '\s\+' )
+if exists( 'g:C_ProjectDirs' )
+ let s:C_ProjectList = split( g:C_ProjectDirs, ',' )
+endif
+
"------------------------------------------------------------------------------
"------------------------------------------------------------------------------
@@ -2702,6 +2706,16 @@
let s:C_FileVisited = []
let messsage = ''
"
+
+ for proj in s:C_ProjectList
+ if stridx(getcwd(), proj) != -1
+ if filereadable( proj."/.cvim.templates/Templates" )
+ call C_ReadTemplates( proj."/.cvim.templates/Templates" )
+ return
+ endif
+ endif
+ endfor
+
if s:installation == 'system'
"
if filereadable( s:C_GlobalTemplateFile )
Здесь вводится новая глобальная переменная C_ProjectDirs, которая представляет собой список проектов, разделенных запятыми, для которых могут быть предложены отдельные наборы шаблонов. Например, в C_ProjectDirs добавим проект /path/to/proj1, далее в указанной директории создадим директорию .cvim.templates/, скопируем туда шаблоны из ~/.vim/c-support/templates/ и отредактируем по вкусу. Теперь при редактировании файлов в директории /path/to/proj1 и любой ее поддиректории будут использоваться новые шаблоны. При редактировании файла, не входящего ни в один из указанных в C_ProjectDirs проектов, будут использоваться шаблоны по умолчанию.Переменную C_ProjectDirs можно определить в ~/.vimrc, например так:
let g:C_ProjectDirs = "/path/to/proj1,".$PROJ2WORKDIRЗдесь указаны 2 проекта: /path/to/proj1 и проект, определенный через переменную среды PROJ2WORKDIR, проекты разделены запятой.
2. Проблема взаимодействия fuzzyfinder и taglist. Taglist - самый популярный плагин vim. Он предоставляет отдельное окно для навигации по тегам исходного кода в открытых файлах. Это очень старый плагин и, к сожалению, давно не обновлялся, поэтому ему присущи недостатки, в частности, его сложно использовать при наличии нескольких табов (которые стали доступны в vim 7.0). Fuzzyfinder - очень интересный плагин, который легко использовать для навигации по файловой системе, тегам, закладкам и др. Особенностью данного плагина является то, что он не использует отдельное окно, а открывает временное окно поиска в левом верхнем углу терминала по запросу. К сожалению, при определенных настройках taglist, эти два плагина не дружат, что выражается в выводе нового буфера в окно taglist после закрытия окна поиска fuzzyfinder (см. здесь). Починить это поведение можно с помощью простого изменения в файле ~/.vim/autoload/l9/tempbuffer.vim (библиотека l9 поставляется вместе с fuzzyfinder, патч приведен относительно версии l9 1.1):
--- tempbuffer.vim 2010-09-28 23:55:28.000000000 +0400
+++ tempbuffer.vim.new 2011-06-26 13:13:54.000000000 +0400
@@ -22,7 +22,9 @@
endif
if bufnr('%') == s:dataMap[a:bufname].bufNr && winnr('#') != 0
" if winnr('#') returns 0, "wincmd p" causes ringing the bell.
- wincmd p
+ " my cmt: 'wincmd p' works badly with taglist - using 'wincmd j' instead
+ "wincmd p
+ wincmd j
endif
endfunction
@@ -43,7 +45,8 @@
" a:listener:
" a:listener.onClose(written)
function l9#tempbuffer#openScratch(bufname, filetype, lines, topleft, vertical, height, listener)
- let openCmdPrefix = (a:topleft ? 'topleft ' : '')
+ " my cmt: open fuf buffer above current window ('leftabove' instead 'topleft')
+ let openCmdPrefix = (a:topleft ? 'leftabove ' : '')
\ . (a:vertical ? 'vertical ' : '')
\ . (a:height > 0 ? a:height : '')
if !exists('s:dataMap[a:bufname]') || !bufexists(s:dataMap[a:bufname].bufNr)
Данный патч делает еще одно, на мой взгляд, полезное изменение в поведении fuzzyfinder: теперь окно поиска будет открываться не в левом верхнем угла терминала, а вверху окна, в котором осуществляется редактирование.3. Поддержка ack в grep.vim. ack - это grep для пограммистов. Это очень удобная утилита для поиска текста в директории исходников, она знает о служебных директориях CVS, Subversion и др. и игнорирует их, поддерживает регулярные выражения perl и обладает другими полезными свойствами. В vim существует плагин, который поддерживает ack, однако он реализует простейшую обертку встроенного в vim grep и "мусорит" в stdout. Плагин grep.vim реализован лучше, однако не обладает поддержкой ack. Следующий патч реализует это поддержку в grep.vim (относительно версии grep.vim 1.9):
--- grep.vim 2011-06-26 13:19:02.000000000 +0400
+++ grep.vim.new 2011-06-26 13:22:22.000000000 +0400
@@ -317,6 +317,10 @@
let Agrep_Path = 'agrep'
endif
+if !exists("Ack_Path")
+ let Ack_Path = 'ack'
+endif
+
" Location of the find utility
if !exists("Grep_Find_Path")
let Grep_Find_Path = 'find'
@@ -731,7 +735,7 @@
let grep_opt = g:Grep_Default_Options
endif
- if a:grep_cmd != 'agrep'
+ if a:grep_cmd != 'agrep' && a:grep_cmd != 'ack'
" Don't display messages about non-existent files
" Agrep doesn't support the -s option
let grep_opt = grep_opt . " -s"
@@ -749,6 +753,9 @@
elseif a:grep_cmd == 'agrep'
let grep_path = g:Agrep_Path
let grep_expr_option = ''
+ elseif a:grep_cmd == 'ack'
+ let grep_path = g:Ack_Path
+ let grep_expr_option = ' -H --nogroup --nocolor'
else
return
endif
@@ -763,7 +770,7 @@
\ g:Grep_Shell_Quote_Char
endif
- if filenames == ""
+ if filenames == "" && a:grep_cmd != 'ack'
if v:version >= 700
let filenames = input("Search in files: ", g:Grep_Default_Filelist,
\ "file")
@@ -777,8 +784,12 @@
" Add /dev/null to the list of filenames, so that grep print the
" filename and linenumber when grepping in a single file
- let filenames = filenames . " " . g:Grep_Null_Device
- let cmd = grep_path . " " . grep_opt . " -n "
+ if a:grep_cmd != 'ack'
+ let filenames = filenames . " " . g:Grep_Null_Device
+ let cmd = grep_path . " " . grep_opt . " -n "
+ else
+ let cmd = grep_path . " " . grep_opt
+ endif
let cmd = cmd . grep_expr_option . " " . pattern
let cmd = cmd . " " . filenames
@@ -810,6 +821,9 @@
command! -nargs=* -complete=file Ragrep
\ call s:RunGrepRecursive('Ragrep', 'agrep', 'set', <f-args>)
+command! -nargs=* -complete=file Ack
+ \ call s:RunGrep('Ack', 'ack', 'set', <f-args>)
+
if v:version >= 700
command! -nargs=* -complete=file GrepAdd
\ call s:RunGrep('GrepAdd', 'grep', 'add', <f-args>)
Теперь, для того чтобы выполнить рекурсивный поиск вхождения sample в текущей директории из vim, достаточно ввести команду:Ack sampleТот же поиск, но во всех файлах с расширением .cc в текущей директории:
:Ack sample *.cc4. Навигация между окнами с помощью комбинаций клавиш Ctrl-Arrow. Это очень полезный совет, который можно найти на многих ресурсах в сети. Суть идеи в том, чтобы при наличии нескольких открытых окон переключаться между ними простой комбинацией клавиш Ctrl-Up и Ctrl-Down. Такое поведение требует некоторой настройки, в частности, значение bufhidden должно быть равным delete, чтобы при навигации скрытые буферы (т.е. те файлы, которые ранее редактировались в открытых окнах, но были в дальнейшем скрыты новыми файлами) не открывались в отдельных окнах. Итак, настройки для данного поведения, которые следует поместить в ~/.vimrc выглядят так:
set switchbuf=usetab autocmd BufEnter * setlocal bufhidden=delete nmap <C-up> :sbn<CR> nmap <C-down> :sbp<CR> nmap <C-left> :tabp<CR> nmap <C-right> :tabn<CR>Последние два маппинга добавляют возможность навигации между табами по комбинациям клавиш Ctrl-Left и Ctrl-Right и не имеют отношения к рассматриваемой далее проблеме.
А проблема заключается в том, что если некоторый файл попал по той или иной причине в список bufhidden, то при его повторном открытии попасть в его окно с помощью комбинаций Ctrl-Up или Ctrl-Down становится невозможно. Это означает, что, скорее всего, vim не удаляет файл из списка bufhidden при его повторном открытии. Лечится это добавлением еще одной авто-команды в ~/.vimrc:
autocmd BufEnter * if empty(&buftype) | setlocal buflisted | endifUpdate: Кажется редактор blogger превратил символы табуляции в патчах в пробелы :( Так что для автоматического наложения патчей теперь придется использовать опцию -l, например так:
patch -l -p0 < /path/to/c.vim.patch