GetCharAt() 공개 메소드

public GetCharAt ( Mono.TextEditor.DocumentLocation location ) : char
location Mono.TextEditor.DocumentLocation
리턴 char
        static IEnumerable <KeyValuePair <char, int> > GetTextWithoutCommentsAndStrings(Mono.TextEditor.TextDocument doc, int start, int end)
        {
            bool isInString = false, isInChar = false;
            bool isInLineComment = false, isInBlockComment = false;

            for (int pos = start; pos < end; pos++)
            {
                char ch = doc.GetCharAt(pos);
                switch (ch)
                {
                case '\r':
                case '\n':
                    isInLineComment = false;
                    break;

                case '/':
                    if (isInBlockComment)
                    {
                        if (pos > 0 && doc.GetCharAt(pos - 1) == '*')
                        {
                            isInBlockComment = false;
                        }
                    }
                    else if (!isInString && !isInChar && pos + 1 < doc.TextLength)
                    {
                        char nextChar = doc.GetCharAt(pos + 1);
                        if (nextChar == '/')
                        {
                            isInLineComment = true;
                        }
                        if (!isInLineComment && nextChar == '*')
                        {
                            isInBlockComment = true;
                        }
                    }
                    break;

                case '"':
                    if (!(isInChar || isInLineComment || isInBlockComment))
                    {
                        isInString = !isInString;
                    }
                    break;

                case '\'':
                    if (!(isInString || isInLineComment || isInBlockComment))
                    {
                        isInChar = !isInChar;
                    }
                    break;

                default:
                    if (!(isInString || isInChar || isInLineComment || isInBlockComment))
                    {
                        yield return(new KeyValuePair <char, int> (ch, pos));
                    }
                    break;
                }
            }
        }
		int FindNextWordOffset (TextDocument doc, int offset, bool subword)
		{
			int lineNumber   = doc.OffsetToLineNumber (offset);
			DocumentLine line = doc.GetLine (lineNumber);
			if (line == null)
				return offset;
			
			int result    = offset;
			int endOffset = line.Offset + line.Length;
			if (result == endOffset) {
				line = doc.GetLine (lineNumber + 1);
				if (line != null)
					result = line.Offset;
				return result;
			}
			
			CharacterClass current = GetCharacterClass (doc.GetCharAt (result), subword, false);
			while (result < endOffset) {
				CharacterClass next = GetCharacterClass (doc.GetCharAt (result), subword, false);
				if (next != current) {
					
					// camelCase and PascalCase handling
					bool camelSkip = false;
					if (next == CharacterClass.LowercaseLetter && current == CharacterClass.UppercaseLetter) {
						if (result-2 > line.Offset) {
							CharacterClass previous = GetCharacterClass (doc.GetCharAt (result-2), subword, false);
							if (previous == CharacterClass.UppercaseLetter && result-2 > offset)
								result--;
							else
								camelSkip = true;
						}
					}
					
					if (!camelSkip)
						break;
				}
				
				current = next;		
				result++;
			}
			while (result < endOffset && GetCharacterClass (doc.GetCharAt (result), subword, false) == CharacterClass.Whitespace) {
				result++;
			}
			return result;
		}
		int FindNextWordOffset (TextDocument doc, int offset, bool subword)
		{
			if (offset + 1 >= doc.TextLength)
				return doc.TextLength;
			int result = offset + 1;
			CC previous = SW.GetCharacterClass (doc.GetCharAt (result), subword, includeUnderscore);
			bool inIndentifier = previous != CC.Unknown && previous != CC.Whitespace;			
			while (result < doc.TextLength) {
				char ch = doc.GetCharAt (result);
				CC current = SW.GetCharacterClass (ch, subword, includeUnderscore);
				
				//camelCase / PascalCase splitting
				if (subword) {
					if (current == CC.Digit && (previous != CC.Digit || (result-1 == offset && !Char.IsDigit (doc.GetCharAt (result-1))))) {
						break;
					} else if (previous == CC.Digit && current != CC.Digit) {
						break;
					} else if (current == CC.UppercaseLetter && previous != CC.UppercaseLetter) {
						break;
					} else if (current == CC.LowercaseLetter && previous == CC.UppercaseLetter && result - 2 > 0
					           && SW.GetCharacterClass (doc.GetCharAt (result - 2), subword, includeUnderscore) != CC.LowercaseLetter)
					{
						result--;
						break;
					}
				}
				
				//else break at end of identifiers
				if (previous != CC.Unknown && previous != CC.Whitespace) {
					inIndentifier = true;
				} else if (inIndentifier) {
					result--;
					break;
				}
				previous = current;
				result++;
			}
			foreach (FoldSegment segment in doc.GetFoldingsFromOffset (result)) {
				if (segment.IsFolded)
					result = System.Math.Max (result, segment.EndLine.Offset + segment.EndColumn);
			}
			return result;
		}
