Scripts discussion (2)

Discuss and announce AkelPad plugins
Locked
  • Author
  • Message
Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Visitor7, доки Вам не нужны, а вот без окна не обойдетесь. Я пока другого способа контроля не нашел(точнее не пробовал).
Во-первых, окно - как связующий мост между экземплярами скрипта. Первый создает(CreateWindowEx), второй находит(FindWindow)его и просит закруглятся(AkelPad.SendMessage(dock, 16 /*WM_CLOSE*/, 0, 0);).
Во-вторых, окно как метод фонового "ничегонеделания". Фактически фоновость выполнения скрипта обеспечивает AkelPad.WindowGetMessage(); но вся соль именно в том, что оно будет сидеть в этом вызова до посинения. Выкинуть из него может только одна вещь - oSys.Call("user32::PostQuitMessage", 0); а её можно вызвать лишь единым способом - когда WindowGetMessage() вызовет что-то, что вызовет это. Это "что-то" - оконная процедура любого окна созданного скриптом. Т.е окно нужно всегда(окна бывают невидимыми, т.е. фактически работают как диспетчер команд).
Вся трудность в том, что действительной многопоточной модели в скриптах не реализовать - мешает реализация WSH, а потому приходится использовать то что есть и минимумы того что нету(причем хорошо отлаженные). У меня History.js тоже иногда падает. В плагине написать это на много проще было бы, но пока не судьба(три своих подтянуть не доходят руки, четвертого пока не очень хочется заводить).

Offline
Posts: 88
Joined: Sun Jun 03, 2012 8:15 am

Post by Visitor7 »

FeyFre
Ладно, спасибо, окно так окно.
Но все равно странно что оконная процедура выполняется в отдельном потоке, а процедура перехвата событий в потоке со скриптом.
Я как то глянул исходники плагинов - более сложный синтаксис, более низкоуровненвые методы и куча функций. Это надо знать среду, акелпад и написанные к нему библиотеки как свои пять пальцев.

Offline
Posts: 88
Joined: Sun Jun 03, 2012 8:15 am

Post by Visitor7 »

FeyFre
Получается, что QuitMutext = true не нужен.
И это не нужно:

Code: Select all

   if(umsg == AKDN_MAIN_ONFINISH)
   {
      AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
      while(!QuitMutext)
      {
         oSys.Call("kernel32::SwitchToThread");
      }
   }
В случае с использованием объекта(окна, дока), мы сюда попросту вовсе не попадаем. А команды close и destroy AkelPad сам дает окну при выходе.
Даже перехват закрытия нашего окна при выключении AkelPad

Code: Select all

    if(umsg == 16 /*WM_CLOSE*/)
       return 1;
не позволяет попасть в обработку события AKDN_MAIN_ONFINISH.
Странно все это. Без окна попадаем, с окном - нет.

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

Post by FeyFre »

AutohideTab.js

Code: Select all

   if(umsg == (1046 || 1078))      //AKDN_  FRAME_ACTIVATE, OPENDOCUMENT_FINISH 
       OneTabHide(); 
 
Чего-чего?

Offline
Posts: 88
Joined: Sun Jun 03, 2012 8:15 am

Post by Visitor7 »

FeyFre )))) Спасибо, исправил.

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

Post by KDJ »

Visitor7

AutohideTab.js
It seems to me that it is unnecessary lpBuffer variable and memory allocation:
var lpBuffer;
if (lpBuffer=AkelPad.MemAlloc(256 * _TSIZE))
AkelPad.MemFree(lpBuffer);

Offline
Posts: 88
Joined: Sun Jun 03, 2012 8:15 am

Post by Visitor7 »

KDJ Благодарю, действительно ненужное, тоже исправил.

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Подскажите как сделать так, чтобы не вылетало диалоговое окно когда я пытаюсь сохранить безымянную вкладку о том, что "Строка содержит символы, которые будут утеряны..."

т.е. цель сохранить безымянную вкладку в Ansi , если есть спец символы в UTF-8

но при

Code: Select all

If AkelPad.SaveFile(0, File) < 0 Then Call AkelPad.SaveFile(0, File, 65001, 1)
всё равно вылетает окно. Может есть метод, чтобы этого избежать?

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

Post by opk44 »

Andrey_A_A wrote:Может есть метод, чтобы этого избежать?
1. Сохранять сразу в UTF чтобы ничего не терялось.
2. В параметрах командной строки есть опции "/L+", "/L-", "/L". Поэтому можно затем запустить AkelPad в командной строке и "заказать" ему обработку того же файла(-ов) с пересохранением его(их) в кодировке ANSI c параметром "/L-" (не сохранять файл, если потеряются символы в указанной кодировке).
Т.е. так он пересохранит кого сможет в ANSI, а кого не сможет, оставит в UTF.
P.S. Но можно было бы и просто на пункте 1 успокоиться :)

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

В параметрах командной строки есть опции "/L+", "/L-", "/L"
Как-то некрасиво получается...
Сохранить, Закрыть, Открыть...
Может ещё есть варианты

