Closed lafrank closed 4 years ago
The property HighlightGuide
is strictly tied to brace matching.
This is the code for HighLightGuide
from Scintilla.cs
:
public int HighlightGuide
{
get
{
return DirectMessage(NativeMethods.SCI_GETHIGHLIGHTGUIDE).ToInt32();
}
set
{
value = Helpers.ClampMin(value, 0);
DirectMessage(NativeMethods.SCI_SETHIGHLIGHTGUIDE, new IntPtr(value));
}
}
Here's the documentation for SCI_GETHIGHLIGHTGUIDE
& SCI_SETHIGHLIGHTGUIDE
:
SCI_SETHIGHLIGHTGUIDE(position column)
SCI_GETHIGHLIGHTGUIDE → position
When brace highlighting occurs, the indentation guide corresponding to the braces may be highlighted with the brace highlighting style, STYLE_BRACELIGHT (34). Set column to 0 to cancel this highlight.
AFAIK, there's no built-in way to highlight guides without matching braces.
So how do I provide indent guide highlighting for Python ?
That would be extremely useful since Python is heavily depending on indentation but brace-matching has no added value here due to language syntax. Just look at below example and imagine one has to find the right position for the next line :
Any idea how to resolve this ? Thank you.
Looking at SciTE's (Scintilla's demonstrator editor) way of highlighting Python indent guides, it seems based on a combination of two things:
The following method is a very rough translation of SciTE's code to highlight Python's indent guides:
static bool IsPythonColon(Scintilla sci, int pos)
{
return sci.Lexer == Lexer.Python &&
sci.GetStyleAt(pos) == sci.Styles[Style.Python.Operator].Index &&
sci.GetCharAt(pos) == ':';
}
static void HighlightPyIndentGuide(Scintilla sci)
{
var caretPos = sci.CurrentPosition;
var braceAtCaret = -1;
// Check if caret is before or after the colon and set pos
if (caretPos > 0 && IsPythonColon(sci, caretPos - 1))
braceAtCaret = caretPos - 1;
else if (IsPythonColon(sci, caretPos))
braceAtCaret = caretPos;
// Colon exists
if (braceAtCaret >= 0)
{
var lineStart = sci.LineFromPosition(braceAtCaret);
var lineMaxSubord = sci.Lines[lineStart].GetLastChild(-1);
var braceOpposite = sci.Lines[lineMaxSubord].EndPosition;
var indentPos = sci.Lines[lineStart].IndentPosition;
var indentPosNext = sci.Lines[lineStart + 1].IndentPosition;
var columnAtCaret = sci.GetColumn(indentPos);
var columnOpposite = sci.GetColumn(braceOpposite);
// Don't highlight colon if at a parent-level indent (no guides)
if (columnAtCaret != 0)
sci.BraceHighlight(braceAtCaret, braceOpposite);
var caretColumnNext = sci.GetColumn(indentPosNext);
var indentSize = sci.IndentWidth;
if ((caretColumnNext - indentSize) > 1)
columnAtCaret = caretColumnNext - indentSize;
if (columnOpposite == 0)
columnOpposite = columnAtCaret;
sci.HighlightGuide = Math.Min(columnAtCaret, columnOpposite);
}
else
{
sci.BraceHighlight(Scintilla.InvalidPosition, Scintilla.InvalidPosition);
sci.HighlightGuide = 0;
}
}
The method relies on lineMaxSubord
to find the line where the indent guide ends, which in turn relies on the folding mechanism of the lexer to provide the correct folding levels. Therefore, you should only use it when folding is enabled, otherwise you'll observe incorrect highlighting behaviour.
You should carefully examine SciTE's code to learn form. This translation is buggy and it's merely just a push-start. It doesn't take into account colons that aren't used to start an indent suite, such as:
# setting the caret on the colons would result in incorrectly
# highlighting the indent guide
dict = {
'brand': "prada",
'price': "treefiddy",
}
Thank you xv, much appreciate your help with this !
For Python there should be no brace matching to perform indentation guide highlighting, but I caould not find a way to enable the latter when brace matching is disabled.
That is, the code below has no effect whatever column number is set for HighLighGuide:
scintilla.BraceHighlight(Scintilla.InvalidPosition, Scintilla.InvalidPosition); scintilla.HighlightGuide = caretPos;