﻿Utilities for logging, i18n, storing plugin options/states and so on

Author: Andrey Kvichansky    (kvichans on github.com)
License: MIT

Состав библиотеки.

============
1. log
Функция log для трассировки переменных с отметками о времени и месте вызова.
Описание
- Встроенное применение str.format - результаты таких вызовов совпадают
    log(s, args, kwargs)
    log(s.format(args, kwargs))
- Автоматический отсчет времени.
- Автоматическое определение места вызова.

Примеры:
Простой вызов  
    log('a={}', 1)
    выводит в sys.stdout строку
    [12.34"]fn:123 a=1
    Пояснение 
    [12.34"]        Отметка времени, прошедшего с момента запуска трассировки.
    fn              Имя модуля/функции/метода, из которого был вызов log.
    123             Номер строки файла, в которой находится log.
    
Другие возможности
    log('###')      Выводит в виде одной дополнительной строки "стек вызовов"
                    ### fn:123 fn2:354 <module>:89
    log('¬¶')       Автоматически заменяются "¬" на chr(9), "¶" на chr(10).

Перенаправление вывода
    Чтобы трассировка попадала в файл dir/my.log нужно вызвать
        Tr.tr=Tr('dir/my.log')
    Чтобы вернуть трассировку в sys.stdout нужно вызвать
        Tr.tr=Tr()
        
============
2. (i18n) get_translation
Утилита для подстановки строк на текущем языке Куд.
Способ применения
    В своем модуле сделать назначение
        _   = get_translation(__file__)
    В тех местах, где нужны переводы строковых констант сделать их применение так
        msg(_('my text'))
После этого сбор всех таких констант и их перевод на нужный язык возможен через применение
- Штатной Питон утилиты pygettext
- Редактора типа poedit
Переключение языков происходит синхронно с Куд.

============
3. Запись и чтение данных из хранилища в json формате.
Цель - предоставить плагинам средство для хранения настроек/состояний.
Запись
    def set_hist(key_or_path, 
                 value=None, 
                 module_name='_auto_detect', 
                 kill=False, 
                 to_file=PLING_HISTORY_JSON)
Чтение
    def get_hist(key_or_path, 
                 default=None, 
                 module_name='_auto_detect', 
                 to_file=PLING_HISTORY_JSON)

- Место файла для хранения. 
Файл задается параметром to_file. Если он не задан, то используется
    settings/plugin history.json 
Если значение параметра to_file не является полным путем, 
то оно используется как указание файла в папке settings.

- Совместное хранение.
Чтобы разные плагины могли хранить свои данные в одном файле, используется параметр module_name.
Если он не задан, то внутри json дерева, будет ветка, имя которой совпадает именем модуля, 
из которого вызываются set_hist/get_hist. Имя ветки можно задать явно. 
При вызове с
    module_name=None
ветка не образуется, и все данные попадают в корень json дерева. 
Это может быть удобно, если плагин использует собственный файл.

- Место в файле.
Параметр key_or_path указывает ключ в json дереве, который нужно использовать для записи/чтения.
Либо key_or_path это строка. Тогда это прямое указание ключа (может быть в ветке module_name).
Либо key_or_path это список строк. Тогда это указание на последовательность прохода по json дереву.
При записи все промежуточные узлы дерева всегда создаются. 
    Но если уже существующий ключ, указан как промежуточный узел, то бросается KeyError.

- Удаление ключей и веток.
Если в set_hist указан kill=True, и указанный в key_or_path ключ (или ветка) найден(а), то он(а) удаляется.
При этом значение value игнорируется. 

- Комментарии и форматирование (сдвиги и промежутки) в хранилище не сохраняются.
В отличие от user.json, где комментарии не пропадают при обновлении через set_opt.

- Возврат
При чтении отсутствие любого из промежуточных узлов или конечного ключа приводит к возврату default.
При записи возвращается
- значение входного параметра value, если оно успешно записано в хранилище,
- значение, хранившееся по key_or_path, если его нужно было удалить (kill=True), и удаление произошло,
- None, если требовалось удаление (kill=True), но ключ не был найден.

============
4. Разное
- Короткие имена 
odict       = collections.OrderedDict
T,F,N       = True, False, None
c13,c10,c9  = chr(13),chr(10),chr(9)

- Короткий вызов str.format
Вместо 
    msg('a {}, b {}'.format('A', 'B'))
можно использовать
    msg(f('a {}, b {}', 'A', 'B'))

- Команда для запуска текущего файла так, чтобы из него был доступ к API редактора
    Execute current file as plugin
Сохраняет активный файл.
Очищает выдачу консоли.
Запускает файл.
