Hotkeys plugin

Discuss and announce AkelPad plugins
  • Author
  • Message
Offline
Posts: 176
Joined: Sat Dec 24, 2011 4:05 pm

Post by F. Phoenix »

VladSh, ну да, вижу.

Общая карта хоткеев в любом случае полезна, хотя и возможность изменять бинды других плагинов прямо из диалога Hotkeys была бы удобна (например, посредством каких-нибудь сообщений целевому плагину). Но тут уж как реализуют.
rst256 wrote:Я вот хочу иметь гор. клавиши зависящие от типа файла, например помимо общего списка г.к. был бы дополнительный только для файлов "*.с;*.h;*.cpp;..." или хотя бы поддержку нескольких профилей гор. клавиш.
Мне тоже не хватает штатной поддержки "режимов файлов", как это сделано во многих IDE: не только для хоткеев, для пунктов меню и некоторых дефолтных настроек. Приходится изобретать скриптовые велосипеды, и других вариантов пока не вижу.

Вот, например:

Code: Select all

// Определяет тип файла по его расширению, имени или хедеру; и устанавливает соответствующее окружение AkelPad.

nTab = 4; // размер табуляции по умолчанию

AkelPad.Include("CommonFunctions.js");
AkelPad.Include("TextFunctions.js");
AkelPad.Include("CoderFunctions.js");

var hWndMain = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();

if (hWndEdit)
{
	pFile = AkelPad.GetEditFile(0);
	pSyntax = pCurrentSyntax = GetSyntaxAliasExtension();
	nCodePage = nCurrentCodePage = AkelPad.GetEditCodePage(0);
	nCurrentTab = AkelPad.SendMessage(hWndEdit, 3239 /*AEM_GETTABSTOP*/, 0, 0);
	pStartLine = GetLineText(0);

	if ((/<\?xml(?: version="\d\.\d")?(?: encoding="([\w-]+?)" ?)?\?>/.exec(pStartLine))) {pSyntax = "xml"; SetCodePageFromText(RegExp.$1);} // XML
	else if ((new RegExp('^#! */bin/sh', 'i')).test(pStartLine)) pSyntax = "sh";  // Bash
	else if ((new RegExp('^#! *(/usr/bin/(env )?)?perl', 'i')).test(pStartLine)) pSyntax = "pl";  // Perl
	else if ((new RegExp('^#! *(/usr/bin/(env )?)?python', 'i')).test(pStartLine)) pSyntax = "py";  // Python
	else if (pFile.search(/\.git\\?config$/) != -1) pSyntax = "ini"; // INI для файлов ".gitconfig" и ".git\config"
	else pSyntax = getFileExt(pFile); // Расширение
	
	switch (pSyntax)
	{
		case "bat": nCodePage = 866; break;
		case "coder": nCodePage = 1200; nTab = 8; break;
	}

	// Применение параметров кодировки, синтаксиса и табуляции
	if (nCodePage != nCurrentCodePage) AkelPad.Command(GetCodePageCommand());
	if (pSyntax != pCurrentSyntax) SetSyntax(pSyntax);
	if (nTab != nCurrentTab) AkelPad.SendMessage(hWndEdit, 3240 /*AEM_SETTABSTOP*/, nTab, 0);

	//AkelPad.MessageBox(hWndEdit, RegExp.$1 + " = " + nCodePage, WScript.ScriptName, 0 /*MB_OK*/);
}


// Устанавливает значение nCodePage по текстовому имени кодировки
function SetCodePageFromText(pEncoding)
{
	switch (pEncoding)
	{
		case "utf-8": nCodePage = 65001; break;
	}
}

// Возвращает команду AkelPad для переоткрытия документа в кодировке nCodePage
function GetCodePageCommand()
{
	switch (nCodePage)
	{
		case 1251:	return 4122; // ANSI
		case 866:	return 4123; // OEM
		case 20866:	return 4124; // KOI8-R
		case 1200:	return 4125; // UTF-16 LE
		case 1201:	return 4126; // UTF-16 BE
		case 65001:	return 4127; // UTF-8
		default:	return 0;
	}
}

Code: Select all

