Scripts collection

Discuss and announce AkelPad plugins
Post Reply
  • Author
  • Message
Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// (c) Infocatcher 2010
// version 0.1.6 - 2010-12-09

//===================
// Convert JavaScript escape sequences like "\u00a9" or "\xa9" ((c) symbol)

// Arguments:
//   -mode=0  - (default) auto encode or decode
//   -mode=1  - encode
//   -mode=2  - decode

// Usage:
//   Call("Scripts::Main", 1, "convertEscapes.js", "-mode=0")
//===================

function _localize(s) {
	var strings = {
		"Nothing to recode!": {
			ru: "Нечего перекодировать!"
		}
	};
	var lng;
	switch(AkelPad.SystemFunction().Call("kernel32::GetUserDefaultLangID") & 0x3ff /*PRIMARYLANGID*/) {
		case 0x19: lng = "ru"; break;
		default:   lng = "en";
	}
	_localize = function(s) {
		return strings[s] && strings[s][lng] || s;
	};
	return _localize(s);
}

// Read arguments:
var args = {};
for(var i = 0, argsCount = WScript.Arguments.length; i < argsCount; i++)
	if(/^-(\w+)(=(.+))?$/i.test(WScript.Arguments(i)))
		args[RegExp.$1.toLowerCase()] = RegExp.$3 ? eval(RegExp.$3) : true;
function getArg(argName, defaultVal) {
	return typeof args[argName] == "undefined" // argName in args
		? defaultVal
		: args[argName];
}

var MODE_AUTO   = 0;
var MODE_ENCODE = 1;
var MODE_DECODE = 2;

var mode = getArg("mode", MODE_AUTO);
var auto   = mode == MODE_AUTO;
var encode = mode == MODE_ENCODE;
var decode = mode == MODE_DECODE;


//var AkelPad = new ActiveXObject("AkelPad.document");
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd && !AkelPad.GetEditReadOnly(hWndEdit))
	convertEscapes();

function convertEscapes() {
	var text = AkelPad.GetSelText();
	var selectAll = false;
	if(!text) {
		text = getAllText();
		selectAll = true;
	}

	var res;
	if(encode || auto) {
		res = encodeEscapes(text);
		if(auto)
			decode = res == text; // Can't encode
	}
	if(decode) {
		res = decodeEscapes(text);
		if(res == null) // Decode error
			return;
	}
	if(res == text) {
		AkelPad.MessageBox(hMainWnd, _localize("Nothing to recode!"), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
		return;
	}

	insertNoScroll(res, selectAll);
}

function encodeEscapes(str) {
	return str.replace(
		/[^!-~ \t\n\r]/ig,
		function(s) {
			var hex = s.charCodeAt(0).toString(16);
			return "\\u" + "0000".substr(hex.length) + hex;
		}
	);
}
function decodeEscapes(str) {
	// Keep some escaped chars inside string literals
	// "ab\ncd" => "ab\\ncd" => eval() => "ab\ncd"
	var doubleEscape = function(s) {
		return s.replace(
			/(\\+)([nrt'"])?/g,
			function(s, bs, chr) {
				if(bs.length % 2 == 0 || chr) // \ => \\ (*2)
					return new Array(bs.length + 1).join("\\") + s;
				// \\\ => \\ + \ => (\\)*2 + \
				return new Array(Math.floor(bs.length/2)*2 + 1).join("\\") + s;
			}
		);
	};
	str = str // Single RegExp like /("|')(?:\\\1|[^\1])*\1/g fail
		.replace(/"(?:\\"|[^"\n\r])*"/g, doubleEscape)
		.replace(/'(?:\\'|[^'\n\r])*'/g, doubleEscape);

	try {
		// Stupid, but sample :D
		str = eval(
			'"' +
			str // Make valid string
				.replace(
					/(\\*)["']/g,
					function(s, bs) {
						return bs.length % 2 == 0
							? "\\" + s
							: s;
					}
				)
				.replace(/\n/g, "\\n")
				.replace(/\r/g, "\\r")
				.replace(/\u2028/g, "\\u2028")
				.replace(/\u2029/g, "\\u2029") +
			'"'
		);
	}
	catch(e) {
		AkelPad.MessageBox(hMainWnd, e.name + '\neval("string") fail\n' + e.message, WScript.ScriptName, 16 /*MB_ICONERROR*/);
		return null;
	}

	return str;
}

function getAllText() {
	if(typeof AkelPad.GetTextRange != "undefined")
		return AkelPad.GetTextRange(0, -1);
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return "";
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	var columnSel = AkelPad.SendMessage(hWndEdit, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
	var ss = AkelPad.GetSelStart();
	var se = AkelPad.GetSelEnd();

	AkelPad.SetSel(0, -1);
	var str = AkelPad.GetSelText();

	AkelPad.SetSel(ss, se);
	columnSel && AkelPad.SendMessage(hWndEdit, 3128 /*AEM_UPDATESEL*/, 0x1 /*AESELT_COLUMNON*/, 0);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	AkelPad.MemFree(lpPoint);
	setRedraw(hWndEdit, true);
	return str;
}
function insertNoScroll(str, selectAll) {
	var lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/);
	if(!lpPoint)
		return;
	setRedraw(hWndEdit, false);
	AkelPad.SendMessage(hWndEdit, 1245 /*EM_GETSCROLLPOS*/, 0, lpPoint);

	selectAll && AkelPad.SetSel(0, -1);
	//var ss = AkelPad.GetSelStart();
	AkelPad.ReplaceSel(str, true);
	//if(ss != AkelPad.GetSelStart())
	//	AkelPad.SetSel(ss, ss + str.length);

	AkelPad.SendMessage(hWndEdit, 1246 /*EM_SETSCROLLPOS*/, 0, lpPoint);
	setRedraw(hWndEdit, true);
	AkelPad.MemFree(lpPoint);
}
function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
<download> (see converter.js)

Converts JavaScript escape sequences like "\u00a9" or "\xa9" («©» symbol)
Example: before, after (or vice versa :)).

Version 0.1.5 - 2010-12-06
[x] Fixed insertNoScroll() function.

Version 0.1.4 - 2010-11-25
[*] Improved logic of text operations.

Version 0.1.3 - 2010-11-23
[*] New localization method.


Version 0.1.2 - 2010-11-22
[+] Added localization.

Version 0.1.1 - 2010-11-16
[*] Improved handling of «\» character inside string literals («var someStr = "\\n - \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0440\u043e\u043a\u0438";» => «var someStr = "\\n - перевод строки";»).
Last edited by Infocatcher on Fri May 11, 2012 6:19 pm, edited 9 times in total.

Offline
Posts: 767
Joined: Mon Sep 28, 2009 10:03 am
Location: Minsk, Belarus

Post by se7h »

Process current file in HTML TiDy

Tidy reads HTML, XHTML and XML files and writes cleaned up markup. For HTML variants, it detects and corrects many common coding errors and strives to produce visually equivalent markup that is both W3C compliant and works on most browsers. A common use of Tidy is to convert plain HTML to XHTML. For generic XML files, Tidy is limited to correcting basic well-formedness errors and pretty printing.

tidy.exe put in AkelPad\AkelFiles\Tools\HTMLTidy\

Tidy documentation

Code: Select all

/// Process current file in HTML TiDy
// Version 1.11
//
// Usage:
// Call("Scripts::Main", 1, "HTMLTidy.js", "config_name")
//
// Support ShowMenuEx.js if you do not specify a flags in argument:
// Call("Scripts::Main", 1, "HTMLTidy.js")
//
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7814#p7814

var WshShell = new ActiveXObject("WScript.shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

var pToolPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Tools\\HTMLTidy\\tidy.exe";
var pConfigPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Tools\\HTMLTidy\\";

if(WScript.Arguments.length) {
    pConfigPath += WScript.Arguments(0);
} else {
    if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();
    var pCfgFile = getSelectedMenuItem(POS_CURSOR, "", 0);

    if(pCfgFile == "") {
        WScript.Quit();
    }

    pConfigPath += pCfgFile;
}

var hEditWnd = AkelPad.GetEditWnd();
var pTmpFile;

if(pTmpFile = CreateTempFile()) {
    AkelPad.SaveFile(hEditWnd, pTmpFile, 1200 /*UTF-16LE*/, true, false);
    pToolPath = correctCommandLine(pToolPath);
    pConfigPath = correctCommandLine(pConfigPath);
    pTmpFile = correctCommandLine(pTmpFile);
    
    WshShell.Run("%COMSPEC% /c " + "\"" + pToolPath + " -config " + pConfigPath + " -m -utf16le " + pTmpFile + "\"", 0, true);

    pText = AkelPad.ReadFile(pTmpFile);
    setRedraw(hEditWnd, false);
    AkelPad.SetSel(0, -1);
    AkelPad.ReplaceSel(pText);
    setRedraw(hEditWnd, true);
    fso.DeleteFile(pTmpFile);
}


//Functions
function CreateTempFile() {
    var oTmpFolder;
    var oTmpFile;
    var pTmpName;

    if(oTmpFolder = fso.GetSpecialFolder(2 /*TemporaryFolder*/)) {
        pTmpName = fso.GetTempName();

        if(oTmpFile = oTmpFolder.CreateTextFile(pTmpName)) {
            oTmpFile.Close();
        }

        return (oTmpFolder.Path + "\\" + pTmpName);
    }

    return "";
}

function correctCommandLine(pPath) {
    if(pPath.search( / /) != -1) {
        return "\"" + pPath + "\"";
    } else {
        return pPath;
    }
}

function setRedraw(hWnd, bRedraw) { 
   var oSys = AkelPad.SystemFunction(); 
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0); 
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true); 
}
(v1.11 - 30.03.2012)

Code: Select all

Call("Scripts::Main", 1, "HTMLTidy.js", "reformat.cfg")


Argument - file name of config file in AkelPad\AkelFiles\Tools\HTMLTidy\

Code: Select all

indent-attributes: yes
indent: yes
indent-spaces: 4
markup: yes
output-xhtml: yes
quiet: yes
wrap: 0
wrap-asp: yes
wrap-attributes: yes
wrap-jste: yes
wrap-php: yes
numeric-entities: yes
show-errors: 0
tab-size: 4


Support ShowMenuEx.js if you do not specify a file name in argument

Code: Select all

reformat.cfg = Reformat
custom.cfg = Custom


________________________

Process current file in AStyle

Artistic Style is a source code indenter, formatter, and beautifier for the C, C++, C# and Java programming languages.

AStyle.exe put in AkelPad\AkelFiles\Tools\AStyle\

AStyle documentation

Code: Select all

/// Process current file in AStyle
// v1.11
//
// Usage:
// Call("Scripts::Main", 1, "AStyle.js", "`flags`")
//
// Or support ShowMenuEx.js if you do not specify a flags in argument:
// Call("Scripts::Main", 1, "AStyle.js")
//
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7814#p7814

var WshShell = new ActiveXObject("WScript.shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var pToolPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Tools\\AStyle\\AStyle.exe";

var pToolFlags = "";

if(WScript.Arguments.length) {
    pToolFlags = WScript.Arguments(0);
} else if(pToolFlags == "") {
    if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();
    var pFlags = getSelectedMenuItem(POS_CURSOR, "", 0);

    if(pFlags == "") {
        WScript.Quit();
    }

    pToolFlags = pFlags;
}

var hEditWnd = AkelPad.GetEditWnd();
var pTmpFile;
var pText;

if(pTmpFile = CreateTempFile()) {
    AkelPad.SaveFile(hEditWnd, pTmpFile, 65001 /*UTF-8*/, true, false);

    pToolPath = correctCommandLine(pToolPath);
    pTmpFile = correctCommandLine(pTmpFile);

    WshShell.Run("%COMSPEC% /c " + pToolPath + " " + pToolFlags + " " + pTmpFile, 0, true);
    pText = AkelPad.ReadFile(pTmpFile);

    setRedraw(hEditWnd, false);
    AkelPad.SetSel(0, -1);
    AkelPad.ReplaceSel(pText);
    setRedraw(hEditWnd, true);

    fso.DeleteFile(pTmpFile);
}


//Functions
function CreateTempFile() {
    var oTmpFolder;
    var oTmpFile;
    var pTmpName;

    if(oTmpFolder = fso.GetSpecialFolder(2 /*TemporaryFolder*/)) {
        pTmpName = fso.GetTempName();

        if(oTmpFile = oTmpFolder.CreateTextFile(pTmpName)) {
            oTmpFile.Close();
        }

        return (oTmpFolder.Path + "\\" + pTmpName);
    }

    return "";
}

function correctCommandLine(pPath) {
    if(pPath.search( / /) != -1) {
        return "\"" + pPath + "\"";
    } else {
        return pPath;
    }
}

function setRedraw(hWnd, bRedraw) { 
   var oSys = AkelPad.SystemFunction(); 
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0); 
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true); 
}
(v1.11 - 30.03.2012)

Code: Select all

Call("Scripts::Main", 1, "AStyle.js", "`flags`")


Code: Select all

-aCfjKm0Nps4SUwxY = Custom
-A1 = Allman Style


________________________

Process current file in CSSTidy

CSSTidy is an opensource CSS parser and optimiser.

csstidy.exe put in AkelPad\AkelFiles\Tools\CSSTidy\

CSSTidy documentation

Code: Select all

/// Process current file in CSSTidy
// v1.11
//
// Usage:
// Call("Scripts::Main", 1, "CSSTidy.js", "`flags`")
//
// Or support ShowMenuEx.js if you do not specify a flags in argument:
// Call("Scripts::Main", 1, "CSSTidy.js")
//
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7814#p7814

var WshShell = new ActiveXObject("WScript.shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

var pToolPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Tools\\CSSTidy\\csstidy.exe";

var pToolFlags = "";

if(WScript.Arguments.length) {
    pToolFlags = WScript.Arguments(0);
} else if(pToolFlags == "") {
    if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();
    var pFlags = getSelectedMenuItem(POS_CURSOR, "", 0);

    if(pFlags == "") {
        WScript.Quit();
    }

    pToolFlags = pFlags;
}

var hEditWnd = AkelPad.GetEditWnd();
var pTmpFile1;
var pTmpFile2;
var pText;

if(pTmpFile1 = CreateTempFile()) {
    if(pTmpFile2 = CreateTempFile()) {
        AkelPad.SaveFile(hEditWnd, pTmpFile1, 65001 /*UTF-8*/, true, false);
        pToolPath = correctCommandLine(pToolPath);
        pTmpFile1 = correctCommandLine(pTmpFile1);
        WshShell.Run("%COMSPEC% /c " + pToolPath + " " + pTmpFile1 + " " + pToolFlags + " " + pTmpFile2, 0, true);
        pText = AkelPad.ReadFile(pTmpFile2);

        setRedraw(hEditWnd, false);
        AkelPad.SetSel(0, -1);
        AkelPad.ReplaceSel(pText);
        setRedraw(hEditWnd, true);

        fso.DeleteFile(pTmpFile2);
    }

    fso.DeleteFile(pTmpFile1);
}


//Functions
function CreateTempFile() {
    var oTmpFolder;
    var oTmpFile;
    var pTmpName;

    if(oTmpFolder = fso.GetSpecialFolder(2 /*TemporaryFolder*/)) {
        pTmpName = fso.GetTempName();

        if(oTmpFile = oTmpFolder.CreateTextFile(pTmpName)) {
            oTmpFile.Close();
        }

        return (oTmpFolder.Path + "\\" + pTmpName);
    }

    return "";
}

function correctCommandLine(pPath) {
    if(pPath.search( / /) != -1) {
        return "\"" + pPath + "\"";
    } else {
        return pPath;
    }
}

function setRedraw(hWnd, bRedraw) { 
   var oSys = AkelPad.SystemFunction(); 
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0); 
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true); 
}
(v1.11 - 30.03.2012)

Code: Select all

Call("Scripts::Main", 1, "CSSTidy.js", "`flags`")


________________________

Process current file in phpCodeBeautifier

phpCodeBeautifier is a tool which avoid you of spending hours on reformating PHP-code to suit your own way of presenting it.

phpCB.exe put in AkelPad\AkelFiles\Tools\phpCB\

phpCB documentation

Code: Select all

/// Process current file in phpCB
// v1.11
//
// Usage:
// Call("Scripts::Main", 1, "phpCB.js", "`flags`")
//
// Or support ShowMenuEx.js if you do not specify a flags in argument:
// Call("Scripts::Main", 1, "phpCB.js")
//
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7814#p7814

var WshShell = new ActiveXObject("WScript.shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");

var pToolPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Tools\\phpCB\\phpCB.exe";

var pToolFlags = "";

if(WScript.Arguments.length) {
    pToolFlags = WScript.Arguments(0);
} else if(pToolFlags == "") {
    if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();
    var pFlags = getSelectedMenuItem(POS_CURSOR, "", 0);

    if(pFlags == "") {
        WScript.Quit();
    }

    pToolFlags = pFlags;
}

var hEditWnd = AkelPad.GetEditWnd();
var pTmpFile1;
var pTmpFile2;
var pText;

if(pTmpFile1 = CreateTempFile()) {
    if(pTmpFile2 = CreateTempFile()) {
        AkelPad.SaveFile(hEditWnd, pTmpFile1, 65001 /*UTF-8*/, true, false);

        pToolPath = correctCommandLine(pToolPath);
        pTmpFile1 = correctCommandLine(pTmpFile1);

        WshShell.Run("%COMSPEC% /c " + pToolPath + " " + pToolFlags + " " + pTmpFile1 + ">" + pTmpFile2, 0, true);

        pText = AkelPad.ReadFile(pTmpFile2);

        setRedraw(hEditWnd, false);
        AkelPad.SetSel(0, -1);
        AkelPad.ReplaceSel(pText);
        setRedraw(hEditWnd, true);

        fso.DeleteFile(pTmpFile2);
    }

    fso.DeleteFile(pTmpFile1);
}


//Functions
function CreateTempFile() {
    var oTmpFolder;
    var oTmpFile;
    var pTmpName;

    if(oTmpFolder = fso.GetSpecialFolder(2 /*TemporaryFolder*/)) {
        pTmpName = fso.GetTempName();

        if(oTmpFile = oTmpFolder.CreateTextFile(pTmpName)) {
            oTmpFile.Close();
        }

        return (oTmpFolder.Path + "\\" + pTmpName);
    }

    return "";
}

function correctCommandLine(pPath) {
    if(pPath.search( / /) != -1) {
        return "\"" + pPath + "\"";
    } else {
        return pPath;
    }
}

function setRedraw(hWnd, bRedraw) { 
   var oSys = AkelPad.SystemFunction(); 
   AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0); 
   bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true); 
}
(v1.11 - 30.03.2012)

