Scripts discussion (3)

Discuss and announce AkelPad plugins
Locked
  • Author
  • Message
KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Instructor
I will try to do it. Thanks for the example.
It seems to me, that if _X64, offsetof(AEMARKTEXTITEMW, pMarkText) is equal to 24, not 20.
Is there any function to check the correctness of a regular expression?


Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Instructor
Возможно ли добавить в OpenSaveMask.js диалог выбора файла и диалог выбора каталога для сохранения? Или хотя бы открытие. Например с ключами -OpenList=1 и -SaveDir=1. Хотел воткнуть FileDialog из InsertFile.js, только что-то не соображу, как нужно обработать параметры.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

KDJ wrote:It seems to me, that if _X64, offsetof(AEMARKTEXTITEMW, pMarkText) is equal to 24, not 20.
Corrected.
Is there any function to check the correctness of a regular expression?

Code: Select all

var hMainWnd=AkelPad.GetMainWnd();

WScript.Echo("" + CheckPat("(23)(.*)(89)"));

function CheckPat(pPat)
{
  var lpPatExec;
  var lpStr;
  var nErrorOffset=0;

  if (lpPatExec=AkelPad.MemAlloc(_X64?0:76 /*sizeof(PATEXEC)*/))
  {
    if (lpStr=AkelPad.MemAlloc(2 /*sizeof(wchat_t)*/))
    {
      if (lpPat=AkelPad.MemAlloc((pPat.length + 1) * 2 /*sizeof(wchat_t)*/))
      {
        AkelPad.MemCopy(lpPat, pPat, 1 /*DT_UNICODE*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:12) /*offsetof(PATEXEC, wpStr)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:16) /*offsetof(PATEXEC, wpMaxStr)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:20) /*offsetof(PATEXEC, wpText)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:24) /*offsetof(PATEXEC, wpMaxText)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:4) /*offsetof(PATEXEC, wpPat)*/, lpPat, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:8) /*offsetof(PATEXEC, wpMaxPat)*/, lpPat + pPat.length * 2 /*sizeof(wchat_t)*/, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:52) /*offsetof(PATEXEC, dwOptions)*/, 0x1 /*RESE_MATCHCASE*/, 3 /*DT_DWORD*/);
        AkelPad.SendMessage(hMainWnd, 1415 /*AKD_PATEXEC*/, 0, lpPatExec);
        nErrorOffset=AkelPad.MemRead(lpPatExec + (_X64?0:64) /*offsetof(PATEXEC, nErrorOffset)*/, 2 /*DT_QWORD*/);

        AkelPad.MemFree(lpPat);
      }
      AkelPad.MemFree(lpStr);
    }
    AkelPad.MemFree(lpPatExec);
  }
  return nErrorOffset;
}


Skif_off
Возможно будет удобнее так:
Пример кнопки Total Commander'а для конвертирования выделенных файлов в UTF-8

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Instructor
Нет, это не то, по сути получается, что мне нужна часть функционала плагина Sessions, создать список файлов проще и быстрее, чем ту же пачку файлов сначала открыть (да и плагин включаю только при необходимости).

В общем, беру просьбу взад, есть пара идей, к тому же, сразу не вспомнил: самый простой - %a и OpenFile() из ContextMenu, будет просто два пункта меню, а не один :) (у меня так прикручен переименованный и немного модифицированный replaceDiacriticLetters.js от Infocatcher, существенно ускоряет поиск/замену, правда, не запустишь для всех вкладок сразу, как в случае с 4161, но пока и не требовалось)

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

Post by KDJ »

Instructor wrote:

Code: Select all

var hMainWnd=AkelPad.GetMainWnd();

WScript.Echo("" + CheckPat("(23)(.*)(89)"));