// Скрипт выполняет команды в зависимости от входящего параметры и активного синтаксиса
// Рассчитан на запуск из плагина Hotkeys
//
// Например:
// Call("Scripts::Main", 1, "SyntaxCommands.js", "help")		Ctrl+F1
// Call("Scripts::Main", 1, "SyntaxCommands.js", "help-alt")	Alt+F1
// для js-файлов будет вызвана либо справка по JavaScript, либо по Windows Script Host (если с альтом),
// для html - его справка

AkelPad.Include("CommonFunctions.js");
AkelPad.Include("CoderFunctions.js");
AkelPad.Include("TextFunctions.js");

var hWndEdit = AkelPad.GetEditWnd();
if (hWndEdit)
{
	var aCommands = AkelPad.GetArgLine().split(" ");
	var pSyntax = getFileNameOnly(GetSyntaxFile(hWndEdit));
	var pFile = AkelPad.GetEditFile(0);
	var oFileInfo = separateFile(pFile);

	//AkelPad.MessageBox(hWndEdit, pSyntax, WScript.ScriptName, 0 /*MB_OK*/);

	for (var i in aCommands)
	{
		// Общее \\
		if (aCommands[i] == "comments")
		{
			switch (pSyntax)
			{
				case "gettext-ex": AkelPad.Call("Scripts::Main", 1, "Gettext-ToggleComments.js"); break;
				case "wesnoth-wml-ex": AkelPad.Call("Scripts::Main", 1, "toggleComments.js", '-defaultExt="py"'); break;
				default: AkelPad.Call("Scripts::Main", 1, "toggleComments.js", "-preferLineComments=true"); break;
			}
		}

		switch (pSyntax + ":" + aCommands[i])
		{
			// JScript \\
			case "js:help":
				AkelPad.Call("Scripts::Main", 1, "LanguageHelp.js", "JavaScript.chm");
				break;
			case "js:help-alt":
				AkelPad.Call("Scripts::Main", 1, "LanguageHelp.js", "WSH.chm");
				break;
			case "js:lint":
				var oRun = RunCommand(AkelPad.GetAkelDir(1) + '/Tools/jsl.exe -process "' + getFileName(pFile) +
				                      '" -conf "' + AkelPad.GetAkelDir(1) + '/Tools/jsl.conf" -nologo -nofilelisting',
				                      getParent(pFile));
				AkelPad.Call("Log::Output", 4, oRun.Output, oRun.Output.length, 0);
				// AkelPad.Call("Log::Output", 1, AkelPad.GetAkelDir(1) + '/Tools/jsl.exe -process "' + getFileName(pFile) +
				//              '" -conf "' + AkelPad.GetAkelDir(1) + '/Tools/jsl.conf" -nologo -nofilelisting', getParent(pFile),
				//              "^(.+)\t(\\d+)", "/FILE=$1 /GOTOLINE=$2:1", 1251, 1251);
				break;

			// C#, C# Script, JScript.NET \\
			case "cs:compile": case "cs:run": case "jsnet:compile": case "jsnet:run":
				AkelPad.Command(4105 /*Save*/);
				var pApp = (pSyntax == "jsnet" ? "jsc" : oFileInfo.ext == "csx" ? "csi" : "csc");
				if (pApp == "csi")
				{
					pCommand = '"C:\\Program Files (x86)\\MSBuild\\14.0\\Bin\\csi.exe" "' + pFile + '"';
					AkelPad.Call("Log::Output", 1, pCommand, oFileInfo.path);
				}
				else
				{
					if (pApp == "csc") pCommand = '"C:\\Program Files (x86)\\MSBuild\\14.0\\Bin\\csc.exe" ';
					else pCommand = 'C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\jsc.exe ';
					var pHeader =  GetLineText(0);
					if (new RegExp("^//! ?" + pApp + "(?:\.exe)? (.+)").exec(pHeader) != null) pCommand += RegExp.$1 + ' '; // параметры компиляции
					pCommand += '"' + pFile + '"';
					AkelPad.Call("Log::Output", 1, pCommand, oFileInfo.path);
					if (WaitCompiler() == 0 && aCommands[i] == "run")
						AkelPad.Exec('"' + oFileInfo.path + oFileInfo.name + '.exe"', oFileInfo.path);
				}
				// Плагин Log нормально перехватывает компилятор roslyn для C# 6.0,
				// но те не, которые идут в составе .NET Framework, для них нужен такой код:
				/*
				// if (pSyntax == "cs")
				// {
				// 	var oRun = RunCommand(pCommand, oFileInfo.path);
				// 	if (oRun.ExitCode == 0) oRun.Output += "Компиляция файла успешно проведена.";
				// 	AkelPad.Call("Log::Output", 4, oRun.Output, oRun.Output.length, 0);
				// 	if (aCommands[i] == "run")
				// 		AkelPad.Exec('"' + oFileInfo.path + oFileInfo.name + '.exe"', oFileInfo.path);
				// }
				// else
				// {
				// 	AkelPad.Call("Log::Output", 1, pCommand, oFileInfo.path);
				// 	if (WaitCompiler() == 0 && aCommands[i] == "run")
				// 		AkelPad.Exec('"' + oFileInfo.path + oFileInfo.name + '.exe"', oFileInfo.path);
				// }
				*/
				break;

			// HTML \\
			case "html:help":
				AkelPad.Call("Scripts::Main", 1, "LanguageHelp.js", "HTML.chm");
				break;

			// Gettext \\
			case "gettext-ex:compile":
				var pProgram = "msgfmt"; // путь к msgfmt.exe
				var pOutFile = oFileInfo.name + ".mo";
				var pCommand = pProgram + ' "' + oFileInfo.name + '.' + oFileInfo.ext + '" -o "' + pOutFile + '"';
				AkelPad.Call("Log::Output", 1, pCommand, oFileInfo.path);
				WaitCompiler();
				break;

			// Wesnoth Markup Language \\
			case "wesnoth-wml-ex:lint":
				AkelPad.Call("Scripts::Main", 1, "WesnothWML-CheckSyntax.js");
				break;
		}
	}
}

