Ejemplo n.º 1
0
void OutputCtrl::ActivateLine( int line, bool openFile )
{
   // Get the file name and line.
   bool isError = false;
   wxString File;
   long Line;
   if ( line != -1 ) 
   {
      wxString Text = GetLine( line );
      if ( m_ErrorExpr.Matches( Text ) && m_ErrorExpr.GetMatchCount() > 3 ) 
      {
         isError = true;
         File = m_ErrorExpr.GetMatch( Text, 1 );
         m_ErrorExpr.GetMatch( Text, 2 ).ToLong( &Line );
      } 
      else if ( m_WarnExpr.Matches( Text ) && m_WarnExpr.GetMatchCount() > 3 ) 
      {
         isError = true;
         File = m_WarnExpr.GetMatch( Text, 1 );
         m_WarnExpr.GetMatch( Text, 2 ).ToLong( &Line );
      }
   }

   if ( m_Selected != -1 ) 
   {
      int start = PositionFromLine( m_Selected );
      int len = GetLineEndPosition( m_Selected ) - start;

      // Reverse the style!
      StartStyling( start, 0xFF );
      SetStyling( len, 2 );
   }

   m_Selected = line;
   if ( !isError )
      m_Selected = -1;

   if ( m_Selected != -1 ) 
   {
      int start = PositionFromLine( m_Selected );
      int len = GetLineEndPosition( m_Selected ) - start;

      // Reverse the style!
      StartStyling( start, 0xFF );
      SetStyling( len, 1 );
   }

   if ( m_Selected != -1 )
      ShowLine( m_Selected );

   // Ok read the file name from the list.
   if ( openFile && !File.IsEmpty() ) 
   {
      // TODO: Should we launch 3rd party apps here or allow the 
      // file to be opened as text?
      wxASSERT( tsGetMainFrame() );
      tsGetMainFrame()->OpenFile( File, Line-1 );
   }
}
Ejemplo n.º 2
0
void CodeEdit::CommentSelection(const wxString& comment)
{


    if (GetSelectionStart() < GetSelectionEnd())
    {
  
        int startLine = LineFromPosition(GetSelectionStart());
        int endLine   = LineFromPosition(GetSelectionEnd());

        // Find the minimum indentation level for all of the selected lines.

        int minIndentation = INT_MAX;

        for (int i = startLine; i <= endLine; ++i)
        {
            
            wxString lineText = GetLine(i);
            int firstNonWhitespace = GetFirstNonWhitespace(lineText);

            if (firstNonWhitespace != -1)
            {
                minIndentation = wxMin(firstNonWhitespace, minIndentation);
            }

        }

        // Insert the comment string on each non-blank line.

        wxString result;

        for (int i = startLine; i <= endLine; ++i)
        {

            wxString lineText = GetLine(i);

            if (GetFirstNonWhitespace(lineText) != -1)
            {
                lineText.insert(minIndentation, comment);
            }

            result += lineText;

        }

        SetTargetStart(PositionFromLine(startLine));
        SetTargetEnd(PositionFromLine(endLine + 1));

        ReplaceTarget(result);

        // Select the replaced text.
        SetSelectionStart(GetTargetStart());
        SetSelectionEnd(GetTargetEnd() - 1);
    
    }

}
Ejemplo n.º 3
0
	/// Indent if newline was added.
	void OnCharAdded(wxScintillaEvent &event) {
		// Change this if support for mac files with \r is needed
		if (event.GetKey() == '\n' || event.GetKey() == '\r') {
			int currentLine = GetCurrentLine();
			if (currentLine <= 0) {
				return;
			}

			// width of one indent character
			int indentWidth = (GetUseTabs() ? GetTabWidth() : 1);
			if (indentWidth == 0) {
				return;
			}

			// indent as prev line level
			int indentSize = GetLineIndentation(currentLine - 1);
			SetLineIndentation(currentLine, indentSize);

			// position = (line start pos) + (tabs count) + (space count)
			GotoPos(PositionFromLine(currentLine)
				+ (indentSize / indentWidth)
				+ (indentSize % indentWidth));

			// notify that the text was changed
			ChangeModified(true);
		}
	}
