📄 qsteeditor.cpp
字号:
}IndentationStatus QSteEditor::getIndentState(int line){ // C like language indentation defined by braces and keywords IndentationStatus indentState = isNone; SString controlWords[20]; unsigned int parts = getLinePartsInStyle(line, m_statementIndent.styleNumber,-1, controlWords, ELEMENTS(controlWords)); unsigned int i; for (i = 0; i < parts; i++) { if (includes(m_statementIndent, controlWords[i])) indentState = isKeyWordStart; } parts = getLinePartsInStyle(line, m_statementEnd.styleNumber, -1, controlWords, ELEMENTS(controlWords)); for (i = 0; i < parts; i++) { if (includes(m_statementEnd, controlWords[i])) indentState = isNone; } // Braces override keywords SString controlStrings[20]; parts = getLinePartsInStyle(line, m_blockEnd.styleNumber,-1, controlStrings, ELEMENTS(controlStrings)); for (unsigned int j = 0; j < parts; j++) { if (includes(m_blockEnd, controlStrings[j])) indentState = isBlockEnd; if (includes(m_blockStart, controlStrings[j])) indentState = isBlockStart; } return indentState;}//commentvoid QSteEditor::boxComment(){ if(m_lexer == NULL) return; SString filetype = "."; filetype += m_lexer->getLanguageType(); SString lexerName = m_lexer->GetNewExpand("lexer.", filetype.c_str()); SString start_base("comment.box.start."); SString middle_base("comment.box.middle."); SString end_base("comment.box.end."); SString white_space(" "); start_base += m_lexer->getLanguageType(); middle_base += m_lexer->getLanguageType(); end_base += m_lexer->getLanguageType(); SString start_comment = m_lexer->Get(start_base.c_str()); SString middle_comment = m_lexer->Get(middle_base.c_str()); SString end_comment = m_lexer->Get(end_base.c_str()); if (start_comment == "" || middle_comment == "" || end_comment == "") { return; } // Note selection and cursor location so that we can reselect text and reposition cursor after we insert comment strings size_t selectionStart = sendMsgToSci(SCI_GETSELECTIONSTART); size_t selectionEnd = sendMsgToSci(SCI_GETSELECTIONEND); size_t caretPosition = sendMsgToSci(SCI_GETCURRENTPOS); bool move_caret = caretPosition < selectionEnd; size_t selStartLine = sendMsgToSci(SCI_LINEFROMPOSITION, static_cast<int>(selectionStart)); size_t selEndLine = sendMsgToSci(SCI_LINEFROMPOSITION, static_cast<int>(selectionEnd)); size_t lines = selEndLine - selStartLine + 1; // If selection ends at start of last selected line, fake it so that selection goes to end of second-last selected line if (lines > 1 && selectionEnd == static_cast<size_t>(sendMsgToSci(SCI_POSITIONFROMLINE, static_cast<int>(selEndLine)))) { selEndLine--; lines--; selectionEnd = sendMsgToSci(SCI_GETLINEENDPOSITION,static_cast<int>(selEndLine)); } // Pad comment strings with appropriate whitespace, then figure out their lengths (end_comment is a bit special-- see below) start_comment += white_space; middle_comment += white_space; size_t start_comment_length = start_comment.length(); size_t middle_comment_length = middle_comment.length(); size_t end_comment_length = end_comment.length(); size_t whitespace_length = white_space.length(); // Calculate the length of the longest comment string to be inserted, and allocate a null-terminated char buffer of equal size size_t maxCommentLength = start_comment_length; if (middle_comment_length > maxCommentLength) maxCommentLength = middle_comment_length; if (end_comment_length + whitespace_length > maxCommentLength) maxCommentLength = end_comment_length + whitespace_length; char *tempString = new char[maxCommentLength + 1]; sendMsgToSci(SCI_BEGINUNDOACTION); // Insert start_comment if needed int lineStart = sendMsgToSci(SCI_POSITIONFROMLINE, static_cast<int>(selStartLine)); getRange(lineStart, lineStart + start_comment_length, tempString); tempString[start_comment_length] = '\0'; if (start_comment != tempString) { sendMsgToSci(SCI_INSERTTEXT, lineStart, start_comment.c_str()); selectionStart += start_comment_length; selectionEnd += start_comment_length; } if (lines <= 1) { // Only a single line was selected, so just append whitespace + end-comment at end of line if needed int lineEnd = sendMsgToSci(SCI_GETLINEENDPOSITION, static_cast<int>(selEndLine)); getRange(lineEnd - end_comment_length, lineEnd, tempString); tempString[end_comment_length] = '\0'; if (end_comment != tempString) { end_comment.insert(0, white_space.c_str()); sendMsgToSci(SCI_INSERTTEXT, lineEnd, end_comment.c_str()); } } else { // More than one line selected, so insert middle_comments where needed for (size_t i = selStartLine + 1; i < selEndLine; i++) { lineStart = sendMsgToSci(SCI_POSITIONFROMLINE, static_cast<int>(i)); getRange(lineStart, lineStart + middle_comment_length, tempString); tempString[middle_comment_length] = '\0'; if (middle_comment != tempString) { sendMsgToSci(SCI_INSERTTEXT, lineStart, middle_comment.c_str()); selectionEnd += middle_comment_length; } } // If last selected line is not middle-comment or end-comment, we need to insert // a middle-comment at the start of last selected line and possibly still insert // and end-comment tag after the last line (extra logic is necessary to // deal with the case that user selected the end-comment tag) lineStart = sendMsgToSci(SCI_POSITIONFROMLINE, static_cast<int>(selEndLine)); getRange(lineStart, lineStart + end_comment_length, tempString); tempString[end_comment_length] = '\0'; if (end_comment != tempString) { getRange(lineStart, lineStart + middle_comment_length, tempString); tempString[middle_comment_length] = '\0'; if (middle_comment != tempString) { sendMsgToSci(SCI_INSERTTEXT, lineStart, middle_comment.c_str()); selectionEnd += middle_comment_length; } // And since we didn't find the end-comment string yet, we need to check the *next* line // to see if it's necessary to insert an end-comment string and a linefeed there.... lineStart = sendMsgToSci(SCI_POSITIONFROMLINE, static_cast<int>(selEndLine + 1)); getRange(lineStart, lineStart + (int) end_comment_length, tempString); tempString[end_comment_length] = '\0'; if (end_comment != tempString) { end_comment.append("\n"); sendMsgToSci(SCI_INSERTTEXT, lineStart, end_comment.c_str()); } } } if (move_caret) { // moving caret to the beginning of selected block sendMsgToSci(SCI_GOTOPOS,static_cast<int>(selectionEnd)); sendMsgToSci(SCI_SETCURRENTPOS,static_cast<int>(selectionStart)); } else { sendMsgToSci(SCI_SETSEL, selectionStart, selectionEnd); } sendMsgToSci(SCI_ENDUNDOACTION); delete[] tempString;}//most copy from SciTEvoid QSteEditor::blockComment(){ if(m_lexer == NULL) return; SString filetype("'"); filetype += m_lexer->getLanguageType(); SString base("comment.block."); SString comment_at_line_start("comment.block.at.line.start."); base += m_lexer->getLanguageType(); comment_at_line_start += m_lexer->getLanguageType(); bool placeCommentsAtLineStart = m_lexer->GetInt(comment_at_line_start.c_str()) != 0; SString comment = m_lexer->Get(base.c_str()); if(comment == "") return; SString long_comment = comment; int selectionStart = sendMsgToSci(SCI_GETSELECTIONSTART); int selectionEnd = sendMsgToSci(SCI_GETSELECTIONEND); int caretPosition = sendMsgToSci(SCI_GETCURRENTPOS); bool move_caret = caretPosition < selectionEnd; int selStartLine = sendMsgToSci(SCI_LINEFROMPOSITION, selectionStart); int selEndLine = sendMsgToSci(SCI_LINEFROMPOSITION, selectionEnd); int lines = selEndLine - selStartLine; int firstSelLineStart = sendMsgToSci(SCI_POSITIONFROMLINE,selStartLine); // "caret return" is part of the last selected line if ((lines > 0) && (selectionEnd == sendMsgToSci(SCI_POSITIONFROMLINE, selEndLine))) selEndLine--; sendMsgToSci(SCI_BEGINUNDOACTION); for(int i = selStartLine;i <= selEndLine;i++){ int lineStart = sendMsgToSci(SCI_POSITIONFROMLINE,i); int lineIndent = lineStart; int lineEnd = sendMsgToSci(SCI_GETLINEENDPOSITION,i); if(!placeCommentsAtLineStart){ lineIndent = getLineIndentPosition(i); } SString linebuf = getRange(lineIndent,lineEnd); //empty lines are not commented if(linebuf.length() < 1) continue; if(linebuf.startswith(comment.c_str())){ int commentLength = comment.length(); if(linebuf.startswith(long_comment.c_str())){ // Removing comment with space after it. commentLength = long_comment.length(); } sendMsgToSci(SCI_SETSEL,lineIndent,lineIndent + commentLength); sendMsgToSci(SCI_REPLACESEL,0UL,""); if(i == selStartLine) selectionStart -= commentLength; selectionEnd -= commentLength; continue; } if(i == selStartLine) selectionStart += long_comment.length(); selectionEnd += long_comment.length(); // every iteration sendMsgToSci(SCI_INSERTTEXT,lineIndent,long_comment.c_str()); } // after uncommenting selection may promote itself to the lines // before the first initially selected line; // another problem - if only comment symbol was selected; if(selectionStart < firstSelLineStart){ if(selectionStart >= selectionEnd - (static_cast<int>(long_comment.length()) - 1)) selectionEnd = firstSelLineStart; selectionStart = firstSelLineStart; } if (move_caret) { // moving caret to the beginning of selected block sendMsgToSci(SCI_GOTOPOS, selectionEnd); sendMsgToSci(SCI_SETCURRENTPOS, selectionStart); } else { sendMsgToSci(SCI_SETSEL, selectionStart, selectionEnd); } sendMsgToSci(SCI_ENDUNDOACTION);}void QSteEditor::streamComment(){ if(m_lexer == NULL) return; SString filetype("."); filetype += m_lexer->getLanguageType(); SString lexerName = m_lexer->GetNewExpand("lexer.", filetype.c_str()); SString start_base("comment.stream.start."); SString end_base("comment.stream.end."); SString white_space(" "); start_base += m_lexer->getLanguageType(); end_base += m_lexer->getLanguageType(); SString start_comment = m_lexer->Get(start_base.c_str()); SString end_comment = m_lexer->Get(end_base.c_str()); if (start_comment == "" || end_comment == "") { return; } start_comment += white_space; white_space += end_comment; end_comment = white_space; size_t start_comment_length = start_comment.length(); size_t selectionStart = sendMsgToSci(SCI_GETSELECTIONSTART); size_t selectionEnd = sendMsgToSci(SCI_GETSELECTIONEND); size_t caretPosition = sendMsgToSci(SCI_GETCURRENTPOS); // checking if caret is located in _beginning_ of selected block bool move_caret = caretPosition < selectionEnd; // if there is no selection? if (selectionEnd - selectionStart <= 0) { int selLine = sendMsgToSci(SCI_LINEFROMPOSITION,static_cast<int>( selectionStart)); int lineIndent = getLineIndentPosition(selLine); int lineEnd = sendMsgToSci(SCI_GETLINEENDPOSITION,static_cast<int>(selLine)); if (rangeIsAllWhitespace(lineIndent, lineEnd)) return; // we are not dealing with empty lines char linebuf[1000]; getText(linebuf, sizeof(linebuf)); int current = getCaretInLine(); // checking if we are not inside a word if (!wordCharacters.contains(linebuf[current])) return; // caret is located _between_ words int startword = current; int endword = current; int start_counter = 0; int end_counter = 0; while (startword > 0 && wordCharacters.contains(linebuf[startword - 1])) { start_counter++; startword--; } // checking _beginning_ of the word if (startword == current) return; // caret is located _before_ a word while (linebuf[endword + 1] != '\0' && wordCharacters.contains(linebuf[endword + 1])) { end_counter++; endword++; } selectionStart -= start_counter; selectionEnd += (end_counter + 1); } sendMsgToSci(SCI_BEGINUNDOACTION); sendMsgToSci(SCI_INSERTTEXT, selectionStart, start_comment.c_str()); selectionEnd += start_comment_length; selectionStart += start_comment_length; sendMsgToSci(SCI_INSERTTEXT, selectionEnd, end_comment.c_str()); if (move_caret) { // moving caret to the beginning of selected block sendMsgToSci(SCI_GOTOPOS,static_cast<int>( selectionEnd)); sendMsgToSci(SCI_SETCURRENTPOS,static_cast<int>(selectionStart)); } else { sendMsgToSci(SCI_SETSEL,selectionStart,selectionEnd); } sendMsgToSci(SCI_ENDUNDOACTION);}//match bracesvoid QSteEditor::braceMatch(){ if (!m_bracesCheck) return; char chc = getCharacter(sendMsgToSci(SCI_GETCURRENTPOS)); char chp = getCharacter(sendMsgToSci(SCI_GETCURRENTPOS) - 1); if(!IsBrace(chc) && !IsBrace(chp)) return; int braceAtCaret = -1; int braceOpposite = -1; findMatchingBracePosition(braceAtCaret, braceOpposite, m_bracesSloppy); if ((braceAtCaret != -1) && (braceOpposite == -1)) { sendMsgToSci(SCI_BRACEBADLIGHT,braceAtCaret); sendMsgToSci(SCI_SETHIGHLIGHTGUIDE); } else { char chBrace = 0; if (braceAtCaret >= 0) chBrace = static_cast<char>(sendMsgToSci(SCI_GETCHARAT, braceAtCaret)); sendMsgToSci(SCI_BRACEHIGHLIGHT,braceAtCaret,braceOpposite); int columnAtCaret = sendMsgToSci(SCI_GETCOLUMN, braceAtCaret); int columnOpposite = sendMsgToSci(SCI_GETCOLUMN,braceOpposite); if (chBrace == ':') { int lineStart = sendMsgToSci(SCI_LINEFROMPOSITION, braceAtCaret); int indentPos = sendMsgToSci(SCI_GETLINEINDENTPOSITION, lineStart); int indentPosNext = sendMsgToSci(SCI_GETLINEINDENTPOSITION, lineStart + 1); columnAtCaret = sendMsgToSci(SCI_GETCOLUMN, indentPos); int columnAtCaretNext = sendMsgToSci(SCI_GETCOLUMN, indentPosNext); int indentSize = sendMsgToSci(SCI_GETINDENT); if (columnAtCaretNext - indentSize > 1) columnAtCaret = columnAtCaretNext - indentSize; if (columnOpposite == 0) // If the final line of the structure is empty columnOpposite = columnAtCaret; } if (m_global->GetInt("highlight.indentation.guides")) sendMsgToSci(SCI_SETHIGHLIGHTGUIDE, Platform::Minimum(columnAtCaret, columnOpposite)); }}bool QSteEditor::findMatchingBracePosition(int &braceAtCaret,int &braceOpposite,bool sloppy){ int maskStyle = (1 << sendMsgToSci(SCI_GETSTYLEBITSNEEDED)) - 1; bool isInside = false; int bracesStyleCheck = m_bracesStyle; int caretPos = sendMsgToSci(SCI_GETCURRENTPOS); braceAtCaret = -1; braceOpposite = -1; char charBefore = '\0'; char styleBefore = '\0'; int lengthDoc = sendMsgToSci(SCI_GETLENGTH); if((lengthDoc > 0) && (caretPos > 0)) { // Check to ensure not matching brace that is part of a multibyte character if (sendMsgToSci(SCI_POSITIONBEFORE,caretPos) == (caretPos - 1)){ charBefore = getCharacter(caretPos - 1); styleBefore = static_cast<char>(sendMsgToSci(SCI_GETSTYLEAT,caretPos - 1) & maskStyle); } } // Priority goes to character before caret if (charBefore && IsBrace(charBefore) && ((styleBefore == bracesStyleCheck) || (!m_bracesStyle))) { braceAtCaret = caretPos - 1; } bool colonMode = false; if ((lexLanguage == SCLEX_PYTHON) && (':' == charBefore) && (SCE_P_OPERATOR == styleBefore)) { braceAtCaret = caretPos - 1; colonMode = true; } bool isAfter = true; if (lengthDoc > 0 && sloppy && (braceAtCaret < 0) && (caretPos < lengthDoc)) { // No brace found so check other side // Check to ensure not matching brace that is part of a multibyte character if (sendMsgToSci(SCI_POSITIONAFTER,caretPos) == (caretPos + 1)) { char charAfter = getCharacter(caretPos); char styleAfter = static_cast<char>(sendMsgToSci(SCI_GETSTYLEAT,caretPos) & maskStyle); if (charAfter && IsBrace(charAfter) && ((styleAfter == bracesStyleCheck) || (!m_bracesStyle))) { braceAtCaret = caretPos; isAfter = false; } if ((lexLanguage == SCLEX_PYTHON) && (':' == charAfter) && (SCE_P_OPERATOR == styleAfter)) { braceAtCaret = caretPos; colonMode = true; } } } if (braceAtCaret >= 0) { if (colonMode) { int lineStart = sendMsgToSci(SCI_LINEFROMPOSITION,braceAtCaret); int lineMaxSubord = sendMsgToSci(SCI_GETLASTCHILD, lineStart, -1); braceOpposite = sendMsgToSci(SCI_GETLINEENDPOSITION, lineMaxSubord); } else { braceOpposite = sendMsgToSci(SCI_BRACEMATCH, braceAtCaret); } if (braceOpposite > braceAtCaret) { isInside = isAfter; } else { isInside = !isAfter; } } return isInside;}bool QSteEditor::gotoBraceMatch(){ int braceAtCaret = -1; int braceOpposite = -1; bool isInside = findMatchingBracePosition(braceAtCaret,braceOpposite, true); if (isInside) { if (braceOpposite > braceAtCaret) { braceAtCaret++; } else { braceOpposite++; } } else { // Outside if (braceOpposite > braceAtCaret) { braceOpposite++; } else { braceAtCaret++; } } if (braceOpposite >= 0) { ensureRangeVisible(braceOpposite, braceOpposite); setSelection(braceOpposite,braceOpposite); }}void QSteEditor::selectBraceMatch()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -