CopyComment

Название CopyComment
Имя файла (*.txt) CopyComment.txt
Описание Копирует/перемещает комментарий одного файла в комментарий другого
Автор Вахмурка
Параметры см. комментарии
Вызываемые плагины file, vec, miscplugin, ini
Иконка
Версия 1.1
Дата обновления 15.08.2013
local Move

if(ctrl)
	Move = 1

local Path = trim(file.folder(x9), " ", 3) ++ "\"
local Quote = esc(?+\"+, ?+\+)
Path = trim(Path, Quote, 3)
local Name = trim(file.nametype(x9), Quote, 3)
local Source = Path ++ "descript.ion"

if(not file.validpath(Source)) do
	messagebox("ok error", "File " ++ Source ++ " is missing", "No comment file")
	quit
endif

v = vec.create(1, 1)
if(v <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #1")
	quit
endif

w = vec.create(1, 1)
if(w <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #2")
	quit
endif

N = vec.create(1, 1)
if(N <= 0) do
	messagebox("ok error", "Vector not created", "VEC plugin error #3")
	quit
endif

local fh = file.open(Source, "r")
local i, Str, FileName, Comment, Result, Where, Ind, Comms, NotComms
local CR = esc(?+\n+, ?+\+)
local OpQuote = esc(?+\d171+, ?+\+)
local ClQuote = esc(?+\d187+, ?+\+)
local Delim = ". "
local Config = profolder ++ "scripts\ini\CopyComment.ini"

if(fh > 0) do
	for(not(file.eof(fh))) 
		Str = file.readstring(fh)
		if(not Str)
			continue

		FileName = word(Str, 1)

		if(file.validpath(Path ++ FileName)) do
			vec.insert(v, Comms, FileName)
			Comment = select(Str, length(FileName) - length(Str) + 1)
		else
			FileName = word(Str, 1, Quote)
			if(not file.validpath(Path ++ FileName)) do
				vec.insert(N, NotComms, Str)
				NotComms++
				continue
			endif

			vec.insert(v, Comms, Quote ++ FileName ++ Quote)
			Comment = select(Str, length(FileName) - length(Str) + 3)
		endif

		if(FileName == Name) do
			local mpDlgText = "File " ++ Name ++ " has the " ++ OpQuote ++ Comment
			mpDlgText = mpDlgText ++ ClQuote ++ " comment already!\n"
			mpDlgText = mpDlgText ++ "Choose where to put new comment relative "
			mpDlgText = mpDlgText ++ "to the existing one."
			local mpDlgCaption = "CopyComment Script"
			local mpIcon = "QUESTION"
			Ind = Comms

			Where = miscplugin.messagebox(1, "&Before", "&After", "&Instead", "&Cancel")
			if(Where == "&Cancel") do
				file.close(fh)
				vec.destroy(v)
				vec.destroy(w)
				vec.destroy(N)
				quit
			endif
		endif

		vec.insert(w, Comms, Comment)
		Comms++
		Result = Result ++ "File: " ++ FileName ++ ", comment: " ++ OpQuote ++ Comment
		Result = Result ++ ClQuote ++ CR
	endfor
else
	messagebox("ok error", "File not opened", "FILE plugin error #1")
	quit
endif

file.close(fh)

if(Comms == 0) do
	Str = "File " ++ Source ++ " seems to contain no file comments!"
	messagebox("ok warning", Str, "CopyComment Script")
	vec.destroy(v)
	vec.destroy(w)
	vec.destroy(N)
	quit
elseif(Comms == 1) do
	i = 0
elseif(Comms > 1) do
	Str = pickstring(Result, "Pick a comment to copy for file " ++ Name)

	if(not _pickedline_) do
		vec.destroy(v)
		vec.destroy(w)
		vec.destroy(N)
		quit
	endif

	i = _pickedline_ - 1
endif

file.delete(Source)
Str = w[i]

if(ini.check_exists(Config, "Options", "Delimiter") == 3)
	Delim = ini.get(Config, "Options", "Delimiter")

if(not Where) do
	vec.insert(v, Comms, ifelse(index(Name, " "), Quote ++ Name ++ Quote, Name))
	vec.insert(w, Comms, Str)
elseif(Where == "&Before") do
	w[Ind] = Str ++ Delim ++ w[Ind]
elseif(Where == "&After") do
	w[Ind] = w[Ind] ++ Delim ++ Str
elseif(Where == "&Instead") do
	w[Ind] = Str
endif

if(not Move && ini.check_exists(Config, "Options", "Move") == 3)
	Move = ini.get(Config, "Options", "Move")

if(Move == 1) do
	vec.delete(v, i)
	vec.delete(w, i)
elseif(Move == 2) do
	Str = "Delete comment " ++ OpQuote ++ w[i] ++ ClQuote ++ " of file "
	Str = Str ++ v[i] ++ "?"
	if(messagebox("yesno question", Str, "Move or copy comment") == 6) do
		vec.delete(v, i)
		vec.delete(w, i)
	endif
endif

if(ini.check_exists(Config, "Options", "Sort") == 3)
	vec.doublesortstring(v, w)

fh = file.open(Source, "w")

if(fh <= 0) do
	messagebox("ok error", "File not opened", "FILE plugin error #2")
	quit
endif

if(ini.check_exists(Config, "Options", "NotComments") == 3) do
	Str = ini.get(Config, "Options", "NotComments")
else
	Str = 0
endif

if(Str == 1) do
	for(i = 0; i < NotComms; i = i + 1)
		file.writeline(fh, N[i])
	endfor
	file.writeline(fh, CR)
endif

for(i = 0; i < vec.length(v); i = i + 1)
	file.writeline(fh, v[i] ++ " " ++ w[i])
endfor

if(Str == 0) do
	file.writeline(fh, CR)
	for(i = 0; i < NotComms; i = i + 1)
		file.writeline(fh, N[i])
	endfor
endif

file.close(fh)
vec.destroy(v)
vec.destroy(w)
vec.destroy(N)
Source = win.handle("c=TTOTAL_CMD")
win.sendmessage(Source, 0x400+51, 540, 0)

Комментарии:

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

Установите курсор на файл, к которому следует скопировать комментарий, и запустите скрипт. Далее возможны две ситуации: текущий файл уже имеет комментарий или нет. В первом случае будет предложено выбрать, где будет помещен новый комментарий относительно старого: до, после или вместо. Затем в обоих случаях в диалоговом окне можно будет выбрать файл, комментарий к которому необходимо скопировать. Это диалоговое окно, по сути дела, отображает descript.ion, но позволяет выбрать файл.

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

О запуске скрипта и передаче в него параметров следует сказать особо. Прежде всего рассмотрим, как отражаются в descript.ion файлы с пробелами в имени.

Пусть в некоторой директории имеются, среди прочих, следующие файлы:

FileName.ext
Name with Spaces.ext
Создадим к ним комментарии средствами Total Commander и получим следующий файл descript.ion:
FileName.ext Имя без пробелов
"Name with Spaces.ext" Имя с пробелами

То есть если имя файла содержит пробелы, при создании комментариев оно заключается в кавычки. Обычно пользователь и не знает об этом: ни во всплывающей подсказке к файлу, ни в виде "Show Comments Ctrl+Shift+F2" этих кавычек, естественно, не видно. Кавычки нужны самому Total Commander, чтобы отличить пробел внутри имени от пробела, отделяющего имя от комментария.

Оказалось, что передача параметра %N из Total Commander в скрипт PowerPro обычными средствами приводит к ошибке. Вот что по этому поводу сказал в своей статье Gregory: "TC очень умно ставит кавычки вокруг имен файлов - только если кавычки нужны. Эта умность здесь очень мешает, поскольку приходится все записывать в одну переменную x9, а потом разбирать, что же в нее записано".

Есть "корявый" выход из этой ситуации: задать параметром не %N, а %n. Но тогда имя файла Name with Spaces.ext будет передано как NAMEWI~1.EXT. Казалось бы, ничего страшного, однако комментарий к этому файлу, реально присутствуя в descript.ion, не будет показан ни во всплывающей подсказке, ни в виде "Show Comments". Понятно, что по умолчанию включен режим длинных имен (cm_SwitchLongNames).

Поэтому для передачи параметров %P и %N используется предложенный Gregory способ. А для этого поля кнопки Total Commander должны иметь несколько иной вид:

Command: d:\Utils\PowerPro\powerpro.exe *script runfile CopyComment=
Parameters: %P%N

Единственное, что может здесь измениться - путь к PowerPro (и имя скрипта CopyComment, если вы почему-то захотите его поменять). Обратите внимание на знак = в команде!

Можно создать файл конфигурации CopyComment.ini и поместить его в поддиректорию scripts\ini\. Файл имеет один раздел и 4 ключа:

[Options]
Delimiter=". "
Sort=1
Move=0
NotComments=0

Ключ Delimiter задает строку, вставляемую между старым и новым комментариями. По умолчанию (в том числе и при отсутствии файла конфигурации) это сочетание точки и пробела.

Ключ Sort, если присутствует и отличен от "", определяет сортировку файла descript.ion по алфавиту. Для отображения комментариев это не имеет значения, но может оказаться полезным при большом количестве описаний для ручного редактирования descript.ion.

Ключ Move определяет режим копирования/перемещения комментария. Ключ может принимать следующие значения:

  1. Копирование (по умолчанию, то есть при отсутствии ключа или файла конфигурации);
  2. Перемещение (комментарий будет скопирован от старого файла новому, а затем удален со старого);
  3. Запрос пользователю.

Если при запуске скрипта была нажата клавиша Ctrl, комментарий будет перемещен вне зависимости от наличия и значения ключа.

Наконец, ключ NotComments играет роль, если в файле descript.ion, помимо комментариев к файлам, содержится иной текст. Например, это может быть имя пользовательского вида, используемое скриптом WDXdetect. Ключ определяет, где будут (и будут ли) помещены все строки, не являющиеся парой "имя комментарий":

  1. После комментариев (по умолчанию);
  2. До комментариев;
  3. Нигде (удаление "лишних" строк).

В первых двух случаях используется пустая строка в качестве разделителя.


На главную Все о Total Commander PowerPro PowerPro & Total Commander