Offline
Posts: 8
Joined: Fri Aug 12, 2011 6:34 am

Simple script help needed

Post by wallywalters »

Can someone show me how to write a script that will search for every appearance of the word "upper" and replace it with "UPPER?"

I know I can create a macro to do this, but I'd like to write a script to search and replace a (predefined) list of words, and though I don't know the first thing about scripting, I thought I could use this as a template.

Thank you.

Offline
Posts: 88
Joined: Sun Jun 03, 2012 8:15 am

Re: Simple script help needed

Post by Visitor7 »

wallywalters
You can use SearchReplace.js script.
The "What" field: (wordone|wordtwo|wordthree)
The "With" field": $0.toUpperCase();
Check "Regular expressions", "Case sensitive" and "Replace with function".
This will replace the word "wordone" with "WORDONE", "wordtwo" with "WORDTWO", "wordthree" with "WORDTHREE".
Uncheck "Case sensitive" then this will replace the words "wordone", "wOrdonE", "WORDONE" with "WORDONE"; "wordtwo", "WorDtwo", "WORDTWO" with "WORDTWO"... etc.
Change "What" field: (a |the | |un)(wordone|wordtwo|wordthree)(ing|er| )
then this will replace the phrases "worDtwo", "a WordoNeing", "The wordtow", "wordthreeer", "unwordone" to uppercase.

Offline
Posts: 8
Joined: Fri Aug 12, 2011 6:34 am

Re: Simple script help needed

Post by wallywalters »

Visitor7, thanks for your assistance. And my apologies, because I miscommunicated what I want to do. I actually want to be able to search a document and replace every instance of "apple" with "banana" and every "blue" with "green." But unfortunately my word choice made it look like I was trying to replace lower-case words with upper-case.

How can I write a script that replaces one list of words with another (without calling up any dialog boxes)?

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

Post by FeyFre »

It is rather simple script. Just follow instruction.

Code: Select all

var text = AkelPad.GetTextRange(0, -1)

text = text
.replace(/apple/mig,"banana")
.replace(/blue/mig,"green")
//! Repeat this as match as you need(case insensitive)
// .replace(/expression-to-search/mig,"expression-to-be-replaced-by")
//! NOTE: in expression-to-search You MUST escape with "\" all entries of symbols  /()[]{}*?+ and \ itself.
//! I.e. in order to find expression "Hello \*/" you MUST use this: .replace(/Hello \\\*\//mig,"expression-to-be-replaced-by")

AkelPad.SetSel(0,-1)
AkelPad.ReplaceSel(text)

Offline
Posts: 88
Joined: Sun Jun 03, 2012 8:15 am

Post by Visitor7 »

Or something like this:

Code: Select all

var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var lpFrameInit;
var lpFrame;
var i;
var replaceFlags = 0x00200001 /*FR_DOWN|FR_BEGINNING*/;
var replacePair;
var fastUndo = true; //true - collects all changes in a single Undo action, false - collects every change in own Undo action
var wholeWord = true; //true - whole word, false - any part of the word
var caseSensitive = false; //true - case sensitive, false - ignore case
var allDocs = false; //true - all opened documents, false - current only
var replaceArr = ["green:red", "banana:apple","white:black","etc:et cetera"];

if (hMainWnd && hWndEdit)
{
   if (!AkelPad.IsMDI())
      allDocs = false;
   if ((!allDocs) && (AkelPad.GetSelEnd() - AkelPad.GetSelStart()))
      replaceFlags = 0x00400001 /*FR_DOWN|FR_SELECTION*/;
   if (wholeWord)
      replaceFlags += 0x00000002 /*FR_WHOLEWORD*/;
   if (caseSensitive)
      replaceFlags += 0x00000004 /*FR_MATCHCASE*/;
   lpFrameInit = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
   lpFrame = lpFrameInit;
   for (;lpFrame;)
   {
      if (fastUndo)
      {
          AkelPad.SendMessage(hWndEdit, 3080 /*AEM_STOPGROUPTYPING*/, 0, 0);
          AkelPad.SendMessage(hWndEdit, 3081 /*AEM_BEGINUNDOACTION*/, 0, 0);
      }
      for (i in replaceArr)
      {
         replacePair = replaceArr[i].split(':');
         AkelPad.TextReplace(0, replacePair[0], replacePair[1], replaceFlags , true);
      }
      if (fastUndo)
      {
         AkelPad.SendMessage(hWndEdit, 3082 /*AEM_ENDUNDOACTION*/, 0, 0);
         AkelPad.SendMessage(hWndEdit, 3080 /*AEM_STOPGROUPTYPING*/, 0, 0);
      }
      if (!allDocs) break;
      lpFrame = AkelPad.Command(4316 /*IDM_WINDOW_FRAMENEXT*/);
      if (lpFrame == lpFrameInit) break;
   }
}
//See "Java Script manual", "Akelpad Scripts Methods" in "Scripts AkelPad plugin" help, "AkelDLL.h", "AkelEdit.h".
Last edited by Visitor7 on Thu Jul 12, 2012 10:48 pm, edited 3 times in total.
Locked