Code: Select all

Call("Scripts::Main", 1, "phpCB.js", "`flags`")

________________
Based on ExecTool.js
Last edited by se7h on Fri Mar 30, 2012 8:04 pm, edited 7 times in total.

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

Post by VladSh »

Code: Select all

// Description(1033): Convert space to tabulation
// Description(1049): Преобразование пробелов в символы табуляции
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7947#p7947
// Version: 3.2 (2012.09.12) - добален функционал + некоторые идеи взяты из соответствующего скрипта от F.Phoenix (2012-08-18a)
// Author: VladSh
//
// Arguments:
//		lead:
//			• 0 - processing of all text (used for vertical text blocks)
//			• [1] - processing of lead spaces only (used for scripts)
//		bSpaces - definition of count of spaces in block:
//			• [0] - from program settings
//			• -1 - InputBox
//			• > 0 - count of spaces to be replaced by a tab
//		oActn - what to do with other (the residual) single-spaces:
//			• [0] (or without this argument) - do nothing, to limit the processing of block spaces only (used for scripts)
//			• 1 - replace single-spaces
//			• -1 - remove single-spaces (can also be used for scripts)
//		sel (0/-1/-2) - leave the result text selected; without this argument it defined automatically; see more AkelPad.ReplaceSel()...
//
//	Usage:
//		-"Convert space to tabulation" Call("Scripts::Main", 1, "SpacesToTabs.js") - script process by default options: processing of lead spaces only, definition of count of spaces in block from program settings, residual single-spaces will not be processed

var constsDefault = {
	msgp_SpasesInTab: "Enter the number of spaces in a tab character:",
	msgp_InputNaN: "Input non-numeric value, the operation is canceled.",
	msgp_ArgumentNaN: "Arguments passed a non-numeric value, the operation is canceled."
};

if (AkelPad.GetMainWnd()) {
	var hWndEdit = AkelPad.GetEditWnd();
	
	var nTextSelected = -1;
	var pSelText = AkelPad.GetSelText();
	if (!pSelText) {
		pSelText = AkelPad.GetTextRange(0, -1);
		nTextSelected = 0;
	}
	if (!pSelText) WScript.Quit();
	
	var sReplaced = "\t";		// заменяющий текст
	var nTabStop;
	var nBSAction = AkelPad.GetArgValue("bSpaces", 0);
	if (nBSAction <= 0) {
		//0 - from program settings
		var nTabStop = AkelPad.SendMessage(hWndEdit, 3239 /*AEM_GETTABSTOP*/, 0, 0);
		// InputBox
		if (nBSAction == -1) {
			if (!(nTabStop = AkelPad.InputBox(hWndEdit, WScript.ScriptName, getConst("msgp_SpasesInTab"), nTabStop))) WScript.Quit();
			checkTabStopIsNaN(hWndEdit, nTabStop, "msgp_InputNaN");
		}
	}
	else {
		checkTabStopIsNaN(hWndEdit, nBSAction, "msgp_ArgumentNaN");
		nTabStop = nBSAction;
	}
	
	// Обработка блоков из определённого количества пробелов
	if (AkelPad.GetArgValue("lead", 1)) {
		// обработка только лидирующиех пробелов
		pSelText = pSelText.replace(/^\s+/mg, replacer);
	}
	else {
		// обработка пробелов всего текста (для вертикальных блоков)
		pSelText = replacer(pSelText);
		
		// Обработка оставшихся пробелов
		var nOSAction = AkelPad.GetArgValue("oActn", 0);
		if (nOSAction != 0) {
			//replace residual space on a Tab character or remove it
			sReplaced = (nOSAction == 1) ? "\t" : "";
			pSelText = pSelText.replace(/ /g, sReplaced);
		}
	}
	
	if (!nTextSelected) AkelPad.SetSel(0, -1);
	var nTextSelected = AkelPad.GetArgValue("sel", nTextSelected);
	AkelPad.ReplaceSel(pSelText, nTextSelected);
}

function checkTabStopIsNaN(hWndEdit, nTabStop, pPlaceActionMsg) {
	if (isNaN(nTabStop))	{
		AkelPad.MessageBox(hWndEdit, getConst(pPlaceActionMsg), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);			//press Cancel
		WScript.Quit();
	}
}

function replacer(str) {
	for (var nSpaceCount = nTabStop; nSpaceCount > 1; --nSpaceCount) {
		var exprSpases = new RegExp(' {' + nSpaceCount + '}', "g");
		str = str.replace(exprSpases, sReplaced);
	}
	return str;
}

function getConst(constName) {
	var sResult;
	var oSet = AkelPad.ScriptSettings();
	if (oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/)) {
		sResult = oSet.Read(AkelPad.GetLangId(0 /*LANGID_FULL*/) + "_" + constName, 3 /*PO_STRING*/);
		oSet.End();
	}
	else
		sResult = constsDefault[constName];
	return sResult;
}


Code: Select all

[Options]
;= Constants for SpacesToTabs.js
;= 2012.09.12

;= RU
1049_msgp_SpasesInTab=Введите количество пробелов в одном символе табуляции:
1049_msgp_InputNaN=Введено нечисловое значение, операция отменена.
1049_msgp_ArgumentNaN=В аргументах передано нечисловое значение, операция отменена.

;= Enter text of constants for you language
;= _msgp_SpasesInTab=
;= _msgp_InputNaN=
;= _msgp_ArgumentNaN=


:

Code: Select all

"Пробелы -> символы Табуляции"
{
  -"Скрипты (кол-во пробелов из настроек)" Call("Scripts::Main", 1, "SpacesToTabs.js")
  -"Скрипты (кол-во пробелов = 2)" Call("Scripts::Main", 1, "SpacesToTabs.js", `-bSpaces=2`)
  -"Скрипты (запрос...)" Call("Scripts::Main", 1, "SpacesToTabs.js", `-bSpaces=-1`)
  SEPARATOR
  -"Все вхождения (запрос...)" Call("Scripts::Main", 1, "SpacesToTabs.js", `-lead=0 -bSpaces=-1 -oActn=1`)
}
Last edited by VladSh on Wed Jan 14, 2015 10:44 pm, edited 10 times in total.

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

Post by VladSh »

Общий скрипт получения слова, на котором установлена каретка, и работы с ним:

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7969#p7969
// Description(1033): Select the word or link at the cursor position. Script implemented as the library for using in other scripts.
// Description(1049): Библиотека функций для выделения текущего слова или ссылки.
// Version: 3.0 (2015.01.15)
// Author: VladSh

// Возвращает границы слова, на котором установлена каретка
// используется алгоритм от FeyFre: http://akelpad.sourceforge.net/forum/viewtopic.php?p=7973#p7973
function getWordCaretInfo(hWndEdit) {
	if (hWndEdit) {
		var nCaretPos = AkelPad.GetSelStart();
		var crInfo = [];
		crInfo.min = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 0/*WB_LEFT*/, nCaretPos);
		crInfo.max = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 7/*WB_RIGHTBREAK*/, crInfo.min);
		//! For case when caret located on word start position i.e. "prev-word |word-to-copy"
		if (crInfo.max < nCaretPos) {
			crInfo.min = AkelPad.SendMessage(hWndEdit, 1100/*EM_FINDWORDBREAK*/, 0/*WB_LEFT*/, nCaretPos + 1);
			crInfo.max = AkelPad.SendMessage(hWndEdit, 1100/*EM_FINDWORDBREAK*/, 7/*WB_RIGHTBREAK*/, crInfo.min);
		}
		if (crInfo.max >= nCaretPos)
			return crInfo;
	}
}

// Возвращает текст слова, на котором установлена каретка
function getWordCaret() {
	var sResult = "";
	var hWndEdit = AkelPad.GetEditWnd();
	var crInfo = getWordCaretInfo(hWndEdit);
	if (crInfo) sResult = AkelPad.GetTextRange(crInfo.min, crInfo.max);
	return sResult;
}

// Выделяет слово, на котором установлена каретка
function WordCaretSelect() {
	var bSelected = false;
	var hWndEdit = AkelPad.GetEditWnd();
	var crInfo = getWordCaretInfo(hWndEdit);
	if (crInfo) {
		if (crInfo) AkelPad.SetSel(crInfo.min, crInfo.max);
		bSelected = true;
	}
	return bSelected;
}


// Возвращает границы ссылки, на которой установлена каретка
// код KDJ, VladSh, Instructor; начиная отсюда: http://akelpad.sourceforge.net/forum/viewtopic.php?p=19312#p19312
function getLinkCaretInfo(hWndEdit) {
	if (hWndEdit) {
		var bResult = false;
		var lpCaret;
		var lpInfo;
		var crInfo = [];
		if (lpCaret = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/)) {
			AkelPad.SendMessage(hWndEdit, 3130 /*AEM_GETINDEX*/, 5 /*AEGI_CARETCHAR*/, lpCaret);
			if (lpInfo = AkelPad.MemAlloc(_X64 ? 48 : 24 /*sizeof(AECHARInfo)*/)) {
				if (AkelPad.SendMessage(hWndEdit, 3149 /*AEM_INDEXINURL*/, lpCaret, lpInfo)) {
					crInfo.min = AkelPad.SendMessage(hWndEdit, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpInfo);
					crInfo.max = AkelPad.SendMessage(hWndEdit, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpInfo + (_X64 ? 24 : 12) /*offsetof(AECHARInfo, ciMax)*/);
					bResult = true;
				}
				AkelPad.MemFree(lpInfo);
			}
			AkelPad.MemFree(lpCaret);
		}
		if (bResult)
			return crInfo;
	}
}

// Возвращает текст ссылки, на которой установлена каретка
function getLinkCaret() {
	var sResult = "";
	var hWndEdit = AkelPad.GetEditWnd();
	var crInfo = getLinkCaretInfo(hWndEdit);
	if (crInfo) sResult = AkelPad.GetTextRange(crInfo.min, crInfo.max);
	return sResult;
}

// Выделяет ссылку, на которой установлена каретка
function LinkCaretSelect() {
	var bSelected = false;
	var hWndEdit = AkelPad.GetEditWnd();
	var crInfo = getLinkCaretInfo(hWndEdit);
	if (crInfo) {
		if (crInfo) AkelPad.SetSel(crInfo.min, crInfo.max);
		bSelected = true;
	}
	return bSelected;
}


// Открывает файл по заданному пути ищет в нём определённое вхождение ВЫДЕЛЕННОГО ТЕКСТА.
function openHelpString(pFileInAkelDirPath, pSearchText, nCycles) {
	if (!pSearchText) {
		pSearchText = getWordCaret();
	}
	
	var pFile = AkelPad.GetAkelDir() + pFileInAkelDirPath;
	
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	if (fso.FileExists(pFile) == false)
		WScript.Quit();
	
	AkelPad.OpenFile(pFile);
	if (pSearchText) {
		AkelPad.SetSel(0, 0);
		for (var n = nCycles; n > 0; n--) {
			AkelPad.TextFind(AkelPad.GetEditWnd(), pSearchText, 0x00000002 /*FR_WHOLEWORD*/ + 0x00000001 /*FR_DOWN*/);
		}
	}
}

