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