|
Title | IniManager |
File Name | IniManager.txt |
Description | Creates and updates configuration files for different purposes |
Author | Vochomurka |
Parameters |
"b"|"s"|"r"|"c"|"n"|"i"|Configuration_Name" (see Comments) |
Plugins Called | ini, file, vec, win, miscplugin |
Version | 3.0 |
Updated on | 03.03.15 |
;;If wincmd.ini is not in Windows directory, indicate its path implicitly: 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\" – subdirectory of %COMMANDER_PATH% to store configuration files 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
Is there a necessity to run several copies of Total Commander? In the old days it was frequently. Fourth version allowed to copy/move in background, sixth version introduced the folder tabs, finally, version 8.50 aloows to search in separate process. But even now there are at least one operation when the current instance of Total Commander is not available for a certain (often very long) time: multi-rename, because it cannot be sent to background. Before starting long-term rename it is convenient to run another instance and work there while the first instance is working.
There is one more case when another instance of Total Commander is necessary – different configurations. For example, to work with special projects or problems we could need some specific plugins useless for our common tasks. The same concerns different custom views, hotkeys, Lister settings, packers, and so on.
It seems that the solution of the described problem is the /i command line key. But in reality this solution has at least one disadvantage.
Suppose we had spent a long time to create some alternative configuration differing from the default one by the plugin set. Some weeks (months?) later this set became needed again. But after running the new Total Commander instance with this configuration we realize that plugins are the only thing we like. Why? Because during the time we have not been using the alternative configuration the default one has heavily changed. Hotkeys, colors, start and directory menus – all this looks "old-fashioned", "outdated", and thus very inconvenient.
Has it ever happened to you? I am pretty sure it has.
It was just an introduction. Now it's time to talk about the script itself.
The script has six functions depending on the only parameter. First function is to backup the default configuration file (usually wincmd.ini) and is activated by the "b" parameter. Default configuration file is just copied to the inis\ subdirectory of the Total Commander installation folder. It's a good idea to make the backup before any grand-scale experiment with the settings. If this experiment fails, we could restore the initial state by running the same script with the "r" ("restore") parameter. It's the second function.
So, the first step is to backup the "main" (default) configuration ("b"). Then we can fearlessly do anything we want: loading/unloading plugins, changing colors, defining new and disabling old hotkeys, saving and deleting the search templates, and so forth. After the new configuration seems to be finished, the third function of script can be used. This function deals with "saving" the current (changed) configuration and is invoked by the "s" ("save") parameter. The new configuration must be named (for example, as MyConfig). What is happening next? In the inis\ subdirectory the MyConfig.ini file is created. This file contains only the settings that differ from those of the main configuration. The resulting file can be viewed and edited. It's quite simple because the sections and keys are less numerous than those of the main configuration. For example, if the only thing we have changed is the content plugin set, then the MyConfig.ini contains only one section [ContentPlugins]. This ends the second step.
Third step is to create a button or hotkey calling this script with a parameter equal to the new configuration name (runfile.IniManager("MyConfig") in our case). If we want we can create as many configurations as we would probably need. All the configuration files are stored in the same place as the backup copy of the main configuration – that is, in the inis\ subdirectory.
After saving each of new configurations we can restore the main one by running the script with the "r" parameter.
Henceforth we do not care about how much time would elapse till we need any of the saved configurations, and this is the main goal of the script presented. That is, running the script with the configuration name ("MyConfig") we get changes only in those settings that have been saved on the second step. If the MyConfig.ini file contains the only [ContentPlugins] section, then all other settings are exactly the same as in the default (current, one-second-ago) configuration.
Due to the /N command line parameter the script functioning does not depend on the "Allow only 1 copy of Total Commander at a time" option in the configuration.
The fifth function of the script covers all other needs in managing configurations. By running the script with the "c" ("copy") parameter we will invoke three dialog windows in turn.
First window allows to pick the configuration file whose section(s) we would like to copy from (you should carefully read the window caption to learn this). The list of configuration files available comprises:
For example, on my computer the list of available configuration files is as follows:
Picking the desired file moves on the second dialog window with the list of sections containing in the file chosen. Pick one section to copy and press "OK". The third dialog window contains the same file list as the first window, but now you should pick the file to copy section to. After pressing "OK" the indicated section of this file will be completely replaced by the same section of the file picked in the first window. Be careful!
Let's consider an example. We have run the script with the "MyConfig" parameter and thus there are two instances of Total Commander currently loaded. The above list is therefore enriched by the following configuration file:
D:\Documents and Settings\Administrator\Local Settings\Temp\MyConfig5.ini
The same name can be retrieved by picking "Help\About" menu of the second instance of Total Commander.
Further, suppose we want to take the [ContentPlugins] section from MyConfig5.ini and replace the same section in MyConfig.ini. Run the script with the "c" parameter and pick the file
D:\Documents and Settings\Administrator\Local Settings\Temp\MyConfig5.ini
In the second window pick the [ContentPlugins] section, and, finally, in the third dialog pick the MyConfig.ini file. As a result, the content plugins of the MyConfig.ini configuration will be updated.
The sixth function is to run Total Commander with new (the "n" parameter), empty configuration. It is required to check whether some found bug is specific to Total Commander itself, or is a result of plugin, setting conflict, or external utility operation. Being run with an empty configuration, Total Commander has the settings as though we have just installed it. So, if the bug persists, it is Total Commander's one; if it disappears, there is no need to write a bug report.
Finally, the seventh function is copying keys from one section to another, with their synchronous renumbering. It is a rather specific task, but everyone would need it sooner or later.
It is known that greatest number of items for both user's menus from sections [user] and [DirMenu] is 200. It is obvious that reaching this limit is just a matter of time. Suppose you have 197 items in the [DirMenu] section, and you decide to copy some of them to section [user] (let it have enough space). Without the script you have either to edit the configuration manually, or to insert there "stubs": empty, fake items – just to delete them later. Further, even simple drag-n-drop is sophisticated problem for structured, multilevel menu, because Total Commander does not allow to drag-n-drop many items at a time!
Second parameter, if specified, allows to run the 64-bit version of Total Commander. In this case the "TOTALCMD64" parameter is specified. By default the TOTALCMD.exe is run.
All Scripts | Total Commander | TotalCmd.net | PowerPro |