function CheckPat(pPat)
{
  var lpPatExec;
  var lpStr;
  var nErrorOffset=0;

  if (lpPatExec=AkelPad.MemAlloc(_X64?0:76 /*sizeof(PATEXEC)*/))
  {
    if (lpStr=AkelPad.MemAlloc(2 /*sizeof(wchat_t)*/))
    {
      if (lpPat=AkelPad.MemAlloc((pPat.length + 1) * 2 /*sizeof(wchat_t)*/))
      {
        AkelPad.MemCopy(lpPat, pPat, 1 /*DT_UNICODE*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:12) /*offsetof(PATEXEC, wpStr)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:16) /*offsetof(PATEXEC, wpMaxStr)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:20) /*offsetof(PATEXEC, wpText)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:24) /*offsetof(PATEXEC, wpMaxText)*/, lpStr, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:4) /*offsetof(PATEXEC, wpPat)*/, lpPat, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:8) /*offsetof(PATEXEC, wpMaxPat)*/, lpPat + pPat.length * 2 /*sizeof(wchat_t)*/, 2 /*DT_QWORD*/);
        AkelPad.MemCopy(lpPatExec + (_X64?0:52) /*offsetof(PATEXEC, dwOptions)*/, 0x1 /*RESE_MATCHCASE*/, 3 /*DT_DWORD*/);
        AkelPad.SendMessage(hMainWnd, 1415 /*AKD_PATEXEC*/, 0, lpPatExec);
        nErrorOffset=AkelPad.MemRead(lpPatExec + (_X64?0:64) /*offsetof(PATEXEC, nErrorOffset)*/, 2 /*DT_QWORD*/);

        AkelPad.MemFree(lpPat);
      }
      AkelPad.MemFree(lpStr);
    }
    AkelPad.MemFree(lpPatExec);
  }
  return nErrorOffset;
}
Thank you very much. Very usefull function.
The offset values for _X64 I calculated myself.
I think, this function should be in Scripts plugin as AkelPad method.

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Infocatcher
Подскажите, пожалуйста, в какое место нужно добавить вызов скриптов после вставки текста (выделенное или весь файл)?
Получается как-то

Code: Select all

AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\<p\>\n[ \t]*" "<p>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\n[ \t]*\</p\>" "</p>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\<v\>\n[ \t]*" "<v>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\n[ \t]*\</v\>" "</v>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\<subtitle\>\n[ \t]*" "<subtitle>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\n[ \t]*\</subtitle\>" "</subtitle>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\<text-author\>\n[ \t]*" "<text-author>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\n[ \t]*\</text-author\>" "</text-author>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"</body><binary" "</body>\n <binary" 0 1 1 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"\n[ \t]*\</binary\>" "</binary>" 0 1 0 16 3`)
AkelPad.CallW("Scripts::Main", 1, "Multi_SR.js", `"></FictionBook>" ">\n</FictionBook>" 0 1 1 16 3`)
, хотелось бы упростить :) Правильно понимаю, что это происходит в операторе if в строках 5899-5971 (в разрабатываемой версии)?

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Skif_off
Там в двух местах вызов insertNoScroll() для вставки.

Я немного доработал, теперь можно сделать вот такой вспомогательный скрипт:

Code: Select all

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

var _beautifyOrig = beautify;
beautify = function(source, syntax) {
	return _beautifyOrig.apply(this, arguments)
		.replace(/<(p|subtitle)>\n[ \t]*/ig, "<$1>")
		.replace(/\n[ \t]*<\/(p|subtitle)>/ig, "</$1>");
};

handleArgs();
Только если изменения будут касаться не только пробельных символов, то сломается восстановления позиции каретки (если отсутствовало выделение и -onlySelected=false или не передается).

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Infocatcher
Спасибо, как-то даже неловко :) Эта доработка не вылезет боком? Выглядит интересно.

С AkelPad.CallW после insertNoScroll() (точнее - setSyntax(syntax.value)) вроде срабатывает, только заменил "`" на "'".
Так понятнее пока: не силен в JS, в случае вспомогательного скрипта придется разбираться с .replace, ну и со строками замены ($) у меня пока пробелы.
Про ограничение: пока не могу оценить, обычно если есть <binary></binary>, то безусловно выделение до предыдущего закрывающего тэга, а в чем еще всплывет необходимость не могу предположить.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Skif_off wrote:Спасибо, как-то даже неловко :) Эта доработка не вылезет боком? Выглядит интересно.
Вряд ли, подключать скрипт через AkelPad.Include() можно было уже давно, я только завернул стандартную обработку в функцию.

