Page 1 of 1
Scintilla: how to delete multiple lines at once?
Posted: Sat Nov 25, 2017 4:26 am
by novablue
Hi, i want to delete multiple lines from an external Scintilla gadget, for example line 5 to 50. Currently i am deleting each line one by one which can get really slow. surely there must be a better way to delete multiple lines at once?
Code: Select all
Define I.i
Define IDE_HwndScintilla.i = Val(GetEnvironmentVariable("PB_TOOL_Scintilla"))
Define StartLine.i = 5
Define EndLine.i = 50
SendMessage_(IDE_HwndScintilla, #SCI_GOTOLINE, StartLine, 0)
For I=1 To EndLine-StartLine
SendMessage_(IDE_HwndScintilla, #SCI_LINEDELETE, 0, 0)
Next
Re: Scintilla: how to delete multiple lines at once?
Posted: Sat Nov 25, 2017 12:28 pm
by srod
I have used the following. Try it, see if it is any quicker than your routine.
Code: Select all
Procedure Sci_DeleteLines(id, fromLine, toLine)
Protected numLines, lineLength, startPos, endPos
If IsGadget(id) And GadgetType(id) = #PB_GadgetType_Scintilla And toLine >= fromLine And fromLine >=0 And toLine >=0
If ScintillaSendMessage(id, #SCI_GETLENGTH)
numLines = ScintillaSendMessage(id, #SCI_GETLINECOUNT)
If toLine >= numLines
toLine = numLines-1
EndIf
If fromLine >= numLines
fromLine = numLines-1
EndIf
startPos = ScintillaSendMessage(id, #SCI_POSITIONFROMLINE, fromLine)
endPos = ScintillaSendMessage(id, #SCI_POSITIONFROMLINE, toLine) + ScintillaSendMessage(id, #SCI_LINELENGTH, toLine)
;We may have to delete the EOL characters in the previous line.
If fromLine And fromLine = numLines - 1
Select ScintillaSendMessage(id, #SCI_GETEOLMODE)
Case #SC_EOL_CRLF
startPos-2
Default
startpos-1
EndSelect
EndIf
;We now replace the text with an empty string.
ScintillaSendMessage(id, #SCI_SETTARGETSTART, startPos)
ScintillaSendMessage(id, #SCI_SETTARGETEND, endPos)
ScintillaSendMessage(id, #SCI_REPLACETARGET, -1, @"")
EndIf
EndIf
EndProcedure
**EDIT : just realised that you are working with the PB IDE editor so you'll need to edit my routine somewhat - removing all references to gadget# and switching ScintillaSendMessage() with SendMessage_() etc. I see no reason why it won't work though.
Re: Scintilla: how to delete multiple lines at once?
Posted: Sat Nov 25, 2017 12:46 pm
by srod
A version for working with external scintilla controls. Tested and works fine with a scintilla control created in the running program.
Code: Select all
Procedure Sci_DeleteLines(hWnd, fromLine, toLine)
Protected numLines, lineLength, startPos, endPos
If toLine >= fromLine And fromLine >=0 And toLine >=0
If SendMessage_(hWnd, #SCI_GETLENGTH, 0, 0)
numLines = SendMessage_(hWnd, #SCI_GETLINECOUNT, 0, 0)
startPos = SendMessage_(hWnd, #SCI_POSITIONFROMLINE, fromLine, 0)
endPos = SendMessage_(hWnd, #SCI_POSITIONFROMLINE, toLine, 0) + SendMessage_(hWnd, #SCI_LINELENGTH, toLine, 0)
;We may have to delete the EOL characters in the previous line.
If fromLine And fromLine = numLines - 1
Select SendMessage_(hWnd, #SCI_GETEOLMODE, 0, 0)
Case #SC_EOL_CRLF
startPos-2
Default
startpos-1
EndSelect
EndIf
;We now replace the text with an empty string.
SendMessage_(hWnd, #SCI_SETTARGETSTART, startPos, 0)
SendMessage_(hWnd, #SCI_SETTARGETEND, endPos, 0)
SendMessage_(hWnd, #SCI_REPLACETARGET, -1, @"")
EndIf
EndIf
EndProcedure
Re: Scintilla: how to delete multiple lines at once?
Posted: Sat Nov 25, 2017 7:23 pm
by novablue
Thanks this is much better. I had to replace:
Code: Select all
SendMessage_(hWnd, #SCI_REPLACETARGET, -1, @"")
With:
Code: Select all
SendMessage_(hWnd, #SCI_REPLACETARGET, -1, 0)
Or i would get random characters in the IDE, which brings me to my next question: how can i replace the lines with text? So far i have been doing this but of course it changes the current cursor position:
Code: Select all
SendMessage_(IDE_HwndScintilla, #SCI_GOTOLINE, InsertFrom, 0)
String$ = "Hello"
StringToIDE$ = Space(StringByteLength(String$, #PB_UTF8))
PokeS(@StringToIDE$, String$, -1, #PB_UTF8)
SendMessage_(IDE_HwndScintilla, #EM_REPLACESEL, 0, PeekS(@StringToIDE$))
Re: Scintilla: how to delete multiple lines at once?
Posted: Sat Nov 25, 2017 9:37 pm
by srod
Something similar to before might do it. You might need to monkey around with this a bit.
Must admit I would be a little surprised if this works on a Scintilla control created in another process as we are effectively passing a UTF8 buffer across to the other process!
Code: Select all
Procedure Sci_ReplaceLines(hWnd, fromLine, toLine, text$)
Protected numLines, lineLength, startPos, endPos, utf8Text
If toLine >= fromLine And fromLine >=0 And toLine >=0
If SendMessage_(hWnd, #SCI_GETLENGTH, 0, 0)
utf8Text = UTF8(text$)
If utf8Text
numLines = SendMessage_(hWnd, #SCI_GETLINECOUNT, 0, 0)
startPos = SendMessage_(hWnd, #SCI_POSITIONFROMLINE, fromLine, 0)
endPos = SendMessage_(hWnd, #SCI_POSITIONFROMLINE, toLine, 0) + SendMessage_(hWnd, #SCI_LINELENGTH, toLine, 0)
;We may have to delete the EOL characters in the previous line.
If fromLine And fromLine = numLines - 1
Select SendMessage_(hWnd, #SCI_GETEOLMODE, 0, 0)
Case #SC_EOL_CRLF
startPos-2
Default
startpos-1
EndSelect
EndIf
;We now replace the text.
SendMessage_(hWnd, #SCI_SETTARGETSTART, startPos, 0)
SendMessage_(hWnd, #SCI_SETTARGETEND, endPos, 0)
SendMessage_(hWnd, #SCI_REPLACETARGET, -1, utf8Text)
FreeMemory(utf8Text)
EndIf
EndIf
EndIf
EndProcedure