예제 #4
0
        public static int FindNextSubwordEndOffset(TextDocument doc, int offset)
        {
            int myoffset = offset + 1;

            if (!OffsetIsWithinBounds (doc, myoffset)) {
                return myoffset;
            }

            char c = doc.GetCharAt (myoffset);
            // skip whitespace
            while (char.IsWhiteSpace (c)) {
                if (OffsetIsWithinBounds (doc, ++myoffset)) {
                    c = doc.GetCharAt (myoffset);
                } else {
                    return offset;
                }
            }
            var initialClass = ViWordFindStrategy.GetCharacterClass (c);
            while (ViWordFindStrategy.GetCharacterClass (c) == initialClass && 0 <= myoffset && doc.TextLength-1 > myoffset) {
                c = doc.GetCharAt (++myoffset);
            }

            return System.Math.Max (offset, myoffset - 1);
        }
예제 #5
0
			public override void Analyze(TextDocument doc, DocumentLine line, Chunk startChunk, int startOffset, int endOffset)
			{
				// Check line start
				int o = line.Offset;
				char c = '\0';
				for (; o < line.EndOffset && char.IsWhiteSpace(c = doc.GetCharAt(o)); o++) ;

				if (c != '-' && c != '#')
					return;

				DSyntax.Document = doc;
				var spanParser = new SpanParser(DSyntax, new CloneableStack<Span>());
				var chunkP = new ChunkParser(DSyntax, spanParser, Ide.IdeApp.Workbench.ActiveDocument.Editor.ColorStyle, line);

				var n = chunkP.GetChunks(startOffset, endOffset - startOffset);
				if (n == null)
					return;
				startChunk.Next = n;
				startChunk.Length = n.Offset - startChunk.Offset;
			}
예제 #6
0
		static int ScanWord (TextDocument doc, int offset, bool forwardDirection)
		{
			if (offset < 0 || offset >= doc.TextLength)
				return offset;
			var line = doc.GetLineByOffset (offset);
			char first = doc.GetCharAt (offset);
			if (char.IsPunctuation (first))
				return forwardDirection ? System.Math.Min (line.Offset + line.Length, offset + 1) : System.Math.Max (line.Offset, offset - 1);
			while (offset >= line.Offset && offset < line.Offset + line.Length) {
				char ch = doc.GetCharAt (offset);
				if (char.IsWhiteSpace (first) && !char.IsWhiteSpace (ch)
				    || WordFindStrategy.IsNoIdentifierPart (first) && !WordFindStrategy.IsNoIdentifierPart (ch)
				    || (char.IsLetterOrDigit (first) || first == '_') && !(char.IsLetterOrDigit (ch) || ch == '_'))
					break;
				offset = forwardDirection ? offset + 1 : offset - 1;
			}
			return System.Math.Min (line.Offset + line.Length,
			                        System.Math.Max (line.Offset, offset + (forwardDirection ? 0 : 1)));
		}