Ejemplo n.º 4
0
bool wxSTEditorShell::SetMaxLines(int max_lines)
{
    m_max_lines = max_lines;
    if (m_max_lines < 0) return false;

    int total_lines = GetLineCount();
    total_lines     = wxMax(0, total_lines-1);

    // delete lines when more than m_max_lines, you'll eventually crash otherwise
    if (total_lines > m_max_lines)
    {
        BeginWriteable();

        int marker = MarkerGet(total_lines - m_max_lines);

        SetTargetStart(0);
        SetTargetEnd(PositionFromLine(total_lines - m_max_lines));
        ReplaceTarget(wxEmptyString);

        // wipe marker that has moved up if there shouldn't be a marker
        if ((marker & (1<<markerPrompt)) == 0)
            MarkerDelete(0, markerPrompt);

        EndWriteable();
        return true;
    }

    return false;
}
Ejemplo n.º 5
0
void ScintillaWrapper::replaceLine(int lineNumber, boost::python::object newContents)
{
	
	int start = PositionFromLine(lineNumber);	
	int end   = GetLineEndPosition(lineNumber);
	setTarget(start, end);
	ReplaceTarget(newContents);
}
Ejemplo n.º 6
0
void ScintillaWrapper::replaceWholeLine(int lineNumber, boost::python::object newContents)
{
	
	int start = PositionFromLine(lineNumber);	
	int end;
	if (GetLineCount() > lineNumber)
	{
		end = PositionFromLine(lineNumber + 1);
	}
	else
	{
		end = GetLength();
	}

	setTarget(start, end);
	ReplaceTarget(newContents);
}
Ejemplo n.º 7
0
wxString wxSTEditorShell::GetPromptText()
{
    int prompt_line = GetPromptLine();
    int start_pos   = PositionFromLine(prompt_line);
    int end_pos     = GetLength();
    wxString text(GetTextRange(start_pos, end_pos));
    return text;
}
Ejemplo n.º 8
0
void PythonCodeCtrl::OnCharAdded(wxScintillaEvent& ke)
{
    //User has pressed enter
    //if the cursor is at the end of a completed statement, submit the statement to the interpreter
    //otherwise, do auto-indentation
    if (ke.GetKey() == _T('\n'))
    {
        //int pos = GetCurrentPos();
        int line = LineFromPosition(GetCurrentPos());

        if(line>0)
        {
            wxString prevlinetext = GetLine(line-1).Trim();
            int indentation = GetLineIndentation(line-1);

            if((indentation==0) //submit a return pressed on an unindented line
                || (indentation>0 && prevlinetext==wxEmptyString)) // or an indented block where the previous line was empty
            {
                long rs,re;
                GetSelection(&rs,&re);
                //if(rs==re && GetLastPosition()==rs)
                if(rs==re && GetLength()==rs) // only submit if the cursor is at the end of the control (and there is no selection)
                {
                    m_pyctrl->DispatchCode(GetValue());
                    ke.Skip();
                }
            }

            // Otherwise indent the code if necessary
            if (GetLine(line-1).Trim().EndsWith(_T(":")))
            {
                if(GetStyleAt(GetLineEndPosition(line-1)-1) == wxSCI_P_OPERATOR)
                    indentation+=GetIndent();
            }
            if (indentation>0)
            {
                SetLineIndentation(line,indentation);
                SetCurrentPos(PositionFromLine(line)+indentation);
                SetAnchor(PositionFromLine(line)+indentation);
            }
        }
    }
    ke.Skip();
}
Ejemplo n.º 9
0
void wxSTEditorShell::SetPromptText(const wxString& text)
{
    BeginWriteable();
    int length      = GetLength();
    int prompt_line = GetPromptLine();
    int start_pos   = PositionFromLine(prompt_line);
    SetTargetStart(start_pos);
    SetTargetEnd(length);
    ReplaceTarget(text);
    GotoPos(GetLength());
    EndWriteable();
}
Ejemplo n.º 10
0
/*---------------------------------------------------------------------------*/
bool wxSQLEditorBase::EndLineIsComment(int lineindex)
{
   int pos, style;

   pos = PositionFromLine(lineindex) + GetLine(lineindex).Length() - 1;
   style = GetStyleAt(pos);
   if ((style == wxSTC_SQL_COMMENT)||(style == wxSTC_SQL_COMMENTDOC)||
       (style == wxSTC_SQL_SQLPLUS_COMMENT)||(style == wxSTC_SQL_COMMENTDOCKEYWORD)||
       (style == wxSTC_SQL_COMMENTDOCKEYWORDERROR)||(style == wxSTC_SQL_COMMENTLINE)||
       (style == wxSTC_SQL_COMMENTLINEDOC))
      return true;
   return false;
}
Ejemplo n.º 11
0
void CodeEdit::UncommentSelection(const wxString& commentString)
{

    if (GetSelectionStart() < GetSelectionEnd())
    {

        int startLine = LineFromPosition(GetSelectionStart());
        int endLine   = LineFromPosition(GetSelectionEnd());

        wxString result;
        
        for (int i = startLine; i <= endLine; ++i)
        {

            wxString lineText = GetLine(i);

            unsigned int c = GetFirstNonWhitespace(lineText);

            if (c != -1 && lineText.compare(c, commentString.Length(), commentString) == 0)
            {
                lineText.erase(c, commentString.Length());
            }

            result += lineText;

        }

        SetTargetStart(PositionFromLine(startLine));
        SetTargetEnd(PositionFromLine(endLine + 1));

        ReplaceTarget(result);

        // Select the replaced text.
        SetSelectionStart(GetTargetStart());
        SetSelectionEnd(GetTargetEnd() - 1);

    }

}
Ejemplo n.º 12
0
void Edit::OnCharAdded (wxStyledTextEvent &event) {
    char chr = (char)event.GetKey();
    int currentLine = GetCurrentLine();
    // Change this if support for mac files with \r is needed
    if (chr == '\n') {
        int lineInd = 0;
        if (currentLine > 0) {
            lineInd = GetLineIndentation(currentLine - 1);
        }
        if (lineInd == 0) return;
        SetLineIndentation (currentLine, lineInd);
        GotoPos(PositionFromLine (currentLine) + lineInd);
    }
}
Ejemplo n.º 13
0
/**
 * source is modified
 */
