Пример #1
0
void CodeEditor::OnCharAdded(wxScintillaEvent &event)
{
	char ch = event.GetKey();
	int currentLine = GetCurrentLine();
	int pos = GetCurrentPos();

	if (ch == wxT('\n') && currentLine > 0)
	{
		BeginUndoAction();

		wxString indent = GetLineIndentString(currentLine - 1);

		wxChar b = GetLastNonWhitespaceChar();
		if(b == wxT('{'))
		{
			if(GetUseTabs())
				indent << wxT("\t");
			else
				indent << wxT("    ");
		}

		InsertText(pos, indent);
		GotoPos((int)(pos + indent.Length()));
		ChooseCaretX();

		EndUndoAction();
	}
	else if(ch == wxT('}'))
	{
		BeginUndoAction();

		wxString line = GetLine(currentLine);
		line.Trim(false);
		line.Trim(true);
		if(line.Matches(wxT("}")))
		{
			pos = GetCurrentPos() - 2;
			pos = FindBlockStart(pos, wxT('{'), wxT('}'));

			if(pos != -1)
			{
				wxString indent = GetLineIndentString(LineFromPosition(pos));
				indent << wxT('}');
				DelLineLeft();
				DelLineRight();
				pos = GetCurrentPos();
				InsertText(pos, indent);
				GotoPos((int)(pos + indent.Length()));
				ChooseCaretX();
			}
		}

		EndUndoAction();
	}
}
Пример #2
0
void ScintillaWrapper::forEachLine(PyObject* function)
{
	if (PyCallable_Check(function))
	{	
		BeginUndoAction();
		
		long lineCount = GetLineCount();
		for(int line = 0; line < lineCount;)
		{
			
			boost::python::object result = boost::python::call<boost::python::object>(function, GetLine(line), line, lineCount);
				
			if (result.is_none() || !PyInt_Check(result.ptr()))
			{
				++line;
			}
			else
			{
				line += PyInt_AsLong(result.ptr());
			}
			
			lineCount = GetLineCount();
		}

		EndUndoAction();
	}
}
Пример #3
0
void ScintillaWrapper::replace(boost::python::object searchStr, boost::python::object replaceStr, boost::python::object flags)
{
	int start = 0;
	int end = GetLength();
	int iFlags = 0;


	if (!flags.is_none())
	{
		iFlags |= boost::python::extract<int>(flags);
	}


	const char *replaceChars = boost::python::extract<const char*>(replaceStr.attr("__str__")());
	
	size_t replaceLength = strlen(replaceChars);

	Sci_TextToFind src;

	src.lpstrText = const_cast<char*>((const char *)boost::python::extract<const char *>(searchStr.attr("__str__")()));
	
	BeginUndoAction();
	int result = 0;

	while(result != -1)
	{
		src.chrg.cpMin = start;
		src.chrg.cpMax = end;
		result = callScintilla(SCI_FINDTEXT, iFlags, reinterpret_cast<LPARAM>(&src));
		
		// If nothing found, then just finish
		if (-1 == result)
		{
			return;
		}
		else
		{
			// Replace the location found with the replacement text
			SetTargetStart(src.chrgText.cpMin);
			SetTargetEnd(src.chrgText.cpMax);
			callScintilla(SCI_REPLACETARGET, replaceLength, reinterpret_cast<LPARAM>(replaceChars));
			start = src.chrgText.cpMin + (int)replaceLength;
			end = end + ((int)replaceLength - (src.chrgText.cpMax - src.chrgText.cpMin));
		}

	}
	EndUndoAction();
}
bool cbStyledTextCtrl::DoSelectionBraceCompletion(const wxChar& ch)
{
    if (GetLastSelectedText().IsEmpty())
        return false; // nothing changed
    const wxString braces(wxT("([{<'\")]}>'\""));
    const int braceAIdx = braces.Find(ch, true); // from end (so caret is placed after quotes)
    if (braceAIdx == wxNOT_FOUND)
        return false; // nothing changed
    const int braceBIdx = (braceAIdx + (braces.Length() / 2)) % braces.Length();
    BeginUndoAction();
    DeleteBack();
    if (braceAIdx < braceBIdx)
        InsertText(GetCurrentPos(), braces[braceAIdx] + GetLastSelectedText() + braces[braceBIdx]);
    else
        AddText(braces[braceBIdx] + GetLastSelectedText() + braces[braceAIdx]);
    EndUndoAction();
    return true; // succeeded
}
Пример #5
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();
	}

}
Пример #6
0
void ScintillaWrapper::pymlreplace(boost::python::object searchExp, boost::python::object replaceStr, boost::python::object count, boost::python::object flags, boost::python::object startPosition, boost::python::object endPosition)
{
	boost::python::str contents;
	offset_t currentOffset = 0;

	if (startPosition.is_none() && endPosition.is_none())
	{
		contents = GetCharacterPointer();
	}

	else
	{
		Sci_TextRange range;
		if (!startPosition.is_none())
		{
			range.chrg.cpMin = boost::python::extract<int>(startPosition);
		}
		else
		{
			range.chrg.cpMin = 0;
		}

		if (!endPosition.is_none())
		{
			range.chrg.cpMax = boost::python::extract<int>(endPosition);
		}
		else
		{
			range.chrg.cpMax = GetLength();
		}
		
		currentOffset = (offset_t)range.chrg.cpMin;

		range.lpstrText = new char[size_t((range.chrg.cpMax - range.chrg.cpMin) + 1)];
		callScintilla(SCI_GETTEXTRANGE, 0, reinterpret_cast<LPARAM>(&range));
		contents = boost::python::str(const_cast<const char *>(range.lpstrText));
		delete[] range.lpstrText;
	}



	boost::python::object re_module( (boost::python::handle<>(PyImport_ImportModule("re"))) );

	int iFlags = 0;
	int iCount = 0;
	if (!flags.is_none())
	{
		iFlags = boost::python::extract<int>(flags);
	}
	if (!count.is_none())
	{
		iCount = boost::python::extract<int>(count);
	}

	if (0 == iCount)
		iCount = -1;
	
	

	boost::python::object re = re_module.attr("compile")(searchExp, iFlags | boost::python::extract<int>(re_module.attr("MULTILINE")));
	if (!re_module.is_none())
	{
		boost::python::object match;
		BeginUndoAction();
		boost::python::object oreplacement;
		size_t replacementLength;
		idx_t matchStart, matchEnd;
		idx_t startPos = 0;
		

		do
		{
			match = re.attr("search")(contents, startPos);
			if (!match.is_none())
			{
				// Get expanded replacement string
				oreplacement = match.attr("expand")(replaceStr);
				
				
				// Calculate offsets
				matchStart = (idx_t)boost::python::extract<int>(match.attr("start")());
				matchEnd   = (idx_t)boost::python::extract<int>(match.attr("end")());


				// Extract text replacement
				const char *replacement = boost::python::extract<const char *>(oreplacement);
				replacementLength = _len(oreplacement);

				// Replace text in Scintilla
				callScintilla(SCI_SETTARGETSTART, static_cast<offset_t>(matchStart) + currentOffset);
				callScintilla(SCI_SETTARGETEND, static_cast<offset_t>(matchEnd) + currentOffset);
				callScintilla(SCI_REPLACETARGET, replacementLength, reinterpret_cast<LPARAM>(replacement));
				

				// Calculate the difference between the old string, 
				// and the new replacement, and add it to the currentOffset
				currentOffset += static_cast<offset_t>(replacementLength - (matchEnd - matchStart));


				// Set startPos to the end of the last match - startPos is with the original document
				startPos = matchEnd; 


			}
		} while(!match.is_none() && (iCount == -1 || --iCount > 0));
		
		EndUndoAction();
	}

}