// Определяет тип файла по его расширению, имени или хедеру;
// и устанавливает соответствующее окружение 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;
}
}
// Скрипт выполняет команды в зависимости от входящего параметры и активного синтаксиса
// Рассчитан на запуск из плагина 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};
}
// Библиотека для работы с плагином Coder.
// Разработчики: Instructor, F.Phoenix, VladSh
// Версия: 2015/07/08
var fCoderHighLight = "Coder::HighLight";
var fCoderSettings = "Coder::Settings";
//*** СИНТАКСИЧЕСКАЯ ТЕМА ***\\
// Устанавливает синтаксическую тему по указанному расширению.
function SetSyntax(pExt)
{
AkelPad.Call(fCoderSettings, 1, pExt);
}
// Возвращает имя используемого coder-файла.
function GetSyntaxFile(hWndEdit)
{
if (arguments.length == 0) hWndEdit = AkelPad.GetEditWnd();
if (!hWndEdit) return "";
var pFile = "", lpFile;
if (lpFile = AkelPad.MemAlloc(256))
{
AkelPad.Call(fCoderSettings, 16, hWndEdit, lpFile, 256);
pFile = AkelPad.MemRead(lpFile, 1 /*DT_UNICODE*/);
AkelPad.MemFree(lpFile);
}
return pFile;
}
// Возвращает псевдоним синтаксического файла, установленного вручную
// (расширение, по которому тот был установлен).
// Если же тема была определена автоматически, возвращает имя документа.
function GetSyntaxAlias()
{
var hWndEdit = AkelPad.GetEditWnd(), hDocEdit = AkelPad.GetEditDoc();
if (!hWndEdit || !hDocEdit) return "";
var pAlias = "", lpAlias;
if (lpAlias = AkelPad.MemAlloc(256 * 2 /*sizeof(wchar_t)*/))
{
AkelPad.CallW(fCoderSettings, 18 /*DLLA_CODER_GETALIAS*/, hWndEdit, hDocEdit, lpAlias, 0);
pAlias = AkelPad.MemRead(lpAlias, 1 /*DT_UNICODE*/);
AkelPad.MemFree(lpAlias);
}
return pAlias;
}
// Возвращает расширение из псевдонима синтаксического файла.
function GetSyntaxAliasExtension()
{
var pSyntaxAlias = GetSyntaxAlias(), mResult;
return (pSyntaxAlias && (mResult = pSyntaxAlias.match(/\.(.\w*)/)) ? mResult[1] : ""); //всё после точки
}
// Проверяет ассоциацию текущей синтаксической темы с указанным расширением.
function CheckSyntaxExtension(pAlias)
{
var lpActive;
var bActive = false;
if (lpActive = AkelPad.MemAlloc(4 /*sizeof(BOOL)*/))
{
AkelPad.CallW(fCoderSettings, 12, pAlias, lpActive);
bActive = AkelPad.MemRead(lpActive, 3 /*DT_DWORD*/);
AkelPad.MemFree(lpActive);
}
return bActive;
}
// Возвращает массив расширений текущей синтаксической темы.
function GetSyntaxExtensions(hWndEdit)
{
var pText = AkelPad.ReadFile(AkelPad.GetAkelDir(4) + "\\Coder\\" + GetSyntaxFile(hWndEdit), 0xD).replace(/\r\n?/g, "\n");
var mSection = pText.match(/^Files:\s*?\n((?:(?:\*\..*?|;.*?|\s*?)\n)+)/m);
var mResult = mSection[1].match(/^\*\.\w+/gmi);
for (var i = 0; i < mResult.length; i++) mResult[i] = mResult[i].substr(1);
return mResult;
}
//*** ЦВЕТОВАЯ ТЕМА ***\\
// Устанавливает цветовую тему по имени.
function SetColorTheme(pName)
{
AkelPad.CallW(fCoderSettings, 5, pName);
}
// Возвращает имя активной цветовой темы.
function GetColorTheme(hWndEdit)
{
var pVarTheme = "";
var lpVarTheme;
if (lpVarTheme = AkelPad.MemAlloc(256 * 2 /*sizeof(wchar_t)*/))
{
AkelPad.CallW(fCoderSettings, 20, hWndEdit, lpVarTheme, 256);
pVarTheme = AkelPad.MemRead(lpVarTheme, 1 /*DT_UNICODE*/);
AkelPad.MemFree(lpVarTheme);
}
return pVarTheme;
}
// Проверяет активность цветовой темы с указанным именем.
function CheckColorTheme(pName)
{
var lpActive;
var bActive = false;
if (lpActive = AkelPad.MemAlloc(4 /*sizeof(BOOL)*/))
{
AkelPad.CallW(fCoderSettings, 14, pName, lpActive);
bActive = AkelPad.MemRead(lpActive, 3 /*DT_DWORD*/);
AkelPad.MemFree(lpActive);
}
return bActive;
}
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=1582#1582
// Description(1033): Works with for WinFS. Script implemented as the library for using in other scripts.
// Description(1049): Библиотека функций для работы с диалогами, файловой системой и т.п.
// Version: 2.17 (2015.05.29)
// Author: VladSh
//Default variables
var pSlash = "\\";
var pExtTXT = "txt";
var pDefaultExt; //можно задать извне, это будет приоритетнее, т.е. не заменится при вызове функции
//FUNCTIONS
//определение расширения по умолчанию
function getDefaultExt() {
if (!pDefaultExt) {
var lParam;
if (lParam = AkelPad.MemAlloc(256)) {
AkelPad.SendMessage(AkelPad.GetMainWnd(), 1222 /*AKD_GETMAININFO*/, 224 /*MI_DEFAULTSAVEEXT*/, lParam);
pDefaultExt = AkelPad.MemRead(lParam, 1 /*DT_UNICODE*/);
AkelPad.MemFree(lParam);
}
}
return pDefaultExt || pExtTXT;
}
//Вызов диалога Открытия/Сохранения файла (WinAPI) с предварительной обработкой и инициализацией всех необходимых параметров
function fileDialogDefault(bOpenTrueSaveFalse, pInitialDir, pInitialFile, pInitialExt) {
if (pInitialDir == "\\") pInitialDir = "";
pInitialFile = getFileName(pInitialFile);
//<определение фильтров>
var nFilterIndex = 0; //номер по порядку (не индекс!) для arrFilterLines; по умолчанию считаем, что расширение пока не найдено..
var arrFilters;
var arrFilterLines = [];
var arrFTypeInfo;
var arrExts = [];
arrFilters = getFileContent(AkelPad.GetAkelDir(5) + "\\Params\\" + "FileDialogExtentions.ini", false, -1, /\r\n|\n|\r/);
if (arrFilters) {
for (var i = 0, l = arrFilters.length; i < l; i++) {
arrFTypeInfo = arrFilters[i].split("=");
arrExts[i] = arrFTypeInfo[1];
arrFilters[i] = getFilter(arrFTypeInfo[0], arrFTypeInfo[1]);
if ((";" + arrFTypeInfo[1] + ";").split(";" + pInitialExt + ";").length == 2) {
//нашли точное совпадение расширения
nFilterIndex = i + 1;
}
}
//полный список
arrFilterLines = arrFilters;
}
else {
//если файл со списком типов не существует или пуст
arrExts[0] = "*";
arrExts[1] = pExtTXT;
arrFilterLines[0] = getFilter("All Files", arrExts[0]);
arrFilterLines[1] = getFilter("Plain Text files", arrExts[1]);
if (pInitialExt == pExtTXT) nFilterIndex = 2;
}
if (nFilterIndex == 0) {
//если это расширение отсутствует в списке, значит вручную добавляем его как неустановленное..
if (pInitialExt) {
arrExts[arrExts.length] = pInitialExt;
arrFilterLines[arrFilterLines.length] = getFilter("Unspecified file type", pInitialExt);
nFilterIndex = arrFilterLines.length + 1;
}
else
pInitialExt = getDefaultExt(); //для того, чтобы при неопределении расширения файла он не сохранился без расширения
}
var pFilter = arrFilterLines.join("");
//</определение фильтров>
// if (!bOpenTrueSaveFalse)
// pInitialFile = pInitialFile || "filename";
var result = fileDialog(bOpenTrueSaveFalse, AkelPad.GetMainWnd(), pInitialDir, pInitialFile, pInitialExt, pFilter, nFilterIndex);
if (!bOpenTrueSaveFalse) {
if (result.file && result.filterIndex != null) {
arrFTypeInfo = arrExts[result.filterIndex].split(";");
sExtTmp = arrFTypeInfo[0];
if (sExtTmp != "*") {
result.file = separateFile(result.file);
//если расширение в ComboBox'е с расширениями не было изменено
if (sExtTmp == pInitialExt) {
//пробуем взять его из имени файла (возможно вписали туда вручную)
sExtTmp = result.file.ext;
}
return result.file.path + result.file.name + "." + sExtTmp;
}
}
}
return result.file;
}
//Сборка фильтра
function getFilter(sFTypeInfo, sExts /* расширения ч/з ";" */) {
var sMask = "*." + (sExts).replace(/;/g, ";*."); //маска для всех расширений этого типа, без пробелов
return sFTypeInfo + " (" + sMask.replace(/;/g, "; ") + ")\0" + sMask + "\0"; //фильтр в полном виде
}
//Стандартный диалог Открытия/Сохранения файла (WinAPI)
function fileDialog(bOpenTrueSaveFalse, hWnd, pInitialDir, pInitialFile, pInitialExt, pFilter, nFilterIndex) {
var nFlags = 0x880804; //OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_EXPLORER|OFN_ENABLESIZING
var lpStructure;
var lpFilterBuffer;
var lpFileBuffer;
var lpExtBuffer;
var lpDirBuffer;
var oSys;
var pResultFile = "";
var nCallResult;
var lFilterBuffer = pFilter.length; //передаём не 256, а реальный размер pFilter
if (lpFilterBuffer = AkelPad.MemAlloc((lFilterBuffer+1) * _TSIZE)) {
AkelPad.MemCopy(lpFilterBuffer, pFilter.substr(0, lFilterBuffer), _TSTR);
if (lpFileBuffer = AkelPad.MemAlloc(256 * _TSIZE)) {
AkelPad.MemCopy(lpFileBuffer, pInitialFile.substr(0, 255), _TSTR);
if (lpExtBuffer = AkelPad.MemAlloc(256 * _TSIZE)) {
AkelPad.MemCopy(lpExtBuffer, pInitialExt.substr(0, 255), _TSTR);
if (lpDirBuffer = AkelPad.MemAlloc(256 * _TSIZE)) {
AkelPad.MemCopy(lpDirBuffer, pInitialDir.substr(0, 255), _TSTR);
if (lpStructure = AkelPad.MemAlloc(_X64?136:76)) {
//Fill structure
AkelPad.MemCopy(lpStructure, _X64?136:76, 3 /*DT_DWORD*/); //lStructSize
AkelPad.MemCopy(lpStructure + (_X64?8:4), hWnd, 2 /*DT_QWORD*/); //hwndOwner
AkelPad.MemCopy(lpStructure + (_X64?24:12), lpFilterBuffer, 2 /*DT_QWORD*/); //lpstrFilter
AkelPad.MemCopy(lpStructure + (_X64?44:24), nFilterIndex, 3 /*DT_DWORD*/); //nFilterIndex
nFilterIndex = -1;
AkelPad.MemCopy(lpStructure + (_X64?48:28), lpFileBuffer, 2 /*DT_QWORD*/); //lpstrFile
AkelPad.MemCopy(lpStructure + (_X64?56:32), 256, 3 /*DT_DWORD*/); //nMaxFile
AkelPad.MemCopy(lpStructure + (_X64?68:44), lpDirBuffer, 2 /*DT_QWORD*/); //lpstrInitialDir
AkelPad.MemCopy(lpStructure + (_X64?96:52), nFlags, 3 /*DT_DWORD*/); //Flags
AkelPad.MemCopy(lpStructure + (_X64?104:60), lpExtBuffer, 2 /*DT_QWORD*/); //lpstrDefExt
if (oSys = AkelPad.SystemFunction()) {
//Call dialog
if (bOpenTrueSaveFalse == true)
nCallResult = oSys.Call("comdlg32::GetOpenFileName" + _TCHAR, lpStructure);
else
nCallResult = oSys.Call("comdlg32::GetSaveFileName" + _TCHAR, lpStructure);
//Result file
if (nCallResult) {
pResultFile = AkelPad.MemRead(lpFileBuffer, _TSTR);
nFilterIndex = AkelPad.MemRead(lpStructure + (_X64?44:24), 3 /*DT_DWORD*/) - 1;
}
}
AkelPad.MemFree(lpStructure);
}
AkelPad.MemFree(lpDirBuffer);
}
AkelPad.MemFree(lpExtBuffer);
}
AkelPad.MemFree(lpFileBuffer);
}
AkelPad.MemFree(lpFilterBuffer);
}
return {
file: pResultFile,
filterIndex: nFilterIndex
};
}
// Определение основных характеристик формата файла
function getFileFormat(hWnd /*hWndEdit*/) {
return {
cp: AkelPad.GetEditCodePage(hWnd), // CodePage
BOM: AkelPad.GetEditBOM(hWnd),
nl: AkelPad.GetEditNewLine(hWnd) // NewLine
};
}
///Создание вкладки нового файла с передаваемыми параметрами
function createFile(fileFormat /*объект, полученный ранее с помощью getFileFormat*/,
pExt /*расширение, для установки подстветки; если "", будет пытаться определить автоматически*/) {
// пытаемся определить расширение для установки нужной подсветки
var bCoderInclude = AkelPad.Include("CoderFunctions.js");
if (!pExt && bCoderInclude)
pExt = GetSyntaxAliasExtension();
AkelPad.Command(4101 /*IDM_FILE_NEW*/); //создание (закладки) для сохранения текста отдельным файлом
AkelPad.SaveFile(0, "", fileFormat.cp, fileFormat.BOM); //выставление кодировки
AkelPad.SendMessage(AkelPad.GetMainWnd(), 1230 /*AKD_SETNEWLINE*/, 0, fileFormat.nl); //выставление "формата новой строки"
// пытаемся выставить нужную подсветку
if (pExt && bCoderInclude) SetSyntax(pExt);
}
//Разбивает полный путь в массив [Папка, Имя_файла, Расширение]
function separateFile(pFile) {
var pPath = "";
var pFileName = "";
var pFileExt = "";
var pos = pFile.lastIndexOf(pSlash);
if (pos != -1)
pPath = pFile.slice(0, pos + 1);
pFileName = pFile.slice(pos + 1);
if (pFileName) {
pos = pFileName.lastIndexOf(".");
if (pos != -1)
{
pFileExt = pFileName.slice(pos + 1);
pFileName = pFileName.slice(0, pos);
}
}
return {
path: pPath,
name: pFileName,
ext: pFileExt
};
}
//Собирает полное имя файла из объекта, полученного с помощью separateFile()
function joinFile(oFile) {
return oFile.path + oFile.name + "." + oFile.ext;
}
//Возвращает полное имя папки БЕЗ закрывающего \
function getParent(pFile) {
var pDir = "";
var pozLastSep = pFile.lastIndexOf(pSlash);
if (pozLastSep != -1)
pDir = pFile.slice(0, pozLastSep);
return pDir;
}
//Возвращает полное имя папки С закрывающим \
function getParentClosed(pFile) {
var pDir = getParent(pFile);
if (pDir) pDir = pDir + pSlash;
return pDir;
}
//Возвращает имя файла С расширением
function getFileName(pFile) {
return pFile.slice(pFile.lastIndexOf(pSlash) + 1);
}
//Возвращает имя файла БЕЗ расширения
function getFileNameOnly(pFile) {
var pFileName = getFileName(pFile);
var pos = pFileName.lastIndexOf(".");
if (pos != -1)
pFileName = pFileName.slice(0, pos);
return pFileName;
}
//Возвращает расширение файла
function getFileExt(pFile) {
var ext = "";
var pos = pFile.lastIndexOf(".");
if (pos != -1) ext = pFile.substr(pos + 1);
return ext;
}
function getEnvironmentPath(pPath) {
var result = "";
var WshShell = new ActiveXObject("WScript.shell");
var path = WshShell.ExpandEnvironmentStrings(pPath);
var fso = new ActiveXObject("Scripting.FileSystemObject");
if (fso.FileExists(path)) result = path;
return result;
}
//Remove inadmissible symbols (from wisgest)
function correctFileName(pFileNameOnly) {
pFileNameOnly = pFileNameOnly.replace(/\t/g, " "); //валим табуляции, т.к. диалог с ними иногда просто не отображается
pFileNameOnly = pFileNameOnly.replace(/ /g, " "); //убираем повторяющиеся пробелы
return pFileNameOnly.replace(/[\\\/:\*\?"{}<>\|]/g, "");
}
function correctFileNameFull(pFile) {
pFileNameOnly = getFileName(pFile);
pFileNameOnly = correctFileName(pFileNameOnly);
return getParent(pFile) + pSlash + pFileNameOnly;
}
//Получает содержимое файла из файловой системы; возвращает:
//если файла нет - undefined; если pSepRow не передан - возвращает содержимое в виде строки; если передан - возвращает массив, разбитый через pSepRow
//bCurrent = true - если переданный файл является текущим открытым, то его текст берётся сразу, если нет - из файловой системы с помощью FSO
//nSmb - количество возвращаемых символов; 0 или -1 - вернуть содержимое всего файла
function getFileContent(pFile, bCurrent, nBytesMax, pSepRow) {
var result;
if (nBytesMax == 0) {
nBytesMax = -1;
}
if (bCurrent) {
if (pFile == AkelPad.GetEditFile(0)) {
result = AkelPad.GetTextRange(0, nBytesMax);
}
}
if (!result) {
var fso = new ActiveXObject("Scripting.FileSystemObject");
if (fso.FileExists(pFile) == true) {
result = AkelPad.ReadFile(pFile, 0xD, 0, 0, nBytesMax);
}
}
if (result) {
if (pSepRow.length != 0) {
result = result.split(pSepRow);
}
}
return result;
}
//by MSDN
function getDrivesList() {
var e = new Enumerator(fso.Drives);
var x;
var i = 0;
var disks = [];
for (; !e.atEnd(); e.moveNext()) {
x = e.item();
if (x.DriveType == 3 && x.IsReady) {
disks[i] = x.DriveLetter;
i += 1;
}
}
return disks;
}
// Библиотека функций для работы с текстом.
// Последнее обновление: F.Phoenix, 12.05.2012.
// Возвращает смещение объекта, определяемого nType.
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11382#11382
function GetOffset(hWndEdit, nType /*AEGI_*/, nOffset)
{
var lpIndex;
if (lpIndex = AkelPad.MemAlloc(_X64?24:12 /*sizeof(AECHARINDEX)*/))
{
if (nOffset >= 0) AkelPad.SendMessage(hWndEdit, 3137 /*AEM_RICHOFFSETTOINDEX*/, nOffset, lpIndex);
AkelPad.SendMessage(hWndEdit, 3130 /*AEM_GETINDEX*/, nType, lpIndex);
nOffset = AkelPad.SendMessage(hWndEdit, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
AkelPad.MemFree(lpIndex);
}
return nOffset;
}
// Возвращает позиции начала и конца строки указанного символа.
// Также можно использовать отрицательные значения nPos от -1 до -13, соответствующие константам AEGI.
function GetLineInfo(hWndEdit, nPos)
{
if (nPos < 0) nPos = GetOffset(hWndEdit, -nPos, -1);
var nLineStart = GetOffset(hWndEdit, 18 /*AEGI_WRAPLINEBEGIN*/, nPos);
var nLineEnd = GetOffset(hWndEdit, 19 /*AEGI_WRAPLINEEND*/, nPos);
return {Start : nLineStart, End : nLineEnd};
}
// Возвращает номер строки указанного символа. Так же поддерживает AEGI.
function GetLine(nPos)
{
if (nPos < 0) nPos = GetOffset(hWndEdit, -nPos, -1);
var nLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nPos);
return AkelPad.SendMessage(hWndEdit, 3143 /*AEM_GETUNWRAPLINE*/, nLine, 0);
}
// Возвращает индекс начала строки.
function GetLineOffset(nLine)
{
return AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, AkelPad.SendMessage(hWndEdit, 3142 /*AEM_GETWRAPLINE*/, nLine, 0), 0);
}
// Возвращает текст указанной строки, а также ее данные.
function GetLineText(nLine, out)
{
if (out == null) out = [];
out.StartOffset = out.LastLineOffset = GetLineOffset(nLine);
out.EndOffset = GetOffset(hWndEdit, 19 /*AEGI_WRAPLINEEND*/, out.LastLineOffset);
return AkelPad.GetTextRange(out.StartOffset, out.EndOffset);
}
// Возвращает текст указанного диапазона строк, а также их данные.
function GetLinesText(nStartLine, nEndLine, out)
{
if (out == null) out = [];
out.StartOffset = GetLineOffset(nStartLine);
out.LastLineOffset = GetLineOffset(nEndLine);
out.EndOffset = GetOffset(hWndEdit, 19 /*AEGI_WRAPLINEEND*/, out.LastLineOffset);
return AkelPad.GetTextRange(out.StartOffset, out.EndOffset);
}
// Возвращает минимальный и максимальный индекс текущего выделения.
// При bFullLines = true возвращает диапазон от начала первой строки до конца последней.
function GetSelection(bFullLines)
{
var min = AkelPad.GetSelStart();
var max = AkelPad.GetSelEnd();
if (min > max) {var tmp = min; min = max; max = tmp;}
if (bFullLines)
{
var min = GetOffset(hWndEdit, 18 /*AEGI_WRAPLINEBEGIN*/, min);
var max = GetOffset(hWndEdit, 19 /*AEGI_WRAPLINEEND*/, max);
}
return {Min : min, Max : max};
}
// Разбивает текст INI-файла на массив типа "ключ-значение".
function ParseINI(pData)
{
var result = [], group = "", m;
var rx_com = new RegExp("^\\s*[;#]");
var rx_cat = new RegExp("^\\s*\\[(\\w+)\\]");
var astr = pData.split(/\r\n|\r|\n/);
for (var i = 0; i < astr.length; i++)
{
if (rx_com.test(astr[i])) continue;
if ((m = rx_cat.exec(astr[i])) != null) group = m[1];
else
{
var kvp = astr[i].split("=");
if (kvp.length != 2) continue;
kvp[0] = group + "|" + kvp[0];
result.push(kvp);
}
}
return result;
}
// Функция для работы с массивом элементов типа "ключ-значение".
// Возвращает значение для указанного ключа.
function GetValue(kvp, pKey)
{
for (var i = 0; i < kvp.length; i ++)
if (kvp[i][0] == pKey) return kvp[i][1];
return null;
}
/* Константы AEGI *\
// Следующие значения не требуют указания параметра:
AEGI_FIRSTCHAR 1 //Первый символ документа.
AEGI_LASTCHAR 2 //Последний символ документа.
AEGI_FIRSTSELCHAR 3 //Первый символ выделения.
AEGI_LASTSELCHAR 4 //Последний символ выделения.
AEGI_CARETCHAR 5 //Положение каретки.
AEGI_FIRSTVISIBLECHAR 6 //First visible character, collapsed lines are skipped.
AEGI_LASTVISIBLECHAR 7 //Last visible character, collapsed lines are skipped.
AEGI_FIRSTFULLVISIBLECHAR 8 //First fully visible character, collapsed lines are skipped.
AEGI_LASTFULLVISIBLECHAR 9 //Last fully visible character, collapsed lines are skipped.
AEGI_FIRSTVISIBLELINE 10 //First character of the first visible line, collapsed lines are skipped.
AEGI_LASTVISIBLELINE 11 //Last character of the last visible line, collapsed lines are skipped.
AEGI_FIRSTFULLVISIBLELINE 12 //First character of the first fully visible line, collapsed lines are skipped.
AEGI_LASTFULLVISIBLELINE 13 //Last character of the last fully visible line, collapsed lines are skipped.
// Следующие значения требуют указания параметра:
AEGI_VALIDCHARINLINE 15 //Correct character to make sure that it is on line.
AEGI_LINEBEGIN 16 //First character in line.
AEGI_LINEEND 17 //Last character in line.
AEGI_WRAPLINEBEGIN 18 //First character of the unwrapped line. Returns number of characters as AEM_GETINDEX result.
AEGI_WRAPLINEEND 19 //Last character of the unwrapped line. Returns number of characters as AEM_GETINDEX result.
AEGI_NEXTCHARINLINE 20 //Next character in line.
AEGI_PREVCHARINLINE 21 //Previous character in line.
AEGI_NEXTCHAR 22 //Next wide character.
AEGI_PREVCHAR 23 //Previous wide character.
AEGI_NEXTLINE 24 //Первый символ следующей строки.
AEGI_PREVLINE 25 //Первый символ предыдущей строки.
AEGI_NEXTUNCOLLAPSEDCHAR 26 //Next wide character, collapsed lines are skipped.
AEGI_PREVUNCOLLAPSEDCHAR 27 //Previous wide character, collapsed lines are skipped.
AEGI_NEXTUNCOLLAPSEDLINE 28 //First character of the next line, collapsed lines are skipped.
AEGI_PREVUNCOLLAPSEDLINE 29 //First character of the previous line, collapsed lines are skipped.
\* */