void FbEditor::onModified(wxStyledTextEvent & event)
{
    // not directly modifying text?
    auto flags = event.GetModificationType();
    if ((flags & (wxSTC_MOD_INSERTTEXT | wxSTC_MOD_DELETETEXT)) == 0) return;

    // set input buffer
    m_srcCtx->setBuffer(GetCharacterPointer());

    // get modified line & line length
    int line     = LineFromPosition(event.GetPosition());
    int pos      = PositionFromLine(line);
    int length   = this->GetLineLength(line);

    // analyze the source
    m_srcCtx->analyze(line, pos, length);
}
Ejemplo n.º 14
0
void LuaScriptEditorView::CheckSyntax()
{
   CStringA text;
   GetText(text);

   int indicatorNumber = INDIC_CONTAINER;

   AnnotationClearAll();

   Lua::State state;
   std::vector<CString> errorMessages;
   if (state.CheckSyntax(CString(text), errorMessages))
   {
      IndicSetStyle(indicatorNumber, INDIC_HIDDEN);
      AnnotationSetVisible(ANNOTATION_HIDDEN);
      return;
   }

   IndicSetStyle(indicatorNumber, INDIC_SQUIGGLE);
   IndicSetFore(indicatorNumber, RGB(255, 0, 0)); // red

   SetIndicatorCurrent(indicatorNumber);

   for (size_t index = 0, maxIndex = errorMessages.size(); index < maxIndex; index++)
   {
      CString errorMessage = errorMessages[0];

      int pos = errorMessage.Find(_T("]:"));
      int pos2 = errorMessage.Find(_T(':'), pos + 2);

      int lineNumber = _ttoi(errorMessage.Mid(pos + 2, pos2 - (pos + 2)));
      CString error = errorMessage.Mid(pos2 + 1).Trim();

      SetIndicatorValue(index);

      int textStart = static_cast<int>(PositionFromLine(lineNumber - 1));
      int textEnd = GetLineEndPosition(lineNumber - 1);

      IndicatorFillRange(textStart, textEnd - textStart);

      AnnotationSetText(lineNumber - 1, CStringA(error).GetString());
      AnnotationSetVisible(ANNOTATION_BOXED);
   }
}
Ejemplo n.º 15
0
void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
{
	if (GetReadOnly())
		return;
	if (m_database == NULL)
		return;
	if (m_autocompDisabled)
		return;

	wxString what = GetCurLine().Left(GetCurrentPos() - PositionFromLine(GetCurrentLine()));;
	int spaceidx = what.Find(' ', true);

	char *tab_ret;
	if (spaceidx == -1)
		tab_ret = tab_complete(what.mb_str(wxConvUTF8), 0, what.Len() + 1, m_database);
	else
		tab_ret = tab_complete(what.mb_str(wxConvUTF8), spaceidx + 1, what.Len() + 1, m_database);

	if (tab_ret == NULL || tab_ret[0] == '\0')
		return; /* No autocomplete available for this string */

	wxString wxRet = wxString(tab_ret, wxConvUTF8);
	free(tab_ret);

	// Switch to the generic list control. Native doesn't play well with
	// autocomplete on Mac.
#ifdef __WXMAC__
	wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true);
