Scripts discussion (1)

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

Post by Infocatcher »

alignWithSpaces.js
Added -sepAtStart argument (see description).
Added correction, if selection start are not located at line start.


Image

Image

Image

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

Post by Infocatcher »

alignWithSpaces.js
Fixed work with column selection.

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

Post by Infocatcher »

alignWithSpaces.js
Added -sep (to don't ask separator) and -defaultSep arguments.
Improved warning messages.

DV
Offline
Posts: 1291
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Обновлённая пробная версия

Code: Select all

/**********************************************************************
 *  KeySubst.js  v.0.2                                                *
 *  (C) DV, May 2001                                                  *
 **********************************************************************/

var alph = [
 /* eng=0 */ [ "`1234567890-=\\qwertyuiop[]asdfghjkl;\'zxcvbnm,./",
               "~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?" ],
 /* rus=1 */ [ "ё1234567890-=\\йцукенгшщзхъфывапролджэячсмитьбю.",
               "Ё!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ," ],
 /* ukr=2 */ [ "\'1234567890-=\\йцукенгшщзхїфівапролджєячсмитьбю.",
               "\'!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЇФІВАПРОЛДЖЄЯЧСМИТЬБЮ," ] ];
var eng = 0;
var rus = 1;
var ukr = 2;

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

AkelPad.ScriptNoMutex();

var hMutex;
if (hMutex = oSys.Call("kernel32::CreateMutex" + _TCHAR, 0, 1, "KeySubst_js_" + hWndEdit))
{
  if (oSys.GetLastError() == 183 /*ERROR_ALREADY_EXISTS*/)
  {
    oSys.Call("user32::PostMessage", hWndEdit, 0x100 /*WM_KEYDOWN*/, 0xC0, 0);
    WScript.Quit();
  }
}

var lpOldEditProc;
if (lpOldEditProc = AkelPad.WindowSubClass(hWndEdit, EditCallback))
{
  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnsubClass(hWndEdit);
  oSys.Call("kernel32::CloseHandle", hMutex);
}

function EditCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x102 /*WM_CHAR*/)
  {
    var ch = String.fromCharCode(wParam);
    var nLangId = getEditLangId(hWndEdit);
    var nLangFrom = eng;
    var nLangTo = rus;
    if (nLangId == 1049) /* rus */
    {
      nLangFrom = rus;
      nLangTo = eng;
    }
    else if (nLangId == 1058) /* ukr */
    {
      nLangFrom = ukr;
      nLangTo = eng;
    }

    var nCase = 0;
    var i = alph[nLangFrom][nCase].indexOf(ch);
    if (i < 0)
    {
      nCase = 1;
      i = alph[nLangFrom][nCase].indexOf(ch);
    }
    if (i >= 0)
    {
      if (i < alph[nLangTo][nCase].length)
      {
        ch = alph[nLangTo][nCase].charAt(i);
        oSys.Call("user32::CallWindowProc" + _TCHAR, lpOldEditProc, hWnd, uMsg, ch.charCodeAt(0), lParam);
        AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
        //Skip internal CallWindowProc
        return 1;
      }
    }
  }
  else if (uMsg == 0x100 /*WM_KEYDOWN*/)
  {
    if (wParam == 0xC0 /*VK_OEM_3: (`~)*/)
    {
      var nCtrlState = oSys.Call("user32::GetKeyState", 0x11 /*VK_CONTROL: Ctrl*/);
      var nAltState = oSys.Call("user32::GetKeyState", 0x12 /*VK_MENU: Alt*/)
      if ((lParam == 0) || ((nCtrlState & 0x80) && !(nAltState & 0x80)))
      {
        //Exit message loop
        oSys.Call("user32::PostQuitMessage", 0);
        //Skip internal CallWindowProc
        return 1;
      }
    }
  }
}

function getEditLangId(hEdit)
{
  var nEditThreadId = oSys.Call("user32::GetWindowThreadProcessId", hEdit, 0);
  var nLang = oSys.Call("user32::GetKeyboardLayout", nEditThreadId);
  return (nLang & 0xFFFF);
}
(печать кириллических символов при английской раскладке и латинских символов при русской/украинской раскладке).
Магия с

Code: Select all

