СПРАВОЧНИК ПО VIM - Брам Мооленаар


Этот текст важен для тех, кто хочет участвовать в дальнейшей разработке Vim.

  1. Цели дизайна
  2. Стиль программирования
  3. Решения в дизайне
  4. Исходные предположения

Общую информацию об исходном коде читайте в файле README.txt в каталоге "src".

Vim является программой с открытым исходным кодом. Все желающие могут помочь в усовершенствовании Vim. При внесении изменений предпочтительным является контекстный формат заплаток, поэтому просьба использовать для их создания команду "diff -c". См. также http://www.vim.org/tips/tip.php?tip_id=618.

1. Цели дизайна

По мере убывания степени важности (грубо).

Замечание: некоторые цели входят в противоречие друг с другом. Так и было задумано. Между ними должен соблюдаться определённый баланс.

VIM... СОВМЕСТИМ С VI

Прежде всего, должна быть возможность безусловного использования Vim вместо Vi. Если пользователь пожелает использовать Vim в совместимом режиме, он не должен наблюдать отличий от оригинального Vi.

Исключения:

  • Мы не воспроизводим очевидные глюки Vi в Vim.
  • Существуют различные версии Vi. Я пользуюсь версией 3.7 (6/7/85) в качестве эталона. Это не исключает необходимости также по возможности поддерживать и другие версии. Часть Vi в POSIX не считается основным источником.
  • Vim добавляет новые команды. Вы не можете рассчитывать, что какая-то команда не будет работать только потому, что её нет в Vi.
  • В Vim будет множество особенностей, которых нет в Vi. Возврат к Vi из Vim будет болезненным для пользователя, этого нельзя избежать.
  • Некоторые вещи используются редко (открытый режим, отправка почты при зависании программы и т.д.). Такие вещи будут включены только в том случае, если для их включения не потребуется большого труда и имеется веская причина для этого.
  • Для некоторых вещей является спорным вопрос сохранения совместимости с Vi. В этих случаях будет использован флаг в настройках соответствующей опции.
VIM... ЛУЧШЕ

Улучшенные элементы Vim должны делать его лучшим редактором, чем Vim, без превращения Vim в совершенно новый редактор. Расширения вносятся в "духе Vi".

  • Использовать клавиатуру как можно больше. Мышь требует третьей руки, которой нас всех обделили. На многих терминалах мышь не поддерживается.
  • Если всё-таки используется мышь, то необходимо избегать необходимости возвращаться к клавиатуре. Избегать совместного использования клавиатуры и мыши.
  • Добавлять новые команды и опции как можно более стандартным образом, иначе люди не смогут их легко найти и запомнить. Помните, что позднее появятся новые команды и опции.
  • Особенность, о которой не знают пользователи -- бесполезная особенность. не добавляйте непонятных особенностей, по крайней мере укажите в документации, что такая особенность существует.
  • Сводите к минимуму использование CTRL и других модификаторов, поскольку такие команды сложнее набирать.
  • Есть много неопытных пользователей Vim. Использование Vim в первый раз должно быть простым, как и возможность дальнейшего обучения.
  • Количество особенностей, которые могут быть добавлены не ограничено. Выбор новых особенностей зависит от (1) чего хотят пользователи, (2) сколько сил надо на это потратить и (3) кто это в конечном итоге будет делать.
VIM... МНОГОПЛАТФОРМЕННЫЙ РЕДАКТОР

Vim пытается быть полезным для как можно большего числа пользователей на как можно большем количестве платформ.

  • Поддержка большого количества терминалов. Минимальные требования - позиционирование курсора и очистка экрана. Команды должны использовать клавиши, которые есть на большинстве клавиатур. Для привязок должны поддерживаться все клавиши.
  • Поддержка многих платформ. Условием поддержки является наличие кого-нибудь, кто хочет заниматься разработкой на этой платформе и не будет при этом устраивать бардак в исходном коде.
  • Поддержка большого количества библиотек и компиляторов. Не все могут иметь возможность установки другого компилятора или библиотеки для графического интерфейса.
  • Люди переходят с платформы на платформу и из консоли в графический интерфейс. Особенности должны быть доступны во всех версиях, или, по крайней мере, как можно в большем количестве версий. Стремиться избегать ситуации, когда пользователь должен переключаться на другую платформу для решения задачи.
  • Если особенность может быть реализована только на некоторых платформах, или только на одной платформе, это ещё не означает, что она не должна быть реализована [Это противоречит предыдущему пункту преднамеренно, должен соблюдаться баланс между ними].
VIM... ХОРОШО ДОКУМЕНТИРОВАН
  • Недокументированная особенность это бесполезная особенность. Заплатка для новых особенностей должна включать документацию.
  • Документация должна быть понятной и доступной. Рекомендуется приводить примеры.
  • Текст не должен быть излишне длинным. Краткость в документации означает, что необходимую документацию проще найти.
VIM... БЫСТРЫЙ И ЛЁГКИЙ