Должен находиться в ..\Scripts\Include\.

Скрипт выделения текущего слова:

Code: Select all

// Description(1033): Select the word at the cursor position
// Description(1049): Выделение текущего слова (на котором установлена каретка)
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7969#p7969
// Version: 1.5 (2012.08.23)
// Author: VladSh

if (! AkelPad.Include("CaretSelect.js")) WScript.Quit();
WordCaretSelect();

Установил на Ctrl+Alt+Up.

Копирование текущего слова:

Code: Select all

// Description(1033): Copy the word at the cursor position
// Description(1049): Копирование текущего слова (на котором установлена каретка)
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7969#p7969
// Version: 1.4 (2012.08.23)
// Author: VladSh

if (! AkelPad.Include("CaretSelect.js")) WScript.Quit();
AkelPad.SetClipboardText(getWordCaret());

Установил на Ctrl+Alt+C.
Last edited by VladSh on Wed Jan 14, 2015 11:37 pm, edited 21 times in total.

Offline
Posts: 876
Joined: Tue Jul 24, 2007 8:54 am

Post by Fr0sT »

=== Base64 encode/decode ===
converts selection to Base64 and vice versa (also supports decoding of HTML &#nnnn; char codes)

Thanks to Infocatcher & VladSh for script examples

Code: Select all

// === Base64 encode/decode ===
// (c) Fr0sT 2010
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7972#p7972
//
// Сonverts selection to Base64 and vice versa
// Arguments:
//	enc - encode
//	dec - decode
// Example:
//	Call("Scripts::Main", 1, "Base64.js", "enc")
//
// v0.1.0 - 18:55 09.07.2010.
//	First release
// v0.1.1 - 20:30 10.07.2010.
//	Optimized encoding/decoding, added dec16 parameter, text length checking
// v1.0   - 17:05 04.08.2010.
//	Completely rewritten decoding/endcoding. Removed dec16 parameter. Works significantly faster!
//	Selected text is converted from wide char to multi-byte 
//	string (using current document code page) so that decode now works perfectly with every text code 
//	page. Text remains selected after recoding to allow quickly adjust text code page by Alt-R. Remember 
//	that in recode dialog you should set target code page in the field "TO" while field "FROM" must be 
//	the current document codepage. Added GetLastError to error reports. Removed buffer zero-padding in 
//	decode() - it's already zeroed by MemAlloc. Added workaround if current document codepage is UTF16/32
// v1.1   - 11:28 06.08.2010
//	Added HTML entity decoding (&#nnnn;), parameter "dechtml"
// v1.2   - 12:43 08.12.2010
//	Fixed wrong buffer boundary checking (random characters appeared beyond the trailing "=")


/* Base64 encode / decode (originally from http://www.webtoolkit.info) */
/* Text-only modification: stops at 0 character */

var Base64 = {
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	// in:  pBuf - buffer with multibyte string (ZERO-TERMINATED!)
	//      bufLen - buffer size
	// out: Base64 string
	encode : function(pBuf, bufLen)
	{
		var output = "";
		var pCurr = pBuf;

		while (true)
		{
			var chr1 = (pCurr < pBuf+bufLen) ? AkelPad.MemRead(pCurr++, 5 /* DT_BYTE */) : 0;
			var chr2 = (pCurr < pBuf+bufLen) ? AkelPad.MemRead(pCurr++, 5 /* DT_BYTE */) : 0;
			var chr3 = (pCurr < pBuf+bufLen) ? AkelPad.MemRead(pCurr++, 5 /* DT_BYTE */) : 0;
			if (!chr1) break;
			var enc1 = chr1 >> 2;
			var enc2 = ((chr1 & 0x03) << 4) | ((chr2 & 0xf0) >> 4);
			var enc3 = (!chr2) ? 0x40 : ((chr2 & 0x0f) << 2) | ((chr3 & 0xc0) >> 6);
			var enc4 = (!chr3) ? 0x40 : (chr3 & 0x3f);
			output += this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
			if (!chr3) break;
		}
		return output;
	},

	// public method for decoding
	// in:  base64str - Base64 string
	//      pBuf - buffer for output
	// out: decoded multibyte string (written to pBuf),
	//      remaining space filled with zero's by MemAlloc (!)
	decode : function(base64str, pBuf)
	{
		// chr1, chr2, chr3;
		// enc1, enc2, enc3, enc4;
		var i = 0;
		base64str = base64str.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		if (base64str.length = 0 || base64str.length % 4 != 0)
			throw("Not a Base64 string!");
		var pCurr = pBuf;

		while (i < base64str.length)
		{
			var enc1 = this._keyStr.indexOf(base64str.charAt(i++));
			var enc2 = this._keyStr.indexOf(base64str.charAt(i++));
			var enc3 = this._keyStr.indexOf(base64str.charAt(i++));
			var enc4 = this._keyStr.indexOf(base64str.charAt(i++));
			var chr1 = (enc1 << 2) | (enc2 >> 4);
			var chr2 = (enc3 != 0x40) ? (((enc2 & 0x0f) << 4) | (enc3 >> 2)) : 0;
			var chr3 = (enc4 != 0x40) ? (((enc3 & 0x03) << 6) | enc4) : 0;
			AkelPad.MemCopy(pCurr++, chr1, 5 /* DT_BYTE */);
			AkelPad.MemCopy(pCurr++, chr2, 5 /* DT_BYTE */);
			AkelPad.MemCopy(pCurr++, chr3, 5 /* DT_BYTE */);
		}
		
		return;
	}
}

var hWndEdit;
var Usage = "Usage: select text and execute Call(\"Scripts::Main\", 1, \""+WScript.ScriptName+"\", \"enc|dec\")";

function ReportError(msg, printUsage)
{
	AkelPad.MessageBox(hWndEdit, msg+(printUsage?("\n"+Usage):""), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
	WScript.Quit();
}

if (hWndEdit = AkelPad.GetMainWnd())
{
	// check arguments
	if (WScript.Arguments.length == 0)
		ReportError("Expect parameter", true);

	// Get & check selected text
	if ((selText = AkelPad.GetSelText()) == "")
		ReportError("No text selected!", true);

	// Warn about long text
	if (selText.length > 60000)
	{
		if (AkelPad.MessageBox(hWndEdit,
			"Selected text is "+selText.length+" characters long.\n"+
			"Process may take a long time. Continue?",
			WScript.ScriptName, 0x4 | 0x30 /*MB_YESNO | MB_ICONWARNING*/) != 6)
				WScript.Quit();
	}

	try
	{
		var pWCBuf = 0; // buffer to store wide char string
		var pMBBuf = 0; // buffer to store multi-byte string
		var sysFn = AkelPad.SystemFunction();
		var codePage = AkelPad.GetEditCodePage(0);
		// current code page is UTF16* or UTF32* - set ansi current code page
		// (WideChar <-> MultiByte functions don't work with this code pages)
		if (codePage == 1 || codePage == 1200 || codePage == 1201 || codePage == 12000 || codePage == 12001)
			codePage = 0;

		switch(WScript.Arguments(0))
		{
			// Encode selected text to Base64.
			// Before encoding convert it from UTF16 to multibyte string using current codepage (!)
			case "enc" :
				selText += "\u0000"; // so we don't worry about string length in conversions

				if (!(pWCBuf = AkelPad.MemAlloc(selText.length * _TSIZE)))
					throw("MemAlloc fail");
				AkelPad.MemCopy(pWCBuf, selText, _TSTR);

				// get required buffer size
				var bufLen = sysFn.Call(
						"Kernel32::WideCharToMultiByte",
						codePage, //   __in   UINT CodePage,          
						0,        //   __in   DWORD dwFlags,          
						pWCBuf,   //   __in   LPCWSTR lpWideCharStr,  
						-1,       //   __in   int cchWideChar,        
						0,        //   __out  LPSTR lpMultiByteStr,   
						0,        //   __in   int cbMultiByte,        
						0,        //   __in   LPCSTR lpDefaultChar,   
						0);       //   __out  LPBOOL lpUsedDefaultChar
				if (bufLen == 0)
					throw("WCtoMB fail "+sysFn.GetLastError());
				if (!(pMBBuf = AkelPad.MemAlloc(bufLen)))
					throw("MemAlloc fail");

				// convert buffer
				bufLen = sysFn.Call(
						"Kernel32::WideCharToMultiByte",
						codePage, //   __in   UINT CodePage,          
						0,        //   __in   DWORD dwFlags,          
						pWCBuf,   //   __in   LPCWSTR lpWideCharStr,  
						-1,       //   __in   int cchWideChar,        
						pMBBuf,   //   __out  LPSTR lpMultiByteStr,   
						bufLen,   //   __in   int cbMultiByte,        
						0,        //   __in   LPCSTR lpDefaultChar,   
						0);       //   __out  LPBOOL lpUsedDefaultChar
				if (bufLen == 0)
					throw("WCtoMB fail "+sysFn.GetLastError());
 
				// encode buffer
				selText = Base64.encode(pMBBuf, bufLen);

				break;

			case "dec"  : 
				selText += "\u0000"; // so we don't worry about string length in conversions

				// allocate buffer with enough space for trailing zero's
				var bufLen = Math.ceil(selText.length * 3/4) + 1;
				if (!(pMBBuf = AkelPad.MemAlloc(bufLen)))
					throw("MemAlloc fail");

				// decode string to buffer
				Base64.decode(selText, pMBBuf);
				
				// get required buffer size
				var code = sysFn.Call(
						"Kernel32::MultiByteToWideChar",
						codePage, //   __in   UINT CodePage,          
						0,        //   __in   DWORD dwFlags,          
						pMBBuf,   //   __in   LPCSTR lpMultiByteStr,  
						-1,       //   __in   int cbMultiByte,        
						0,        //   __out  LPWSTR lpWideCharStr,   
						0);       //   __in   int cchWideChar		
				if (code == 0)
					throw("MBtoWC fail "+sysFn.GetLastError());
				if (!(pWCBuf = AkelPad.MemAlloc(code * _TSIZE)))
					throw("MemAlloc fail");
				
				// convert buffer to wide char
				code = sysFn.Call(
						"Kernel32::MultiByteToWideChar",
						codePage,   //   __in   UINT CodePage,          
						0,          //   __in   DWORD dwFlags,          
						pMBBuf,     //   __in   LPCSTR lpMultiByteStr,  
						-1,         //   __in   int cbMultiByte,        
						pWCBuf,     //   __out  LPWSTR lpWideCharStr,   
						code);      //   __in   int cchWideChar		
				if (code == 0)
					throw("MBtoWC fail "+sysFn.GetLastError());

				selText = AkelPad.MemRead(pWCBuf, 1 /* DT_UNICODE */);

				break;

			case "dechtml"  :
				var regex = new RegExp("&#([0-9][0-9][0-9][0-9]);", "gm");
				selText = selText.replace(regex, 
				    function (str, p1, offs, s) { return String.fromCharCode(Number(p1));}
				    );

				break;
			default :
				throw("Wrong parameter: "+WScript.Arguments(0));
		} // switch
	} // try
	catch(err)
	{
		ReportError(err);
	}
	finally
	{
		if (pWCBuf) AkelPad.MemFree(pWCBuf);
		if (pMBBuf) AkelPad.MemFree(pMBBuf);
	}

	AkelPad.ReplaceSel(selText, true);
}
Last edited by Fr0sT on Thu Oct 11, 2012 12:16 pm, edited 5 times in total.

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

Чуток кода для разбора и унификации старого LotusScript'а.

Post by VladSh »

Code: Select all

// Description(1049): Преобразование столбца наименований айтемов в строки описаний констант
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7982#p7982
// Version: 1.5 (2012.10.30)
// Author: VladSh

var pBreak = "\r";
var strContent = AkelPad.GetSelText() || AkelPad.GetClipboardText();

if (strContent) {
	// идентификатор константы; по умолчанию для VB или LS
	var constLang = "Const";
	var smbEndRow = "";
	// если у файла установлена синтаксическая тема java или js, изменяем идентификатор на Java
	if (AkelPad.Include("CoderFunctions.js")) {
		if (GetSyntaxAliasExtension().indexOf("j") != -1) {
			constLang = "final String";
			smbEndRow = ";";
		}
	}
	
	var arrContent = strContent.split(pBreak);
	
	for (var nLine = 0; nLine < arrContent.length; nLine++) {
		sLine = arrContent[nLine].replace(/([ \t]+$)/, "");		//Убираем пустые символы в конце
		if (sLine) {
			arrContent[nLine] = constLang + ' IN_' + sLine.toUpperCase() + ' = "' + sLine + '"' + smbEndRow;
		}
	}
	strContent = arrContent.join(pBreak);
	
	AkelPad.ReplaceSel(strContent);
	AkelPad.SetClipboardText(strContent);
}


исходное выражение:

Code: Select all

ItemName1
ItemName2
результат:

Code: Select all

Const IN_ITEMNAME1 = "ItemName1"
Const IN_ITEMNAME2 = "ItemName2"
для установленной синтаксической темы Java или js работает так:

Code: Select all

final String IN_ITEMNAME1 = "ItemName1";
final String IN_ITEMNAME2 = "ItemName2";


Code: Select all

// Description(1049): Преобразование dot-синтаксиса GetItemValue к стандартному
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7982#p7982
// Version: 1.4 (2015.01.15)
// Author: VladSh

var strContent = AkelPad.GetSelText() || AkelPad.GetClipboardText();

if (strContent) {
	if (! AkelPad.Include("selCompleteLine.js")) WScript.Quit();
	
	var arrContent = strContent.split(pBreak);
	var sLine = "";
	var iPoint; var iEnd; var iTmp;
	
	for (var nLine = 0; nLine < arrContent.length; nLine++) {
		sLine = oStr.rtrim(arrContent[nLine], " \t");		//Убираем пустые символы в конце
		if (sLine) {
			iPoint = sLine.indexOf(".");
			
			iEnd = sLine.indexOf(", ", iPoint);		//пример: Join(nd.Value, "/") + text
			iTmp = sLine.indexOf("(", iPoint);		//пример: nd.Value(0) + function(...)
			if (iTmp < iEnd)		//это вариант (nd.Value(0), ...)
				iEnd = iTmp;
			
			iTmp = sLine.indexOf(")", iPoint);
			
			if (iTmp > iEnd || iEnd > 0)		//значит это закрывающая скобка для (0)
				sLine = replacebyBorders(sLine, iEnd, iEnd, '")');		//вставка в нужное место закрывающей кавычки и скобки
			else
				sLine = sLine + '")';		//пример: выделено просто nd.Value

			sLine = replacebyBorders(sLine, iPoint, iPoint + 1, '.GetItemValue("');		//замена точки
			
			arrContent[nLine] = sLine;
		}
	}
	strContent = arrContent.join(pBreak);
	
	AkelPad.ReplaceSel(strContent, -1);
	AkelPad.SetClipboardText(strContent);
}


исходное выражение:

Code: Select all

ND.ItemName1
ND.ItemName2(0)
результат:

Code: Select all

ND.GetItemValue("ItemName1")
ND.GetItemValue("ItemName2")(0)


Code: Select all

// Description(1049): Преобразование dot-синтаксиса ReplaceItemValue к стандартному
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7982#p7982
// Version: 1.5 (2015.01.15)
// Author: VladSh

var pBreak = "\r";
var strContent = AkelPad.GetSelText() || AkelPad.GetClipboardText();

if (strContent) {
	var arrContent = strContent.split(pBreak);
	var sLine = "";
	
	for (var nLine = 0; nLine < arrContent.length; nLine++) {
		sLine = arrContent[nLine].replace(/([ \t]+$)/, "");		//Убираем пустые символы в конце
		if (sLine) {
			sLine = sLine.replace(/\./, '.ReplaceItemValue("');
			sLine = sLine.replace(/\s*=\s*/, '", ');
			arrContent[nLine] = 'Call ' + sLine + ')'
		}
	}
	strContent = arrContent.join(pBreak);
	
	AkelPad.ReplaceSel(strContent, -1);
	AkelPad.SetClipboardText(strContent);
}


исходное выражение:

Code: Select all

ND.ItemName1 = ""
ND.ItemName2 = Values
результат:

Code: Select all

Call ND.ReplaceItemValue("ItemName1", "")
Call ND.ReplaceItemValue("ItemName2", Values)


Code: Select all

// Description(1049): Преобразование наименований полей в функциях в константы
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7982#p7982
// Version: 1.3 (2011.04.06)
// Author: VladSh

var pBreak = "\r";
var strContent = AkelPad.GetSelText() || AkelPad.GetClipboardText();

if (strContent) {
	var arrContent = strContent.split(pBreak);
	var sLine = "";
	var iStart;
	var iEnd;
	var sItemName = "";
	
	for (var nLine = 0; nLine < arrContent.length; nLine++) {
		sLine = arrContent[nLine].replace(/([ \t]+$)/, "");		//Убираем пустые символы в конце
		
		if (sLine) {
			iStart = sLine.indexOf('("');
			if (iStart != -1) {
				iStart += 2;
				iEnd = sLine.indexOf('"', iStart);
			}
			else {
				iEnd = sLine.lastIndexOf('")');
				if (iEnd != -1) {
					iStart = sLine.lastIndexOf('"', iEnd - 1);
					if (iStart != -1) iStart += 1;
				}
			}
			sItemName = sLine.substring(iStart, iEnd);
			
			var expr = new RegExp('"' + sItemName + '"', 'g');
			sLine = sLine.replace(expr, 'IN_' + sItemName.toUpperCase());
			
			arrContent[nLine] = sLine;
		}
	}
	strContent = arrContent.join(pBreak);
	
	AkelPad.ReplaceSel(strContent);
	AkelPad.SetClipboardText(strContent);
}


исходное выражение:

Code: Select all

Call ND.ReplaceItemValue("ItemName1", "")
Result = ND.AnyFunction("ItemName2", Values)
результат:

Code: Select all

Call ND.ReplaceItemValue(IN_ITEMNAME1, "")
Result = ND.AnyFunction(IN_ITEMNAME2, Values)


Code: Select all

// Description(1049): Раскодирование текста, скопированного из NotesPeek
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=7982#p7982
// Version: 1.0 (2011.04.13)
// Author: VladSh

//eval(AkelPad.ReadFile(AkelPad.GetAkelDir(5) + "\\converter.js"));		//временно закоменчено (ждём выделение функций для конвертации в отдельную библиотеку)

var CP_NOT_CONVERT = -2;
var CP_CURRENT     = -1;
var oSys = AkelPad.SystemFunction();

var pText = AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();

pText = decodeEscapes(pText);
pText = convertToUnicode(pText, 1251);
pText = pText.replace(/\x05/gm, "");		//рубим тупые квадратики
pText = pText.replace(new RegExp('"\r\t"', "gm"), "");		//убираем ненужные разрывы внутри строк

AkelPad.ReplaceSel(pText);


// Infocatcher's code
function decodeEscapes(str) {
	// Keep some escaped chars inside string literals
	// "ab\ncd" => "ab\\ncd" => eval() => "ab\ncd"
	var doubleEscape = function(s) {
		return s.replace(
			/(\\+)([nrt'"])?/g,
			function(s, bs, chr) {
				if(bs.length % 2 == 0 || chr) // \ => \\ (*2)
					return new Array(bs.length + 1).join("\\") + s;
				// \\\ => \\ + \ => (\\)*2 + \
				return new Array(Math.floor(bs.length/2)*2 + 1).join("\\") + s;
			}
		);
	};
	str = str // Single RegExp like /("|')(?:\\\1|[^\1])*\1/g fail
		.replace(/"(?:\\"|[^"\n\r])*"/g, doubleEscape)
		.replace(/'(?:\\'|[^'\n\r])*'/g, doubleEscape);

	var fixEsc = function(s, bs, chr, hex) {
		return bs.length % 2 == 0 && /[^0-9a-f]/i.test(hex)
			? bs + chr + hex
			: s;
	};

	try {
		str = eval(
			'"' +
			str // Make valid string
				.replace(
					/(\\*)["']/g,
					function(s, bs) {
						return bs.length % 2 == 0
							? "\\" + s
							: s;
					}
				)
				.replace(
					/\\+$/, // Fix qwe\ => "qwe\" => eval() error
					function(s) {
						return s.length % 2 != 0
							? "\\" + s
							: s;
					}
				)

				// Fix invalid \u and \x
				.replace(/(\\*)\\(x)([\s\S]{2})/g, fixEsc)
				.replace(/(\\*)\\(u)([\s\S]{4})/g, fixEsc)

				.replace(/\n/g, "\\n")
				.replace(/\r/g, "\\r")
				.replace(/\x00/g, "\\x00")
				.replace(/\u2028/g, "\\u2028")
				.replace(/\u2029/g, "\\u2029") +
			'"'
		);
	}
	catch(e) {
		throw new (e.constructor || SyntaxError)('eval("string") fail\n' + e.message);
	}

	return str;
}

function convertToUnicode(str, cp) {
   if(cp == CP_NOT_CONVERT)
      return str;
   if(cp == CP_CURRENT || cp === undefined)
      cp = AkelPad.GetEditCodePage(0);

   var ret = "";

   if(
      cp == 1200 //UTF-16LE
      || cp == 1201 //UTF-16BE
      || cp == 12000 //UTF-32LE
      || cp == 12001 //UTF-32BE
   ) {
      var isLE = cp == 1200 || cp == 12000;
      var step = cp == 12000 || cp == 12001 ? 4 : 2;
      if(str.length % step != 0)
         throw "Invalid unicode string";
      for(var i = 0, l = str.length; i < l; i += step) {
         var chars = str.substr(i, step);
         if(isLE) {
            var b1 = chars.charCodeAt(0);
            var b2 = chars.charCodeAt(1);
         }
         else {
            var b1 = chars.charCodeAt(step - 1);
            var b2 = chars.charCodeAt(step - 2);
         }
         ret += String.fromCharCode((b2 << 8) + b1);
      }
      return ret;
   }

   // based on Fr0sT's code: http://akelpad.sourceforge.net/forum/viewtopic.php?p=7972#p7972

   // current code page is UTF16* or UTF32* - set ansi current code page
   // (WideChar <-> MultiByte functions don't work with this code pages)
   if(cp == 1 || cp == 1200 || cp == 1201 || cp == 12000 || cp == 12001)
      cp = 0;

   try {
      var strLen = str.length;
      var pMBBuf = AkelPad.MemAlloc(strLen * 1 /*sizeof(char)*/);
      if(!pMBBuf)
         throw new Error("MemAlloc fail");
      for(var i = 0; i < strLen; i++)
         AkelPad.MemCopy(pMBBuf + i, str.charCodeAt(i), 5 /*DT_BYTE*/);

      // get required buffer size
      var bufLen = oSys.Call(
         "Kernel32::MultiByteToWideChar",
         cp,       //   __in   UINT CodePage,
         0,        //   __in   DWORD dwFlags,
         pMBBuf,   //   __in   LPCSTR lpMultiByteStr,
         strLen,   //   __in   int cbMultiByte,
         0,        //   __out  LPWSTR lpWideCharStr,
         0         //   __in   int cchWideChar
      );
      if(!bufLen)
         throw new Error("MultiByteToWideChar fail " + oSys.GetLastError());
      bufLen *= 2 /*sizeof(wchar_t)*/;

      var pWCBuf = AkelPad.MemAlloc(bufLen);
      if(!pWCBuf)
         throw new Error("MemAlloc fail");

      // convert buffer
      bufLen = oSys.Call(
         "Kernel32::MultiByteToWideChar",
         cp,       //   __in   UINT CodePage,
         0,        //   __in   DWORD dwFlags,
         pMBBuf,   //   __in   LPCSTR lpMultiByteStr,
         strLen,   //   __in   int cbMultiByte,
         pWCBuf,   //   __out  LPWSTR lpWideCharStr,
         bufLen    //   __in   int cchWideChar
      );
      if(!bufLen)
         throw new Error("MultiByteToWideChar fail " + oSys.GetLastError());

      //ret = AkelPad.MemRead(pWCBuf, 1 /*DT_UNICODE*/);
      for(var pCurr = pWCBuf, bufMax = pWCBuf + bufLen*2; pCurr < bufMax; pCurr += 2)
         ret += String.fromCharCode(AkelPad.MemRead(pCurr, 4 /*DT_WORD*/));
   }
   catch(e) {
      throw e;
   }
   finally {
      pMBBuf && AkelPad.MemFree(pMBBuf);
      pWCBuf && AkelPad.MemFree(pWCBuf);
   }

   return ret;
}
Благодарности: Infocatcher'у за функции раскодирования и помощь!
Last edited by VladSh on Thu Jan 15, 2015 8:26 pm, edited 13 times in total.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

zen-coding bindings for AkelPad(not finished yet!)
zen-coding привязки к AkelPad(не закончено!)

zen_coding-20100715.7z
zen_coding-20100715-v2.7z удалось заставить работать ещё пару скриптов
zen_coding-20100715-v3.7z заработали ещё пара скриптов + убрано мерцание во время работы скриптов
zen_coding-20100716.7z исправлено сворачивание/разворачивание окна запроса
zen_coding-20100915.7z
  1. Исправления в реализации интерфейса zen_editor
  2. Реализован интерфейс zen_file (минимальная версия плагина 6.5)
  3. Исправлены некоторые внутренние ошибки zen
zen_coding-20110209.7z fixed type, caused error on newer AkelPad versions
zen_coding-20140630.zip New external location

Scripts to run are zen_*.js All of them does not require additional arguments and can be called using HotKey/ToolBar/ContextMenu or directly from Scripts, but zen_wrapwithabbreviation.js(which requests additional parameter using GUI)
zen subfolder contains zen-coding core. Primary task is to implement interfaces in zen_editor.js and zen_file.js Still working on it.

Скрипты для запуска - zen_*.js Все они не требуют дополнительных параметров и могут быть вызваны из HotKey/ToolBar/ContextMenu или напрямую из Scripts, кроме zen_wrapwithabbreviation.js(который запрашивает параметр используя интерфейс)
Подпапка zen содержит ядро zen-coding. Основная задача - реализовать интерфейсы в файлах zen_editor.js и zen_file.js Работаю над этим.

zen-coding source
Last edited by FeyFre on Sun Jun 29, 2014 10:25 pm, edited 6 times in total.

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

Post by VladSh »

Code: Select all

// Description(1033): Converting the scriptnames to the string for ContextMenu-plugin
// Description(1049): Преобразование имён скриптов в строки вызова ContextMenu-плагина
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8131#p8131
// Version: 2.1 (2011.07.21)
// Author: VladSh
//
// - если выделение есть, то скрипт преобразует выделение в строку меню и заменит выделение результатом;
// - если выделения нет, то текст для преобразования будет браться из буфера обмена, результат будет записываться тоже в буфер

var pArg = AkelPad.GetArgLine();
if (pArg) pArg = ", `" + WScript.Arguments(0) + "`";

var pBreak = "\r";
var pContent = AkelPad.GetSelText();
var bPasteToClipboard = false;

if (!pContent) {
	pContent = AkelPad.GetClipboardText();
	if (!pContent) WScript.Quit();
	bPasteToClipboard = true;
}

var arrContent = pContent.split(pBreak);

for (line = 0; line < arrContent.length; line++) {
	if (arrContent[line]) {
		arrContent[line] = '-"" Call("Scripts::Main", 1, "' + arrContent[line] + '"' + pArg + ')';
	}
}
pContent = arrContent.join(pBreak);

if (bPasteToClipboard)
	AkelPad.SetClipboardText(pContent);
else
	AkelPad.ReplaceSel(pContent);
Last edited by VladSh on Wed Jan 14, 2015 9:59 pm, edited 3 times in total.

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

Post by VladSh »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8153#p8153
// Description(1033): Works with users menu (menu autogenerated from parameter files). Script implemented as the library for using in other scripts.
// Description(1049): Библиотека функций для работы с пользовательскими параметризированными меню
// Version: 5.0 (2015.04.10)
// Author: VladSh
//
/// Getting the value selected in the user menu (getSelectedMenuItem function)
//
// Menu automatically generated from the parameter files.
// Settings are located in files <current script name>.param in the directory "[AkelPad]\AkelFiles\Plugs\Scripts\Params\"
//
/// Получение значения, выбранного в пользовательском меню (функция getSelectedMenuItem)
//
// Меню автоматически формируются из соответствующего скрипту файла параметров.
// Параметры размещается в файлах <имя запускаемого скрипта>.param в директории "[AkelPad]\AkelFiles\Plugs\Scripts\Params\"
//
// Имена параметров, передаваемых в аргументах вызывающих скриптов:
// 	-pExt - расширение файла параметров (если pFile не указан, то имя будет браться из имени запущенного скрипта); поддерживаются:
// 		• "txt"  - каждая строка файла = строка меню;
// 		• "ini"  - <надпись пункта меню> = <значение> (без уголков);
// 		• "json" - настройки в формате json с указанными именами шаблонов настроек (см. -pID)
// 	-pFile - имя файла параметров (с расширением), по которому будет формироваться меню; если не передано, то будет определено по имени запускаемого скрипта
// 	-pID - шаблон определённых настроек из json-файла
// 	-place - место экрана, где будет выведено меню, - значение для pPOS_PLACE (см. ниже) либо идентификатор кнопки тулбара, передавать который в виде -place="%m %i"
// 	-ignore1menu ([0]/1) - если в файле параметров одна строка и bIgnoreMenu = 1, тогда меню выводиться не будет
// 	-debug ([0]/1) - выводить расширенную информацию о возможных ошибках в панель Log-плагина

var hWndMain = AkelPad.GetMainWnd();
if (hWndMain) {
	if (! AkelPad.Include("ShowMenu.js")) WScript.Quit();
	var fso = new ActiveXObject('Scripting.FileSystemObject');
	var WshShell = new ActiveXObject('WScript.Shell');
	var pScriptName = WScript.ScriptName;
	var bIniExist = 0;
	var parser_exts = "txt, ini, json";
	var opts = {'pFile': AkelPad.GetArgValue('pFile', ""),
	            'pExt': AkelPad.GetArgValue('pExt', ""),
	            'pID': AkelPad.GetArgValue('pID', "")};
	var bIgnoreMenu = AkelPad.GetArgValue('ignore1menu', 0);
	var bDebug = AkelPad.GetArgValue('debug', false);
}

//Functions

function getSelectedMenuItem(pPOS_PLACE, bReturnStructure)
//Параметры:
//	pPOS_PLACE - возможность задавать позицию вывода меню; варианты см. в ShowMenu.js var's POS_...
//	bReturnStructure - в каком виде будет возвращаться результат:
//			false - в виде текста (возврат надписи выбранного пункта меню)
//			true - в виде объекта, содержащего свойства name и options (для сложных случаев)
//		если пользователь может использовать любой вариант меню, то лучше передавать 1, а потом универсально анализировать результат pMenuItem[0]
{
	if (hWndMain) {
		opts.pExt = opts.pExt.toLowerCase();
		if (opts.pExt) {
			// Имя файла в этом случае берём по запускаемому скрипту
			opts.pFile = AkelPad.GetFilePath(pScriptName, 3 /* CPF_FILEBASENAME */) + "." + opts.pExt;
		}
		else {
			checkArg("'-pExt' or '-pFile'", opts.pFile);
			opts.pExt = AkelPad.GetFilePath(opts.pFile, 4 /* CPF_FILEEXT */).toLowerCase();
		}
		if (parser_exts.indexOf(opts.pExt) == -1) {
			if (bDebug) AkelPad.Call("Log::Output", 4, WScript.ScriptName + ': -pExt="' + opts.pExt + '"');
			AkelPad.MessageBox(hWndMain, "Papameter parser is not supported extensions different this: " + parser_exts + "!", WScript.ScriptName, 48);
			WScript.Quit();
		}
		if (opts.pFile.indexOf(":") == -1) {
			opts.pFile = expandPath(opts.pFile);
			if (opts.pFile.indexOf(":") == -1)
				opts.pFile = AkelPad.GetAkelDir(5) + "\\Params\\" + opts.pFile;
		}
		if (fso.FileExists(opts.pFile) == true) {
			var lpItems = [];
			var nItem;
			
			var lpContent = AkelPad.ReadFile(opts.pFile);
			lpContent = lpContent.replace(/\n/g, '\r');
			lpContent = lpContent.replace(/\r{2,}/g, '\r');
			lpContent = trim(lpContent, '\r');
			if (lpContent) {
				var arrContent = [];
				var oContent = {};
				var pItem;
				
				//Определение объекта-парсера
				var Parser = {
					proc_txt: function(lpItems) {
						arrContent = lpContent.split('\r');
						for (nItem = 0; nItem < arrContent.length; ++nItem) {
							pItem = arrContent[nItem];
							if (pItem) {
								lpItems[nItem] = [pItem, MF_NORMAL];
								oContent[pItem] = {'name': pItem, 'options': pItem};
								arrContent[nItem] = oContent[pItem];
							}
						}
						return nItem;
					},
					
					proc_ini: function(lpItems) {
						arrContent = lpContent.split('\r');
						var oRegExp = {
							getPureValue: function(pStr) {
								return trim(pStr, ' \t');
							}
						};
						var iSep;
						var pLabel;
						var pOptions;
						for (nItem = 0; nItem < arrContent.length; ++nItem) {
							pItem = arrContent[nItem];
							if (pItem) {
								iSep = pItem.indexOf('=');
								if (iSep == -1) {
									pItem += '=';
									iSep = pItem.length;
								}
								pLabel = oRegExp.getPureValue(pItem.substr(0, iSep));
								pOptions = oRegExp.getPureValue(pItem.substr(iSep + 1));
								if (!pLabel)
									pOptions = "- опции для " + pLabel + " не заданы -";
								
								lpItems[nItem] = [pLabel, MF_NORMAL];
								oContent[pLabel] = {'name': pLabel, 'options': pOptions};
								arrContent[nItem] = oContent[pLabel];
							}
						}
						return nItem;
					},
					
					proc_json: function(lpItems) {
						try {
							eval("var tmpContent = " + lpContent);
							oContent = tmpContent;
							if (oContent.length == undefined) {
								nItem = 0;
								for (var id in oContent) {
									pItem = oContent[id];
									lpItems[nItem] = [pItem.name, MF_NORMAL];
									arrContent[nItem] = pItem;
									nItem += 1;
								}
							}
							else {
								for (nItem = 0; nItem < oContent.length; ++nItem) {
									pItem = oContent[nItem];
									if (pItem) {
										lpItems[nItem] = [pItem.name, MF_NORMAL];
										arrContent[nItem] = pItem;
									}
									else
										throw "Лишняя запятая, разделяющая объекты в json-файле.";
								}
							}
						}
						catch (e) {
							if (bDebug) AkelPad.Call("Log::Output", 4, WScript.ScriptName + ": " + (e.message || e));
							AkelPad.MessageBox(hWndMain, "Structure of config file " + AkelPad.GetFilePath(opts.pFile, 3 /* CPF_FILEBASENAME */) + "." + opts.pExt + " is invalid!", WScript.ScriptName, 48);
							WScript.Quit();
						}
						return nItem;
					}
				};
				
				//Формирование меню
				nItem = Parser["proc_" + opts.pExt](lpItems);
				
				if (!opts.pID || !oContent[opts.pID]) {	// возвращаем структуру, выбранную в диалоге
					var nEditItem;
					if (opts.pExt == "json")
						nEditItem = "изменить конфигурационный файл...";
					else
						nEditItem = "изменить меню...";
					
					if (!(lpItems.length == 1 && bIgnoreMenu)) {
						//Добавление возможности изменять настроечные файлы параметров
						lpItems[nItem] = ["", MF_SEPARATOR];
						lpItems[nItem + 1] = [nEditItem, MF_NORMAL];
						
						//Вывод меню на экран и получение выбранного Item'а
						if (!isNaN(pPOS_PLACE))		//если не числовое значение, то это константа POS_... из ShowMenu.js
							nItem = ShowMenu(lpItems, pPOS_PLACE, pPOS_PLACE);
						else {		//иначе стартовали из тулбара
							pPOS_PLACE = pPOS_PLACE.split(" ");
							var hToolbarHandle = parseInt(pPOS_PLACE[0]);
							var nToolbarItemID = parseInt(pPOS_PLACE[1]);
							var ptPoint = GetToolbarBottonPos(hToolbarHandle, nToolbarItemID)
							nItem = ShowMenu(lpItems, ptPoint.x, ptPoint.y);
						}
					}
					else
						nItem -= 1;
				
					if (nItem != -1) {
						if (lpItems[nItem][0] != nEditItem) {
							// возвращаем структуру по полученному из диалога номеру элемента меню
							if (!bReturnStructure)
								return arrContent[nItem].options;  //Возвращаем опции выбранного пункта меню
							else
								return arrContent[nItem];          //Возвращаем полностью структуру
						}
						else {
							AkelPad.OpenFile(opts.pFile);    //Открываем файл параметров для внесения изменений
							WScript.Quit();
						}
					}
					else
						return "";
				}
				else {
					// возвращаем структуру по переданному id
					if (!bReturnStructure)
						return oContent[opts.pID].options;  //Возвращаем опции выбранного пункта меню
					else
						return oContent[opts.pID];          //Возвращаем полностью структуру
				}
			}
			else {
				if (AkelPad.MessageBox(hWndMain, "Файл параметров '" + opts.pFile + "' ПУСТ! Открыть его?", pScriptName, 4 /*MB_YESNO*/ + 48 /*MB_ICONEXCLAMATION*/) == 6)
					AkelPad.OpenFile(opts.pFile);
				WScript.Quit();
			}
		}
		else {
			if (AkelPad.MessageBox(hWndMain, "Файл параметров '" + opts.pFile + "' НЕ СУЩЕСТВУЕТ! Создать его?", pScriptName, 4 /*MB_YESNO*/ + 48 /*MB_ICONEXCLAMATION*/) == 6) {
				AkelPad.SendMessage(hWndMain, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 0);
				hWndEdit = AkelPad.GetEditWnd();
				AkelPad.SaveFile(hWndEdit, opts.pFile);
			}
			WScript.Quit();
		}
	}
}

function initMenuParams(pPOS_PLACE) {
	var result = false;
	if (hWndMain) {
		var params = getSelectedMenuItem(pPOS_PLACE, false);
		if (params) {
			for (var p in params) {
				opts[p] = AkelPad.GetArgValue(p, "") || params[p] || opts[p] /* ini */ || "";
			}
			result = true;
		}
	}
	return result;
}

function initArgs(pNames) {
	for (var p in pNames) {
		opts[pNames[p]] = AkelPad.GetArgValue(pNames[p], "") || opts[pNames[p]] /* ini */;
	}
}

// low priority
function initIniOptions(pNames) {
	if (bIniExist >= 0) {
		var oSet = AkelPad.ScriptSettings();
		if (oSet.Begin("" /* for current script */ , 0x01 /* POB_READ */)) {
			if (bIniExist == 0) {
				if (!opts['pExt']) pNames.push('pExt');
				if (!opts['pFile']) pNames.push('pFile');
			}
			for (var p in pNames) {
				opts[pNames[p]] = oSet.Read(pNames[p], 3 /*PO_STRING*/) || "";
			}
			oSet.End();
			bIniExist = 1;
		}
	}
	else {
		bIniExist = -1;
	}
}

function checkArg(oTitle, option) {
	if (!option) {
		AkelPad.MessageBox(hWndMain, "Option(s) " + oTitle + " should be set!", WScript.ScriptName, 48);
		WScript.Quit();
	}
}

function expandPath(path) {
	if (path) {
		path = WshShell.ExpandEnvironmentStrings(path);
		path = path.replace("%a", AkelPad.GetAkelDir(0));	//ADTYPE_ROOT
		path = path.replace("%t", AkelPad.GetAkelDir(1) + "\\Tools");
		path = path.replace("%p", AkelPad.GetAkelDir(4));	//ADTYPE_PLUGS
		path = path.replace("%s", AkelPad.GetAkelDir(5));	//ADTYPE_SCRIPTS
		path = path.replace("%i", AkelPad.GetAkelDir(6));	//ADTYPE_INCLUDE
		path = path.replace("%o", AkelPad.GetAkelDir(5) + "\\Params");
	}
	else {
		path = "";
	}
	return path;
}

function checkDirPath(folder) {
	if (!folder || !fso.FolderExists(folder)) {
		AkelPad.MessageBox(hWndMain, "Folder '" + folder + "' does not exist! ", WScript.ScriptName, 48);
		WScript.Quit();
	}
}

function checkFilePath(fTitle, file) {
	if (!file || !fso.FileExists(file)) {
		AkelPad.MessageBox(hWndMain, "Path '" + file + "' is invalid! " + fTitle + " is not found.", WScript.ScriptName, 48);
		WScript.Quit();
	}
}

function trim(pText, chars) {
	return pText.replace(new RegExp("(^[" + chars + "])|([" + chars + "]+$)", "g"), "");
}
Скрипт использует ShowMenu.js из дистрибутива Scripts-плагина.


Пример использования:
создайте в директории со скриптами файл.. например test.js, с таким содержимым:

Code: Select all

if (! AkelPad.Include("ShowMenuEx.js")) WScript.Quit();

var pMenuLabel = getSelectedMenuItem(POS_CARET, false);

WScript.Echo(pMenuLabel);
далее скрипт всё сам расскажет :D

Менюхи можно менять на лету, с помощью "изменить меню..." внизу менюхи ;)


p.s.: Благодарности: Instructor, FeyFre, Infocatcher, se7h, Lenchik.
Last edited by VladSh on Fri Jun 19, 2015 8:57 pm, edited 27 times in total.

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

Opening on the fly internal files of AkelPad

Post by VladSh »


Единственная функция, что здесь была, перенесена в CaretSelect.js.


Code: Select all

// Description(1033): Opens help for Scripts-plugin and goes to the requested method
// Description(1049): Открывает справку по Scripts-плагину и переходит к запрашиваемому методу
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8164#p8164
// Version: 1.4 (2015.01.15)
// Author: VladSh
// 
// Argument: Eng, Rus, etc.

if (! AkelPad.Include("CaretSelect.js")) WScript.Quit();

var pLng = AkelPad.GetArgLine() || "Rus";

var pHelpFile = "\\AkelFiles\\Docs\\Plugs\\Scripts-" + pLng + ".txt";

openHelpString(pHelpFile, AkelPad.GetSelText(), 2);


Code: Select all

// Description(1033): Opens coder-plugin configuration file
// Description(1049): Открывает файл параметров Coder-плагина
// Если в аргументах не передано расширение файла, то открывается файл параметров, применённый к текущему файлу
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8164#p8164
// Version: 1.10 (2015.01.15)
// Author: VladSh

if (! AkelPad.Include("CaretSelect.js")) WScript.Quit();

var pExt = AkelPad.GetArgLine();
var coderFileName;

if (!pExt) {
	if (AkelPad.Include("CoderFunctions.js"))
		coderFileName = GetSyntaxFile(AkelPad.GetEditWnd());
	
	if (!coderFileName) {
		pExt = AkelPad.GetFilePath(AkelPad.GetEditFile(0), 4 /*CPF_FILEEXT*/);
		if (!pExt) WScript.Quit();
		coderFileName = pExt + ".coder";
	}
}
else {
	coderFileName = pExt + ".coder";
}

if (coderFileName) {
	openHelpString("\\AkelFiles\\Plugs\\Coder\\" + coderFileName, AkelPad.GetSelText(), 2);
}
Last edited by VladSh on Thu Jan 15, 2015 4:37 pm, edited 21 times in total.

Offline
Posts: 767
Joined: Mon Sep 28, 2009 10:03 am
Location: Minsk, Belarus

Post by se7h »

Show help for selected or caret position word

(Справка по выделенному или текущему слову)

Code: Select all

/// Show help for selected or word at caret position
//
// Required ChmKw.exe (AkelPad\AkelFiles\Tools)
//
// Version: 1.6 (05.08.2010)
//
// Path to CHM files: AkelPad\AkelFiles\Help
//
// Usage:
// Call("Scripts::Main", 1, "LanguageHelp.js", "help_name.chm")
//
// Or support ShowMenuEx.js if you do not specify a flags in argument:
//  Call("Scripts::Main", 1, "LanguageHelp.js")

var nPos = AkelPad.GetSelStart();
var WshShell = new ActiveXObject("WScript.shell");
var pChmKwPath = AkelPad.GetAkelDir() + "\\AkelFiles\\Tools\\ChmKw.exe";

var fso = new ActiveXObject("Scripting.FileSystemObject");

if(fso.FileExists(pChmKwPath) == false)
    AkelPad.MessageBox(hWndEdit, 'File "' + pChmKwPath + '" Not found!', "AkelPad -> " + WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);

var pHelpDir = AkelPad.GetAkelDir() + "\\AkelFiles\\Help\\";
var pHelpPath = "";

if(WScript.Arguments.length) {
    pHelpPath = pHelpDir + WScript.Arguments(0);
} else if(pHelpPath == "") {
    eval(AkelPad.ReadFile(AkelPad.GetAkelDir() + "\\AkelFiles\\Plugs\\Scripts\\ShowMenuEx.js"));
    var pHelpFile = getSelectedMenuItem(POS_CURSOR, "", 0);

    if(pHelpFile == "") {
        WScript.Quit();
    }

    pHelpPath = pHelpDir + pHelpFile;
}

var hWndEdit = AkelPad.GetEditWnd();

if(hWndEdit) {
    if(AkelPad.GetSelEnd() == nPos) {
        var nWordBeg = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 0/*WB_LEFT*/, nPos);
        var nWordEnd = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 7/*WB_RIGHTBREAK*/, nWordBeg);

        if(nWordEnd < nPos) {
            nWordBeg = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 0/*WB_LEFT*/, nPos);
            nWordEnd = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 7/*WB_RIGHTBREAK*/, nWordBeg);
        }

        if(nWordEnd > nPos) {
            AkelPad.SetSel(nWordBeg, nWordEnd);
        }
    }

    var sSel = AkelPad.GetSelText();
    pHelpPath = pHelpPath + "::/@" + sSel;
}

pHelpPath = correctCommandLine(pHelpPath);
pChmKwPath = correctCommandLine(pChmKwPath);
WshShell.Run("%COMSPEC% /c " + "\"" + pChmKwPath + " " + pHelpPath + "\"", 0, false);

function correctCommandLine(pPath) {
    if(pPath.search( / /) != -1) {
        return "\"" + pPath + "\"";
    } else {
        return pPath;
    }
}
(v1.6 - 05.08.2010)

Download and place ChmKw.exe in AkelPad\AkelFiles\Tools\

ChmKw.exe (only 2 kb) allows you to search for index CHM, forget about recompilations and the like, simply download the help file, place it in folder and enjoy!

Path to CHM files AkelPad\AkelFiles\Help

Support ShowMenuEx.js if you do not specify a file name in argument

Some help files (update 03.08.2010)
HTML.chm (07.10.2010) , CSS.chm (22.07.2010), JS.chm (07.10.2010)

Usage:

Code: Select all

Call("Scripts::Main", 1, "LanguageHelp.js", "help_name.chm")

Code: Select all

-"Select Help" Call("Scripts::Main", 1, "LanguageHelp.js")    // required ShowMenuEx.js
-"HTML Help" Call("Scripts::Main", 1, "LanguageHelp.js", "HTML.chm")
-"CSS Help" Call("Scripts::Main", 1, "LanguageHelp.js", "CSS.chm")
-"JS Help" Call("Scripts::Main", 1, "LanguageHelp.js", "JS.chm")


Code: Select all

HTML.chm = HTML Item
CSS.chm = CSS Item
JS.chm = JS Item


Code: Select all

1.4: transition to ChmKw.exe
1.5: added check for ChmKw.exe
1.6: corrected method call CHM


p.s.: thank VladSh and FeyFre for their scripts
Last edited by se7h on Thu Oct 07, 2010 8:56 pm, edited 11 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Selects entire lines, copies, moves up/down or duplicates selected lines.
New version.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8224#p8224
// Version: 2015-04-05
// Author: KDJ
//
// *** Selects, copies, moves, duplicates entire lines ***
//
// Usage:
//   Call("Scripts::Main", 1, "LinesSelectCopyMoveDuplicate.js"[, "Action Shift"])
//   Action:
//     S  - select entire lines
//     C  - copy block of lines to clipboard
//     M  - move block of lines up/down
//     D  - duplicate block of lines
//     DL - duplicate individual lines (argument Shift is ignored)
//   Shift:
//     -n - shift up n lines
//     n  - shift down n lines
//     T  - shift to top
//     B  - shift to bottom
//
// Examples:
//  "S 5"  - selects entire lines of 5 below
//  "M -3" - moves lines of 3 above
//  "D T"  - duplicates lines at top
//
// Remarks:
//   If no arguments - menu displays.
//   If only the first argument (except DL) - input box.
//   This script processes entire unwrapped lines included by the selection.
//   If there is no selection, processes current line.
//   Remembers the selection and caret position relative moving text.
//   Can assign shortcut keys, eg: Ctrl+Shift+L, Ctrl+Shift+C, Ctrl+Shift+Up, Ctrl+Shift+Down, Ctrl+Shift+Y.

var sTxtSelect   = "Select entire lines";
var sTxtCopy     = "Copy block of lines";
var sTxtMove     = "Move block of liness";
var sTxtDupBlock = "Duplicate block of lines";
var sTxtDupLines = "Duplicate individual lines";
var sTxtShift    = "Shift (T=top, B=bottom)";

var oSys     = AkelPad.SystemFunction();
var hEditWnd = AkelPad.GetEditWnd();
var nWordWrap;
var nBegSel;
var nEndSel;
var bCarAtEnd;
var bColSel;
var nLine1;
var nLine2;
var nLastLine;
var nOffset1;
var nOffset2;
var nOffset3;
var sAction;
var nShift;
var sArg1;
var sText1;
var sText2;
var aLine;
var i;

if (hEditWnd)
{
  //Get arguments
  if (WScript.Arguments.length)
    sAction = WScript.Arguments(0).toUpperCase();
  else
    sAction = GetAction();

  if ((sAction != "S") && (sAction != "C") && (sAction != "M") && (sAction != "D") && (sAction != "DL"))
    WScript.Quit();

  SetRedraw(hEditWnd, false);

  //Disable Word Wrap
  nWordWrap = SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
  if (nWordWrap > 0)
    AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

  nBegSel   = AkelPad.GetSelStart();
  nEndSel   = AkelPad.GetSelEnd();
  bCarAtEnd = (GetOffset(hEditWnd, 5 /*AEGI_CARETCHAR*/) == nEndSel);
  bColSel   = SendMessage(hEditWnd, 3127 /*AEM_GETCOLUMNSEL*/, 0, 0);
  nLine1    = SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nBegSel);
  nLine2    = SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nEndSel);
  nLastLine = SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, -2);

  if (sAction == "DL")
  {
    if (! AkelPad.GetEditReadOnly(hEditWnd))
    {
      nOffset1 = GetBeginLine(nLine1);
      nOffset2 = GetEndLine(nLine2);
      nEndSel += nOffset2 - nOffset1 + 1;

      AkelPad.SetSel(nOffset1, nOffset2);

      aLine = AkelPad.GetSelText().split("\r");

      for (i = aLine.length - 1; i >= 0; --i)
        aLine.splice(i, 0, aLine[i]);

      AkelPad.ReplaceSel(aLine.join("\r"));

      if (bCarAtEnd)
        AkelPad.SetSel(nBegSel, nEndSel);
      else
        AkelPad.SetSel(nEndSel, nBegSel);
  
      SendMessage(hEditWnd, 3128 /*AEM_UPDATESEL*/, bColSel, 0);
    }
  }
  else
  {
    if (WScript.Arguments.length > 1)
      sArg1 = WScript.Arguments(1).toUpperCase();
    else
      sArg1 = GetShift();

    if (sArg1 == "T")
      nShift = -nLine1 - ((sAction == "D") ? 1 : 0);
    else if (sArg1 == "B")
      nShift = nLastLine - nLine2 + ((sAction == "D") ? 1 : 0);
    else
    {
      nShift = parseInt(sArg1);

      if (isFinite(nShift))
      {
        if (sAction =="D")
        {
          if ((nShift < 0) && (nShift < -nLine1 - 1))
            nShift = -nLine1 - 1;
          else if ((nShift > 0) && (nShift > nLastLine - nLine1 + 1))
            nShift = nLastLine - nLine2 + 1;
        }
        else
        {
          if ((nShift < 0) && (nShift < -nLine1))
            nShift = -nLine1;
          else if ((nShift > 0) && (nShift > nLastLine - nLine2))
            nShift = nLastLine - nLine2;
        }
      }
    }

    if (isFinite(nShift))
    {
      //Select or Copy
      if ((sAction == "S") || (sAction == "C"))
      {
        nBegSel = GetBeginLine(nLine1 + nShift);
        nEndSel = GetEndLine(nLine2 + nShift);
      }

      //Move
      else if (sAction == "M")
      {
        if (nShift && (! AkelPad.GetEditReadOnly(hEditWnd)))
        {
          if (nShift < 0)
          {
            nOffset1 = GetBeginLine(nLine1 + nShift);
            nOffset2 = GetEndLine(nLine1 - 1);
            nOffset3 = GetEndLine(nLine2);
          }
          else
          {
            nOffset1 = GetBeginLine(nLine1);
            nOffset2 = GetEndLine(nLine2);
            nOffset3 = GetEndLine(nLine2 + nShift);
          }

          sText1 = AkelPad.GetTextRange(nOffset1,     nOffset2);
          sText2 = AkelPad.GetTextRange(nOffset2 + 1, nOffset3) + "\r";
          AkelPad.SetSel(nOffset1, nOffset3);
          AkelPad.ReplaceSel(sText2 + sText1);

          if (nShift < 0)
          {
            nBegSel -= sText1.length + 1;
            nEndSel -= sText1.length + 1;
          }
          else
          {
            nBegSel += sText2.length;
            nEndSel += sText2.length;
          }
        }
      }

      //Duplicate block
      else
      {
        if (nShift && (! AkelPad.GetEditReadOnly(hEditWnd)))
        {
          nOffset1 = GetBeginLine(nLine1);
          nOffset2 = GetEndLine(nLine2);
  
          if (nShift < 0)
          {
            sText1   = AkelPad.GetTextRange(nOffset1, nOffset2) + "\r";
            nOffset3 = GetBeginLine(nLine1 + nShift + 1);
            nBegSel += nOffset3 - nOffset1;
            nEndSel += nOffset3 - nOffset1;
          }
          else
          {
            sText1   = "\r" + AkelPad.GetTextRange(nOffset1, nOffset2);
            nOffset3 = GetEndLine(nLine2 + nShift - 1);
            nBegSel += nOffset3 - nOffset1 + 1;
            nEndSel += nOffset3 - nOffset1 + 1;
          }
  
          AkelPad.SetSel(nOffset3, nOffset3);
          AkelPad.ReplaceSel(sText1);
        }
      }

      if (sAction == "C")
        AkelPad.SetClipboardText(AkelPad.GetTextRange(nBegSel, nEndSel));
      else
      {
        if (bCarAtEnd)
          AkelPad.SetSel(nBegSel, nEndSel);
        else
          AkelPad.SetSel(nEndSel, nBegSel);
  
        if (sAction != "S")
          SendMessage(hEditWnd, 3128 /*AEM_UPDATESEL*/, bColSel, 0);
      }
    }
  }

  if (nWordWrap > 0)
  {
    AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
    SendMessage(hEditWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
  }

  SetRedraw(hEditWnd, true);
}

