h0rr0rr_drag0n 25.04.2009 17:06
Vim — Сервер vim.
Cтатья предназначена для тех, кто редактирует много файлов в vim'e и желает, чтобы все файлы открывались в одной копии vim'a.В редакторе вим есть режим "сервера" в котором он отсылает файлы, предназначенные для редактирования, т.н. вим-серверу, который их и открывает в своем окне для последующей правки. Таким образом в системе оказывается запущенной только одна копия vim'а - сервер.
Получить список vim-серверов уже запущенных в системе можно опцией --serverlist. Естественно сейчас она ничего вам покажет, потому что у вас не запущено ни одного vim-сервера.
Запустить сервер можно указав виму опцию --servername имя_сервера. Клиенты будут подключаться по имени сервера. Регистр символов в имени сервера роли не играет. Если вы попытаетесь запустить сервер с уже используемым именем, то вим добавит к имени нового сервера единичку и запустит его.
Отправить файл на сервер можно указав виму имя сервера опцией --servername (да она используется и для этого) и использовав одну из опций --remote* имя_файла.
Узнать подробнее об этих опциях можно в vim --help.
Для повышения удобства использования механизма "клиент-сервер" в виме я написал небольшой скрипт, который запускает сервер вима (если он еще не запущен) и отправляет файл на редактирование первому из серверов в списке vim --serverlist. Также скрипт использует механизм notify-osd - выводит красивый поп-ап при запуске вим-сервера.
Чтобы задействовать механизм notify-osd нужно установить пакет libnotify-bin. Хотя скрипт может прекрасно работать и без него.
Пожалуйста! =))
Что-то я не понял, что всё-таки значит этот сервер..
если надо редактировать несколько файлов я использую табы.. и вроде как один вим при этом открыт. И зачем тогда сервер этот нужен? поясните пожалуйста
если надо редактировать несколько файлов я использую табы.. и вроде как один вим при этом открыт. И зачем тогда сервер этот нужен? поясните пожалуйста
Кажется понял, что имелось в виду)
Я говорил про табы не терминала, а табы в самом виме. Они работают без всяких иксов
Я говорил про табы не терминала, а табы в самом виме. Они работают без всяких иксов
Например, если вы будете открывать файл на редактирование, вызывая вим через командную строку, то будет использоваться новая копия вима, но никак не та, в которой у вас уже редактируются файлы. Сервер + мой скрипт позволяют обойти это ограничение - теперь после ввода vim filename файл откроется в новой вкладке уже работающей копии vim'a.
Если в виме написать
:tabe или :new tab
А потом :read filename
то вроде бы один и тот же вим работает...по крайней мере топ так говорит) Но всё равно надо будет попробовать этот скрипт и сервер)
:tabe или :new tab
А потом :read filename
то вроде бы один и тот же вим работает...по крайней мере топ так говорит) Но всё равно надо будет попробовать этот скрипт и сервер)
Спасибо!
Мне показалось, правильным было бы заврапить стандартный вызов редактора этой функцией. Для этого надо положить скрипт в свой локальный bin, и внести несколько изменений:
1. Заменен вызов вима с полным путем, что бы скрипт не вызывал сам себя
2. Поиск сервера через "правильный" вим, а то у меня "vim --serverlist" говорит что такого параметра нет.
3. Обкусывание параметра "-f" который передается из GUI c именем файла и не нужен в случае сервера.
4. Добавлено поднятие окна вим-сервера поверх всех окон. xwininfo - слегка притормаживает при переборе всех окон, может быть кто знает как получить ид-окна быстрее?
Кстати у notify-send парамтр времени задается в миллисекундах... потом за 5 мс... ничего не увидеть.
Мне показалось, правильным было бы заврапить стандартный вызов редактора этой функцией. Для этого надо положить скрипт в свой локальный bin, и внести несколько изменений:
#!/bin/bash
############################################################################
############################################################################
##
## Скрипт для обеспечения редактирования всех открываемых при помощи vim
## файлов в одной копии vim'a/gvim'a.
##
## Автор: h0rr0rr_drag0n
##
############################################################################
############################################################################
#Путь к иконке vim'a
VIM_ICON=/usr/share/pixmaps/gvim.png
# Заголовок для всплывающей подсказки
NOTIFY_HEAD=Vim
# Проверим, установлен ли vim.
whereis -b vim | grep -q '/bin/vim'
if < "`echo $?`" != "0" >; then
echo "Vim not installed! Please install it."
exit 1
fi
# Проверим, установлен ли gvim.
whereis -b gvim | grep -q '/bin/gvim'
if < "`echo $?`" -ne "0" >; then
# gvim не установлен:
# используем по умолчанию vim
VIM=/usr/bin/vim
else
# Установлен gvim -- используем его
VIM=/usr/bin/gvim
fi
# Проверим, установлен ли notify-send
# Если нет -- не используем его
whereis -b notify-send | grep -q '/bin/notify-send'
if < "`echo $?`" -eq "0" >; then
USE_NOTIFY=yes
else
USE_NOTIFY=no
fi
# Получим список Vim серверов
VIM_SERVER=`$VIM --serverlist | head -n 1`
# Если ни один сервер не запущен -- запустим его.
if < ! -n "$VIM_SERVER" >; then
# Без иксов сообщения между клиентом и сервером не пересылаются.
# Проверим, запущены ли иксы.
if < -n "$DISPLAY" >; then
$VIM --servername vimserver1
if < "$USE_NOTIFY" == "yes" >; then
notify-send -u normal -t 20 -i $VIM_ICON "$NOTIFY_HEAD" "Vim server \"vimserver1\" started."
fi
else
echo "No display: server start failed! File opened locally." >&2
vim $*
exit 0
fi
fi
# Перечитаем список серверов.
VIM_SERVER=`$VIM --serverlist | head -n 1`
# Сервер работает -- открываем в нем документ для редактирования.
$VIM --servername "$VIM_SERVER" --remote-tab-silent ${*%%-f} &>/dev/null
VIM_WINDOW=`xwininfo -root -tree|grep $VIM_SERVER|awk -F" " '{print $1;}'`
wmctrl -i -a $VIM_WINDOW
1. Заменен вызов вима с полным путем, что бы скрипт не вызывал сам себя
2. Поиск сервера через "правильный" вим, а то у меня "vim --serverlist" говорит что такого параметра нет.
3. Обкусывание параметра "-f" который передается из GUI c именем файла и не нужен в случае сервера.
4. Добавлено поднятие окна вим-сервера поверх всех окон. xwininfo - слегка притормаживает при переборе всех окон, может быть кто знает как получить ид-окна быстрее?
Кстати у notify-send парамтр времени задается в миллисекундах... потом за 5 мс... ничего не увидеть.
$VIM --servername "$VIM_SERVER" --remote-tab-silent ${*%%-f} &>/dev/null
Если имя файла содержит пробелы, то вместо него будут открыты несколько файлов. Это можно избежать, заменив ${*%%-f} на "${@%%-f}"
Все очень здорово, я постоянно редактирую в vim'е множество файлов, скриптов со множеством вкладок и некоторыми настройками, выставленными "на лету" (разбиение отдельных вкладок на окна, выставление этим окнам соответствующих пропорций в зависимости от данных, возможно кодировка, foldmethod, сами fold'ы и т.д.) и в последнее время все больше становится востребованным применение сервера, т.к. все эти настройки не хотелось бы терять. Собственно, чтобы не тратить время на чтение документации, гугление и т.п. решил сразу зайти сюда и быстренько ознакомиться (просто помню, что тут была такая статья, некогда на нее натыкался). И правда, статья весьма компактная и доходчивая... только мне немноженько поломал мозг скрипт))) зачем такие извращения?
вот конкретно if < "`echo $?`" -eq "0" >; then ... fi ломает мозг))
проще: if < "$?" -eq "0" >; then ... fi
еще проще: if ((! $?)); then ... fi
еще еще проще: if $COMMAND; then ... fi
совсем лучше:
whereis -b notify-send | grep -q '/bin/notify-send'
if < "`echo $?`" -eq "0" >; then
USE_NOTIFY=yes
else
USE_NOTIFY=no
fi
вот конкретно if < "`echo $?`" -eq "0" >; then ... fi ломает мозг))
проще: if < "$?" -eq "0" >; then ... fi
еще проще: if ((! $?)); then ... fi
еще еще проще: if $COMMAND; then ... fi
совсем лучше:
NOTIFY_SEND_EXEC="/bin/notify-send"
if < -x "$NOTIFY_SEND_EXEC" >; then
USE_NOTIFY=yes
else
USE_NOTIFY=no
fi
# или лучше не запоминать yes/no, а в конкретном месте проверять на test -x и если есть (существует такой exec-file), то вызывать
Все просто - скрипт писался давно и мой тогдашний скилл скриптописания на баше был невысок))
Вообще я не понимаю зачем такие извращения, ведь gvim --remote-tab-silent сделает абсолютно то же самое: передаст файл серверу, если он запущен, либо запустит новый вим с этим файлом. Единственное достоинство этого скрипта в том, что он красивое уведомление показывает, в остальном не вижу большого смысла.
я написал небольшой скрипт, который запускает сервер вима (если он еще не запущен)
Вкратце говоря, если сервер внезапно оказался не запущен, то этот скрипт сначала запустит его, а лишь потом передаст ему файл на редактирование.
Уже не помню, но подозреваю, что если просто открывать файл через --remote-tab-silent при не запущенном сервере, то нас ожидает ругань на отсутствие этого самого сервера и все(.
Неправда ваша.
vim --help
Сам пробовал, при первом выполнении gvim --remote-tab-silent молча запускает новый вим, при последующих быстро передаёт файлы существующему. Единственный момент, когда он ругается — отсутствие иксов, тогда он скажет, что не может открыть дисплей, но всё равно запустится в консоли.
vim --help
--remote <файлы> По возможности редактировать <файлы> на сервере Vim
--remote-silent <файлы> То же, но без жалоб на отсутствие сервера
--remote-wait <файлы> То же, что и --remote, но с ожиданием завершения
--remote-wait-silent <файлы> То же, но без жалоб на отсутствие сервера
--remote-tab<-wait><-silent> <files> As --remote but use tab page per file
Сам пробовал, при первом выполнении gvim --remote-tab-silent молча запускает новый вим, при последующих быстро передаёт файлы существующему. Единственный момент, когда он ругается — отсутствие иксов, тогда он скажет, что не может открыть дисплей, но всё равно запустится в консоли.
Вот говно... vim-server немного не то, что я ожидал)) в конечном итоге придется все равно прибегнуть к screen/dtach, осталось только придумать механизм... например, при запуске vim'а проверять рабочий каталог на предмет файла .vim-server (ибо, как правило, группу файлов на одном вим-сервере чаще всего можно связать по рабочему каталогу <�например, по каталогу проекта, над которым работаешь, а сами файлы, разумеется, лежат где угодно, но большинство из них именно в дочерних каталогах от рабочего>). Осталось только решить, использовать ~/bin/vim заглушку или реализовать через vim-скрипт (~/.vimrc или ~/.vim/)...
screen-сессию обозвать vim-server-$name, vim-server-сиссию $name, сами редактируемые файлы, при наличии уже поднятого vim-сервера, отправлять на него и открывать уже поднятную screen-сессию (можно и с -x), в противном случае — все поднять (vim-server в screen'е) и работать в свое удовольствие :-). В конечном итоге все сведется к: $ cd ~/projects/current-project-dir && echo "my-project-name" > .vim-server && vim # в последующие разы просто $ vim, вся магия в .vim-server
Что ж, идей много...
screen-сессию обозвать vim-server-$name, vim-server-сиссию $name, сами редактируемые файлы, при наличии уже поднятого vim-сервера, отправлять на него и открывать уже поднятную screen-сессию (можно и с -x), в противном случае — все поднять (vim-server в screen'е) и работать в свое удовольствие :-). В конечном итоге все сведется к: $ cd ~/projects/current-project-dir && echo "my-project-name" > .vim-server && vim # в последующие разы просто $ vim, вся магия в .vim-server
Что ж, идей много...
vim --servername VIM --remote-tab-silent.
Читайте уже справку, всё прекрасно работает без костылей.
Читайте уже справку, всё прекрасно работает без костылей.
))) ты просто не уловил идею и проблему, вставшую передо мной. дело в том, что, во-первых, такая команда отправляет файл на сервер, при этом сама ничего не дает (возвращает консоль непосредственно), во-вторых, всегда должен быть открыт vim-server, т.е. он не может висеть как демон... а проблема как раз в этом и заключается, что я могу случайно или по необходимости грохнуть иксовую консоль, в которой висит vim-server, ну и в-третьих, тебе не кажется, что каждый раз писать такую команду несколько накладно?
что я хочу:
1. чтобы vim-server висел демоном (вне зависимости от той консоли, где его запустили)
2. чтобы к нему всегда можно было приконнектиться простой командой (например, vim)
есть идеи, кроме как использования screen/dtach и исключая ручного патчинга сорцов vim'a?
что я хочу:
1. чтобы vim-server висел демоном (вне зависимости от той консоли, где его запустили)
2. чтобы к нему всегда можно было приконнектиться простой командой (например, vim)
есть идеи, кроме как использования screen/dtach и исключая ручного патчинга сорцов vim'a?
о_О и как ты себе это представляешь? дай готовый, а главное рабочий пример))
как я понимаю (читай вижу), это поднимает gvim? а если грохнуть иксы? :-), а если так же успешно "случайно" (или по необходимости) закрыть окно? я хочу, чтобы вим работал в режиме демона — т.е. висел вне зависимости от иксов. Например, как mpd. Вот было бы здорово, если бы он именно так и работал в режиме демона... поднимался бы себе в фоне, а уже vim-клиенты бы к нему подключались и отвечали за работу с tty (читай вывод на экран), сама же работа с файлами производилась бы именно на сервере.
Вопрос имеет более, так сказать, "правильное" решение (не без помощи philosoft, за что ему спасибо): http://ajayfromiiit.wordpress.com/2009/10/15/vim-sessions/
Вообщем, жирный "+" со всего размаху мышкой! Спасибо!