function WaitCompiler()
{
	// ожидание завершения процесса компилятора
	var lpState, lpCode, nState = -1, nCode = -1;
	if (lpState = AkelPad.MemAlloc(4 /*sizeof(DWORD)*/ ))
	{
		if (lpCode = AkelPad.MemAlloc(4 /*sizeof(DWORD)*/ ))
		{
			while (nState != 0)
			{
				AkelPad.Call("Log::Output", 3, lpState, null, null, null, lpCode);
				nState = AkelPad.MemRead(lpState, 3 /*DT_DWORD*/ );
				nCode = AkelPad.MemRead(lpCode, 3 /*DT_DWORD*/ );
				WScript.Sleep(200);
			}
			if (nCode == 0) AkelPad.Call("Log::Output", 5, 'Компиляция файла успешно проведена.'); 
			AkelPad.MemFree(lpCode);
		}
		AkelPad.MemFree(lpState);
	}
	return nCode;
}

function RunCommand(command, dir)
{
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var wshShell = new ActiveXObject("WScript.Shell");
	do { var tempName = fso.BuildPath(fso.GetSpecialFolder(2), fso.GetTempName()); }
	while ( fso.FileExists(tempName) );
	var cmdLine = fso.BuildPath(fso.GetSpecialFolder(1), "cmd.exe") + ' /C ' + command + ' > "' + tempName + '"';
	wshShell.CurrentDirectory = dir;
	var exit_code = wshShell.Run(cmdLine, 0, true);
	var output = "";
	try {
		// var ts = fso.OpenTextFile(tempName, 1, false);
		// output = ts.ReadAll();
		// ts.Close();
		output = AkelPad.ReadFile(tempName);
	}
	catch(err) {
	}
	if ( fso.FileExists(tempName) )
	fso.DeleteFile(tempName);
	return {ExitCode: exit_code, Output: output};
}


(скрипты также выложил на glot.io - они довольно сырые, писал чисто для себя, и в таком виде их врядли поюзаете, но как пример сойдет)

Offline
Posts: 1
Joined: Thu Feb 01, 2018 1:10 pm
Location: USA
Contact:

Post by sifatu »

The command that directly opened the All keys window, without the main plugin dialog. So peeping is more convenient when I forget.

Offline
Posts: 6
Joined: Tue Nov 20, 2018 10:46 am

Как задать гор. клавиши для вызова синтаксич. темы XML?

Post by Arnold Shwartz »

День добрый.
Не смог разобраться и не нашел нигде ответа.
Проблема вот в чем.
Пишу тексты на AkelPad'е и какие-то фрагменты надо скрывать, чтоб не отвлекали. Поэтому заключаю их в теги, напр. <p> или <div>
А сам файл с расширением .txt. Каждый раз открывая приходится выбирать синтаксис из списка. Ну и т.д.
Если кто в теме, подскажите.

