Config.tcl
Материал из Tkabber Wiki.
Содержание |
Общие сведения
Прежде чем читать эту статью, подумайте, достаточно ли вы хорошо представляете себе, что такое файл config.tcl (в частности, где Ткаббер ищет его при старте); если нет, начните с чтения этой статьи.
Чтобы понять место и роль файла config.tcl в процедуре загрузки Ткаббера, прочитайте ещё одну статью.
А после прочтения данного опуса можно со знанием дела переходить к "книге рецептов".
Файл конфигурации — config.tcl — читается на ранней стадии запуска Ткаббера и поэтому позволяет влиять на большинство аспектов работы этой программы.
- Файл конфигурации выполняется интерпретатором тикля, который исполняет код Ткаббера. То есть этот файл является полноценной программой на тикле. Этот аспект следует хорошо прочувствовать, имея в виду беспрецедентный динамизм языка Tcl, позволяющий, среди прочего, переопределять процедуры Ткаббера и "перепаковывать" его окна.
Наиболее важные способы влияния на Ткаббер из его конфига можно условно разделить на три группы:
- Установка предопределённых (документированных) переменных Ткаббера. Например, переменная debug_lvls управляет "темами" отладочных сообщений Ткаббера, а ifacetk::options(use_tabbar) — стилем интерфейса (0 — многооконный, 1 — "с табами"). Эти переменные описаны в официальной документации к Ткабберу.
- Переопределение процедур Ткаббера. Например, таким образом можно "деактивировать" IRC-команду чата /exec, которую некоторые считают опасной, или переделать реакцию Ткаббера на запрос jabber:iq:last (см. код плагина "Last Activity").
- Изменение привязок событий Tk (нажатий комбинаций клавиш, к примеру) к определённым действиям.
- Просто выполнение некоторого кода, который может, к примеру, менять изначальный "лук и фил" Ткаббера.
- Установка обработчиков определённых хуков (см. ниже). Внутри этих обработчиков можно делать интересные вещи, описанные в предыдущих пунктах.
Вообще же, вещи, которые можно сделать с Ткаббером при помощи файла его конфигурации, ограничены, в основном, лишь фантазией и знаниями ковыряющегося.
Важно осмыслить и запомнить следующее правило:
- Ткаббер читает свой файл конфигурации ровно один раз за сеанс своей работы. Механизма "перечитывания" файла конфигурации нет (и не будет). Это означает, что после внесения изменений в файл конфигурации Ткаббер нужно перезапустить (а лучше для начала запустить его вторую копию "рядом" — см. ниже обсуждение тестирования конфигурации).
Ткаббер прекрасно обходится без config.tcl — как он, так и "парный" файл custom.tcl не нужны Ткабберу для запуска и работы. Поэтому, если у Вас нет файла config.tcl в условленном месте, просто создайте его сами.
Немного о синтаксисе тикля
Вообще, если вы собираетесь заняться "продвинутым" конфигурированием Ткаббера всерьёз (а не просто применять готовые рецепты не задумываясь), подумайте о самообразовании. Для начала можно порекомендовать такую последовательность действий:
- Изучить туториал;
- Изучить "эндекалогию";
- Почитать классику (переведённую и на язык родных осин).
В качестве "быстрого погружения" для нетерпеливых предложим самые главные правила, про которые нужно помнить, занимаясь правкой конфига на тикле:
- Любые пробельные символы являются разделителем слов
- Это означает, что символы логически цельных строк (они именуются в тикле "словами"), содержащих пробелы, нужно группировать.
- Для группировки используются ограничители {} и ""
- Внутри {} не выполняется никакая интерпретация содержимого, внутри "" тикль выполняет подстановку переменных (нотация $имя_переменной), выполняет команды (нотация [команда аргументы...]) и раскрывает "escape-последовательности" (нотация \X, где "X" — спецсимвол).
- Путевые имена файлов в Windows могут содержать прямые слэши
- То есть имя "C:/Program files/FrobozzMagic 2000" является вполне допустимым.
- Строка без пробелов и группирующих символов также интерполируется
- То есть используйте прямые слэши под Windows, если данная строка — путевое имя файла.
Следствия этих правил:
- Всегда заключайте имена файлов в "" или {}, если эти имена содержат пробелы.
- Предпочтительно заключайте такие имена в {} чтобы подавить интерпретацию содержимого строки.
- Если вы всё-таки хотите использовать "", указывайте прямые слэши в путевых именах файлов Windows — это убережёт имена от раскрытия "escape-последовательностей", вводимых обратными слэшами.
- Также можно обойтись вообще без группирующих символов, но тогда нужно удваивать все обратные слэши и "искейпить" пробелы обратными слэшами.
Примеры:
# Путь в {} — подавляется любая интерпретация содержимого:
set somepath {C:\Documents and Settings\Vassily Petrovich}
# Путь в "" + прямые слэши = тот же эффект:
set someotherpath "C:/Program files/Новая папка"
# Группирующие символы не нужны — имя не содержит пробелов;
# Однако слэши — прямые, ибо такие строки интерполируются:
set thethirdpath C:/TMP
# Нет группирующих символов ⇒ танцы с "искейпингом":
set falsepath C:\\Program\ Files\\Common\ Files\\Woohoo
Обратный слэш, за которым сразу следует перевод строки, обозначает "продлённую" строку
То есть запись
command arg1 \ arg2 arg3
полностью эквивалентна записи
command arg1 arg2 arg3
Продление строк используется для улучшения читабельности.
Ссылки на элементы массивов не должны содержать пробелов
Имя переменной в такой, к примеру, команде присваивания
set ifacetk::options(use_tabbar) false # ifacetk::options(use_tabbar) — имя переменной
вовсе не означает, что скобки являются какой-то операцией, как могли бы предположить программисты на ALGOL-подобных языках. Скобки являются частью имени переменной, хоть и обрабатываются особым образом (запись foo(bar) означает переменную с именем "bar" в массиве с именем "foo"), поэтому нельзя писать так:
set ifacetk::options (use_tabbar) false
или так:
ifacetk::options( use_tabbar ) false
Временное исключение кусков кода конфигурации
Для временного исключения некоторого куска кода длиннее одной строчки удобно использовать стандартную идиому Tcl — условный оператор if с ложным условием, который компенсирует отсутствие в тикле "блочных" комментариев (в стиле "сишного" /* ... */), например:
Нужно отключить некую настройку, которая введена примерно так:
hook::add postload_hook {
do this
now do that
}
Запрещаем выполнение этого кода так:
if 0 {
hook::add postload_hook {
do this
now do that
}
}
При следующем старте Ткаббера всё, что находится внутри блоков if 0 { ... }, выполнено не будет.
Отдельные строчки удобнее комментировать символом "#", который вводит однострочный комментарий (который, впрочем, может быть продлён на следующую строку при помощи "\", за которым сразу же следует перевод строки).
Имейте в виду весьма необычное поведение комментариев в тикле: в отличие от "классических" языков, в тикле комментарии обрабатываются во время выполнения программы, а не являются чем-то вроде директив препроцессора. Невнимание к этому факту может привести как к ошибкам на стадии чтения конфига, например:
missing close-brace: possible unbalanced brace in comment
так и к ошибкам во время выполнения, например:
invalid command name "}"
Объясним "на пальцах": есть такой код:
proc foo {a b} {
if {some conditional expr} {
...
}
}
и вы хотите изменить условное выражение, закомментировав старое.
Разумный на первый взгляд способ
proc foo {a b} {
# if {some conditional expr} {
if {some other cond expr} {
...
}
}
вызовет ошибку интерпретатора на этапе формирования аргументов для команды proc, так как в комментарии есть несбалансированный символ "{", но этот комментарий игнорируется до фактического выполнения точки кода, в которой он находится, и символ "{" в комментарии "уравновешивается" символом "}", закрывающем тело процедуры, а скобка, открывающая тело процедуры, оказывается без пары.
Правильным решением будет, к примеру, такое решение:
# if {some conditional expr} { } <-- балансирующая скобка
if {some other cond expr} {
...
}
или такое:.
# if {some conditional expr} {
if {some other cond expr} {
...
}
# } <-- балансирующая скобка
или такое:
if {some other cond expr} { # {some conditional expr}
...
}
Хардкорные подробности этих "странностей" описаны тут.
Хуки
Большинство полезных настроек использует механизм "хуков" — обработчиков различных событий Ткаббера; подробнее о них можно прочитать тут. Здесь приведены некоторые неочевидные особенности работы с ними.
На каждый хук можно "навесить" произвольное количество обработчиков.
С другой стороны, код для одних и тех же хуков можно объединять. К примеру, вы хотите использовать два рецепта, которые вешают свой код на один и тот же хук:
hook::add finload_hook {
do_this
do_that
}
...
hook:add finload_hook {
foo -config bar
}
ничего не мешает вам написать в конфиг:
hook::add finload_hook {
do_this
do_that
foo -config bar
}
То есть по сути это вопрос стиля.
Имейте, однако, в виду, что обработчики хуков могут иметь приоритет, и объединять код обработчиков, имеющих разный приоритет, естественно, нельзя.
Код обработчиков хуков выполняется интерпретатором тикля при помощи команды eval. То есть, если мы имеем, к примеру,
hook::add finload_hook {
frobnicate foo
}
то этот код в соответствующий момент будет выполнен примерно так:
eval {
frobnicate foo
}
что в данном случае приведёт к выполнению команды
fronbnicate foo
Ситуация усложняется в том случае, когда коду хука передаются некоторые параметры (аргументы). Пример такого хука — open_chat_post_hook: он принимает параметры chatid и type (описание хука см. в официальной документации). Текущие значения параметров хука "присоединяются" (или "дописываются через пробел", если так мыслить удобнее) к коду хука, после чего полученная конструкция вычисляется с помощью eval. В этом случае выполнение, скажем, такой реализации обработчика данного хука:
hook::add open_chat_post_hook {
frobnicate foo
}
будет произведено так:
eval {
frobnicate foo
} some_chatid some_type
что "развернётся" командой eval в следующий код:
frobnicate foo some_chatid some_type
В подавляющем случае это не то, чего хотел достичь автор хука.
Решение проблемы обработчиков "параметризованных хуков" — реализация их в виде процедуры тикля. Пример:
proc tweak_something {chatid type} {
frobnicate foo
}
hook::add open_chat_post_hook tweak_something
будет выполнено как
eval tweak_something some_chatid some_type
то есть, в результате, как простой вызов процедуры с двумя параметрами. Что и требовалось получить.
Тестирование конфигурации
Несмотря на то, что подавляющее большинство настроек Ткаббера "применяются" сразу, без перезагрузок, некоторые настройки требуют перезапуска Ткаббера. К ним относятся, к примеру, настройки шрифтов, подключение "цветовых схем", изменение стиля интерфейса (многооконный/с табами) и другие. Также перезапуска Ткаббера требует установка/обновление некоторого пакета Tcl, который может использоваться Ткаббером.
Удобнее (и правильнее) всего не перезапускать Ткаббер, а запускать "рядом" его вторую копию.
Достоинства этого способа:
- Не мешает оставаться на связи, так как основной Ткаббер продолжает работать;
- Может потребоваться несколько раундов редактирования и перезапуска Ткаббера чтобы "допилить" настройку, которую вы делаете, до нужной вам кондиции.
Недостатки:
- Ткаббер прожорлив и медленно стартует, поэтому на некоторых очень старых машинах запуск второй копии Ткаббера нежелателен;
- При запуске второй копии Ткаббера, если вы собираетесь соединяться из неё с сервером, требуется соблюдать некоторые меры предосторожности, о которых рассказано ниже.
Как запустить второй Ткаббер, не помешав первому
Большинство требуемых мер предосторожности требуется только если вы собираетесь подключаться к серверу из второй копии Ткаббера.
"Общая" проблема — одна: соревнование при записи настроек. Суть её в том, что все N запущенных "рядом" Ткабберов будут сохранять настройки в один и тот же файл custom.tcl (и некоторые другие). Ткаббер использует весьма прямолинейный, но разумный метод сохранения настроек: при изменении некоторой настройки файл custom.tcl тут же перезаписывается, отражая новое состояние конфигурации. Понятно, что после редактировании настроек параллельно в нескольких копиях Ткаббера, сохранённым останется набор настроек того Ткаббера, в котором он менялся последним по времени.
Имейте в виду, что это относится только к сохранению настроек "для текущей и следующих сессий"; установка настройки "только для текущей сессии" не вызывает перезапись custom.tcl.
Теперь перейдём к мерам предосторожности, которые нужно соблюдать при одновременном соединении с сервером из нескольких копий Ткаббера.
Они чуть отличаются для случев:
- Подключение к тому же серверу с тем же логином;
- Подключение к другому серверу, или к тому же, но с другим логином.
Подключение с тем же логином
- Обязательно в окне логина поставьте ресурс отличный от ресурса основного Ткаббера — это позволит Вам создать разные сессии (сеансы работы) с сервером;
- Там же можете выбрать приоритет, меньший, чем у основной копии. Для чего это может пригодиться, читайте в указанной заметке про приоритеты.
Теперь можете подключиться — будет создано второе подключение с тем же логином (к тому же аккаунту), но одно будет являться другой сессией и не будет "пересекаться" с первой.
Прежде чем продолжить тестирование, усвойте ещё несколько вещей:
- Подключаясь к тем же конференциям, в которых вы сидите из основной копии Ткаббера, выбирайте другой ник — ваш уже занят (вами);
- При таком подключении поведение сообщений, приходящих от гейтов, зависит от приоритетов запущенных копий Ткаббера.
Подключение с другим логином (или к другому серверу)
В этом случае единственное, о чём нужно думать, это регистрация на гейтах в другие системы быстрого обмена сообщениями: к примеру, если как на первом, так и на втором аккаунте вы зарегистрированы на гейте в ICQ, логин на второй аккаунт также подключит вас к гейту, что вызовет отключение от гейта первого аккаунта. Причина этого не в гейте, а в самой "вражеской" системе быстрого обмена сообщениями, которая не позволяет делать одновременные подключения к одному своему аккаунту с разных IP-адресов (которыми будут выступать IP-адреса гейтов).
Если вы столкнулись с этой проблемой, временно отключитесь ("отлогиньтесь") от гейтов в основном Ткаббере.
Тестирование конфигурации "вживую"
Пока в качестве примера можно изучить это.