function GetAction()
{
  var MF_STRING = 0x0000;
  var MF_GRAYED = 0x0001;
  var lpPoint = AkelPad.MemAlloc(8); //sizeof(POINT)
  var hMenu   = oSys.Call("User32::CreatePopupMenu");
  var hWndHid = oSys.Call("User32::CreateWindowEx" + _TCHAR, 0, "STATIC", 0, 0x50000000 /*WS_VISIBLE|WS_CHILD*/, 0, 0, 0, 0, hEditWnd, 0, AkelPad.GetInstanceDll(), 0);
  var aAction = ["", "S", "C", "M", "D", "DL"];
  var nX;
  var nY;
  var nCmd;

  SendMessage(hEditWnd, 3190 /*AEM_GETCARETPOS*/, lpPoint, 0);
  oSys.Call("User32::ClientToScreen", hEditWnd, lpPoint);

  nX = AkelPad.MemRead(_PtrAdd(lpPoint, 0), 3 /*DT_DWORD*/);
  nY = AkelPad.MemRead(_PtrAdd(lpPoint, 4), 3 /*DT_DWORD*/) + SendMessage(hEditWnd, 3188 /*AEM_GETCHARSIZE*/, 0 /*AECS_HEIGHT*/, 0);

  oSys.Call("User32::SetFocus", hWndHid);
  oSys.Call("User32::AppendMenu" + _TCHAR, hMenu, MF_STRING, 1, sTxtSelect + "...");
  oSys.Call("User32::AppendMenu" + _TCHAR, hMenu, MF_STRING, 2, sTxtCopy + "...");
  oSys.Call("User32::AppendMenu" + _TCHAR, hMenu, AkelPad.GetEditReadOnly(hEditWnd) ? MF_GRAYED : MF_STRING, 3, sTxtMove + "...");
  oSys.Call("User32::AppendMenu" + _TCHAR, hMenu, AkelPad.GetEditReadOnly(hEditWnd) ? MF_GRAYED : MF_STRING, 4, sTxtDupBlock + "...");
  oSys.Call("User32::AppendMenu" + _TCHAR, hMenu, AkelPad.GetEditReadOnly(hEditWnd) ? MF_GRAYED : MF_STRING, 5, sTxtDupLines);

  nCmd = oSys.Call("User32::TrackPopupMenu", hMenu, 0x0180 /*TPM_RETURNCMD|TPM_NONOTIFY*/, nX, nY, 0, hWndHid, 0);

  AkelPad.MemFree(lpPoint);
  oSys.Call("User32::DestroyMenu", hMenu);
  oSys.Call("User32::DestroyWindow", hWndHid);

  return aAction[nCmd];
}