예제 #7
0
			static string GenerateRtf (TextDocument doc, Mono.TextEditor.Highlighting.ISyntaxMode mode, Mono.TextEditor.Highlighting.ColorScheme style, ITextEditorOptions options)
			{
				StringBuilder rtfText = new StringBuilder ();
				List<Gdk.Color> colorList = new List<Gdk.Color> ();
	
				var selection = new TextSegment (0, doc.TextLength);
				int startLineNumber = doc.OffsetToLineNumber (selection.Offset);
				int endLineNumber = doc.OffsetToLineNumber (selection.EndOffset);
				
				bool isItalic = false;
				bool isBold = false;
				int curColor = -1;

				foreach (var line in doc.GetLinesBetween (startLineNumber, endLineNumber)) {
					bool appendSpace = false;
					foreach (Chunk chunk in mode.GetChunks (style, line, line.Offset, line.Length)) {
						int start = System.Math.Max (selection.Offset, chunk.Offset);
						int end = System.Math.Min (chunk.EndOffset, selection.EndOffset);
						ChunkStyle chunkStyle = style.GetChunkStyle (chunk);
						if (start < end) {
							if (isBold != chunkStyle.Bold) {
								rtfText.Append (chunkStyle.Bold ? @"\b" : @"\b0");
								isBold = chunkStyle.Bold;
								appendSpace = true;
							}
							if (isItalic != chunkStyle.Italic) {
								rtfText.Append (chunkStyle.Italic ? @"\i" : @"\i0");
								isItalic = chunkStyle.Italic;
								appendSpace = true;
							}
							if (!colorList.Contains (chunkStyle.Color)) 
								colorList.Add (chunkStyle.Color);
							int color = colorList.IndexOf (chunkStyle.Color);
							if (curColor != color) {
								curColor = color;
								rtfText.Append (@"\cf" + (curColor + 1));
								appendSpace = true;
							}
							for (int i = start; i < end; i++) {
								char ch = doc.GetCharAt (i);
								
								switch (ch) {
								case '\\':
									rtfText.Append (@"\\");
									break;
								case '{':
									rtfText.Append (@"\{");
									break;
								case '}':
									rtfText.Append (@"\}");
									break;
								case '\t':
									rtfText.Append (@"\tab");
									appendSpace = true;
									break;
								default:
									if (appendSpace) {
										rtfText.Append (' ');
										appendSpace = false;
									}
									rtfText.Append (ch);
									break;
								}
							}
						}
					}
					rtfText.Append (@"\par");
					rtfText.AppendLine ();
				}
				
				// color table

				StringBuilder colorTable = new StringBuilder ();
				colorTable.Append (@"{\colortbl ;");
				for (int i = 0; i < colorList.Count; i++) {
					Gdk.Color color = colorList[i];
					colorTable.Append (@"\red");
					colorTable.Append (color.Red / 256);
					colorTable.Append (@"\green");
					colorTable.Append (color.Green / 256); 
					colorTable.Append (@"\blue");
					colorTable.Append (color.Blue / 256);
					colorTable.Append (";");
				}
				colorTable.Append ("}");
				
				StringBuilder rtf = new StringBuilder();

				rtf.Append (@"{\rtf1\ansi\deff0\adeflang1025");
				
				// font table
				rtf.Append (@"{\fonttbl");

				rtf.Append (@"{\f0\fnil\fprq1\fcharset128 " + options.Font.Family + ";}");

				rtf.Append ("}");
				
				rtf.Append (colorTable.ToString ());
				
				rtf.Append (@"\viewkind4\uc1\pard");

				rtf.Append (@"\f0");
				try {
					string fontName = options.Font.ToString ();
					double fontSize = Double.Parse (fontName.Substring (fontName.LastIndexOf (' ')  + 1), System.Globalization.CultureInfo.InvariantCulture) * 2;
					rtf.Append (@"\fs");
					rtf.Append (fontSize);
				} catch (Exception) {};
				rtf.Append (@"\cf1");
				rtf.Append (rtfText.ToString ());
				rtf.Append("}");
//				System.Console.WriteLine(rtf);
				return rtf.ToString ();
			}
예제 #8
0
		public ErrorMarker (TextDocument doc, Error info, DocumentLine line)
		{
			Info = info;
			LineSegment = line;
			// may be null if no line is assigned to the error.
			Wave = true;
			
			ColorName = info.ErrorType == ErrorType.Warning ? Mono.TextEditor.Highlighting.ColorScheme.WarningUnderlineString : Mono.TextEditor.Highlighting.ColorScheme.ErrorUnderlineString;
			StartCol = Info.Region.BeginColumn + 1;
			if (Info.Region.EndColumn > StartCol) {
				EndCol = Info.Region.EndColumn;
			} else {
				if (line == null) {
					EndCol = StartCol + 1;
					return;
				}
				var start = line.Offset + StartCol - 1;
				int o = start + 1;
				while (o < line.EndOffset) {
					char ch = doc.GetCharAt (o);
					if (!(char.IsLetterOrDigit (ch) || ch == '_'))
						break;
					o++;
				}
				EndCol = Info.Region.BeginColumn + o - start + 1;
			}
		}
