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