function GetShift()
{
  var sText = "1";
  var sCaption;

  if (sAction == "S")
  {
    sCaption = sTxtSelect;
    sText    = "0";
  }
  else if (sAction == "C")
  {
    sCaption = sTxtCopy;
    sText    = "0";
  }
  else if (sAction == "M")
    sCaption = sTxtMove;
  else if (sAction == "D")
    sCaption = sTxtDupBlock;
  else
    sCaption = sTxtDupLines;

  sCaption += ": " + (nLine1 + 1) + " - " + (nLine2 + 1);

  sText = AkelPad.InputBox(hEditWnd, sCaption, sTxtShift, sText);

  if (sText)
    sText = sText.toUpperCase();

  return sText;
}

function SetRedraw(hWnd, bRedraw)
{
  SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
  bRedraw && oSys.Call("User32::InvalidateRect", hWnd, 0, true);
}

function GetOffset(hWnd, nFlag)
{
  var lpIndex;
  var nOffset = -1;

  if (lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/))
  {
    SendMessage(hWnd, 3130 /*AEM_GETINDEX*/, nFlag, lpIndex);
    nOffset = SendMessage(hWnd, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, lpIndex);
    AkelPad.MemFree(lpIndex);
  }
  return nOffset;
}

function GetBeginLine(nLine)
{
  return SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine, 0);
}