Использование Vim не должно превращаться в атаку на системные ресурсы. Редактор должен быть быстрым и лёгким.

  • Компьютеры с каждым годом становятся быстрее и мощнее. Vim также может расти, но не быстрее, чем растут компьютеры. Vim должен быть вполне рабочим на старых системах.
  • Многие пользователи часто запускают Vim из оболочки. Время запуска должно быть как можно меньше.
  • Команды должны работать эффективно. Время, затрачиваемое на их выполнение, должно быть как можно меньше. Полезные команды могут выполняться немного дольше.
  • Не забывайте, что некоторые люди используют Vim по медленному каналу связи. Стремитесь к уменьшению трафика.
  • Элементы, которые серьёзно увеличивают размер и не используются многими людьми, должны быть оформлены в виде особенности, которую можно отключить.
  • Vim это компонент среди других компонентов. Не превращайте его в огромное приложение, лучше пусть Vim хорошо работает совместно с другими программами.
VIM... ЛЕГКО ПОДДЕРЖИВАТЬ
  • Не надо устраивать бардак из исходного кода. Код должен быть ясный и устойчивый.
  • Во всех файлах используйте одинаковый формат |программирование-стиль|.
  • Пользуйтесь комментариями разумно!
  • Портирование на другую платформу должно быть лёгким, без необходимости в изменении большого количества платформо-независимого кода.
  • Используйте объектно-ориентированный подход: данные и код помещайте вместе. Сводите к минимум обращения к другим частям кода.
VIM... ГИБКИЙ

Vim должен позволять пользователям работать в том стиле, в каком им больше нравится, вместо того, чтобы насильно навязывать им определённые методы работы. Это касается как элементов, имеющих большие последствия (например, опция 'compatible'), так и менее значительных деталей. Значения по умолчанию должны выбираться тщательным образом с тем, чтобы большинство пользователей получало наслаждение от работы с Vim. Команды и опции могут использоваться для настройки Vim по желанию пользователя и в зависимости от его окружения.

VIM ЭТО НЕ...
  • Vim это не оболочка и не операционная система. Вы не сможете запускать оболочку внутри Vim или пользоваться Vim для управления отладчиком. Наоборот: Vim должен использоваться как компонент оболочки или в интегрированной среде разработки. Другими словами, "В отличие от Emacs, Vim не пытается вместить в себя всё, включая унитаз, но говорят, что с его помощью можно его почистить ;)"
  • Vim это не модный редактор, который пытается выглядеть красивым ценой несовместимости с другими платформами. В то же время, функциональные особенности для графического интерфейса приветствуются.

2. Стиль программирования

Здесь описаны правила внесения изменений в исходный код Vim. Просьба придерживаться этих правил с тем, чтобы исходный код можно было легко читать и поддерживать.

Этот список не полный. Обратитесь за дополнительными примерами к самому исходному коду.


ВНЕСЕНИЕ ИЗМЕНЕНИЙ

Шаги для изменения исходного кода:

  1. Исправьте документацию. Выполнение этого шага прежде всего даёт вам возможность понять, как изменения отразятся на пользователе.
  2. Внесите изменения в исходный код.
  3. Проверьте ../doc/todo.txt, не затрагивают ли изменения что-либо из перечисленного.
  4. Сделайте заплатку с помощью "diff -c" для кода и документации.
  5. Напишите, что было изменено и включите этот текст в заплатку.
ИСПОЛЬЗОВАНИЕ ОБЩИХ ФУНКЦИЙ

У некоторых функций общего назначения есть аналог Vim. Всегда уделяйте внимание возможности использовать эти функции, они были созданы специально для этого.

ОБЫЧНОЕ ИМЯ  ИМЯ VIM РАЗЛИЧИЯ В ВЕРСИИ ДЛЯ VIM
free() vim_free() Проверяет при освобождении памяти для NULL
malloc() alloc() Отслеживает ситуацию с нехваткой памяти
malloc() lalloc() Как alloc(), но с аргументом типа long
strcpy() STRCPY() Преобразует тип к (char *), для char_u * args
strchr() vim_strchr() Допускает использование спецсимволов
strrchr() vim_strrchr() Допускает использование спецсимволов
isspace() vim_isspace() Может работать с символами > 128
iswhite() vim_iswhite() Возвращает TRUE только для Tab и пробелов
memcpy() vim_memmove() Работает с пересекающимися копиями
bcopy() vim_memmove() Работает с пересекающимися копиями
memset() vim_memset() Работает одинаково во всех системах
ИМЕНА

Имена функций не могут быть длиннее, чем 31 символ (из-за VMS).

Не пользуйтесь в качестве имени переменной "delete", C++ этого не любит.

Поскольку Vim должен работать на как можно большем количестве систем, нам требуется избегать использования имён, которые определяются в системе. Приводим список имён, которые приводят к проблемам. Имена указаны в виде шаблона регулярного выражения.