예제 #9
0
 public char GetCharAt(int position)
 {
     return(document.GetCharAt(position));
 }
예제 #10
0
		/// <summary>
		/// This method gets the line indentation.
		/// </summary>
		/// <param name="doc">
		/// The <see cref="Document"/> the line belongs to.
		/// </param>
		/// <returns>
		/// The indentation of the line (all whitespace chars up to the first non ws char).
		/// </returns>
		public string GetIndentation (TextDocument doc)
		{
			var result = new StringBuilder ();
			int offset = Offset;
			int max = System.Math.Min (offset + LengthIncludingDelimiter, doc.TextLength);
			for (int i = offset; i < max; i++) {
				char ch = doc.GetCharAt (i);
				if (ch != ' ' && ch != '\t')
					break;
				result.Append (ch);
			}
			return result.ToString ();
		}
		public int SearchMatchingBracketForward (System.ComponentModel.BackgroundWorker worker, TextDocument document, int offset, char openBracket, char closingBracket)
		{
			bool isInBlockComment = false;
			bool isInLineComment  = false;
			int  curStringQuote   = -1;
			
			bool startsInLineComment = StartsInLineComment (document, offset);
			
			List<string> lineComments       = GetList (document, "LineComment");
			List<string> blockCommentStarts = GetList (document, "BlockCommentStart");
			List<string> blockCommentEnds   = GetList (document, "BlockCommentEnd");
			List<string> stringQuotes       = GetList (document, "StringQuote");
			int depth = -1;
			while (offset >= 0 && offset < document.TextLength) {
				if (worker != null && worker.CancellationPending)
					return -1;
				if (curStringQuote < 0) {
					// check line comments
					if (!isInBlockComment && !isInLineComment) 
						isInLineComment = StartsWithListMember (document, lineComments, offset) >= 0;
					
					// check block comments
					if (!isInLineComment) {
						if (!isInBlockComment) { 
							isInBlockComment = StartsWithListMember (document, blockCommentStarts, offset) >= 0;
						} else {
							isInBlockComment = StartsWithListMember (document, blockCommentEnds, offset) < 0;
						}
					}
				}
				
				if (!isInBlockComment && !isInLineComment) {
					int i = StartsWithListMember (document, stringQuotes, offset);
					if (i >= 0) {
						if (curStringQuote >= 0) {
							if (curStringQuote == i)
								curStringQuote = -1;
						} else {
							curStringQuote = i;
						}
					}
				}
				
				char ch = document.GetCharAt (offset);
				switch (ch) {
					case '\n':
					case '\r':
						if (startsInLineComment)
							return -1;
						isInLineComment = false;
						break;
					default :
						if (ch == closingBracket) {
							if (!(isInLineComment || curStringQuote >= 0 || isInBlockComment)) 
								--depth;
						} else if (ch == openBracket) {
							if (!(isInLineComment || curStringQuote >= 0 || isInBlockComment)) {
								++depth;
								if (depth == 0) 
									return offset;
							}
						}
						break;
				}
				offset++;
			}
			return -1;
		}
예제 #12
0
        public static int FindNextWordEndOffset(TextDocument doc, int offset)
        {
            int myoffset = offset + 1;

            if (!OffsetIsWithinBounds (doc, myoffset)) {
                return myoffset;
            }

            char c = doc.GetCharAt (myoffset);
            // skip whitespace
            while (char.IsWhiteSpace (c)) {
                if (OffsetIsWithinBounds (doc, ++myoffset)) {
                    c = doc.GetCharAt (myoffset);
                } else {
                    return offset;
                }
            }

            while (!char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset) {
                c = doc.GetCharAt (++myoffset);
            }

            return System.Math.Max (offset, myoffset - 1);
        }