hMutex = oSys.Call("kernel32::CreateMutex"
теоретически должна заставлять скрипт завершаться по Ctrl+` при условии, что Ctrl+` является горячей клавишей для скрипта. Но на практике это не работает :( Вызов

Code: Select all

oSys.Call("user32::PostMessage"
выполняется, но в EditCallback это сообщение почему-то не приходит.

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

Post by FeyFre »

DV
Строчка 27 у Вас

Code: Select all

     oSys.Call("user32::PostMessage", hWndEdit, 0x100 /*WM_KEYDOWN*/, 0xC0, 0); 
а надое

Code: Select all

     oSys.Call("user32::PostMessage"+_TCHAR, hWndEdit, 0x100 /*WM_KEYDOWN*/, 0xC0, 0); 

DV
Offline
Posts: 1291
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Более работоспособный и стабильный вариант

Code: Select all

/**********************************************************************
 *  KeySubst.js  v.0.3                                                *
 *  (C) DV, May 2011                                                  *
 *  Thanks to: Instructor, FeyFre                                     *
 **********************************************************************/

var alph = [
 /* eng=0 */ [ "`1234567890-=\\qwertyuiop[]asdfghjkl;\'zxcvbnm,./",
               "~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?" ],
 /* rus=1 */ [ "ё1234567890-=\\йцукенгшщзхъфывапролджэячсмитьбю.",
               "Ё!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ," ],
 /* ukr=2 */ [ "\'1234567890-=\\йцукенгшщзхїфівапролджєячсмитьбю.",
               "\'!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЇФІВАПРОЛДЖЄЯЧСМИТЬБЮ," ] ];
var eng = 0;
var rus = 1;
var ukr = 2;

var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

AkelPad.ScriptNoMutex();

var hMutex;
if (hMutex = oSys.Call("kernel32::CreateMutex" + _TCHAR, 0, 1, "KeySubst_js_" + hWndEdit))
{
  if (oSys.GetLastError() == 183 /*ERROR_ALREADY_EXISTS*/)
  {
    oSys.Call("kernel32::CloseHandle", hMutex);
    oSys.Call("user32::SendMessage" + _TCHAR, hWndEdit, 0x100 /*WM_KEYDOWN*/, 0xC0, 0);
    WScript.Quit();
  }
}

var lpOldEditProc;
if (lpOldEditProc = AkelPad.WindowSubClass(hWndEdit, EditCallback))
{
  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnsubClass(hWndEdit);
  oSys.Call("kernel32::CloseHandle", hMutex);
}

function EditCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x102 /*WM_CHAR*/)
  {
    var ch = String.fromCharCode(wParam);
    var nLangId = getEditLangId(hWndEdit);
    var nLangFrom = eng;
    var nLangTo = rus;
    if (nLangId == 1049) /* rus */
    {
      nLangFrom = rus;
      nLangTo = eng;
    }
    else if (nLangId == 1058) /* ukr */
    {
      nLangFrom = ukr;
      nLangTo = eng;
    }

    var nCase = 0;
    var i = alph[nLangFrom][nCase].indexOf(ch);
    if (i < 0)
    {
      nCase = 1;
      i = alph[nLangFrom][nCase].indexOf(ch);
    }
    if (i >= 0)
    {
      if (i < alph[nLangTo][nCase].length)
      {
        ch = alph[nLangTo][nCase].charAt(i);
        oSys.Call("user32::CallWindowProc" + _TCHAR, lpOldEditProc, hWnd, uMsg, ch.charCodeAt(0), lParam);
        AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
        //Skip internal CallWindowProc
        return 1;
      }
    }
  }
  else if (uMsg == 0x100 /*WM_KEYDOWN*/)
  {
    if (wParam == 0xC0 /*VK_OEM_3: (`~)*/)
    {
      var nCtrlState = oSys.Call("user32::GetKeyState", 0x11 /*VK_CONTROL: Ctrl*/);
      var nAltState = oSys.Call("user32::GetKeyState", 0x12 /*VK_MENU: Alt*/)
      if ((lParam == 0) || ((nCtrlState & 0x80) && !(nAltState & 0x80)))
      {
        //Exit message loop
        oSys.Call("user32::PostQuitMessage", 0);
        //Skip internal CallWindowProc
        return 1;
      }
    }
  }
  else if (uMsg == 0x0002 /*WM_DESTROY*/)
  {
    //Exit message loop
    oSys.Call("user32::PostQuitMessage", 0);
  }
}

function getEditLangId(hEdit)
{
  var nEditThreadId = oSys.Call("user32::GetWindowThreadProcessId", hEdit, 0);
  var nLang = oSys.Call("user32::GetKeyboardLayout", nEditThreadId);
  return (nLang & 0xFFFF);
}
. И этот скрипт лучше сохранять как UTF-16 LE.

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

Post by FeyFre »

Вроде бы работает. Сохранял в UTF8.
Парочка замечаний:
1. WM_KEYDOWN лучше сделать POST-ом, а не SEND-ом. MSDN пишет что они Posted(и другие клавиатуропричастные сообщения), и лучше что-бы так и оставалось(мало ли, вдруг кто-то что-то будет писать фильтрующее).
2. А как его заставить набирать на той раскладке, на которой я хочу. Оно мне предлагает на русской, а я хочу укр?(Да, локализация винды русская, локализация системы - Украина).
3. Нужно использовать имя для мютекса уникальнее. Иначе возможно параллельно два скрипта в двух сессиях работать не будут.
4. Воспользоваться ToUnicodeEx не пробовали?

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

Post by KDJ »

Translator.js
Added: single-window mode - translation directly from AkelPad edit window.

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

Post by Infocatcher »

KDJ

Code: Select all

sTarget   = sTarget.replace(/'/g, "'");
?

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

Post by KDJ »

Infocatcher wrote:KDJ

Code: Select all

sTarget   = sTarget.replace(/'/g, "'");
?
download file KDJ.zip->Translator.js and compare.

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

Post by Infocatcher »

KDJ
<del>Seems like you don't disable HTML in this post.</del>
Seems like forum bug. :?
Last edited by Infocatcher on Mon May 30, 2011 9:37 pm, edited 3 times in total.

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

Post by FeyFre »

KDJ
What about this ?
Important: The Google Translate API has been officially deprecated as of May 26, 2011. Due to the substantial economic burden caused by extensive abuse, the number of requests you may make per day will be limited and the API will be shut off completely on December 1, 2011. For website translations, we encourage you to use the Google Translate Element.
Last edited by FeyFre on Mon May 30, 2011 9:49 pm, edited 1 time in total.

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

Post by Infocatcher »

Hack:

Code: Select all

sTarget   = sTarget.replace(/'/g, "'");
& #38;#39; (without space)

DV
Offline
Posts: 1291
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Обновлённый

Code: Select all

/*************************************************************************
 *  KeySubst.js  v.0.4                                                   *
 *  (C) DV, May 2011                                                     *
 *  Thanks to: Instructor, FeyFre                                        *
 *************************************************************************/
/*  Examples:                                                            *
 *    -"Eng as Rus" Call("Scripts::Main", 1, "KeySubst.js")              *
 *    -"Eng as Rus" Call("Scripts::Main", 1, "KeySubst.js", `-to=rus`)   *
 *    -"Eng as Ukr" Call("Scripts::Main", 1, "KeySubst.js", `-to=ukr`)   *
 *************************************************************************/

var alph = [
 /* eng=0 */ [ "`1234567890-=\\qwertyuiop[]asdfghjkl;\'zxcvbnm,./`",
               "~!@#$%^&*()_+|QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?~" ],
 /* rus=1 */ [ "ё1234567890-=\\йцукенгшщзхъфывапролджэячсмитьбю.ё",
               "Ё!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё" ],
 /* ukr=2 */ [ "\'1234567890-=\\йцукенгшщзхїфівапролджєячсмитьбю.ё",
               "\'!\"№;%:?*()_+/ЙЦУКЕНГШЩЗХЇФІВАПРОЛДЖЄЯЧСМИТЬБЮ,Ё" ] ];
// Note: trailing 'ё' is needed for Ukrainian because of ` to ' hack.
var eng = 0;
var rus = 1;
var ukr = 2;

var argTo = (getScriptArg("-to").toLowerCase() == "ukr") ? ukr : rus;
//var argTo = (getScriptArg("-to").toLowerCase() == "rus") ? rus : ukr;
var hWndMain = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();

AkelPad.ScriptNoMutex();

var mutexName = "KeySubst_js_" + hWndMain + "_" + hWndEdit;
var hMutex;
if (hMutex = oSys.Call("kernel32::CreateMutex" + _TCHAR, 0, 1, mutexName))
{
  if (oSys.GetLastError() == 183 /*ERROR_ALREADY_EXISTS*/)
  {
    oSys.Call("kernel32::CloseHandle", hMutex);
    oSys.Call("user32::SendMessage" + _TCHAR, hWndEdit, 0x100 /*WM_KEYDOWN*/, 0xC0, 0);
    WScript.Quit();
  }
}

var lpOldEditProc;
if (lpOldEditProc = AkelPad.WindowSubClass(hWndEdit, EditCallback))
{
  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnsubClass(hWndEdit);
  oSys.Call("kernel32::CloseHandle", hMutex);
}

function EditCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x102 /*WM_CHAR*/)
  {
    var ch = String.fromCharCode(wParam);
    var nLangId = getEditLangId(hWndEdit);
    var nLangFrom = eng;
    var nLangTo = argTo;
    if (nLangId == 1049) /* rus */
    {
      nLangFrom = rus;
      nLangTo = eng;
    }
    else if (nLangId == 1058) /* ukr */
    {
      nLangFrom = ukr;
      nLangTo = eng;
    }

    var nCase = 0;
    var i = alph[nLangFrom][nCase].indexOf(ch);
    if (i < 0)
    {
      nCase = 1;
      i = alph[nLangFrom][nCase].indexOf(ch);
    }
    if (i >= 0)
    {
      if (i < alph[nLangTo][nCase].length)
      {
        ch = alph[nLangTo][nCase].charAt(i);
        oSys.Call("user32::CallWindowProc" + _TCHAR, lpOldEditProc, hWnd, uMsg, ch.charCodeAt(0), lParam);
        AkelPad.SendMessage(hWnd, 3377 /*AEM_UPDATECARET*/, 0, 0);
        //Skip internal CallWindowProc
        return 1;
      }
    }
  }
  else if (uMsg == 0x100 /*WM_KEYDOWN*/)
  {
    if (wParam == 0xC0 /*VK_OEM_3: (`~)*/)
    {
      var nCtrlState = oSys.Call("user32::GetKeyState", 0x11 /*VK_CONTROL: Ctrl*/);
      var nAltState = oSys.Call("user32::GetKeyState", 0x12 /*VK_MENU: Alt*/)
      if ((lParam == 0) || ((nCtrlState & 0x80) && !(nAltState & 0x80)))
      {
        //Exit message loop
        oSys.Call("user32::PostQuitMessage", 0);
        //Skip internal CallWindowProc
        return 1;
      }
    }
  }
  else if (uMsg == 0x0002 /*WM_DESTROY*/)
  {
    //Exit message loop
    oSys.Call("user32::PostQuitMessage", 0);
  }
}

function getEditLangId(hEdit)
{
  var nEditThreadId = oSys.Call("user32::GetWindowThreadProcessId", hEdit, 0);
  var nLang = oSys.Call("user32::GetKeyboardLayout", nEditThreadId);
  return (nLang & 0xFFFF);
}

function getScriptArg(argName)
{
  var s = "";
  argName = argName.toLowerCase();
  for (var n = 0; n < WScript.Arguments.length; n++)
  {
    var t = WScript.Arguments(n);
    var a = t.split("=");
    if (a[0].toLowerCase() == argName)
    {
      s = a[1];
      break;
    }
  }
  return s;
}
.
FeyFre,
1. WM_KEYDOWN лучше сделать POST-ом, а не SEND-ом.
Если сделать Post, то временами весь AkelPad валится. Судя по всему, из-за характера PostMessage, приводящего к отсутствию синхронизации между моментами завершения скрипта и принятия сообщения.
2. А как его заставить набирать на той раскладке, на которой я хочу.
Добавлен параметр -to=ukr. Пока что ничего изящнее не придумал.
3. Нужно использовать имя для мютекса уникальнее.
Сделано :)
4. Воспользоваться ToUnicodeEx не пробовали?
Тут моя позиция такова: зачем её использовать, если и без неё всё хорошо?

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

Post by FeyFre »

Если сделать Post, то временами весь AkelPad валится. Судя по всему, из-за характера PostMessage, приводящего к отсутствию синхронизации между моментами завершения скрипта и принятия сообщения.
Падает изза чего-то другого. Скрипты работают независимо друг от друга(каждый в своем потоке), после PostMessage Вы не пользуетесь никаими данными которые получили из первого экземпляра скрипта, и вообще к нему не обращаетесь. Так что падение нужно ловить, желательно отладчиком. Возможно даже глюк плагина.
Добавлен параметр -to=ukr. Пока что ничего изящнее не придумал.
Так вполне нормально. Других наворотов просить не будем - не та структура скрипта.
Тут моя позиция такова: зачем её использовать, если и без неё всё хорошо?
У меня на Укр раскладке на комбинации Alt+Ctrl+u(или Alt+Ctrl+г) забинден ввод буква "ґ"(а если добавить Shift - "Ґ"), естественно Ваш скрипт не в крусе этого и ничего не делает. А вот ToUnicodeEx какраз и в курсе.
Locked