|
Название | IniManager |
Имя файла (*.txt) | IniManager.txt |
Описание | Создает и обновляет файлы конфигурации для разных целей |
Автор | Вахмурка |
Параметры |
"b"|"s"|"r"|"c"|"n"|"i"|"имя_конфигурации" (см. комментарии) |
Вызываемые плагины | ini, file, vec, win, miscplugin |
Версия | 3.0 |
Дата обновления | 03.03.15 |
;;Если wincmd.ini находится не в директории Windows, укажите его полный путь: static Config = env("WINDIR") ++ "\wincmd.ini" local hwnd = win.handle("c=TTOTAL_CMD") local TotalPath = file.folder(win.exepath(hwnd)) local Total = TotalPath ++ "\" ++ ifelse(arg(2), arg(2), win.exename(hwnd)) ++ ".exe" ;"\inis\" – имя поддиректории %COMMANDER_PATH%, в которой лежат разные файлы конфигурации local Path = TotalPath ++ "\inis\" local Backup = Path ++ "Backup.ini" local j, k, OneSec, OneKey, NewKeys, MainKeys, Counter, NewValue, MainValue, Name local MainSections, MainNumber, TempConf static I = ".ini" static IMS = "IniManager Script" ini.error_dialog_off() v = vec.createfromwords("left right lefttabs righttabs") if(v <= 0) do messagebox("ok error", "Vector not created", "VEC plugin error #1") quit endif if(arg(1) == "b") do file.copy(Config, Backup) quit elseif(arg(1) == "r") do file.copy(Backup, Config) win.sendmessage(hwnd, 0x400+51, 24340, 0) for(j = 0; j < 4; j++) ini.delete_section(Backup, v[j]) ini.copy_section(v[j], Backup, v[j], Config) endfor do(Total) quit elseif(arg(1) == "s") do jump Save elseif(arg(1) == "c") do jump Copy elseif(arg(1) == "n") do jump New elseif(arg(1) == "i") do jump Insert endif Name = arg(1) TempConf = miscplugin.tempfilename(Name, Path) ++ I Name = Path ++ Name ++ I MainSections = ini.enum_sections(Config) MainNumber = line(MainSections, 0) for(j = 1; j <= MainNumber; j++) OneSec = line(MainSections, j) MainKeys = ini.enum_keys(Config, OneSec) Counter = line(MainKeys, 0) if(ini.check_exists(Name, OneSec) == 2) do for(k = 1; k <= Counter; k++) OneKey = line(MainKeys, k) if(ini.check_exists(Name, OneSec, OneKey) == 3) do NewValue = ini.get(Name, OneSec, OneKey) else NewValue = ini.get(Config, OneSec, OneKey) endif ini.set(TempConf, OneSec, OneKey, NewValue) endfor else ini.copy_section(OneSec, Config, OneSec, TempConf) endif endfor for(j = 0; j < 4; j++) ini.delete_section(TempConf, v[j]) ini.copy_section(v[j], Name, v[j], TempConf) endfor do(Total, "/n /i=" ++ TempConf) quit @Save win.sendmessage(hwnd, 0x400+51, 580, 0) MainSections = ini.enum_sections(Backup) MainNumber = line(MainSections, 0) Name = inputcancel("Input new INI file name") Name = Path ++ Name ++ I flag set 1 for(j = 1; j <= MainNumber; j++) OneSec = line(MainSections, j) if(ini.check_exists(Config, OneSec) == 2) do MainKeys = ini.enum_keys(Backup, OneSec) Counter = line(MainKeys, 0) for(k = 1; k <= Counter; k++) OneKey = line(MainKeys, k) if(ini.check_exists(Config, OneSec, OneKey) == 3) do NewValue = ini.get(Config, OneSec, OneKey) MainValue = ini.get(Backup, OneSec, OneKey) if(NewValue != MainValue) do ini.set(Name, OneSec, OneKey, NewValue) flag clear 1 endif endif endfor endif endfor if(pproflag(1)) messagebox("ok warning", "No changes detected", "INI file not created") for(j = 0; j < 4; j++) ini.delete_section(Backup, v[j]) ini.copy_section(v[j], Config, v[j], Name) endfor quit @Copy win.sendmessage(hwnd, 0x400+51, 580, 0) Name = file.listfiles(Path ++ "*" ++ I) v = vec.createfromlines(Name, 1) if(v == 0) do messagebox("ok error", "Vector not created", "VEC plugin error #2") quit endif Counter = vec.length(v) vec.insert(v, Counter, Config) Counter++ if(TempConf) vec.insert(v, Counter, TempConf) Name = vec.makelines(v) local From = pickstring(Name, "Select FILE to copy FROM") if(not From) do quit MainSections = ini.enum_sections(From) NewValue = "Select SECTION in file '" ++ From ++ "' to copy FROM" OneSec = pickstring(MainSections, NewValue) if(not OneSec) quit NewValue = "Select FILE to copy section '" ++ OneSec ++ "' TO" local To = pickstring(Name, NewValue) if(not To) quit ini.copy_section(OneSec, From, OneSec, To) quit @New TempConf = miscplugin.tempfilename() ++ I do(Total, "/n /i=" ++ TempConf) quit @Insert local Point, From, To, Dir local Str = "~Dir=Copy direction (Source > Target)??|[Dirmenu] > [user]|[user] > [Dirmenu]," Str ++= "From=Source item number to copy (FROM),To=Source item number to copy (TO)," Str ++= "Point=Target section number to copy AFTER" Name = inputdialog(Str, "Copy Keys from One Section to Another") if(not Name) quit v[0] = "user" v[1] = "Dirmenu" local Source = v[not Dir] local Target = v[Dir] MainKeys = ini.enum_keys(Config, Target) for(j = line(MainKeys, 0); j >= 0; j--) Name = line(MainKeys, j) NewKeys = ini.get(Config, Target, Name) Counter = 0 NewValue = "" for(k = 0; k <= length(Name); k++) MainValue = Name[k] if(miscplugin.is_int(MainValue)) do Counter ++= MainValue else NewValue ++= MainValue endif endfor if(Counter < Point) do break else MainNumber = Counter + To - From + 1 ini.set(Config, Target, NewValue ++ MainNumber, NewKeys) endif endfor MainKeys = ini.enum_keys(Config, Source) for(j = 1; j <= line(MainKeys, 0); j++) Name = line(MainKeys, j) NewKeys = ini.get(Config, Source, Name) Counter = 0 NewValue = "" for(k = 0; k <= length(Name); k++) MainValue = Name[k] if(miscplugin.is_int(MainValue)) do Counter ++= MainValue else NewValue ++= MainValue endif endfor if(Counter >= From && Counter <= To) do MainNumber = Counter - From + Point ini.set(Config, Target, NewValue ++ MainNumber, NewKeys) endif if(Counter > To) break endfor
На первый взгляд может показаться, что с введением в четвертой версии копирования в фоне, а в шестой – вкладок, а в версии 8.50 – поиска в отдельном процессе, отпала необходимость в запуске нескольких копий Total Commander. Однако со временем оказывается, что такая необходимость стала менее насущной, но вовсе не исчезла.
Самый распространенный случай, когда она возникает – групповое переименование. При большом числе файлов для переименования с полями content-плагинов процесс может занять несколько десятков минут, в течение которых работа с Total Commander (точнее, с текущей ее копией) оказывается невозможной. Скрипт работает вне зависимости от того, установлен или сброшен флаг "Allow only 1 copy of Total Commander at a time".
Второй случай, когда предлагаемый скрипт может оказаться полезным – необходимость работы в Total Commander с разными настройками. К примеру, для определенных проектов нужен особый набор плагинов, который при обычной работе не используется и только мешает. То же самое может касаться настроек колонок, цветовых схем, горячих клавиш и т. п.
В Total Commander предусмотрено решение и этой проблемы – ключ /i командной строки, позволяющий загружать заданный файл конфигурации вместо оного по умолчанию wincmd.ini. Однако оказывается, что это решение не всегда удобно.
Представьте себе, что вы кропотливым трудом создали некий альтернативный файл конфигурации, отличающегося от стандартного ("основного") набором плагинов. За те несколько месяцев, когда новый файл был не нужен, вы успели внести много нового – определили несколько горячих клавиш (и основательно к ним привыкли), добавили множество пунктов в Start menu, изменили цвета, создали пользовательские виды с полями content-плагинов, и т. д. В итоге, загрузив другой файл конфигурации, вы больше проиграли, чем выиграли – клавиши работают "по-старому", цветовая гамма выглядит ужасно, в меню (Start и Directory hotlist) не хватает самого необходимого... Короче говоря – интерфейс непривычен и не соответствует вашему текущему уровню.
Через все это я в свое время прошел и наконец-то сподобился предложить себе (ну и остальным заодно) если не панацею, то некое приближение к ней.
Скрипт выполняет шесть разных функций в зависимости от значения единственного параметра. Первая функция – сохранение текущей конфигурации, задается параметром "b" (от "backup"). Резервная копия основной конфигурации сохраняется в поддиректории inis рабочей директории Total Commander и получает имя Backup.ini. Кстати, операцию резервного копирования имеет смысл проводить и перед тем, как, к примеру, затевать какие-либо смелые экспериметы. Если их результат окажется неудачным, конфигурация восстанавливается с помощью параметра "r" (от "restore").
Итак, шаг первый – сохранение основной конфигурации ("b"). Затем мы начинаем изменять настройки, подключая и отключая плагины, подбирая цвета, создавая новые горячие клавиши, настраивая шаблоны поиска и т. д. После того, как создание новой конфигурации закончено, вызываем скрипт с параметром "s" (от "save"). На запрос вводим подходящее имя новой конфигурации (для определенности MyConfig) и получаем файл MyConfig.ini, содержащий только те настройки, которые отличаются от соответствующих настроек основной конфигурации. Полученный файл, разумеется, можно просмотреть и подправить, если необходимо. Упрощает задачу "чистовой обработки" то, что файл MyConfig.ini будет содержать относительно немного разделов и ключей. Этим завершается шаг второй.
Шаг третий – если вы собираетесь использовать новую конфигурацию довольно часто (по меньшей мере раз в несколько месяцев), то можно создать кнопку на панели с вызовом данного скрипта, причем параметром является имя конфигурации. В нашем случае параметр команды запуска будет выглядеть как runfile.IniManager("MyConfig").
Таким образом, можно наплодить конфигураций под все проекты, на все случаи жизни, и каждой из них сопоставить кнопку и/или горячую клавишу. Все шаблоны конфигураций хранятся там же, где и резервная копия основной конфигурации.
Когда создание разных конфигураций завершено, запускаем скрипт с параметром "r" и возвращаемся к основной конфигурации.
Время для четвертого шага придет, возможно, очень не скоро, когда в основную конфигурацию будет внесено сколь угодно много изменений. Зато можно быть уверенным – запустив скрипт с именем другой конфигурации (например, через созданную кнопку), мы, соответственно, получим изменения только в настройках, которые были сохранены на втором шаге. Таким образом, если целью создания конфигурации MyConfig был новый набор плагинов, то именно он, и только он, будет отличаться от основного. Все остальные настройки будут точно такими же, как и минуту назад.
Может показаться, что скрипт мало полезен в тех случаях, когда предполагается проводить групповое переименование. Я тоже так думал. Но вот допустим, что вы просто открыли вторую копию Total Commander, а в первой запустили переименование. Но к тому моменту, как процесс завершится, вы уже успеете, к примеру, открыть несколько файлов в Lister'е. Теперь, если закрыть вторую копию как более не нужную, Lister закроется вместе с ней, и придется начинать все заново. Поэтому, скорее всего, до конца сеанса у вас так и останутся запущенными две копии... Вы в них не путаетесь?! Завидую. Настройки почти одинаковые, внешний вид – тоже... Мало того – обе копии используют один и тот же файл конфигурации. Конфликтов я, правда, в такой ситуации не наблюдал, но мелкие неприятности случались. Так что по всем признакам лучше запускать вторую копию со второй конфигурацией, третью – с третьей, и т. д.
Еще одна функция скрипта, стоящая несколько особняком от ранее описанных – копирование раздела одного файла конфигурации в другой файл. Собственно говоря, термин "копирование" не вполне уместен, поскольку старое содержимое раздела удаляется и полностью заменяется новым. Поэтому лучше было бы вести речь о "замене", но Alan Campbell, автор плагина ini, по одному ему известным причинам, называет эту операцию "copy", а соответствующую функцию – "copy_section".
Итак, запустив скрипт с параметром "c" (copy), мы последовательно получаем три запроса. Прежде всего необходимо выбрать имя файла конфигурации, из которого будет копироваться раздел. Чтобы не запутаться, что куда копируется, следует внимательно читать заголовок окна. В список файлов конфигурации входят следующие файлы:
Второй запрос будет содержать список разделов выбранного файла. Наконец, третье и последнее окно выдаст тот же список, что и первое, только теперь необходимо выбрать файл, в который будет скопирован раздел.
Рассмотрим пример. Как мы помним, файл конфигурации с другим списком плагинов был нами создан и назван MyConfig.ini. Если запустить скрипт с параметром "c", первое диалоговое окно будет содержать следующие файлы:
Напомним, что файл Backup.ini был создан тогда, когда мы создавали MyConfig.ini, поэтому, возможно, его разделы давным-давно потеряли актуальность, а возможно, напротив, содержат нечто, ценность чего вы в свое время не осознали.
Теперь предположим, что мы запустили вторую копию Total Commander на основе MyConfig.ini, и тогда список дополнится файлом с именем типа
D:\Documents and Settings\Administrator\Local Settings\Temp\MyConfig5.ini
(само собой, пути соответствуют моему компьютеру).
Скорее всего, возникнет необходимость скопировать раздел из MyConfig5.ini в MyConfig.ini. Пусть это будет раздел [ContentPlugins] – потому что мы добавили несколько новых плагинов. Итак, в первом окне выбираем
D:\Documents and Settings\Administrator\Local Settings\Temp\MyConfig5.ini
и нажимаем "ОК". Во втором окне выберем раздел ContentPlugins, и, наконец, в третьем окне d:\Utils\TotalCmd\inis\MyConfig.ini, тем самым обновив последний.
Еще одна функция скрипта – запуск Total Commander'а с пустой конфигурацией (параметр "n"). Это – первый шаг при обнаружении бага. Ведь вполне возможно (и скорее всего, так оно и есть), что баг вызван не ошибками в самом Total Commander'е, а ошибками в плагинах или внешних утилитах. Тогда в новой, пустой конфигурации он неминуемо исчезнет. Затем начинают поиск "злодея", либо копируя разделы один за другим из основного файла в новый, либо последовательным комментированием раздела основного.
Наконец, последняя функция скрипта – копирование ключей из одного раздела в другой с их перенумерацией. Это довольно специфичная задача, но рано или поздно с ее актуальностью столкнется каждый.
Известно, что максимальное число пунктов обоих пользовательских меню, содержащихся в разделах [user] и [DirMenu], равно 200. Практика показала, что достижение этого предела – лишь вопрос времени. Допустим, что у вас в [DirMenu] 197 пунктов, и вы решаете перенести часть меню в раздел [user] (пусть там еще достаточно места). Но как? Надо либо вручную менять номера у всех ключей, либо вставлять большое число пустых, фиктивных команд, "заглушек", чтобы потом их же и удалить. К тому же, даже тогда простое перетаскивание создать много сложностей для структурированного, многоуровневого, меню, потому что перемещать пункты в обоих списках средствами ТС можно лишь по одной!
В случае благополучного результата удалять ключи из раздела [DirMenu] можно вручную.
Второй параметр скрипта полезен при запуске 64-битной версии Total Commander'а: для этого достаточно написать "TOTALCMD64". При отсутствии параметра запускается TOTALCMD.exe.
В заключение следует отметить, что скрипт может быть легко приспособлен для управления файлами конфигурации любой другой программы, хранящей свои настройки в файлах формата INI и позволяющей загружать заданный файл конфигурации.
На главную | Все о Total Commander | PowerPro | PowerPro & Total Commander |