Script or macro to enumerate lines?

English main discussion
Post Reply
  • Author
  • Message
Offline
Posts: 8
Joined: Fri Aug 12, 2011 6:34 am

Script or macro to enumerate lines?

Post by wallywalters »

Just wondering if anyone has a technique for getting the current line number and placing it in the document (preferably at the start of the line).

Offline
Posts: 32
Joined: Thu Oct 15, 2015 2:20 am

Post by CBruce »

Code: Select all

// InsertLineNum.js
// Insert the current line's line number at the beginning of the line.
// Version: 1.0 (2018-01-29)
// Author: Bruce Huber (CBruce)

// Why?... I don't know.
// Ask WallyWalters - the guy who wanted it to do this.  [smile]

var hWndEdit=AkelPad.GetEditWnd();
if (hWndEdit)
{
    var WshShell = new ActiveXObject("WScript.Shell");
      //Reposition cursor at the beginning of the current line.
    WshShell.SendKeys("{HOME}");
      //Get the the position of the current character in the document.
      //Yes. Even though we have no text selected, we still have GetSelStart.
    var nDocCharPos = AkelPad.GetSelStart();
      //Get the line number that our character is sitting in.
    var nCurrentLineNum = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nDocCharPos);
      //API value is zero based... increment it to get what we think the line number is.
    nCurrentLineNum += 1
      //Insert the line number at the beginning of the line.
    AkelPad.ReplaceSel(nCurrentLineNum + ": ");
      //Put the cursor back at the beginning of the current line.
    WshShell.SendKeys("{HOME}");
}

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

Post by opk44 »

CBruce
Works wrong if "Wrap words" [Ctrl+U] is "ON".

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

Post by Skif_off »

Maybe try using WM_SETREDRAW and command 4209 (if necessary), without SendKeys?

Code: Select all

var hWndEdit = AkelPad.GetEditWnd();
var nStart   = AkelPad.GetSelStart();
var oSys     = AkelPad.SystemFunction();
var nWordWrap;
var nLine;
var nLineIndex;

SetRedraw(hWndEdit, false);

nWordWrap = AkelPad.SendMessage(hWndEdit, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
if (nWordWrap > 0)
  AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);

nLine = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nStart);
nLineIndex = AkelPad.SendMessage(hWndEdit, 187 /*EM_LINEINDEX*/, nLine, 0);

AkelPad.SetSel(nLineIndex, nLineIndex);
nLine += 1
AkelPad.ReplaceSel(nLine + ": ");

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

SetRedraw(hWndEdit, true);

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

Offline
Posts: 32
Joined: Thu Oct 15, 2015 2:20 am

Post by CBruce »

Thanks, Skif_off!

I didn't know how to handle wordwrap. And once I made this loop through a selection, I understand why you toggle redraw also.

Code: Select all

// InsertLineNum.js
// Insert the current line's line number at the beginning of each line in selection.
// Version: 1.0 (2018-01-29)
// Version: 2.0 (2018-01-30)
// Author: Bruce Huber (CBruce)

// Why?... I don't know.
// Ask WallyWalters - the guy who wanted it to do this.  [smile]

var nWordWrap;
var nDocCharPos;
var nCurrentLineNum;
var pSelText;
var pLinesArray;
var nIndex;
var oSys=AkelPad.SystemFunction(); 

var hWndEdit=AkelPad.GetEditWnd();
if (hWndEdit)
{
    SetRedraw(hWndEdit, false);
      //Is WordWrap on?
    nWordWrap = AkelPad.SendMessage(hWndEdit, 3241 /*AEM_GETWORDWRAP*/, 0, 0);
    if (nWordWrap > 0)
        AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);    //Command 4209 toggles WordWrap on/off.
      //Get the the position of the current character in the document.
      //Yes. Even though we have no text selected, we still have GetSelStart.
    nDocCharPos = AkelPad.GetSelStart();
      //Get the line number that our character is sitting in.
    nCurrentLineNum = AkelPad.SendMessage(hWndEdit, 1078 /*EM_EXLINEFROMCHAR*/, 0, nDocCharPos);
      //API value is zero based... increment it to get what we see the line number as.
    nCurrentLineNum += 1
      //Loop through the selected lines and insert line numbers.
    if (pSelText=AkelPad.GetSelText())
    {
        if (pLinesArray=pSelText.split("\r"))     // Split the lines into an array.
        {
            for (nIndex=0; nIndex < pLinesArray.length; ++nIndex) {
                  //Insert line numbers at the beginning of each selected line.
                pLinesArray[nIndex] = nCurrentLineNum + ": " + pLinesArray[nIndex];
                nCurrentLineNum += 1
            }
            pSelText=pLinesArray.join("\r");
            AkelPad.ReplaceSel(pSelText, -2);
        }
    }
    if (nWordWrap > 0)
        AkelPad.Command(4209 /*IDM_VIEW_WORDWRAP*/);    //Command 4209 toggles WordWrap on/off.
    SetRedraw(hWndEdit, true);
}


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

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

Post by Instructor »

InsertCurLineNumber.js

Code: Select all

var hWndEdit=AkelPad.GetEditWnd();
var nCaretOffset;
var nUnwrapLine;

nCaretOffset=AkelPad.SendMessage(hWndEdit, 3138 /*AEM_GETRICHOFFSET*/, 5 /*AEGI_CARETCHAR*/, 0);
nUnwrapLine=AkelPad.SendMessage(hWndEdit, 3129 /*AEM_GETLINENUMBER*/, 21 /*AEGL_UNWRAPLINEFROMRICHOFFSET*/, nCaretOffset);
nLineStart=AkelPad.SendMessage(hWndEdit, 3138 /*AEM_GETRICHOFFSET*/, 18 /*AEGI_WRAPLINEBEGIN*/, nCaretOffset);
AkelPad.SetSel(nLineStart, nLineStart);
AkelPad.ReplaceSel("" +(nUnwrapLine + 1) + ": ", -1 /*RST_SELECT*/);

Offline
Posts: 32
Joined: Thu Oct 15, 2015 2:20 am

Post by CBruce »

Instructor
Cool! But in case he wanted to do a whole selection, I went LOOP'y in my script.

("went loopy" is also an American slang for "went crazy") :P
Post Reply