예제 #13
0
        /// <summary>
        /// Move to end of previous whitespace group.
        /// </summary>
        public override int FindPrevWordOffset(TextDocument doc, int offset)
        {
            --offset;
            if (0 > offset || doc.TextLength-1 <= offset){ return offset; }

            for (char c = doc.GetCharAt (offset);
                 char.IsWhiteSpace (c) && 0 < offset && doc.TextLength > offset;
                 c = doc.GetCharAt (--offset));
            for (char c = doc.GetCharAt (offset);
                 !char.IsWhiteSpace (c) && 0 < offset && doc.TextLength > offset;
                 c = doc.GetCharAt (--offset));

            return (0 == offset)? offset: offset+1;
        }
예제 #14
0
        /// <summary>
        /// Move to previous non-whitespace change in character class.
        /// </summary>
        public override int FindPrevSubwordOffset(TextDocument doc, int offset)
        {
            int myoffset = offset-1;
            char c;
            if (0 > myoffset || doc.TextLength-1 <= myoffset){ return myoffset; }

            for (c = doc.GetCharAt (myoffset);
                 char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset;
                 c = doc.GetCharAt (--myoffset));

            CharacterClass initialClass = GetCharacterClass (c);

            for (; GetCharacterClass (c) == initialClass &&
                 0 <= myoffset && doc.TextLength-1 > myoffset;
                 c = doc.GetCharAt (--myoffset));

            return (0 == myoffset)? myoffset: myoffset+1;
        }
예제 #15
0
        /// <summary>
        /// Move past next whitespace group.
        /// </summary>
        public override int FindNextWordOffset(TextDocument doc, int offset)
        {
            int myoffset = offset;
            if (0 > myoffset || doc.TextLength-1 <= myoffset){ return myoffset; }

            for (char c = doc.GetCharAt (myoffset);
                 !char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset;
                 c = doc.GetCharAt (++myoffset));
            for (char c = doc.GetCharAt (myoffset);
                 char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset;
                 c = doc.GetCharAt (++myoffset));

            return (myoffset == offset)? myoffset+1: myoffset;
        }
예제 #16
0
        /// <summary>
        /// Move to next non-whitespace change in character class.
        /// </summary>
        public override int FindNextSubwordOffset(TextDocument doc, int offset)
        {
            int myoffset = offset;
            if (0 > myoffset || doc.TextLength-1 <= myoffset){ return myoffset; }

            char c = doc.GetCharAt (myoffset);
            CharacterClass initialClass = GetCharacterClass (c);

            while (GetCharacterClass (c) == initialClass && 0 <= myoffset && doc.TextLength-1 > myoffset) {
                c = doc.GetCharAt (++myoffset);
            }
            for (c = doc.GetCharAt (myoffset);
                 char.IsWhiteSpace (c) && 0 <= myoffset && doc.TextLength-1 > myoffset;
                 c = doc.GetCharAt (++myoffset));

            return (myoffset == offset)? myoffset+1: myoffset;
        }