function GetEndLine(nLine)
{
  return SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine, 0) + SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine, 0), 0);
}

function SendMessage(hWnd, uMsg, wParam, lParam)
{
  return oSys.Call("User32::SendMessage" + _TCHAR, hWnd, uMsg, wParam, lParam);
}


Old version.
Vertically moves the lines covered by the selection.

Code: Select all

// Move up or down selected lines - 2010-07-28
// If there is no selection, it moves the current line.
// Moved lines, are selected in their entirety.
//
// Call("Scripts::Main", 1, "MoveLinesUpDown_alt.js", "-1") - move up
// Call("Scripts::Main", 1, "MoveLinesUpDown_alt.js", "1")  - move down
//
// Can assign shortcut keys, eg: Ctrl+Alt+Up, Ctrl+Alt+Down


var nMovDir;
if (WScript.Arguments.length)
	nMovDir = WScript.Arguments(0);
if (!((nMovDir == -1) || (nMovDir == 1)))
	WScript.Quit();

var hEditWnd = AkelPad.GetEditWnd();

SetRedraw(hEditWnd, false);


// SmartSel::NoSelEOL plugin
var pFuncEOL  = "SmartSel::NoSelEOL";
var bNoSelEOL = AkelPad.IsPluginRunning(pFuncEOL);
if (bNoSelEOL)
   AkelPad.Call(pFuncEOL);