#endif

	if (spaceidx == -1)
		AutoCompShow(what.Len(), wxRet);
	else
		AutoCompShow(what.Len() - spaceidx - 1, wxRet);

	// Now switch back
#ifdef __WXMAC__
	wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false);
#endif
}
Ejemplo n.º 16
0
void CodeEdit::OnModified(wxStyledTextEvent& event)
{
    
    event.Skip();    

    int linesAdded = event.GetLinesAdded();
        
    // If we're inserting new lines before a line, so we need to move the
    // markers down. STCntilla doesn't do this automatically for the current line.

    if (linesAdded > 0)
    {
    
        unsigned int position = event.GetPosition();
    
        unsigned int line = LineFromPosition(position);
        unsigned int lineStartPosition = PositionFromLine(line);

        if (position == lineStartPosition)
        {
            
            int markers = MarkerGet(line);

            // Delete all of the markers from the line.
            for (int i = 0; i < 32; ++i)
            {
                MarkerDelete(line, i);
            }

            // Add the markers back on the new line.
            MarkerAddSet(line + linesAdded, markers);

        }

    }    

}
Ejemplo n.º 17
0
void FB_STC::OnSelectline ( wxCommandEvent& event ) {
    int lineStart = PositionFromLine (GetCurrentLine());
    int lineEnd = PositionFromLine (GetCurrentLine() + 1);
    SetSelection (lineStart, lineEnd);
}
Ejemplo n.º 18
0
bool ctlSQLBox::BlockComment(bool uncomment)
{
	wxString lineEnd;
	switch (GetEOLMode())
	{
		case wxSTC_EOL_LF:
			lineEnd = wxT("\n");
			break;
		case wxSTC_EOL_CRLF:
			lineEnd = wxT("\r\n");
			break;
		case wxSTC_EOL_CR:
			lineEnd = wxT("\r");
			break;
	}

	// Save the start position
	const wxString comment = wxT("-- ");
	int start = GetSelectionStart();

	if (!GetSelectedText().IsEmpty())
	{
		wxString selection = GetSelectedText();
		if (!uncomment)
		{
			selection.Replace(lineEnd, lineEnd + comment);
			selection.Prepend(comment);
			if (selection.EndsWith(comment))
				selection = selection.Left(selection.Length() - comment.Length());
		}
		else
		{
			selection.Replace(lineEnd + comment, lineEnd);
			if (selection.StartsWith(comment))
				selection = selection.Right(selection.Length() - comment.Length());
		}
		ReplaceSelection(selection);
		SetSelection(start, start + selection.Length());
	}
	else
	{
		// No text selection - (un)comment the current line
		int column = GetColumn(start);
		int curLineNum = GetCurrentLine();
		int pos = PositionFromLine(curLineNum);

		if (!uncomment)
		{
			InsertText(pos, comment);
		}
		else
		{
			wxString t = GetTextRange(pos, pos + comment.Length());
			if (t == comment)
			{
				// The line starts with a comment, so we remove it
				SetTargetStart(pos);
				SetTargetEnd(pos + comment.Length());
				ReplaceTarget(wxT(""));
			}
			else
			{
				// The line doesn't start with a comment, do nothing
				return false;
			}
		}

		if (GetLineCount() > curLineNum)
		{
			wxString nextLine = GetLine(curLineNum + 1);
			if (nextLine.EndsWith(lineEnd))
				nextLine = nextLine.Left(nextLine.Length() - lineEnd.Length());

			int nextColumn = (nextLine.Length() < (unsigned int)column ? nextLine.Length() : column);
			GotoPos(PositionFromLine(curLineNum + 1) + nextColumn);
		}
	}

	return true;
}
Ejemplo n.º 19
0
void ScintillaWrapper::pyreplace(boost::python::object searchExp, boost::python::object replaceStr, boost::python::object count, boost::python::object flags, boost::python::object startLine, boost::python::object endLine)
{
	
	boost::python::object re_module( (boost::python::handle<>(PyImport_ImportModule("re"))) );
	if (!re_module.is_none())
	{
		BeginUndoAction();
		const char *strCount = boost::python::extract<const char *>(count.attr("__str__")());
		int iCount;
		int iFlags = 0;
		
		if (!flags.is_none())
		{
			iFlags = boost::python::extract<int>(flags);
		}

		int start = 0;
		if (!startLine.is_none())
		{
			start = boost::python::extract<int>(startLine);
		}

		int end = -1;
		if (!startLine.is_none())
		{
			 end = boost::python::extract<int>(endLine);
		}

		iCount = atoi(strCount);
		bool ignoreCount = (iCount == 0);
		bool includeLineEndings = (iFlags & RE_INCLUDELINEENDINGS) == RE_INCLUDELINEENDINGS;

		long lineCount = GetLineCount();
		boost::python::object re = re_module.attr("compile")(searchExp, flags);
		
		size_t bufferLength = 0;
		Sci_TextRange range;
		range.chrg.cpMin = 0;
		range.lpstrText = NULL;
		boost::python::tuple result;
		idx_t currentStartPosition;
		int infiniteLoopCheck = 0;
		int previousLine = -1;
		for(int line = start; line < lineCount && (ignoreCount || iCount > 0) && (-1 == end || line <= end); ++line)
		{
			if (line == previousLine)
			{
				if (++infiniteLoopCheck >= 1000)
				{
					EndUndoAction();
					PyErr_SetString(PyExc_SystemError, "Infinite loop detected in pyreplace");
					if (range.lpstrText)
					{
						delete[] range.lpstrText;
					}

					throw boost::python::error_already_set();
				}
			}
			previousLine = line;

			if (includeLineEndings)
			{
				result = boost::python::extract<boost::python::tuple>(re.attr("subn")(replaceStr, GetLine(line), ignoreCount ? 0 : iCount));
			}
			else
			{
				range.chrg.cpMin = PositionFromLine(line);
				range.chrg.cpMax = GetLineEndPosition(line);
			
				if (bufferLength < (size_t)((range.chrg.cpMax - range.chrg.cpMin) + 1))
				{
					if (range.lpstrText)
						delete [] range.lpstrText;
					bufferLength = (size_t)((range.chrg.cpMax - range.chrg.cpMin) + 1);
					range.lpstrText = new char[bufferLength + 1];
				}
			
				callScintilla(SCI_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&range));

				result = boost::python::extract<boost::python::tuple>(re.attr("subn")(replaceStr, const_cast<const char *>(range.lpstrText), ignoreCount ? 0 : iCount));
			}

			int numSubs = boost::python::extract<int>(result[1]);
			if (numSubs != 0)
			{
				size_t resultLength = _len(result[0]);
				if (includeLineEndings)
				{
					currentStartPosition = (idx_t)PositionFromLine(line);
					replaceWholeLine(line, result[0]);
				}
				else
				{
					currentStartPosition = (idx_t)range.chrg.cpMin;
					replaceLine(line, result[0]);
				}

				int newLine = LineFromPosition((int)(currentStartPosition + resultLength));
				
				// If the line number has moved on more than one
				// there must have been one or more new lines in the 
				// replacement, or no newline, hence the lines have become less
				if ((newLine - line) != (includeLineEndings ? 1 : 0))
				{
					line = newLine - (includeLineEndings ? 1 : 0);
					lineCount = GetLineCount();
				}
				iCount -= numSubs;
			}
		}	

		if (range.lpstrText)
			delete[] range.lpstrText;
		EndUndoAction();
	}

}
Ejemplo n.º 20
0
wxString wxSTEditorShell::GetPromptText()
{
    int prompt_line = GetPromptLine();
    wxString text = GetTextRange(PositionFromLine(prompt_line), GetLength());
    return text;
}
Ejemplo n.º 21
0
void Edit::OnEditSelectLine (wxCommandEvent &WXUNUSED(event)) {
    int lineStart = PositionFromLine (GetCurrentLine());
    int lineEnd = PositionFromLine (GetCurrentLine() + 1);
    SetSelection (lineStart, lineEnd);
}
Ejemplo n.º 22
0
/**
 * Style needed
 */
