An IDE editor control has a method, IsLineElided
. Elision[*] is the IDE's internal term for a line being hidden when it is part of a collapsed region, method, or other structure. In the UI, this is called "folding", as in "code folding", but it's quite common for the internal term for something to be different to the UI term presented to the user.
This method is not publicly accessible; it's a method of the internal TEditControl class. To use it, you need to call an IDE method. Unlike a lot of IDE hacks you don't need to hook it, since you don't need to change its behaviour - just call it.
- Mangled name:
@Editorcontrol@TCustomEditControl@LineIsElided$qqri
- with method prototype:
TLineIsElidedProc = function(Self: TObject; LineNum: Integer): Boolean;
- located in the coreide*.bpl file.
For example,
PFLineIsElided := GetProcAddress(CoreIDEHandle, StrIDELineIsElidedName);
You can get the core IDE BPL handle by reading loaded modules. The first parameter should be the editor window - not the ToolsAPI edit view, but the internal editor. This article shows the relationship between the editor control and IOTAEditView.
You can now ask if a line is elided (that is, is it hidden?) from your plugin like so:
if PFLineIsElided(FCodeEditor, 123) then ...
However, putting that together to see which areas are folded - or rather, since the top line of any folded region is still drawn, finding the line after which one or more lines are elided - require slightly more logic. The best way is to iterate through the lines onscreen in a view, IOTAEditView.TopRow
and BottomRow
. If the line after the one you're looking at is folded, but the one you're looking at isn't, then the one you're looking at is the representative line for the folded area (the line that has the +/- symbol in the gutter.)
Note that if you are painting on the code editor the difference between logical line numbers (line numbers as printed in the code gutter) and nominal line numbers (lines visible onscreen in the view) will be important for you, and code elision is what controls this. When code is folded, logical and nominal line numbers won't match: an edit view always draws nominal line numbers in order, but if there is a folded region in the middle, the logical line numbers will have gaps.
Further reading: A large article about integrating with the code editor, one section of which discusses code folding and handling line numbers. It's one of two on the topic of Delphi plugins / wizards integrating with the code editor on the Parnassus blog. Although it covers much more than folded code, if you're writing an IDE plugin that needs to handle this kind of stuff, there's a lot of useful material there. (Disclaimer: my blog.)
[*] As an aside, elision is an auto-antonym: a word that has two meanings that are opposites (the common example is 'cleave'.) One meaning of elision is omission or removal, and another meaning is joining or merging.