Offline
Posts: 6
Joined: Tue Nov 20, 2018 10:46 am

Как задать гор. клавиши для вызова синтаксич. темы XML?

Post by Arnold Shwartz »

Хотелось бы сразу при открытии файла задавать ему синтаксис (XML или HTML) с пом. гор. клавиш. Но как сделать с пом. плагина – фиг разберешь.
Подскажите, плиз, кто понимает.

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

Arnold Shwartz
1. Что должно означать "Ну и т.д."?
2. Почему бы просто не втащить соответствующие правила фолдинга из файла "html.coder" в файл "txt.coder"?
3. Чтобы установить синтаксическую тему вручную по горячей клавише, требуется ознакомится с файлом документации на плагин Coder "Coder-Rus.txt".
В нём, каким бы странным это не показалось, поясняется что и как.
Смотрим раздел "*** Внешний вызов Coder::Settings ***".
Выбираем один из двух подходящих вариантов:

Code: Select all

Call("Coder::Settings", 1, "EXTENSION")
Call("Coder::Settings", 6, "ALIAS")
Затем (можно даже пропустив изучение документации на плагин Hotkeys "Hotkeys-Rus.txt") открываете плагин Hotkeys::Main. Заполняете графы Имя/Команда/Клавиша.
Имя = любое
Команда = Call("Coder::Settings", 1, "html")
Клавиша = тут вам виднее.

Offline
Posts: 6
Joined: Tue Nov 20, 2018 10:46 am

Post by Arnold Shwartz »

opk44

Спасибо.

А еще вот это интересно:
2. Почему бы просто не втащить соответствующие правила фолдинга из файла "html.coder" в файл "txt.coder"?

Но не оч. в этом понимаю. Чтобы велосипед не изобретать, чуть подробнее – как это можно сделать?

"Ну и т.д." – имел в виду, что приходится этим (выбор XML-синтаксиса) включать возм-ть сворачивать текст, заключенный в теги.

М.б. есть еще какие способы, но не додумался. Да и за то разработчикам спасибо огромное. AkelPad когда открываю, прямо глаз радует.
Last edited by Arnold Shwartz on Wed Nov 21, 2018 12:03 pm, edited 2 times in total.

Offline
Posts: 6
Joined: Tue Nov 20, 2018 10:46 am

Post by Arnold Shwartz »

opk44

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

Спасибо еще раз

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

Arnold Shwartz
Из вышеописанного предположу, что:
1) файла "txt.coder" у вас нет
2) вам было бы удобнее просто использовать html-подсветку по дефолту
Если справедливы оба тезиса, то достаточно сделать следующее:
Coder::Settings --> Общие --> "Псевдоним для неизвестного файла".
включить галочку и вписать ".html" (без кавычек, но с точкой!)

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Re: Как задать гор. клавиши для вызова синтаксич. темы XML?

Post by YuS »

Arnold Shwartz wrote:Хотелось бы сразу при открытии файла задавать ему синтаксис (XML или HTML) с пом. гор. клавиш. Но как сделать с пом. плагина – фиг разберешь.
Подскажите, плиз, кто понимает.
Самый простой вариант:
Почему бы не задать файлу требующееся расширение, чтобы правила синтаксиса применялись автоматически?
По завершении работы, файлу можно вернуть первоначальное расширение.

Offline
Posts: 157
Joined: Thu Nov 26, 2015 8:03 pm
Location: Rostov-on-Don

Post by Eskander88 »

Как вызвать диалоговое окно "Все клавиши.." ("All keys..") горячей клавишей?

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

Eskander88
1. Первая буква подчеркнута (All keys...)/(Все клавиши...) , следовательно сработает акселератор {Alt+A} для английской версии или {Alt+В} для русской ("A" - латинская, "В" - русская). Но это, естественно, при открытой главной форме Hotkeys-плагина.

2. Если же вопрос был с "подковыркой", т. е. как достучаться до подчинённой формы сразу, минуя главную, то так обычными средствами "не получится"*.

* Если вы работаете с ангийской версией, то можно сделать "что-то похожее" с помощью Macros-плагина. Для этого записать макрос с перемещением по главному меню до плагина Hotkeys, вызовом его и нажатием {Alt+A}.
Например (для моего меню): Alt + 5 раз {RIGHT} + 17 раз {DOWN} + {ENTER} + {Alt+A}.