// Word Wrap
var nWordWrap = AkelPad.SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
if (nWordWrap > 0)
	AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);


var nBegSel   = AkelPad.GetSelStart();
var nEndSel   = AkelPad.GetSelEnd();
var nLine1    = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nBegSel);
var nLine2    = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nEndSel);
var nLastLine = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, -2);
var pEOL      = "\r";

var nBegLine1;
var nBegLine2;
var nLenLine2;
var nSel1;
var nSel2;
var pSelTxt;
var pTxt1;
var pTxt2;

if (((nMovDir == 1) && (nLine2 < nLastLine) || (nMovDir == -1) && (nLine1 > 0)) && !AkelPad.GetEditReadOnly(hEditWnd))
{
	nBegSel = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nEndSel = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0) + AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nEndSel, 0);

	if (nMovDir == 1)
		++ nLine2;
	else
		-- nLine1;

	nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
	nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
	nSel1 = nBegLine1;
	nSel2 = nBegLine2 + nLenLine2;
	if (nLine2 < nLastLine)
		++ nSel2; 

	AkelPad.SetSel(nSel1, nSel2);
	pSelTxt = AkelPad.GetSelText(1 /*\r*/);

	if (nMovDir == 1)
	{
		if (nLine2 < nLastLine)
		{
			pTxt1 = pSelTxt.substr(0, pSelTxt.lastIndexOf(pEOL) - nLenLine2);
			pTxt2 = pSelTxt.substr(pTxt1.length);
		}
		else
		{
			pTxt1 = pSelTxt.substr(0, pSelTxt.lastIndexOf(pEOL));
			pTxt2 = pSelTxt.substr(pSelTxt.lastIndexOf(pEOL) + 1) + pEOL;
		}
		nBegSel += pTxt2.length;
		nEndSel += pTxt2.length;
	}
	else
	{
		if (nLine2 < nLastLine)
		{
			pTxt1 = pSelTxt.substr(0, pSelTxt.indexOf(pEOL) + 1);
			pTxt2 = pSelTxt.substr(pSelTxt.indexOf(pEOL) + 1);
			nBegSel -= pTxt1.length;
			nEndSel -= pTxt1.length;
		}
		else
		{
			pTxt1 = pSelTxt.substr(0, pSelTxt.indexOf(pEOL));
			pTxt2 = pSelTxt.substr(pSelTxt.indexOf(pEOL) + 1) + pEOL;
			nBegSel -= (pTxt1.length + 1);
			nEndSel -= (pTxt1.length + 1);
		}
	}

	AkelPad.ReplaceSel(pTxt2 + pTxt1);

	if (nMovDir == 1)
		AkelPad.SetSel(nBegSel, nEndSel);
	else
		AkelPad.SetSel(nEndSel, nBegSel);
}

if (nWordWrap > 0)
	AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

if (bNoSelEOL)
	AkelPad.Call(pFuncEOL);

SetRedraw(hEditWnd, true);


///////////////////////////////

function SetRedraw(hWnd, bRedraw)
{
	var oSys = AkelPad.SystemFunction();
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}


Old version.
Improved version of the script MoveLinesUpDown_alt.js. In addition, the script duplicates the lines or only selects.

Code: Select all

// Move up/down, duplicate selected lines or only select whole lines - 2010-10-12
// If there is no selection, it selects, moves or duplicates the current line.
//
// Call("Scripts::Main", 1, "LinesMoveDuplicateSelect.js", "0")  - only select whole lines
// Call("Scripts::Main", 1, "LinesMoveDuplicateSelect.js", "-1") - move up
// Call("Scripts::Main", 1, "LinesMoveDuplicateSelect.js", "1")  - move down
// Call("Scripts::Main", 1, "LinesMoveDuplicateSelect.js", "2")  - duplicate
//
// Can assign shortcut keys, eg: Ctrl+Shift+L, Ctrl+Shift+Up, Ctrl+Shift+Down, Ctrl+Shift+Y.


var hEditWnd = AkelPad.GetEditWnd();
if (! hEditWnd)
	WScript.Quit();

var nAction;
if (WScript.Arguments.length)
	nAction = WScript.Arguments(0);
if (!((nAction == -1) || (nAction == 1)  || (nAction == 0)  || (nAction == 2)))
	WScript.Quit();


SetRedraw(hEditWnd, false);

// Word Wrap
var nWordWrap = AkelPad.SendMessage(hEditWnd, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

if (! LinesSelect(hEditWnd) || (nAction == 0) || AkelPad.GetEditReadOnly(hEditWnd))
{
	if (nWordWrap > 0) AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);
	SetRedraw(hEditWnd, true);
	WScript.Quit();
}

// SmartSel::NoSelEOL plugin
var pFuncEOL  = "SmartSel::NoSelEOL";
var bNoSelEOL = AkelPad.IsPluginRunning(pFuncEOL);
if (bNoSelEOL)
   AkelPad.Call(pFuncEOL);

var nBegSel   = AkelPad.GetSelStart();
var nEndSel   = AkelPad.GetSelEnd();
var nLine1    = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nBegSel);
var nLine2    = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nEndSel);
var nLastLine = AkelPad.SendMessage(hEditWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, -2);
var pEOL      = "\r";

var nBegLine1;
var nBegLine2;
var nLenLine2;
var nSel1;
var nSel2;
var pSelTxt;
var pTxt1;
var pTxt2;

if (((nAction == 1) && (nLine2 < nLastLine) || (nAction == -1) && (nLine1 > 0)))
{
	if (nAction == 1)
		++ nLine2;
	else
		-- nLine1;

	nBegLine1 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nBegLine2 = AkelPad.SendMessage(hEditWnd, 187 /*EM_LINEINDEX*/, nLine2, 0);
	nLenLine2 = AkelPad.SendMessage(hEditWnd, 193 /*EM_LINELENGTH*/, nBegLine2, 0);
	nSel1 = nBegLine1;
	nSel2 = nBegLine2 + nLenLine2;

	AkelPad.SetSel(nSel1, nSel2);
	pSelTxt = AkelPad.GetSelText(1 /*\r*/);

	if (nAction == 1)
	{
		pTxt1 = pSelTxt.substr(0, pSelTxt.lastIndexOf(pEOL));
		pTxt2 = pSelTxt.substr(pSelTxt.lastIndexOf(pEOL) + 1) + pEOL;
		nBegSel += pTxt2.length;
		nEndSel += pTxt2.length;
	}
	else
	{
		pTxt1 = pSelTxt.substr(0, pSelTxt.indexOf(pEOL));
		pTxt2 = pSelTxt.substr(pSelTxt.indexOf(pEOL) + 1) + pEOL;
		nBegSel -= (pTxt1.length + 1);
		nEndSel -= (pTxt1.length + 1);
	}

	AkelPad.ReplaceSel(pTxt2 + pTxt1);

	if (nAction == 1)
		AkelPad.SetSel(nBegSel, nEndSel);
	else
		AkelPad.SetSel(nEndSel, nBegSel);
}
else if (nAction == 2)
{
	pSelTxt = pEOL + AkelPad.GetSelText(1 /*\r*/);
	AkelPad.SetSel(nEndSel, nEndSel);
	AkelPad.ReplaceSel(pSelTxt);
	AkelPad.SetSel(nBegSel, nEndSel);
}

if (nWordWrap > 0)
	AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

if (bNoSelEOL)
	AkelPad.Call(pFuncEOL);

SetRedraw(hEditWnd, true);


///////////////////////////////

function LinesSelect(hWnd)
{
	var bSelLine;
	var nBegSel = AkelPad.GetSelStart();
	var nEndSel = AkelPad.GetSelEnd();
	var nLine1  = AkelPad.SendMessage(hWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nBegSel);
	var nLine2  = AkelPad.SendMessage(hWnd, 1078 /*EM_EXLINEFROMCHAR*/, 0, nEndSel);

	nBegSel = AkelPad.SendMessage(hWnd, 187 /*EM_LINEINDEX*/, nLine1, 0);
	nEndSel = AkelPad.SendMessage(hWnd, 187 /*EM_LINEINDEX*/, nLine2, 0) + AkelPad.SendMessage(hWnd, 193 /*EM_LINELENGTH*/, nEndSel, 0);

	if (nBegSel < nEndSel)
	{
		AkelPad.SetSel(nBegSel, nEndSel);
		bSelLine = true;
	}
	return bSelLine;
}


function SetRedraw(hWnd, bRedraw)
{
	var oSys = AkelPad.SystemFunction();
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}
Last edited by KDJ on Sun Apr 05, 2015 10:19 am, edited 26 times in total.

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

Post by VladSh »

Alternative script offset the text vertically, without limitation selected strings.

Code: Select all

// Description(1033): Move the text vertically
// Description(1049): Перемещение выделенного текста вверх или вниз, в зависимости от переданного аргумента
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8255#p8255
// Version: 2.3 (2012.06.26)
// Author: VladSh
// 
// Usage:
// 	Call("Scripts::Main", 1, "ShiftVerticaly.js", "-1")	- Up
// 	Call("Scripts::Main", 1, "ShiftVerticaly.js", "1")	- Down

var nMoveDirection = AkelPad.GetArgLine();
if (!nMoveDirection) WScript.Quit();

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var bSelEOL = 1;
var pBreak = "\r";
var nStartCorrect = 0;
var nEndCorrect = 0;
var nMinSel = AkelPad.GetSelStart();
var nMaxSel = AkelPad.GetSelEnd();
var nLastLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, -2);			//Последняя строка файла!
var nMinLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nMinSel);
if (nMoveDirection < 0) {
	if (nMinLine == 0) WScript.Quit();
	nMinLine -= 1;
}
var nMaxLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nMaxSel) + 1;
if (nMoveDirection > 0) {
	if (nMaxLine -1 == nLastLine) WScript.Quit();
	nMaxLine += 1;
}
nMinLineIndex = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, nMinLine, 0);
nMaxLineIndex = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, nMaxLine, 0) - bSelEOL;

setRedraw(hWndEdit, false);

AkelPad.SetSel(nMinLineIndex, nMaxLineIndex);

var pSelText = AkelPad.GetSelText();

if (nMoveDirection < 0) nSep = pSelText.indexOf(pBreak); else nSep = pSelText.lastIndexOf(pBreak);

var partFirst = pSelText.substr(0, nSep);
var partRest = pSelText.substr(nSep + 1);

if (nMoveDirection < 0) {
	nEndCorrect = nEndCorrect + partFirst.length + bSelEOL;
}
else {
	nStartCorrect = partRest.length + 1;
	nEndCorrect = nEndCorrect - 1 + bSelEOL;
}
AkelPad.ReplaceSel(partRest + pBreak + partFirst, -1);
AkelPad.SetSel(AkelPad.GetSelStart() + nStartCorrect, AkelPad.GetSelEnd() - nEndCorrect);

setRedraw(hWndEdit, true);


function setRedraw(hWnd, bRedraw) {
	AkelPad.SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
	bRedraw && oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}


p.s.: KDJ thanks for the idea of this script, DV thanks for the new NoSelEOL!
Last edited by VladSh on Wed Jan 14, 2015 10:46 pm, edited 9 times in total.

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

Post by VladSh »

Code: Select all

// Description(1033): Opens files located in the folder
// Description(1049): Открывает файлы, находящиеся в папке
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8303#p8303
// Version: 1.5 (2015.01.15)
// Author: VladSh
// 
// Arguments:
// 	-file - initial file
// 	-binary:
// 		• [""]    - behavior by default
// 		• "1warn" - one question about binary
// 		• "ignoreAll" - ignore all binaries
// 		• "openAll" - silent opening all binaries
// 		
// Usage:
// 	-"Открыть все файлы папки" Call("Scripts::Main", 1, "OpenAllFilesFromFileFolder.js", `-file="%f" -binary="1warn"`) Icon("%a\AkelFiles\Plugs\Coder.dll", 1)

var hWndMain = AkelPad.GetMainWnd();
var pFileCurrent = AkelPad.GetEditFile(0);
var path = AkelPad.GetArgValue("file", pFileCurrent);
var binary = AkelPad.GetArgValue("binary", "");
var openBinary = null;

if (! AkelPad.Include("ProcessFolderFiles.js")) WScript.Quit();
//if (typeof(processFolderFiles) == "function")		//Проверка, подключена ли функция, т.к. подключаемого скрипта может не быть на диске (оставил для памяти)
processFolderFiles(path, true);


function processFile(file) {
	if (file == pFileCurrent) return;
	
	if (!binary) {	//behavior by default
		AkelPad.OpenFile(file);
	}
	else {
		if (!isFileBinary(file)) {
			AkelPad.OpenFile(file, 0x002 /* OD_ADT_REG_CODEPAGE */);	//opening nonbinary
		}
		else {
			if (binary == "ignoreAll") {
				return;
			}
			else if (binary == "1warn") {
				if (openBinary == null) {
					openBinary = AkelPad.OpenFile(file, 0x001 /* OD_ADT_BINARY_ERROR */);	//opening binary with question
					return;
				}
				else if (openBinary == -22 /* EOD_MSGCANCELBINARY */) {	//skip
					return;
				}
			}
			//в т.ч. binary == "openAll"
			AkelPad.OpenFile(file, 0x002 /* OD_ADT_REG_CODEPAGE */);	//silent opening binary WITH codepage detecting
//			AkelPad.OpenFile(file, 0);	//silent opening binary WITHOUT codepage detecting
		}
	}
}

