Dear Paul,help me!
It's me again – I hope you don't mind me bothering you once more. I've seen your continuous new releases, and I really appreciate your hard work.
I've always wanted to have auto‑formatting while typing, similar to what QB64 does. So I tried to write a module (modformatter.inc) that formats a line immediately after it's entered – mainly adding spaces around operators and such simple things. (I'm a beginner and my code is quite messy, so I'm a bit embarrassed to share it.) I tested the module and it basically works. Then I included my module in frmonmainnotify.inc and added the following code:
case chr(13) ' ENTER KEY PRESSED
pDoc->AutoCompleteType = AUTOCOMPLETE_NONE
AttemptAutoInsert()
' ===== 新增:格式化上一行(开始)=====
pDoc->AutoCompleteType = AUTOCOMPLETE_NONE
AttemptAutoInsert()
dim nLine as long = pDoc->GetCurrentLineNumber()
if nLine > 0 then
dim strPrevLine as string = pDoc->GetLine(nLine - 1)
dim sTrim as string = trim(strPrevLine)
' 跳过空行和单行注释
if sTrim <> "" and left(sTrim, 1) <> "'" then
' 检测是否在多行注释内
dim hEdit as HWND = pDoc->hWndActiveScintilla
dim lineStart as long = SciExec(hEdit, SCI_POSITIONFROMLINE, nLine - 1, 0)
dim style as long = SciExec(hEdit, SCI_GETSTYLEAT, lineStart, 0)
if style <> SCE_B_MULTILINECOMMENT then
dim fmtPrevLine as string = AddSpacesAroundOperators(strPrevLine)
if strPrevLine <> fmtPrevLine then
pDoc->SetLine(nLine - 1, fmtPrevLine)
end if
end if
end if
end if
' ===== 新增:格式化上一行(结束)=====After recompiling, the formatting works, but it breaks the auto‑indentation. With only one level of indentation it works fine, but with two levels (nested blocks) it stops auto‑indenting. I also tried not to format immediately – instead I posted a message to a queue to process it later – but the problem remains.
case chr(13)
dim nLine as long = pDoc->GetCurrentLineNumber()
if nLine > 0 then
' 保存行号,稍后处理
gPendingFormatLine = nLine - 1
PostMessage(HWND_FRMMAIN, MSG_USER_FORMAT_LINE, 0, 0)
end if
This has been bothering me for a long time. Could you please tell me what I'm doing wrong? Any help would be greatly appreciated.
Additionally, I downloaded and tried the new release immediately. Unfortunately, the TODO list garbled text problem is still there. I also attempted to convert the encoding inside frmoutput.inc, but my skills aren't good enough and I failed. Here are a few small suggestions I'd like to raise – hope you can consider them:
1.The TODO list garbled‑text issue is critical for non‑Latin users.
2.Double‑click on the tab bar to create a new tab (new file).
3.Tiko is based on afxNova; the original winfbe seems to have an AFX help document. Why isn't it included in Tiko? It would be very helpful for learning the afxNova library.
4.Can variable names be auto‑completed with the same case as the first time they were typed, and when renaming, all occurrences of the same variable change together – like in QB64PE?
5.Tiko already collects user‑defined functions – could we set a theme colour for them?
6.Since the sidebar is already crowded with icons, maybe a separate toolbar would be a good idea. And it'd be nice if the sidebar could be clicked to show/hide, like the status bar.
7.Auto‑insert should also auto‑complete for SCOPE, NAMESPACE, etc.
P.S. – I also tried to implement auto‑insert for multi‑line comments and for SCOPE/NAMESPACE blocks with the following code (which I inserted into OnAutoInsert). I'm including it here in case it's useful:
' /'/'/多行注释
if (left(strPrevLine, 3) = "/' ") or (strPrevLine = "/'") then
strFill = vbcrlf & FillString(space(nSpaces)) & "'/"
SciExec(hEdit, SCI_ADDTEXT, len(strFill), strptr(strFill))
if trim(strPrevLine) = "/'" then
curPos = SciExec(hEdit, SCI_POSITIONFROMLINE, nLine - 1, 0) + NumTabsFromSpaces(nSpaces) + 2
else
curPos = curPos + NumTabsFromSpaces(nSpaces)
end if
SciExec(hEdit, SCI_SETSEL, curPos, curPos)
exit function
end if
2、增加namespace,scope自动补全
a、在 select case idBlockType段最后加上:
case BLOCK_STATEMENT_SCOPE: sStartMatch = "SCOPE": sEndMatch = "END SCOPE"
case BLOCK_STATEMENT_NAMESPACE: sStartMatch = "NAMESPACE ": sEndMatch = "END NAMESPACE"
b、在上面多选注释后,或者在while/wend后面增加
'''''''''''''
' SCOPE/END SCOPE
if (left(strPrevLine, 6) = "SCOPE ") or (strPrevLine = "SCOPE") then
strFill = FillString(space(nSpaces + IndentSize))
if CanCompleteBlockStatement(pDoc, BLOCK_STATEMENT_SCOPE) then
strFill = strFill & vbcrlf & FillString(space(nSpaces)) & "end scope" & vbcrlf
end if
SciExec(hEdit, SCI_ADDTEXT, len(strFill), strptr(strFill))
curPos = curPos + NumTabsFromSpaces(nSpaces + IndentSize )
SciExec(hEdit, SCI_SETSEL, curPos, curPos)
exit function
end if
'''''''''''''
' NAMESPACE/END NAMESPACE
if (left(strPrevLine, 10) = "NAMESPACE ") or (strPrevLine = "NAMESPACE") then
strFill = FillString(space(nSpaces + IndentSize))
if CanCompleteBlockStatement(pDoc, BLOCK_STATEMENT_NAMESPACE) then
strFill = strFill & vbcrlf & FillString(space(nSpaces)) & "end namespace" & vbcrlf
end if
SciExec(hEdit, SCI_ADDTEXT, len(strFill), strptr(strFill))
curPos = curPos + NumTabsFromSpaces(nSpaces + IndentSize )
SciExec(hEdit, SCI_SETSEL, curPos, curPos)
exit function
end ifAttached is the Chinese localization file for v1.3.2. Also, the lack of BBCode support here makes posting a bit inconvenient.
Thanks for the new Chinese language file. I have included it for the next release.
You have given me a lot to think about. I'll work through your questions and try to post some answers. It might take a while to get answers for everything.
As I make changes, I post them all in the Tiko development branch on Github. I am currently in the middle of a fairly large redesign of the UI with most notably being the Find/Replace functionality. I have changed it from VS Code style to Zed Editor style. It is not 100% working yet but it is getting close. I will be moving some of the toolbar icons, etc.
To fix the TODO garbled Chinese text, replace the ctxParser.GetLine() function located in modParser.inc with the following code: (Hopefully this will work for you. It seemed to work with some Chinese text that I pasted into a Tiko document).
'':::::
function ctxParser.GetLine() as boolean
this.ReadToEOL()
dim as string st = mid( *this.text, this.s + 1, this.i - this.s)
this.fullLine.utf8 = st
this.s = this.i
return true
end function
Double-clicking on the tab bar to create a new empty file:
Add the following code to the frmTopTabs_WndProc() function located in the frmTopTabs.inc file:
case WM_LBUTTONDBLCLK
' If doubleclicking in the unused client area of the tab control then
' add a new file. We do not track the actual unused area, so we need to
' test whether the double click occured over a Tab or over the Action Panel.
if ( getHotTabHitTest(hwnd) = -1 ) andalso _
( isMouseOverRect(hwnd, gTTabCtl.rcActionPanel) = false ) then
PostMessage( HWND_FRMMAIN, WM_COMMAND, MAKEWPARAM(IDM_FILENEW, 0), 0 )
end if
Quote3.Tiko is based on afxNova; the original winfbe seems to have an AFX help document. Why isn't it included in Tiko? It would be very helpful for learning the afxNova library.
There are better sources for this information that having it included within Tiko. The best location is directly from José's repository itself: https://github.com/JoseRoca/AfxNova/tree/main/docs
Fellow forum user hajubu has also created an AfxNova help viewer that may work for you. You can find the latest files at this link: https://www.planetsquires.com/protect/forum/index.php?topic=4834.msg36490
QuoteTiko already collects user‑defined functions – could we set a theme colour for them?
This sounds good in concept but implementing such a feature in practice is quite difficult given the way keywords are handled with the Scintilla editing control.
QuoteSince the sidebar is already crowded with icons, maybe a separate toolbar would be a good idea. And it'd be nice if the sidebar could be clicked to show/hide, like the status bar.
I am redesigning parts of the UI so eventually the toolbar may not be as crowded. The sidebar does not already have n icon to allow it to open/hide. However, you can already show/hide the sidebar via the top menu "View / View Side Panel", or better still, by using the faster keyboard shortcut Ctrl+B.
QuoteAutoinsert....
I have implemented the SCOPE/END SCOPE and NAMESPACE/END NAMESPACE. I also implemented the multiline comment autoinsert but I had to change your code a little bit.
I added the code within thecode block that checks the document's styling to see if we are already within a comment block. I also had to move that entire "Select Case" block to just before where IF/THEN autoinsert code. I had to do this because I needed the code that calculates the nSpaces amount.
' Get the styling of the current line to determine if we are in a
' multiline or single line comment block then abort the autoinsert.
select case SciExec(hEdit, SCI_GETSTYLEAT, curPos, 0)
case SCE_B_MULTILINECOMMENT
'''''''''''''
' MULTILINE COMMENTS /' '/
if (left(strPrevLine, 3) = "/' ") orelse (strPrevLine = "/'") then
strFill = FillString(space(nSpaces)) & vbcrlf & FillString(space(nSpaces)) & "'/"
SciExec(hEdit, SCI_INSERTTEXT, curPos, strptr(strFill))
curPos += nSpaces
SciExec(hEdit, SCI_SETSEL, curPos, curPos)
exit function
end if
exit function
case SCE_B_COMMENT
' Allow to continue for single line comments because we want the ENTER
' key to position our cursor under the preceeding ' mark.
end select
''''''''''
' IF/THEN
' Before autoindenting an if statement make sure that this
' is in fact a multiline if statement.
if (left(strPrevLine, 3) = "IF " andalso right(strPrevLine, 5) = " THEN") then
' Remove the current line because we will add it again below
'etc...
QuoteCan variable names be auto‑completed with the same case as the first time they were typed, and when renaming, all occurrences of the same variable change together – like in QB64PE?
This type of feature has been requested before. Tiko currently does not have the ability to do this because it does not parse and store variable names. Maybe in a future Tiko version after I implement the full FB compiler's parsing code.
Quotemodformatter.inc ....
If you like, you can email me your code and I will try to incorporate it into the editor. I would have to also implement a Setting where the user can enable or disable the auto formatting (similar to turning on or off AutoIndent, etc).
Don't be concerned about the quality or beauty of your code. If you have seen some of the code I've written over the years then you wouldn't be worried about your code. Some of the code within Tiko itself is code that I've carried over from 20 years worth of previous editors that I've written. I cringe when I see that code and I know that I should rewrite it with the knowledge that I have now..... but it works.
My email address is support@planetsquires.com if you want to share it.
Thank you very much for your reply.
I immediately applied your code, recompiled, and tested it. The TODO list now works perfectly – I tested with ANSI, UTF‑8 and UTF‑16, and there is no garbled text at all. Great work!
The double‑click to create a new file also works flawlessly. I modified the code to this:
case WM_LBUTTONDBLCLK
dim tabIdx as integer = getHotTabHitTest(hwnd)
if tabIdx >= 0 then
' Double‑click on a tab → close that tab
' If CloseTab only works on the active tab, activate it first
if gTTabCtl.CurSel <> tabIdx then
gTTabCtl.SetFocusTab(tabIdx)
end if
gTTabCtl.CloseTab(tabIdx)
frmTopTabs_PositionWindows()
elseif isMouseOverRect(hwnd, gTTabCtl.rcActionPanel) = false then
' Double‑click on empty area (and not on the action panel) → new file
PostMessage( HWND_FRMMAIN, WM_COMMAND, MAKEWPARAM(IDM_FILENEW, 0), 0 )
end if
Now I can both open and close files with a double‑click.
One suggestion:
The TODO detection seems too strict – it only recognises ':TODO:' exactly. For example, ' todo: is not recognised, and even correctly formatted TODOs inside multi‑line comments are not detected (this might be a small bug). I'd suggest relaxing the conditions a little – just match any occurrence of todo: (case‑insensitive, maybe with optional leading whitespace or quotes).
I really appreciate your offer to help with my code formatter. Before I ask you to look into it, I feel I should clean up my code a bit – it's currently too messy to present for analysis. I'll tidy it up and then get back to you, hoping you can help me figure out what went wrong.
Best regards, and thank you again. I'm looking forward to your next major release!
QuoteI would have to also implement a Setting where the user can enable or disable the auto formatting (similar to turning on or off AutoIndent, etc).
Yes, please. And if it is disabled by default, much better. The only option that I use is auto indentation.
Quote from: fbfans on July 04, 2026, 01:01:32 PMOne suggestion:
The TODO detection seems too strict – it only recognises ':TODO:' exactly. For example, ' todo: is not recognised, and even correctly formatted TODOs inside multi‑line comments are not detected (this might be a small bug). I'd suggest relaxing the conditions a little – just match any occurrence of todo: (case‑insensitive, maybe with optional leading whitespace or quotes).
I have refactored the TODO parsing code so it should be much better now. It is case insensitive and allows embedded spaces. I have also fixed the oversight of not parsing for TODO within a multiline comment statement block. That seems to work okay now.
You should be able to use variants of the 'TODO: starting phrase.
You will need to replace two files: modParser.bi and modParser.inc
Get them from the Tiko "development" branch:
https://github.com/PaulSquires/tiko/tree/development/src
hi Paul,
I'm a bit confused, for the 'Todo: / 'todo: situation.
I s this situation intended or only a tempory one ?
b.r.
a) Version 132-main-branch(0623) is still working fine :
--> (tiko.exe 773.632 23.06.2026 11:33:14)
Todo-Report:'TODO: for line 1,3,5,6 displays as expected)
---
b) Version 132-dev-branch(0705) is working fine , except if token is in last last line. (tiko-dev.exe 774.656 05.07.2026 03:48:52)
Todo-report:'TODO: for line 1,3,5 displays as expected, todo in line 6 is missing)
----
'TODO: (in #line)
'#console on
'todo: (in line 3)
print 'Hello - Tiko-132 (main vs dev) user on line 4 with todo: " : sleep
'todo: (in line 5)
'TODO: This is sample text for "I need to do" in the last line 6
--------
PS. v130,v131 i did'nt test / check anymore
@hajubu yes, there does seem to be something wrong with the parsing. I am working on fixing it. There is something about this text that is causing problems and it doesn't matter if it is the last line or not it seems.
'TODO: This is sample text for "I need to do" in the last line 6
I'll get it working and post when you can test it again. I have reverted some previous code and will work through the issue.
@hajubu I have fixed the TODO parsing. Use the files "modParser.inc", and "modParser.bi" in the development branch: https://github.com/PaulSquires/tiko/tree/development/src
I tested the new code with the following test variations:
'TODO: This is sample text for "I need to do" in the last line 6
'ToDo: (upper and lowercase)
' todo: (leading spaces)
/'
' ToDo: (in multiline comment, upper/lower, leading spaces)
'/
thanks , it works
b.r. :-)
Hello Paul,
I've been testing my formatting module again, and unfortunately it still breaks the auto-indentation. I've attached my code — could you please take a look at it when you have a moment? Thank you.
I noticed that you're already preparing the next release and I saw your planned work. I think there's still some room to improve the overall user experience of Tiko, and while you may already be working on some of these, I feel the following issues are quite important:
1.Sidebar refresh problem: When opening or closing files, the sidebar doesn't update synchronously, and there's no manual refresh button either.
2.Function list collapse/expand is not working (I mentioned this in my first post). The Explorer and Bookmarks panels work fine, but the Function list doesn't collapse/expand properly. This makes it less intuitive when many files are open.
3.Bookmarks show garbled text for Chinese characters, and only work correctly when the file encoding is ANSI. You previously fixed the garbled text issue in the TODO list — could you perhaps apply a similar elegant fix here?
4.Suggestion for hover hints on #include lines: For example, on #include once "AfxNova/Dwstring.inc", it would be helpful to show a tooltip like "Dwstring.inc, right-click to open". It took me a long time to discover that Tiko even supports this feature.
5.Localization language selection: Since Tiko already supports several languages, could we have a listbox for selecting the language? It would be much more user-friendly to double-click a file directly.
Thank you for your work on this great editor. I don't mean to put any pressure on you — I just hope that, while you're enjoying coding, you might find some time to address issues like #1 and #2, which would significantly improve the user experience.
Wish you happy coding!
@fbfans Thanks for the source file and suggestions. I will look at the formatter and your suggestions as soon as I can. I have a short list of things to fix/implement before I can get to your list.
QuoteSidebar refresh problem: When opening or closing files, the sidebar doesn't update synchronously, and there's no manual refresh button either.
Maybe you can explain this one a bit more. Opening/Closing files should automatically reload the Explorer and Functions panes (maybe the bookmarks list is not being cleared and refreshed?).
What I do need to work on is updating the Functions list in real time as the user types in a Sub/Function End Sub/End Function combination WITHOUT SAVING. Currently, it is the act of saving the file that triggers a re-parsing of the code thereby updating the Functions list. I plan to switch this to either use continuously scanning background threads, or simply do a re-parse of the code when the ENTER key is pressed.
Quote from: fbfans on July 10, 2026, 05:34:30 AMFunction list collapse/expand is not working (I mentioned this in my first post). The Explorer and Bookmarks panels work fine, but the Function list doesn't collapse/expand properly. This makes it less intuitive when many files are open.
Should be fixed now in "frmFunctions.inc" on the development branch. Just had to slightly change the WM_LBUTTONUP message:
case WM_LBUTTONUP
' determine if we clicked on a function name or a node header
dim as RECT rc
dim as long idx = Listbox_ItemFromPoint( hWin, GET_X_LPARAM(_lParam), GET_Y_LPARAM(_lParam))
' The return value contains the index of the nearest item in the LOWORD. The HIWORD is zero
' if the specified point is in the client area of the list box, or one if it is outside the
' client area.
if hiword(idx) <> 1 then
dim as clsDocument ptr pDoc = cast(clsDocument ptr, ListBox_GetItemData( hWin, idx ))
dim as DWSTRING wszCaption = AfxGetListBoxText( hWin, idx )
if (left(wszCaption, 4) = "true") orelse (left(wszCaption, 5) = "false") then
' Toggle the show/hide of functions under this node
if pDoc then pDoc->bFunctionsExpanded = not pDoc->bFunctionsExpanded
' allow listbox click event to fully process before loading new functions
PostMessage( hWin, MSG_USER_LOAD_FUNCTIONSFILES, 0, 0 )
else
' Attempt to show the function name
dim as long nLineNum = getFunctionsLinenumber( wszCaption )
dim as DWSTRING wszFunctionName = getFunctionsFunctionName( wszCaption )
dim as DWSTRING wszDiskFilename
if pDoc then wszDiskFilename = pDoc->DiskFilename
OpenSelectedDocument( wszDiskFilename, wszFunctionName, nLineNum )
end if
end if
Quote from: fbfans on July 10, 2026, 05:34:30 AMBookmarks show garbled text for Chinese characters, and only work correctly when the file encoding is ANSI. You previously fixed the garbled text issue in the TODO list — could you perhaps apply a similar elegant fix here?
This is now fixed in the development branch. "frmBookmarks.inc"
Also, you were correct that the Bookmarks in side panel list were not getting refreshed/updated when "Save" was invoked. This is now fixed. "frmMainFile.inc" added "LoadBookmarksFiles()" to the "OnCommand_FileSave()" function.
QuoteSuggestion for hover hints on #include lines: For example, on #include once "AfxNova/Dwstring.inc", it would be helpful to show a tooltip like "Dwstring.inc, right-click to open". It took me a long time to discover that Tiko even supports this feature.
This is harder to implement than it should be (because I had already tried to implement such a feature before :-) )
The problem is that the Scintilla editing control does not expose or fire any type of MouseHover notification message. The hacks that I have read indicate having to subclass each editing window and hook into Scintilla's own message loops. I'm sure that it can be done but I decided against it because it would introduce a layer of complexity that I fear would be brittle and possibly lead to instability.
QuoteLocalization language selection: Since Tiko already supports several languages, could we have a listbox for selecting the language? It would be much more user-friendly to double-click a file directly.
I posit that it is extremely rare that Tiko users switch between localized languages enough to necessitate changing the current UI. Maybe you do with Simplified Chinese and English? But I expect that is the exception rather than the rule.
Quote from: fbfans on July 10, 2026, 05:34:30 AMI've been testing my formatting module again, and unfortunately it still breaks the auto-indentation. I've attached my code — could you please take a look at it when you have a moment? Thank you.
I just started to look at this code. I have translated all of the Chinese comments to English so that I can better understand the intention of the different parts of the code. Give me some time to learn and understand how this works and then I will see if there are ways that I can simplify it. I may also take a look at other solutions from other languages to see how they tackle this type of problem.
Quote from: fbfans on July 04, 2026, 01:45:03 AMI've always wanted to have auto‑formatting while typing, similar to what QB64 does. So I tried to write a module (modformatter.inc) that formats a line immediately after it's entered – mainly adding spaces around operators and such simple things. (I'm a beginner and my code is quite messy, so I'm a bit embarrassed to share it.) I tested the module and it basically works. Then I included my module in frmonmainnotify.inc and added the following code:
case chr(13) ' ENTER KEY PRESSED
pDoc->AutoCompleteType = AUTOCOMPLETE_NONE
AttemptAutoInsert()
' ===== 新增:格式化上一行(开始)=====
pDoc->AutoCompleteType = AUTOCOMPLETE_NONE
AttemptAutoInsert()
dim nLine as long = pDoc->GetCurrentLineNumber()
if nLine > 0 then
dim strPrevLine as string = pDoc->GetLine(nLine - 1)
dim sTrim as string = trim(strPrevLine)
' 跳过空行和单行注释
if sTrim <> "" and left(sTrim, 1) <> "'" then
' 检测是否在多行注释内
dim hEdit as HWND = pDoc->hWndActiveScintilla
dim lineStart as long = SciExec(hEdit, SCI_POSITIONFROMLINE, nLine - 1, 0)
dim style as long = SciExec(hEdit, SCI_GETSTYLEAT, lineStart, 0)
if style <> SCE_B_MULTILINECOMMENT then
dim fmtPrevLine as string = AddSpacesAroundOperators(strPrevLine)
if strPrevLine <> fmtPrevLine then
pDoc->SetLine(nLine - 1, fmtPrevLine)
end if
end if
end if
end if
' ===== 新增:格式化上一行(结束)=====After recompiling, the formatting works, but it breaks the auto‑indentation. With only one level of indentation it works fine, but with two levels (nested blocks) it stops auto‑indenting.
...
This has been bothering me for a long time. Could you please tell me what I'm doing wrong? Any help would be greatly appreciated.
I went back and re-read your initial post and question.
The purpose of your code is to beautify and format the line that you have just typed and pressed ENTER. Why not do this formatting BEFORE the AttemptAutoInsert(), rather than your approach of AFTER AttemptAutoInsert()? Maybe try replacing the current line with your newly formatted line and then have AttemptAutoInsert() act on that formatted line? That seems more logical to me and it would probably save you from having to determine previously line and indenting, etc.
Maybe something like this:
dim as long nCurLine = pDoc->GetCurrentLineNumber()
dim as string strLine = pDoc->GetLine(nCurLine)
dim as string strNewLine = AddSpacesAroundOperators( strLine )
pDoc->SetLine( nCurLine, strNewLine )
AttemptAutoInsert()
This may work better than your current approach and you wouldn't have to change your existing code very much? I have no idea if it will work but it may be worth a shot to see if it does.
Paul, thank you for fixing the bookmark issue.
My technical knowledge is limited, and I didn't expect the several issues I brought up to be this tricky. It turns out you'd already thought through all of them long beforehand — I overcomplicated things unnecessarily.
I'd like to explain the current situation of my formatting code.
In the frmmainonnotify.inc module, once the Enter key is pressed, Scintilla moves the cursor to a brand new blank line immediately. That's why my code reads and processes the previous typed line — this logic itself is correct.
I also tried moving the formatting routine before AttemptAutoInsert() as suggested, but the indentation bug still persists.
The specific issue: only the first-level indentation works properly, while all second-level and multi-layer nested indentations break entirely, as shown in this sample:
if a>b then
print "hello"
else
print "china"
end if
do while a>b
print "word"
loop
end ifI consulted an DeepSeek(AI) tool for analysis, and it pointed out the root cause: my formatting function calls SetLine to rewrite the entire line, which triggers the SCN_MODIFIED notification and forces bNeedsParsing = true. This marks the global document's nested level and keyword parsing cache as outdated, so the reference data used to calculate multi-layer indentation stays invalid all the time.
I'm confused about one thing: I only added spaces around operators and never modified the leading indent whitespaces, so I don't understand why this breaks auto-indentation judgment entirely.
If this bug is indeed tied to the underlying global document parsing cache mechanism, I don't have the ability to fully resolve this conflict with my current skill set.
After weighing all factors, I will remove the auto-formatting logic triggered by the Enter key and stop developing this feature.
Thanks again, Paul.
@fbfans I now realize that the problem is that the SCN_CHARADDED notification is received AFTER the ENTER character is inserted. We need to capture the ENTER key BEFORE it ever reaches the Scintilla control. Normally we would do this by subclassing the Scintilla control but there is a much easier way. We test for the keypress in the main message loop via the raw incoming messages received from Windows.
I have tested the following sequence of code and it works.
Modify "frmMain.inc" message loop. That's the code area towards the end of the file that handles the GetMessage.
' Message loop
do while GetMessage(@uMsg, null, 0, 0)
Insert the following after the line that calls "handleKeysFindReplace:
' Handle ENTER for Scintilla control (beautify current line)
if handleScintillaENTER(uMsg) then continue do
Create that "handleScintillaENTER()" function in "modMsgPump.inc"
function handleScintillaENTER( byval uMsg as MSG ) as boolean
' Catch any ENTER key destined for the Scintilla editor and beautify the
' current text line. We replace the line with our new code and then allow
' the ENTER key to continue to pass on to Scintilla where it will do the
' insertion of the ENTER character. Scintilla will then fire SCN_CHARADDED
' where we do additional things like AutoIndent.
dim pDoc as clsDocument ptr = gApp.GetDocumentPtrByWindow( uMsg.HWnd )
if pDoc = 0 then return false
dim as HWND hEdit = pDoc->hWndActiveScintilla
if (uMsg.HWnd = hEdit) andalso (uMsg.message = WM_KEYDOWN) andalso (uMsg.wParam = VK_RETURN) then
dim as long nCurLine = pDoc->GetCurrentLineNumber()
dim as string strLine = pDoc->GetLine(nCurLine)
' CALL YOUR FORMATTING ROUTINE HERE AND RETURN THE NEW LINE
' Beautify the current line
'dim as string strNewLine ='AddSpacesAroundOperators( strLine )
' Replace the old line with our new line (don't use pDoc->SetLine)
dim as long lineStart = SendMessage( hEdit, SCI_POSITIONFROMLINE, nCurLine, 0)
dim as long lineEnd = SendMessage( hEdit, SCI_GETLINEENDPOSITION, nCurLine, 0)
SendMessage( hEdit, SCI_SETSELECTIONSTART, lineStart, 0)
SendMessage( hEdit, SCI_SETSELECTIONEND, lineEnd, 0)
SendMessage( hEdit, SCI_REPLACESEL, 0, cast(LPARAM, strptr(strNewLine)) )
end if
' we want our message to continue so return FALSE
return false
end function
This should work.
"I made the changes following your suggestions, but the problem still isn't resolved. I've been randomly debugging this for a while now.
It should be that after formatting, Scintilla's cache gets altered and doesn't refresh immediately—I just can't figure it out.
Seeing your post about the improvements in the new Tiko, it seems you've already implemented parsing. If you have some spare time later, perhaps you could consider implementing code formatting as well? If that's the case, I won't waste your valuable development time on this anymore. I'm giving up on this project.
Thank you for your selfless help."