예제 #17
0
		static InsertionPoint GetInsertionPosition (TextDocument doc, int line, int column)
		{
			int bodyEndOffset = doc.LocationToOffset (line, column) + 1;
			DocumentLine curLine = doc.GetLine (line);
			if (curLine != null) {
				if (bodyEndOffset < curLine.Offset + curLine.Length) {
					// case1: positition is somewhere inside the start line
					return new InsertionPoint (new DocumentLocation (line, column + 1), NewLineInsertion.Eol, NewLineInsertion.BlankLine);
				}
			}
			
			// -> if position is at line end check next line
			DocumentLine nextLine = doc.GetLine (line + 1);
			if (nextLine == null) // check for 1 line case.
				return new InsertionPoint (new DocumentLocation (line, column + 1), NewLineInsertion.BlankLine, NewLineInsertion.BlankLine);
			
			for (int i = nextLine.Offset; i < nextLine.Offset + nextLine.Length; i++) {
				char ch = doc.GetCharAt (i);
				if (!char.IsWhiteSpace (ch)) {
					// case2: next line contains non ws chars.
					return new InsertionPoint (new DocumentLocation (line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.BlankLine);
				}
			}
			// case3: whitespace line
			return new InsertionPoint (new DocumentLocation (line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.None);
		}
		int FindPrevWordOffset (TextDocument doc, int offset, bool subword)
		{
			int lineNumber = doc.OffsetToLineNumber (offset);
			DocumentLine line = doc.GetLine (lineNumber);
			if (line == null)
				return offset;
			
			int result = offset;
			if (result == line.Offset) {
				line = doc.GetLine (lineNumber - 1);
				if (line != null)
					result = line.Offset + line.Length;
				return result;
			}
			
			CharacterClass current = GetCharacterClass (doc.GetCharAt (result - 1), subword, false);
			
			if (current == CharacterClass.Whitespace && result - 1 > line.Offset) {
				result--;
				current = GetCharacterClass (doc.GetCharAt (result - 2), subword, false);
			}
			
			while (result > line.Offset) {
				CharacterClass prev = GetCharacterClass (doc.GetCharAt (result - 1), subword, false);
				if (prev != current) {
					
					// camelCase and PascalCase handling
					bool camelSkip = false;
					if (prev == CharacterClass.UppercaseLetter && current == CharacterClass.LowercaseLetter) {
						if (result-2 > line.Offset) {
							CharacterClass back2 = GetCharacterClass (doc.GetCharAt (result-2), subword, false);
							if (back2 == CharacterClass.UppercaseLetter)
								result--;
							else
								camelSkip = true;
						}
					}
					
					if (!camelSkip)
						break;
				}
				
				current = prev;
				result--;
			}
			
			return result;
		}
예제 #19
0
		public ErrorMarker (TextDocument doc, Error info, DocumentLine line)
		{
			Info = info;
			LineSegment = line;
			// may be null if no line is assigned to the error.
			Wave = true;
			
			StartCol = Info.Region.BeginColumn;
			if (line != null) {
				var startOffset = line.Offset;
				if (startOffset + StartCol - 1 >= 0) {
					while (StartCol < line.Length) {
						char ch = doc.GetCharAt (startOffset + StartCol - 1);
						if (!char.IsWhiteSpace (ch))
							break;
						StartCol++;
					}
				}
			}

			if (Info.Region.EndColumn > StartCol) {
				EndCol = Info.Region.EndColumn;
			} else {
				if (line == null) {
					EndCol = StartCol + 1;
					return;
				}
				var start = line.Offset + StartCol - 1;
				int o = start + 1;
				while (o < line.EndOffset) {
					char ch = doc.GetCharAt (o);
					if (!(char.IsLetterOrDigit (ch) || ch == '_'))
						break;
					o++;
				}
				EndCol = Info.Region.BeginColumn + o - start + 1;
			}
		}
예제 #20
0
 public char this[int o] {
     get {
         return(doc.GetCharAt(o));
     }
 }
		static int GetHomeMark (TextDocument document, DocumentLine line)
		{
			int result;
			for (result = 0; result < line.Length; result++)
				if (!Char.IsWhiteSpace (document.GetCharAt (line.Offset + result)))
					return result + 1;
			return result + 1;
		}
예제 #22
0
		int FindPrevWordOffset (TextDocument doc, int offset, bool subword)
		{
			if (offset <= 0)
				return 0;
			int  result = offset - 1;
			CC previous = SW.GetCharacterClass (doc.GetCharAt (result), subword, treat_);
			bool inIndentifier = previous != CC.Unknown && previous != CC.Whitespace;			
			while (result > 0) {
				char ch = doc.GetCharAt (result);
				CC current = SW.GetCharacterClass (ch, subword, treat_);
				
				//camelCase / PascalCase splitting
				if (subword) {
					if (current == CC.Digit && previous != CC.Digit) {
						result++;
						break;
					} else if (previous == CC.Digit && current != CC.Digit) {
						result++;
						break;
					} else if (current == CC.UppercaseLetter && previous != CC.UppercaseLetter) {
						break;
					} else if (current == CC.LowercaseLetter && previous == CC.UppercaseLetter && result + 2 < doc.TextLength
					           && SW.GetCharacterClass (doc.GetCharAt (result + 2), subword, treat_) != CC.LowercaseLetter)
					{
						result++;
						break;
					}
				}
				
				//else break at end of identifiers
				if (previous != CC.Unknown && previous != CC.Whitespace) {
					inIndentifier = true;
				} else if (inIndentifier) {
					result += 2;
					break;
				}
				previous = current;
				result--;
			}
			foreach (FoldSegment segment in doc.GetFoldingsFromOffset (result)) {
				if (segment.IsFolded)
					result = System.Math.Min (result, segment.StartLine.Offset + segment.Column);
			}
			return result;
		}