Затем к записанному макросу привязать горячую клавишу. И всё.
Но при переключении языка редактора на русский, эта конструкция работать перестаёт (из-за того, что последний акселератор в русской версии отличается). Редактирование меню (добавление/удаление пунктов) также ломает всю конструкцию и потребует перезаписи макроса. Т. е. данный способ, как минимум, не вполне надёжен.

Ещё важное замечание.
Попытка экспортировать макрос в скрипт и запуск скрипта вместо макроса, ни к чему хорошему не приведёт - "%{RIGHT}" ((Альт+Вправо)) через WshShell.SendKeys заслать не удаётся. Поэтому ТОЛЬКО макрос!

Offline
Posts: 157
Joined: Thu Nov 26, 2015 8:03 pm
Location: Rostov-on-Don

Post by Eskander88 »

opk44, вариант 2й. У меня получился макрос такой

Code: Select all

^j{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{ENTER}
Где первое сочетание [CTRL][J] - горячая клавиша для запуска Hotkeys plugin. Очень давно не запускал Макрос Плагин. При попытке сохранить макрос всплывает окно с ошибкой "невозможно открыть файл". Сам макрос проигрывается и работает, а вот сохранить, чтобы назначить хоткей, не получается. :(

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

Eskander88 wrote:opk44, вариант 2й. У меня получился макрос такой

Code: Select all

^j{TAB}{TAB}{TAB}{TAB}{TAB}{TAB}{ENTER}
Где первое сочетание [CTRL][J] - горячая клавиша для запуска Hotkeys plugin. Очень давно не запускал Макрос Плагин. При попытке сохранить макрос всплывает окно с ошибкой "невозможно открыть файл". Сам макрос проигрывается и работает, а вот сохранить, чтобы назначить хоткей, не получается. :(
1. По вопросу невозможности сохранения макроса ответа у меня нет. Придётся проверять и решать на месте. Возможно что-то с правами доступа. Если память не подводит, на старых версиях надо было вручную создавать папку "\AkelFiles\Plugs\Macros" но на свежей версии такой проблемы уже нет. Использую 4.9.9 (x86) dev-r4409.
2. Использовать табуляторы на форме Hotkeys-плагина - очень плохое решение. Т. к. форма запоминает свое последнее состояние, а количество активных кнопок на ней может быть разным!
3. Если вы нашли как обойти ограничение на перемещения по главному меню (%{RIGHT}), тогда можно экспортировать макро-решение в скрипт и пользоваться им. Только с оговоркой пункта 2 желательно либо использовать перемещение с "обратной" табуляцией ([Shift]+[Tab]), чтобы гарантировано обойти кнопки [Add][Up][Down][Delete] на форме, либо просто использовать акселератор {Alt+A} кнопки (All keys...) данной формы:

Code: Select all

var WshShell=new ActiveXObject("WScript.shell");
WshShell.SendKeys("^j+({TAB}{TAB}){ENTER}");

Code: Select all

var WshShell=new ActiveXObject("WScript.shell");
WshShell.SendKeys("^j%a");

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Instructor
Если можно, реализуйте пожалуйста возможность использования кнопки Fn. К примеру, на ноутбуках Lenovo комбинации клавиш:
Fn+Right - перебрасывает курсор в конец строки;
Fn+Left - в начало;
Fn+Up - делает PgUp;
Fn+Down - PgDown.
Это очень удобно, - не надо тянуться в правый верхний угол клавиатуры. А когда привык, то на других компах и ноутбуках это действие делаешь уже не задумываясь, и... облом :( Без этих комбинаций уже как без рук.

Offline
Posts: 84
Joined: Wed Jan 27, 2016 6:53 pm
Location: Europe

Post by SaFeTyPe »

Could you please explain the difference of Command(-1) and Command(0) in the Hotkey Plugin?

- I do understand that 0 completely blocks the shortcut.
- I do also understand that Command(-1) bypasses the "accelaration table" and causes
"standard processing of the shortcut". --> but what exactly does that mean for (for example) :

---plugins
---scripts
---richedit commands(?)
---windows-wide commands
---akelpad standard shortcuts
---active and non-active windows

For example, command(-1) vor CTRL-Y will change it from "delete line" to "REDO last action".

I could not find any definite/complete answers in the forums.

Thank you a lot!
Post Reply