void FbEditor::onStyleNeeded(wxStyledTextEvent & event)
{
    // startint position
    auto startPos  = GetEndStyled();
    auto startLine = LineFromPosition(startPos);
    startPos       = PositionFromLine(startLine);
    // end position
    int lastPos    = event.GetPosition();
    int lastLine   = std::max(LineFromPosition(lastPos), std::min(GetLineCount(), GetFirstVisibleLine() + LinesOnScreen()));
    lastPos        = GetLineEndPosition(lastLine);
        
    // get token
    auto token = m_srcCtx->getLine(startLine, lastLine);
    
    // set stylling position
    StartStyling(startPos, INT_MAX);
    
    // clear indicatirs
    SetIndicatorCurrent(ErrorIndicator);
    IndicatorClearRange(startPos, lastPos - startPos);
    
    // no token? just colour to default
    if (!token) {
        style(lastPos - startPos, TokenStyle::Default);
        return;
    }
    
    
    // style the tokens
    int line = startLine;
    int col  = 0;
    while (token && line <= lastLine) {
        // end of the line?
        if (token->getKind() == TokenKind::EndOfLine) {
            token = token->getNext();
            continue;
        }
        
        // token line
        int tline = token->getLine();
        
        // token started before current line
        if (line > tline) {
            int start = PositionFromLine(line);
            int end   = PositionFromLine(token->getEndLine()) + token->getEndCol();
            style(end - start, token);
            
            // end on line and column
            col  = token->getEndCol();
            line = token->getEndLine();
            
            // get next token and continue
            token = token->getNext();
            continue;
        }
        
        // empty lines before next token?
        if (line < tline) {
            int start = PositionFromLine(line) + col;
            int end   = PositionFromLine(tline) + token->getCol();
            style(end - start, TokenStyle::Default);
            
            // end on line and column
            line = token->getLine();
            col = token->getCol();
            continue;
        }
        
        // started on the current line
        if (line == tline) {
            // empty space ?
            if (token->getCol() > col) {
                style(token->getCol() - col, TokenStyle::Default);
            }
            
            // style the token
            style(token->getLength(), token);
            col = token->getEndCol();
            line = token->getEndLine();
            
            // advance to the next one
            token = token->getNext();
            continue;
        }
        
        // some empty space till end of the line
        int length = GetLineLength(line);
        if (col < length) {
            style(length - col, TokenStyle::Default);
        }
        
        // incement line
        line++;
        col = 0;
    }
}
Ejemplo n.º 23
0
bool CodeEdit::GetTokenFromPosition(int position, const wxString& joiners, wxString& token)
{

    if (position != -1)
    {
       
        // Search the text.

        int line = LineFromPosition(position);
        int seek = position - PositionFromLine(line);

        wxString text = GetLine(LineFromPosition(position));

        if (!isalnum(text[seek]) && joiners.Find(text[seek]) == wxNOT_FOUND)
        {
            return false;
        }
        
        // Search from the seek point to the left until we hit a non-alphanumeric which isn't a "."
        // "." must be handled specially so that expressions like player.health are easy to evaluate. 

        int start = seek;

        while (start > 0 && (GetIsIdentifierChar(text[start - 1]) || joiners.Find(text[start - 1]) != wxNOT_FOUND || text[start - 1] == ')'))
        {
          if (text[start - 1] == ')')
          {
            while (start > 0 && text[start - 1] != '(')
              start--;

            start--;
          }
          else
            --start;
        }

        // Search from the seek point to the right until we hit a non-alphanumeric

        unsigned int end = seek;

        while (end + 1 < text.Length() && (GetIsIdentifierChar(text[end + 1]) || text[end + 1] == '('))
        {
          if (text[end + 1] == '(')
          {
            while (end + 1 < text.Length() && text[end + 1] != ')')
              ++end;

            ++end;
          }

            ++end;
        }

        token = text.SubString(start, end);
        return true;

    }

    return false;

}