is.*() POSIX, ctype.h
to.*() POSIX, ctype.h
d_.* POSIX, dirent.h
l_.* POSIX, fcntl.h
gr_.* POSIX, grp.h
pw_.* POSIX, pwd.h
sa_.* POSIX, signal.h
mem.* POSIX, string.h
str.* POSIX, string.h
wcs.* POSIX, string.h
st_.* POSIX, stat.h
tms_.* POSIX, times.h
tm_.* POSIX, time.h
c_.* POSIX, termios.h
MAX.* POSIX, limits.h
__.* POSIX, system
_[A-Z].* POSIX, system
E[A-Z0-9]* POSIX, errno.h
*_t POSIX, для typedefs.  Пользуйтесь вместо этого *_T.
wait не используйте в качестве аргумента функции, конфликтует с types.h
index скрывает глобальное объявление
time скрывает глобальное объявление
new зарезервированное ключевое слово C++
try Borland C++ не любит использования этого имени в качестве переменной.
basename() строковая функция GNU
dirname() строковая функция GNU
get_env_value() системная функция Linux
РАЗНОЕ

Имена определённых typedef типов должны оканчиваться на "_t":

typedef int some_t;

Имена, определённые в #define должны состоять из прописных символов:

#define SOME_THING

Определения особенностей всегда начинаются с "FEAT_":

#define FEAT_FOO

Не пользуйтесь '\"', некоторые компиляторы этого терпеть не могут. Можно пользоваться '"'.

Не используйте:

#if HAVE_SOME

Некоторые компиляторы этого понять не способны и будут ругаться, то"HAVE_SOME" не определено.

Используйте

#ifdef HAVE_SOME

или

#if defined(HAVE_SOME)
СТИЛЬ

Правило: Одна строка, одно выражение.

Неправильно: if (cond) a = 1;
Правильно: if (cond)
    a = 1;
Неправильно: while (cond);
Правильно: while (cond)
;
Неправильно: do a = 1; while (cond);
Правильно: do
    a = 1;
while (cond);

Как начинаются функции:

Неправильно: int function_name(int arg1, int arg2)
Правильно: /*
 * Explanation of what this function is used for.
 *
 * Return value explanation.
 */

int
function_name(arg1, arg2)
    int arg1;   /* short comment about arg1 */
    int arg2;   /* short comment about arg2 */
{
    int local;  /* comment about local */

    local = arg1 * arg2;

ЗАМЕЧАНИЕ: не используйте декларации в стиле ANSI. Некоторые до сих пор пользуются компиляторами, которые это не поддерживают.

ПРОБЕЛЫ И ПУНКТУАЦИЯ

Между именем функции и скобкой пробела нет:

Неправильно: func (arg);
Правильно: func(arg);

После if, while, switch и т.д. идёт пробел:

Неправильно: if(arg)     for(;;)
Правильно: if (arg)    for (;;)

После запятой и точки с запятой пробел:

Неправильно: func(arg1,arg2);    for (i = 0;i < 2;++i)
Правильно: func(arg1, arg2);    for (i = 0; i < 2; ++i)

Пробел до и после '=', '+', '/' и т.п.:

 Неправильно: var=a*5;
 Правильно: var = a * 5;

В целом: для группировки строк кода используйте пустые строки. Комментарий помещайте сразу перед группой строк. Это позволяет быстро разбираться в коде.

 Правильно: /* Prepare for building the table. */
get_first_item();
table_idx = 0;

/* Build the table */
while (has_item())
    table[table_idx++] = next_item();

/* Finish up. */
cleanup_items();
generate_hash(table);

3. Решения в дизайне

Складки

В буфере допускается использовать разные виды складок. Например, одно окно может показывать текст, в котором функции спрятаны в складках, в другом окне функции показаны полностью.

Складки это способ отображения текста. Сам текст при использовании складок не изменяется. Поэтому складки реализованы в виде фильтра между текстом, хранящимся в буфере (строками буфера) и текстом, отображающимся в окне (логическими строками).

Термин "окно"

Слово "окно" часто используется для разных вещей: окно на экране, окно xterm, окно внутри Vim для просмотра буфера.

Чтобы избежать путаницы, используются разные термины для разных элементов, которые могли бы также быть названы "окно".

экран Весь экран. То, что в графическом интерфейсе будет 1024x768 пикселов. Оболочка Vim может использовать весь экран или его часть.
оболочка Приложение Vim. Может покрывать весь экран (например, в консоли), или занимать только его часть (xterm или графический интерфейс).
окно Вид буфера. В Vim может быть несколько окон, вместе с командной строкой, меню, панелью инструментов и т.д. они образуют оболочку.

Продолжение следует...

4. Исходные предположения

Размер переменных:

char 8 bit signed
char_u 8 bit unsigned
int 16, 32 или 64 bit signed
unsigned 16, 32 или 64 bit unsigned
long 32 или 64 bit signed, может содержать указатель

Обратите внимание, что некоторые компиляторы не могут обрабатывать длинные строки или строки C. Стандарт C89 предусматривает ограничение в 509 символов.