Tkabber Wiki

Config.tcl
Login

Материал из Tkabber Wiki

Содержание

Общие сведения

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

Чтобы понять место и роль файла config.tcl в процедуре загрузки Ткаббера, прочитайте ещё одну статью.

А после прочтения данного опуса можно со знанием дела переходить к "книге рецептов".

Файл конфигурации — config.tcl — читается на ранней стадии запуска Ткаббера и поэтому позволяет влиять на большинство аспектов работы этой программы.

Файл конфигурации выполняется интерпретатором тикля, который исполняет код Ткаббера. То есть этот файл является полноценной программой на тикле. Этот аспект следует хорошо прочувствовать, имея в виду беспрецедентный динамизм языка Tcl, позволяющий, среди прочего, переопределять процедуры Ткаббера и "перепаковывать" его окна.

Наиболее важные способы влияния на Ткаббер из его конфига можно условно разделить на три группы:

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

Важно осмыслить и запомнить следующее правило:

Ткаббер читает свой файл конфигурации ровно один раз за сеанс своей работы. Механизма "перечитывания" файла конфигурации нет (и не будет). Это означает, что после внесения изменений в файл конфигурации Ткаббер нужно перезапустить (а лучше для начала запустить его вторую копию "рядом" — см. ниже обсуждение тестирования конфигурации).

Ткаббер прекрасно обходится без config.tcl — как он, так и "парный" файл custom.tcl не нужны Ткабберу для запуска и работы. Поэтому, если у Вас нет файла config.tcl в условленном месте, просто создайте его сами.

Немного о синтаксисе тикля

Вообще, если вы собираетесь заняться "продвинутым" конфигурированием Ткаббера всерьёз (а не просто применять готовые рецепты не задумываясь), подумайте о самообразовании. Для начала можно порекомендовать такую последовательность действий:

  1. Изучить туториал;
  2. Изучить "додекалогию";
  3. Почитать классику (переведённую и на язык родных осин).

В качестве "быстрого погружения" для нетерпеливых предложим самые главные правила, про которые нужно помнить, занимаясь правкой конфига на тикле:

Любые пробельные символы являются разделителем слов 

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

Для группировки используются ограничители {} и "" 

Внутри {} не выполняется никакая интерпретация содержимого, внутри "" тикль выполняет подстановку переменных (нотация $имя_переменной), выполняет команды (нотация [команда аргументы...]) и раскрывает "escape-последовательности" (нотация \X, где "X" — спецсимвол).

Путевые имена файлов в Windows могут содержать прямые слэши 

То есть имя "C:/Program files/FrobozzMagic 2000" является вполне допустимым.

Строка без пробелов и группирующих символов также интерполируется 

То есть используйте прямые слэши под Windows, если данная строка — путевое имя файла.

Следствия этих правил:

Примеры:

# Путь в {} — подавляется любая интерпретация содержимого:
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

то есть, в результате, как простой вызов процедуры с двумя параметрами. Что и требовалось получить.

Тестирование конфигурации

Несмотря на то, что подавляющее большинство настроек Ткаббера "применяются" сразу, без перезагрузок, некоторые настройки требуют перезапуска Ткаббера. К ним относятся, к примеру, настройки шрифтов (в версиях Ткаббера ниже 0.11.0 либо у приверженцев Tk 8.4), подключение "цветовых схем", изменение стиля интерфейса (многооконный/с табами) и другие. Также перезапуска Ткаббера требует установка/обновление некоторого пакета Tcl, который может использоваться Ткаббером.

Удобнее (и правильнее) всего не перезапускать Ткаббер, а запускать "рядом" его вторую копию.

Достоинства этого способа:

Недостатки:

Как запустить второй Ткаббер, не помешав первому

Большинство требуемых мер предосторожности требуется только если вы собираетесь подключаться к серверу из второй копии Ткаббера.

"Общая" проблема — одна: соревнование при записи настроек. Суть её в том, что все N запущенных "рядом" Ткабберов будут сохранять настройки в один и тот же файл custom.tcl (и некоторые другие). Ткаббер использует весьма прямолинейный, но разумный метод сохранения настроек: при изменении некоторой настройки файл custom.tcl тут же перезаписывается, отражая новое состояние конфигурации. Понятно, что после редактировании настроек параллельно в нескольких копиях Ткаббера, сохранённым останется набор настроек того Ткаббера, в котором он менялся последним по времени.

Имейте в виду, что это относится только к сохранению настроек "для текущей и следующих сессий"; установка настройки "только для текущей сессии" не вызывает перезапись custom.tcl.

Теперь перейдём к мерам предосторожности, которые нужно соблюдать при одновременном соединении с сервером из нескольких копий Ткаббера.

Они чуть отличаются для случев:

Подключение с тем же логином

Теперь можете подключиться — будет создано второе подключение с тем же логином (к тому же аккаунту), но одно будет являться другой сессией и не будет "пересекаться" с первой.

Прежде чем продолжить тестирование, усвойте ещё несколько вещей:

Подключение с другим логином (или к другому серверу)

В этом случае единственное, о чём нужно думать, это регистрация на гейтах в другие системы быстрого обмена сообщениями: к примеру, если как на первом, так и на втором аккаунте вы зарегистрированы на гейте в ICQ, логин на второй аккаунт также подключит вас к гейту, что вызовет отключение от гейта первого аккаунта. Причина этого не в гейте, а в самой "вражеской" системе быстрого обмена сообщениями, которая не позволяет делать одновременные подключения к одному своему аккаунту с разных IP-адресов (которыми будут выступать IP-адреса гейтов).

Если вы столкнулись с этой проблемой, временно отключитесь ("отлогиньтесь") от гейтов в основном Ткаббере.

Тестирование конфигурации "вживую"

(!) Сделать: написать раздел

Пока в качестве примера можно изучить это.