Coder::Fold Выделить фолд-блок из скрипта.

Russian main discussion
Post Reply
  • Author
  • Message
Offline
Posts: 7
Joined: Sun Oct 30, 2016 7:12 pm

Coder::Fold Выделить фолд-блок из скрипта.

Post by ilia »

Используя плагин Coder::Fold можно разделить текст на блоки. Например, *.ini-файл.
[Options]
SaveSettings=2
CmdLineBegin=
CmdLineEnd=
***

[Plugs]
Coder::HighLight=65649
Hotkeys::Main=65536
Coder::CodeFold=65536
***

[Themes]
Notepad++=000040008000
***
Хочу создать скрипт, который в имеющемся файле сортирует блоки текста в определенной последовательности. INI-файл взят как пример: блок Plugs допустим всегда должен идти после блока Themes. А также только в блоке Options надо заменить некоторые строки.

Я предположил, что раз существует уже плагин Фолд, который разбивает текст на дерево блоков, можно использовать его. Выделить блок и пройтись по нему заменой. А потом переместить блоки в нужном порядке в новый файл.

Не нашел как получить доступ к блокам фолда.
У кого есть идеи?

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

Post by Instructor »

Code: Select all

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

ReplaceInCaretFold(hWndEdit, "1", "2");
SortIni(hWndEdit);

function ReplaceInCaretFold(hWndEdit, pFindIt, pReplaceWith)
{
  var lpFold;
  var aFold=[];
  var nCaretOffset=AkelPad.SendMessage(hWndEdit, 3138 /*AEM_GETRICHOFFSET*/, 5 /*AEGI_CARETCHAR*/, 0);
  
  if (lpFold=FoldGet(hWndEdit, 0x59 /*AEFF_FINDOFFSET|AEFF_FOLDSTART|AEFF_FOLDEND|AEFF_GETROOT*/, nCaretOffset))
  {
    aFold=FoldInfo(lpFold);
    AkelPad.SetSel(aFold.nMinPointOffset + aFold.nNameOffsetFromPoint, aFold.nMaxPointOffset + aFold.nMaxPointLen);
    AkelPad.TextReplace(hWndEdit, pFindIt, pReplaceWith, 0x00000001|0x00400000 /*FRF_DOWN|FRF_SELECTION*/, 0x1 /*RRF_ALL*/);
  }
}

function SortIni(hWndEdit)
{
  var hFoldStack=AkelPad.SendMessage(hWndEdit, 3405 /*AEM_GETFOLDSTACK*/, 0, 0);
  var lpFold=AkelPad.MemRead(_PtrAdd(hFoldStack, 0) /*offsetof(HSTACK, first)*/, 2 /*DT_QWORD*/);
  var aFold=[];
  var pText="";
  var nFirstFoldStart;

  while (lpFold)
  {
    aFold[aFold.length]=FoldInfo(lpFold);
    lpFold=AkelPad.MemRead(_PtrAdd(lpFold, 0) /*offsetof(AEFOLD, next)*/, 2 /*DT_QWORD*/)
  }

  if (aFold.length)
  {
    nFirstFoldStart=aFold[0].nMinPointOffset + aFold[0].nNameOffsetFromPoint;
    aFold.sort(function(a, b)
    {
      return oSys.Call("kernel32::lstrcmpi" + _TCHAR, a.pName, b.pName);
    });

    for (i=0; i < aFold.length; ++i)
    {
      pText+=AkelPad.GetTextRange(aFold[i].nMinPointOffset + aFold[i].nNameOffsetFromPoint, aFold[i].nMaxPointOffset + aFold[i].nMaxPointLen);
    }
    AkelPad.SetSel(nFirstFoldStart, -1);
    AkelPad.ReplaceSel(pText);
  }
}

function FoldInfo(lpFold)
{
  var lpMinPoint=AkelPad.MemRead(_PtrAdd(lpFold, _X64?40:20) /*offsetof(AEFOLD, lpMinPoint)*/, 2 /*DT_QWORD*/);
  var lpMaxPoint=AkelPad.MemRead(_PtrAdd(lpFold, _X64?48:24) /*offsetof(AEFOLD, lpMaxPoint)*/, 2 /*DT_QWORD*/);
  var nMinPointOffset=AkelPad.MemRead(_PtrAdd(lpMinPoint, _X64?40:20) /*offsetof(AEPOINT, nPointOffset)*/, 2 /*DT_QWORD*/);
  var nMinPointLen=AkelPad.MemRead(_PtrAdd(lpMinPoint, _X64?48:24) /*offsetof(AEPOINT, nPointLen)*/, 3 /*DT_DWORD*/);
  var nMaxPointOffset=AkelPad.MemRead(_PtrAdd(lpMaxPoint, _X64?40:20) /*offsetof(AEPOINT, nPointOffset)*/, 2 /*DT_QWORD*/);
  var nMaxPointLen=AkelPad.MemRead(_PtrAdd(lpMaxPoint, _X64?48:24) /*offsetof(AEPOINT, nPointLen)*/, 3 /*DT_DWORD*/);
  var lpFoldData=AkelPad.MemRead(_PtrAdd(lpFold, _X64?88:56) /*offsetof(AEFOLD, dwUserData)*/, 2 /*DT_QWORD*/);
  var nNameOffsetFromPoint=AkelPad.MemRead(_PtrAdd(lpFoldData, _X64?32:16) /*offsetof(FOLDDATA, nNameOffsetFromPoint)*/, 3 /*DT_DWORD*/);
  var lpName=AkelPad.MemRead(_PtrAdd(lpFoldData, _X64?24:12) /*offsetof(FOLDDATA, wpName)*/, 2 /*DT_QWORD*/);
  var pName=AkelPad.MemRead(lpName, 1 /*DT_UNICODE*/);

  return {lpFold:lpFold,
          lpMinPoint:lpMinPoint,
          lpMaxPoint:lpMaxPoint,
          nMinPointOffset:nMinPointOffset,
          nMinPointLen:nMinPointLen,
          nMaxPointOffset:nMaxPointOffset,
          nMaxPointLen:nMaxPointLen,
          lpFoldData:lpFoldData,
          nNameOffsetFromPoint:nNameOffsetFromPoint,
          pName:pName};
}

function FoldGet(hWndEdit, dwFlags, dwFindIt)
{
  var lpFindFold;
  var lpParent=0;

  if (lpFindFold=AkelPad.MemAlloc(_X64?0:16 /*sizeof(AEFINDFOLD)*/))
  {
    AkelPad.MemCopy(_PtrAdd(lpFindFold, 0) /*offsetof(AEFINDFOLD, dwFlags)*/, dwFlags, 3 /*DT_DWORD*/);
    AkelPad.MemCopy(_PtrAdd(lpFindFold, _X64?8:4) /*offsetof(AEFINDFOLD, dwFindIt)*/, dwFindIt, 3 /*DT_DWORD*/);
    AkelPad.SendMessage(hWndEdit, 3410 /*AEM_FINDFOLD*/, lpFindFold, 0);
    lpParent=AkelPad.MemRead(_PtrAdd(lpFindFold, _X64?16:8) /*offsetof(AEFINDFOLD, lpParent)*/, 2 /*DT_QWORD*/);
    AkelPad.MemFree(lpFindFold);
  }
  return lpParent;
}


Требуется Coder плагин версии 19.9 или выше.
Post Reply