bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab, String& blockIndent, String& lastLineIndent) { int braceCount = 0; bool indentFound = false; while (pos.getLineNumber() > 0) { pos = pos.movedByLines (-1); const String line (pos.getLineText()); const String trimmedLine (line.trimStart()); braceCount += getBraceCount (trimmedLine.getCharPointer()); if (braceCount > 0) { blockIndent = getLeadingWhitespace (line); if (! indentFound) lastLineIndent = blockIndent + tab; return true; } if ((! indentFound) && trimmedLine.isNotEmpty()) { indentFound = true; lastLineIndent = getLeadingWhitespace (line); } } return false; }
void LivePropertyEditorBase::findOriginalValueInCode() { CodeDocument::Position pos (document, value.sourceLine, 0); String line (pos.getLineText()); String::CharPointerType p (line.getCharPointer()); p = CharacterFunctions::find (p, CharPointer_ASCII ("JUCE_LIVE_CONSTANT")); if (p.isEmpty()) { // Not sure how this would happen - some kind of mix-up between source code and line numbers.. jassertfalse; return; } p += (int) (sizeof ("JUCE_LIVE_CONSTANT") - 1); p = p.findEndOfWhitespace(); if (! CharacterFunctions::find (p, CharPointer_ASCII ("JUCE_LIVE_CONSTANT")).isEmpty()) { // Aargh! You've added two JUCE_LIVE_CONSTANT macros on the same line! // They're identified by their line number, so you must make sure each // one goes on a separate line! jassertfalse; } if (p.getAndAdvance() == '(') { String::CharPointerType start (p), end (p); int depth = 1; while (! end.isEmpty()) { const juce_wchar c = end.getAndAdvance(); if (c == '(') ++depth; if (c == ')') --depth; if (depth == 0) { --end; break; } } if (end > start) { valueStart = CodeDocument::Position (document, value.sourceLine, (int) (start - line.getCharPointer())); valueEnd = CodeDocument::Position (document, value.sourceLine, (int) (end - line.getCharPointer())); valueStart.setPositionMaintained (true); valueEnd.setPositionMaintained (true); wasHex = String (start, end).containsIgnoreCase ("0x"); } } }
bool update (CodeDocument& codeDoc, int lineNum, CodeDocument::Iterator& source, CodeTokeniser* tokeniser, const int tabSpaces, const CodeDocument::Position& selStart, const CodeDocument::Position& selEnd) { Array <SyntaxToken> newTokens; newTokens.ensureStorageAllocated (8); if (tokeniser == nullptr) { const String line (codeDoc.getLine (lineNum)); addToken (newTokens, line, line.length(), -1); } else if (lineNum < codeDoc.getNumLines()) { const CodeDocument::Position pos (codeDoc, lineNum, 0); createTokens (pos.getPosition(), pos.getLineText(), source, *tokeniser, newTokens); } replaceTabsWithSpaces (newTokens, tabSpaces); int newHighlightStart = 0; int newHighlightEnd = 0; if (selStart.getLineNumber() <= lineNum && selEnd.getLineNumber() >= lineNum) { const String line (codeDoc.getLine (lineNum)); CodeDocument::Position lineStart (codeDoc, lineNum, 0), lineEnd (codeDoc, lineNum + 1, 0); newHighlightStart = indexToColumn (jmax (0, selStart.getPosition() - lineStart.getPosition()), line, tabSpaces); newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selEnd.getPosition() - lineStart.getPosition()), line, tabSpaces); } if (newHighlightStart != highlightColumnStart || newHighlightEnd != highlightColumnEnd) { highlightColumnStart = newHighlightStart; highlightColumnEnd = newHighlightEnd; } else if (tokens == newTokens) { return false; } tokens.swapWith (newTokens); return true; }
void CodeEditor::codeDocumentChanged(const CodeDocument::Position& affectedTextStart, const CodeDocument::Position& affectedTextEnd) { static const String BRACKETS[] = {String(L"("), String(L")"), String(L"{"), String(L"}"), String(L"["), String(L"]"), String(L"<"), String(L">"), String(L"'"), String(L"'"), String(L"\""), String(L"\"")}; if(do_bracket_closing.getValue() && affectedTextEnd.getPosition() - affectedTextStart.getPosition() == 1){ //assume that the length of the affected text is 1 //We're finding an opening character and inserting the other one. const String C = String::charToString(affectedTextStart.getCharacter()); int index = 0; for(; index < numElementsInArray(BRACKETS); index += 2){ //search for an existing parenthesis if(C == BRACKETS[index]){ break; } } if(index < numElementsInArray(BRACKETS)){ //If the index is out of range, we couldn't find the first character editor->insertTextAtCaret(BRACKETS[index+1]); editor->moveCaretTo(affectedTextEnd, false); } } static const String LOOK_UP_CHARS[] = {String(L"{"), String(L"}")}; if(do_auto_indent.getValue() && affectedTextStart.getLineNumber() < affectedTextEnd.getLineNumber()){ //assume that we're at the beginning of a line //calculate the number of tabs that will be inserted to the next line const String LINE_ABOVE = affectedTextStart.getLineText(), LINE = affectedTextEnd.getLineText(); const int TAB_SIZE = editor->getTabSize(); const int LENGTH_BEFORE = LINE_ABOVE.trimEnd().length(); const int LENGTH_AFTER = LINE_ABOVE.trimStart().length(); const String TARGET_STRINGS[] = {String::charToString(affectedTextStart.movedBy(-1).getCharacter()), String::charToString(affectedTextEnd.getCharacter())}; int tab_size_to_add = (TARGET_STRINGS[0] == LOOK_UP_CHARS[0] && TARGET_STRINGS[1] != LOOK_UP_CHARS[1]) ? ((LENGTH_AFTER - LENGTH_BEFORE) / TAB_SIZE) + 1 //add another tab : (TARGET_STRINGS[1] == LOOK_UP_CHARS[1] && TARGET_STRINGS[0] != LOOK_UP_CHARS[0]) ? ((LENGTH_AFTER - LENGTH_BEFORE) / TAB_SIZE) - 1 //remove one tab : ((LENGTH_AFTER - LENGTH_BEFORE) / TAB_SIZE); for(; tab_size_to_add > 0; --tab_size_to_add){ editor->insertTabAtCaret(); } } }
bool update (CodeDocument& document, int lineNum, CodeDocument::Iterator& source, CodeTokeniser* analyser, const int spacesPerTab, const CodeDocument::Position& selectionStart, const CodeDocument::Position& selectionEnd) { OwnedArray <SyntaxToken> newTokens; if (analyser == 0) { newTokens.add (new SyntaxToken (document.getLine (lineNum), -1)); } else if (lineNum < document.getNumLines()) { const CodeDocument::Position pos (&document, lineNum, 0); createTokens (pos.getPosition(), pos.getLineText(), source, analyser, newTokens); } replaceTabsWithSpaces (newTokens, spacesPerTab); int newHighlightStart = 0; int newHighlightEnd = 0; if (selectionStart.getLineNumber() <= lineNum && selectionEnd.getLineNumber() >= lineNum) { const String line (document.getLine (lineNum)); CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0); newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()), line, spacesPerTab); newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()), line, spacesPerTab); } if (newHighlightStart != highlightColumnStart || newHighlightEnd != highlightColumnEnd) { highlightColumnStart = newHighlightStart; highlightColumnEnd = newHighlightEnd; } else { if (tokens.size() == newTokens.size()) { bool allTheSame = true; for (int i = newTokens.size(); --i >= 0;) { if (*tokens.getUnchecked(i) != *newTokens.getUnchecked(i)) { allTheSame = false; break; } } if (allTheSame) return false; } } tokens.swapWithArray (newTokens); return true; }