1 | // Scintilla source code edit control |
---|---|
2 | /** @file Accessor.cxx |
3 | ** Interfaces between Scintilla and lexers. |
4 | **/ |
5 | // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org> |
6 | // The License.txt file describes the conditions under which this software may be distributed. |
7 | |
8 | #include <cstdlib> |
9 | #include <cassert> |
10 | |
11 | #include <string> |
12 | #include <string_view> |
13 | |
14 | #include "ILexer.h" |
15 | #include "Scintilla.h" |
16 | #include "SciLexer.h" |
17 | |
18 | #include "PropSetSimple.h" |
19 | #include "WordList.h" |
20 | #include "LexAccessor.h" |
21 | #include "Accessor.h" |
22 | |
23 | using namespace Lexilla; |
24 | |
25 | Accessor::Accessor(Scintilla::IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) { |
26 | } |
27 | |
28 | int Accessor::GetPropertyInt(std::string_view key, int defaultValue) const { |
29 | return pprops->GetInt(key, defaultValue); |
30 | } |
31 | |
32 | int Accessor::IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { |
33 | const Sci_Position end = Length(); |
34 | int spaceFlags = 0; |
35 | |
36 | // Determines the indentation level of the current line and also checks for consistent |
37 | // indentation compared to the previous line. |
38 | // Indentation is judged consistent when the indentation whitespace of each line lines |
39 | // the same or the indentation of one line is a prefix of the other. |
40 | |
41 | Sci_Position pos = LineStart(line); |
42 | char ch = (*this)[pos]; |
43 | int indent = 0; |
44 | bool inPrevPrefix = line > 0; |
45 | Sci_Position posPrev = inPrevPrefix ? LineStart(line-1) : 0; |
46 | while ((ch == ' ' || ch == '\t') && (pos < end)) { |
47 | if (inPrevPrefix) { |
48 | const char chPrev = (*this)[posPrev++]; |
49 | if (chPrev == ' ' || chPrev == '\t') { |
50 | if (chPrev != ch) |
51 | spaceFlags |= wsInconsistent; |
52 | } else { |
53 | inPrevPrefix = false; |
54 | } |
55 | } |
56 | if (ch == ' ') { |
57 | spaceFlags |= wsSpace; |
58 | indent++; |
59 | } else { // Tab |
60 | spaceFlags |= wsTab; |
61 | if (spaceFlags & wsSpace) |
62 | spaceFlags |= wsSpaceTab; |
63 | indent = (indent / 8 + 1) * 8; |
64 | } |
65 | ch = (*this)[++pos]; |
66 | } |
67 | |
68 | *flags = spaceFlags; |
69 | indent += SC_FOLDLEVELBASE; |
70 | // if completely empty line or the start of a comment... |
71 | if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || |
72 | (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos))) |
73 | return indent | SC_FOLDLEVELWHITEFLAG; |
74 | else |
75 | return indent; |
76 | } |
77 |