/* Instructor's code (http://akelpad.sourceforge.net/forum/viewtopic.php?p=11344#p11344) */
function isFileBinary(pFile) {
	var lpDetectCodepage;
	var bResult = false;

	if (lpDetectCodepage = AkelPad.MemAlloc(_X64?24:20 /*sizeof(DETECTCODEPAGEW)*/)) {
		AkelPad.MemCopy(lpDetectCodepage /*offsetof(DETECTCODEPAGEW, pFile)*/, AkelPad.MemStrPtr(pFile), 2 /*DT_QWORD*/);
		AkelPad.MemCopy(lpDetectCodepage + (_X64?8:4) /*offsetof(DETECTCODEPAGEW, dwBytesToCheck)*/, 1024, 3 /*DT_DWORD*/);
		AkelPad.MemCopy(lpDetectCodepage + (_X64?12:8) /*offsetof(DETECTCODEPAGEW, dwFlags)*/, 0x11 /*ADT_BINARY_ERROR|ADT_NOMESSAGES*/, 3 /*DT_DWORD*/);
		if (AkelPad.SendMessage(hWndMain, 1177 /*AKD_DETECTCODEPAGEW*/, 0, lpDetectCodepage) == -4 /*EDT_BINARY*/)
			bResult = true;

		AkelPad.MemFree(lpDetectCodepage);
	}
	return bResult;
}


Script uses: ProcessFolderFiles.js.
Last edited by VladSh on Thu Jan 15, 2015 4:05 pm, edited 7 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Moves selected text to the left and right or up and down.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=8506#p8506
// Version: 2015-01-08
// Author: KDJ
//
// *** Move left/right/up/down selected text ***
//
// Usage:
//   Call("Scripts::Main", 1, "TextMove.js", "-1") - move left one character
//   Call("Scripts::Main", 1, "TextMove.js", "1")  - move right one character
//   Call("Scripts::Main", 1, "TextMove.js", "-2") - move to the begin of the line
//   Call("Scripts::Main", 1, "TextMove.js", "2")  - move to the end of the line
//   Call("Scripts::Main", 1, "TextMove.js", "-3") - move one line up
//   Call("Scripts::Main", 1, "TextMove.js", "3")  - move one line down
//
// Can assign shortcut keys, eg: Ctrl+Alt+Left, Ctrl+Alt+Right, Ctrl+Alt+Home, Ctrl+Alt+End, Ctrl+Alt+Up, Ctrl+Alt+Down

var DT_QWORD              = 2;
var DT_DWORD              = 3;
var AEGL_LINECOUNT        = 0;
var AEGL_FIRSTSELLINE     = 1;
var AEGL_LASTSELLINE      = 2;
var AEGI_LASTCHAR         = 2;
var AEGI_FIRSTSELCHAR     = 3;
var AEGI_LASTSELCHAR      = 4;
var AEGI_CARETCHAR        = 5;
var AESELT_COLUMNON       = 0x1;
var AEM_GETSEL            = 3125;
var AEM_SETSEL            = 3126;
var AEM_GETCOLUMNSEL      = 3127;
var AEM_GETLINENUMBER     = 3129;
var AEM_GETINDEX          = 3130;
var AEM_INDEXUPDATE       = 3132;
var AEM_INDEXTORICHOFFSET = 3136;
var AEM_GETWORDWRAP       = 3241;
var IDM_VIEW_WORDWRAP     = 4209;
var EM_LINEINDEX          = 187;
var EM_LINELENGTH         = 193;
var EM_EXLINEFROMCHAR     = 1078;

var hEditWnd = AkelPad.GetEditWnd();
if ((! hEditWnd) || AkelPad.GetEditReadOnly(hEditWnd))
  WScript.Quit();

var nAction;
if (WScript.Arguments.length)
  nAction = WScript.Arguments(0);
if (!((nAction == -1) || (nAction == 1) || (nAction == -2) || (nAction == 2) || (nAction == -3) || (nAction == 3)))
  WScript.Quit();

SetRedraw(hEditWnd, false);

// Word Wrap
var nWordWrap = SendMessage(hEditWnd, AEM_GETWORDWRAP, 0, 0);
if (nWordWrap > 0)
  AkelPad.Command(IDM_VIEW_WORDWRAP);

// SmartSel::NoSelEOL plugin
var sFuncEOL  = "SmartSel::NoSelEOL";
var bNoSelEOL = AkelPad.IsPluginRunning(sFuncEOL);
if (bNoSelEOL)
  AkelPad.Call(sFuncEOL);

var nMove = parseInt(nAction);

if (SendMessage(hEditWnd, AEM_GETCOLUMNSEL, 0, 0))
  TextMoveColumn();
else
  TextMoveNoColumn();

if (nWordWrap > 0)
  AkelPad.Command(IDM_VIEW_WORDWRAP);

if (bNoSelEOL)
  AkelPad.Call(sFuncEOL);

SetRedraw(hEditWnd, true);

function TextMoveColumn()
{
  var sSelText  = AkelPad.GetSelText(1 /*\r*/);
  var nLine1    = SendMessage(hEditWnd, AEM_GETLINENUMBER, AEGL_FIRSTSELLINE, 0);
  var nLine2    = SendMessage(hEditWnd, AEM_GETLINENUMBER, AEGL_LASTSELLINE,  0);
  var nLastLine = SendMessage(hEditWnd, AEM_GETLINENUMBER, AEGL_LINECOUNT,    0) - 1;
  var nLenLine  = SendMessage(hEditWnd, EM_LINELENGTH, GetOffset(hEditWnd, AEGI_CARETCHAR), 0);
  var lpFirstC  = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpLastC   = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpCaret   = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var lpSelect  = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
  var lpSelect1 = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
  var lpBegSel  = lpSelect;
  var lpEndSel  = _PtrAdd(lpSelect, _X64 ? 24 : 12);
  var lpBegSel1 = lpSelect1;
  var lpEndSel1 = _PtrAdd(lpSelect1, _X64 ? 24 : 12);
  var nShiftRow = 0;
  var nShiftCol = 0;
  var nCol1;
  var nCol2;

  SendMessage(hEditWnd, AEM_GETINDEX, AEGI_FIRSTSELCHAR, lpFirstC);
  SendMessage(hEditWnd, AEM_GETINDEX, AEGI_LASTSELCHAR,  lpLastC);
  SendMessage(hEditWnd, AEM_GETSEL, lpCaret, lpSelect);

  nCol1 = AkelPad.MemRead(_PtrAdd(lpFirstC, _X64 ? 16 : 8), DT_DWORD);
  nCol2 = AkelPad.MemRead(_PtrAdd(lpLastC,  _X64 ? 16 : 8), DT_DWORD);

  if (nMove == 1)
    nShiftCol = 1;
  else if ((nMove == -1) && (nCol1 > 0))
    nShiftCol = -1;
  else if ((nMove == 2) && (nLenLine > nCol2))
    nShiftCol = nLenLine - nCol2;
  else if (nMove == -2)
    nShiftCol = - nCol1;
  else if ((nMove == 3) && (nLine2 < nLastLine))
    nShiftRow = 1;
  else if ((nMove == -3) && (nLine1 > 0))
    nShiftRow = -1;

  if ((nShiftRow != 0) || (nShiftCol != 0))
  {
    AkelPad.ReplaceSel("");

    ShiftCharIndex(lpFirstC, nShiftRow, nShiftCol);
    ShiftCharIndex(lpLastC,  nShiftRow, nShiftCol);

    CopyCharIndex(lpBegSel1, lpFirstC);
    CopyCharIndexRowCol(lpEndSel1, lpLastC, lpFirstC);
    AkelPad.MemCopy(_PtrAdd(lpSelect1, _X64 ? 48 : 24), AESELT_COLUMNON, DT_DWORD);

    SendMessage(hEditWnd, AEM_SETSEL, 0, lpSelect1);
    AkelPad.ReplaceSel(sSelText);

    ShiftCharIndex(lpCaret,  nShiftRow, nShiftCol);
    ShiftCharIndex(lpBegSel, nShiftRow, nShiftCol);
    ShiftCharIndex(lpEndSel, nShiftRow, nShiftCol);

    SendMessage(hEditWnd, AEM_SETSEL, lpCaret, lpSelect);
  }

  AkelPad.MemFree(lpFirstC);
  AkelPad.MemFree(lpLastC);
  AkelPad.MemFree(lpCaret);
  AkelPad.MemFree(lpSelect);
  AkelPad.MemFree(lpSelect1);
}

function TextMoveNoColumn()
{
  var nBegSel   = AkelPad.GetSelStart();
  var nEndSel   = AkelPad.GetSelEnd();
  var nCarChar  = GetOffset(hEditWnd, AEGI_CARETCHAR);
  var bCarOnEnd = (nCarChar == nBegSel) ? false : true;
  var nLastChar = GetOffset(hEditWnd, AEGI_LASTCHAR);
  var nLine1    = SendMessage(hEditWnd, EM_EXLINEFROMCHAR, 0, nBegSel);
  var nLine2    = SendMessage(hEditWnd, EM_EXLINEFROMCHAR, 0, nEndSel);
  var nLastLine = SendMessage(hEditWnd, EM_EXLINEFROMCHAR, 0, -2);
  var nBegLine;
  var nLenLine;
  var nCol;
  var sSelText;
  var sText1;
  var sText2;

  if ((nBegSel == nEndSel) || ((nMove > 0) && (nMove < 3) && (nEndSel == nLastChar)) || ((nMove > -3) && (nMove < 0) && (nBegSel == 0)) || ((nMove == 3) && (nLine2 == nLastLine)) || ((nMove == -3) && (nLine1 == 0)))
    nMove = 0;
  else if (nMove == 2)
  {
    nBegLine = SendMessage(hEditWnd, EM_LINEINDEX, nLine2, 0);
    nLenLine = SendMessage(hEditWnd, EM_LINELENGTH, nBegLine, 0);
    nMove    = nBegLine + nLenLine - nEndSel;
  }
  else if (nMove == -2)
  {
    nBegLine = SendMessage(hEditWnd, EM_LINEINDEX, nLine1, 0);
    nMove    = nBegLine - nBegSel;
  }
  else if (nMove == 3)
  {
    nBegLine = SendMessage(hEditWnd, EM_LINEINDEX, nLine1, 0);
    nCol     = nBegSel - nBegLine;
    nBegLine = SendMessage(hEditWnd, EM_LINEINDEX, nLine2 + 1, 0);
    nLenLine = SendMessage(hEditWnd, EM_LINELENGTH, nBegLine, 0);
    if (nCol < nLenLine)
      nMove = nBegLine + nCol - nEndSel;
    else
      nMove = nBegLine + nLenLine - nEndSel;
  }
  else if (nMove == -3)
  {
    nBegLine = SendMessage(hEditWnd, EM_LINEINDEX, nLine1, 0);
    nCol     = nBegSel - nBegLine;
    nBegLine = SendMessage(hEditWnd, EM_LINEINDEX, nLine1 - 1, 0);
    nLenLine = SendMessage(hEditWnd, EM_LINELENGTH, nBegLine, 0);
    if (nCol < nLenLine)
      nMove = - nLenLine - 1;
    else
      nMove = - nCol - 1;
  }

  if (nMove != 0)
  {
    if (nMove > 0)
      AkelPad.SetSel(nBegSel, nEndSel + nMove);
    else
      AkelPad.SetSel(nBegSel + nMove, nEndSel);
  
    sSelText = AkelPad.GetSelText(1 /*\r*/);
  
    if (nMove > 0)
    {
      sText1 = sSelText.substr(0, nEndSel - nBegSel);
      sText2 = sSelText.substr(nEndSel - nBegSel);
    }
    else
    {
      sText1 = sSelText.substr(0, -nMove);
      sText2 = sSelText.substr(-nMove);
    }
  
    nBegSel += nMove;
    nEndSel += nMove;
  
    AkelPad.ReplaceSel(sText2 + sText1);
  
    if (bCarOnEnd)
      AkelPad.SetSel(nBegSel, nEndSel);
    else
      AkelPad.SetSel(nEndSel, nBegSel);
  }
}

function SetRedraw(hWnd, bRedraw)
{
  SendMessage(hWnd, 11 /*WM_SETREDRAW*/, bRedraw, 0);
  bRedraw && AkelPad.SystemFunction().Call("User32::InvalidateRect", hWnd, 0, true);
}

function GetOffset(hWnd, nFlag)
{
  var lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
  var nOffset;

  SendMessage(hWnd, AEM_GETINDEX, nFlag, lpIndex);
  nOffset = SendMessage(hWnd, AEM_INDEXTORICHOFFSET, 0, lpIndex);
  AkelPad.MemFree(lpIndex);

  return nOffset;
}

function ShiftCharIndex(lpIndex, nShiftRow, nShiftCol)
{
  AkelPad.MemCopy(lpIndex, AkelPad.MemRead(lpIndex, DT_DWORD) + nShiftRow, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpIndex, _X64 ? 16 : 8), AkelPad.MemRead(_PtrAdd(lpIndex, _X64 ? 16 : 8), DT_DWORD) + nShiftCol, DT_DWORD);
  SendMessage(hEditWnd, AEM_INDEXUPDATE, 0, lpIndex);
}

function CopyCharIndex(lpToIndex, lpFromIndex)
{
  AkelPad.MemCopy(lpToIndex, AkelPad.MemRead(lpFromIndex, DT_DWORD), DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpToIndex, _X64 ?  8 : 4), AkelPad.MemRead(_PtrAdd(lpFromIndex, _X64 ?  8 : 4), DT_QWORD), DT_QWORD);
  AkelPad.MemCopy(_PtrAdd(lpToIndex, _X64 ? 16 : 8), AkelPad.MemRead(_PtrAdd(lpFromIndex, _X64 ? 16 : 8), DT_DWORD), DT_DWORD);
}

function CopyCharIndexRowCol(lpToIndex, lpFromIndexRow, lpFromIndexCol)
{
  var nRow = AkelPad.MemRead(lpFromIndexRow, DT_DWORD);
  var nCol = AkelPad.MemRead(_PtrAdd(lpFromIndexCol, _X64 ? 16 : 8), DT_DWORD);

  AkelPad.MemCopy(lpToIndex, nRow, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpToIndex, _X64 ? 16 : 8), nCol, DT_DWORD);
  SendMessage(hEditWnd, AEM_INDEXUPDATE, 0, lpToIndex);
}

function SendMessage(hWnd, uMsg, wParam, lParam)
{
  return AkelPad.SystemFunction().Call("User32::SendMessage" + _TCHAR, hWnd, uMsg, wParam, lParam);
}

Last edited by KDJ on Thu Jan 08, 2015 8:42 pm, edited 6 times in total.
Post Reply