Да, про AkelPad.CallW/Call. Я так понимаю, все-таки лучше AkelPad.Call(), а AkelPad уже сам будет использовать юникодные строки, если система их поддерживает. Другое дело, что я сомневаюсь, что скрипт вообще запустится на Win 98 (какая там версия JScript?).
Skif_off wrote:Про ограничение: пока не могу оценить, обычно если есть <binary></binary>, то безусловно выделение до предыдущего закрывающего тэга, а в чем еще всплывет необходимость не могу предположить.
Ну, если после вставки вызываются сторонние скрипты, то положение выделения уже на их совести.

И потом, наверное, лучше вот так (у меня иногда падало, если выставить синтаксическую тему до вставки):

Code: Select all

insertNoScroll(...);
postProcess();
setSyntax(...);
С добавлением

Code: Select all

function postProcess() {
	AkelPad.Call(...);
	...
}
Или вообще вот так:

Code: Select all

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

var _insertNoScrollOrig = insertNoScroll;
insertNoScroll = function(str, selectAll, caretPos) {
	var ret = _insertNoScrollOrig.apply(this, arguments);
	AkelPad.Call("Scripts::Main", 1, "Multi_SR.js", ...);
	...
	return ret;
};

handleArgs();

Offline
Posts: 269
Joined: Mon Jun 20, 2011 8:33 am
Location: Электросталь

Post by yozhic »

Infocatcher
Не могли бы прикрутить хотелку к скрипту winMergeTabs.js? :)
Возможность прервать работу скрипта, если случайно нажал кнопку. То есть пока мигает Select Tab! в строке состояния, чтобы можно было нажать Esc (например) и остановить выполнение скрипта. Сейчас в этот момент по Esc закрывается окно Akel' я.

Добавлено:
Ааа, кажется разобрался. Повторное нажатие на кнопку останавливает скрипт...

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

yozhic wrote:winMergeTabs.js
[...]
Повторное нажатие на кнопку останавливает скрипт...
Угу.
И я не уверен, что можно <del>малой кровью</del> малым кодом перехватить Esc.
И можно сделать индикацию нажатости у кнопки:

Code: Select all

// Arguments:
...
//   -item="toolbar:%m:%i"                        - check toolbar button
//        ="menu:%m:%i"                           - check menu item

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Infocatcher
Подсмотрено у KDJ - использовать IsMenu:

ActiveColumnSwitch.js

Code: Select all

  if (nHandle && nItemID)
  {
    if (oSys.Call("User32::IsMenu", nHandle))
      oSys.Call("User32::CheckMenuItem", nHandle, nItemID, bCheckButton?0x8 /*MF_BYCOMMAND|MF_CHECKED*/:0x0 /*MF_BYCOMMAND|MF_UNCHECKED*/);
    else
      AkelPad.SendMessage(nHandle, 1026 /*TB_CHECKBUTTON*/, nItemID, bCheckButton);
  }

Offline
Posts: 269
Joined: Mon Jun 20, 2011 8:33 am
Location: Электросталь

Post by yozhic »

Infocatcher wrote:И можно сделать индикацию нажатости у кнопки
Ага, точно, спасибо. Этот момент я «пролетел» по невнимательности.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Instructor wrote:Подсмотрено у KDJ - использовать IsMenu
Да, так лучше, спасибо.
https://github.com/Infocatcher/AkelPad_ ... 8e710290aa

yozhic
Я тоже забыл, что -item умеют только разрабатываемые версии. :)
Locked