Changeset View
Changeset View
Standalone View
Standalone View
src/document/katedocument.cpp
Show First 20 Lines • Show All 91 Lines • ▼ Show 20 Line(s) | 2959 | if (view->config()->autoBrackets() && chars.size() == 1) { | |||
---|---|---|---|---|---|
2969 | if ( m_currentAutobraceClosingChar == chars[0] && m_currentAutobraceRange ) { | 2969 | if ( m_currentAutobraceClosingChar == chars[0] && m_currentAutobraceRange ) { | ||
2970 | // do nothing | 2970 | // do nothing | ||
2971 | m_currentAutobraceRange.reset(nullptr); | 2971 | m_currentAutobraceRange.reset(nullptr); | ||
2972 | view->cursorRight(); | 2972 | view->cursorRight(); | ||
2973 | return true; | 2973 | return true; | ||
2974 | } | 2974 | } | ||
2975 | } | 2975 | } | ||
2976 | 2976 | | |||
2977 | editStart(); | ||||
2978 | | ||||
2977 | /** | 2979 | /** | ||
2978 | * selection around => special handling if we want to add auto brackets | 2980 | * special handling if we want to add auto brackets to a selection | ||
2979 | */ | 2981 | */ | ||
2980 | if (view->selection() && !closingBracket.isNull()) { | 2982 | if (view->selection() && !closingBracket.isNull()) { | ||
2981 | /** | 2983 | std::unique_ptr<KTextEditor::MovingRange> selectionRange(newMovingRange(view->selectionRange())); | ||
2982 | * add bracket at start + end of the selection | 2984 | const int startLine = qMax(0, selectionRange->start().line()); | ||
2983 | */ | 2985 | const int endLine = qMin(selectionRange->end().line(), lastLine()); | ||
2984 | KTextEditor::Cursor oldCur = view->cursorPosition(); | 2986 | const bool blockMode = view->blockSelection() && (startLine != endLine); | ||
2985 | insertText(view->selectionRange().start(), chars); | 2987 | if (blockMode) { | ||
2986 | view->slotTextInserted(view, oldCur, chars); | 2988 | // Add brackets to each line of the block | ||
2989 | const KTextEditor::Range workingRange = view->selectionRange(); | ||||
2990 | for (int line = startLine; line <= endLine; ++line) { | ||||
2991 | const KTextEditor::Range r(rangeOnLine(workingRange, line)); | ||||
2992 | insertText(r.end(), QString(closingBracket)); | ||||
2993 | insertText(r.start(), chars); | ||||
2994 | } | ||||
2995 | } else { | ||||
2996 | // No block, just add to start & end of selection | ||||
2997 | insertText(selectionRange->end(), QString(closingBracket)); | ||||
2998 | insertText(selectionRange->start(), chars); | ||||
2999 | } | ||||
2987 | 3000 | | |||
2988 | view->setCursorPosition(view->selectionRange().end()); | 3001 | // Refesh selection | ||
2989 | oldCur = view->cursorPosition(); | 3002 | view->setSelection(selectionRange->toRange()); | ||
2990 | insertText(view->selectionRange().end(), QString(closingBracket)); | 3003 | view->setCursorPosition(selectionRange->end()); | ||
2991 | view->slotTextInserted(view, oldCur, QString(closingBracket)); | | |||
2992 | 3004 | | |||
2993 | /** | 3005 | editEnd(); | ||
2994 | * expand selection | 3006 | return true; | ||
2995 | */ | | |||
2996 | view->setSelection(KTextEditor::Range(view->selectionRange().start() + Cursor{0, 1}, | | |||
2997 | view->cursorPosition() - Cursor{0, 1})); | | |||
2998 | view->setCursorPosition(view->selectionRange().start()); | | |||
2999 | } | 3007 | } | ||
3000 | 3008 | | |||
3001 | /** | 3009 | /** | ||
3002 | * else normal handling | 3010 | * normal handling | ||
3003 | */ | 3011 | */ | ||
3004 | else { | 3012 | if (!view->config()->persistentSelection() && view->selection()) { | ||
3005 | editStart(); | 3013 | view->removeSelectedText(); | ||
3014 | } | ||||
3006 | 3015 | | |||
3007 | if (!view->config()->persistentSelection() && view->selection()) { | 3016 | const KTextEditor::Cursor oldCur(view->cursorPosition()); | ||
3008 | view->removeSelectedText(); | | |||
3009 | } | | |||
3010 | 3017 | | |||
3011 | const KTextEditor::Cursor oldCur(view->cursorPosition()); | 3018 | const bool multiLineBlockMode = view->blockSelection() && view->selection(); | ||
3012 | 3019 | if (view->currentInputMode()->overwrite()) { | |||
3013 | const bool multiLineBlockMode = view->blockSelection() && view->selection(); | 3020 | // blockmode multiline selection case: remove chars in every line | ||
3014 | if (view->currentInputMode()->overwrite()) { | 3021 | const KTextEditor::Range selectionRange = view->selectionRange(); | ||
3015 | // blockmode multiline selection case: remove chars in every line | 3022 | const int startLine = multiLineBlockMode ? qMax(0, selectionRange.start().line()) : view->cursorPosition().line(); | ||
3016 | const KTextEditor::Range selectionRange = view->selectionRange(); | 3023 | const int endLine = multiLineBlockMode ? qMin(selectionRange.end().line(), lastLine()) : startLine; | ||
3017 | const int startLine = multiLineBlockMode ? qMax(0, selectionRange.start().line()) : view->cursorPosition().line(); | 3024 | const int virtualColumn = toVirtualColumn(multiLineBlockMode ? selectionRange.end() : view->cursorPosition()); | ||
3018 | const int endLine = multiLineBlockMode ? qMin(selectionRange.end().line(), lastLine()) : startLine; | | |||
3019 | const int virtualColumn = toVirtualColumn(multiLineBlockMode ? selectionRange.end() : view->cursorPosition()); | | |||
3020 | | ||||
3021 | for (int line = endLine; line >= startLine; --line) { | | |||
3022 | Kate::TextLine textLine = m_buffer->plainLine(line); | | |||
3023 | Q_ASSERT(textLine); | | |||
3024 | const int column = fromVirtualColumn(line, virtualColumn); | | |||
3025 | KTextEditor::Range r = KTextEditor::Range(KTextEditor::Cursor(line, column), qMin(chars.length(), | | |||
3026 | textLine->length() - column)); | | |||
3027 | | ||||
3028 | // replace mode needs to know what was removed so it can be restored with backspace | | |||
3029 | if (oldCur.column() < lineLength(line)) { | | |||
3030 | QChar removed = characterAt(KTextEditor::Cursor(line, column)); | | |||
3031 | view->currentInputMode()->overwrittenChar(removed); | | |||
3032 | } | | |||
3033 | 3025 | | |||
3034 | removeText(r); | 3026 | for (int line = endLine; line >= startLine; --line) { | ||
3027 | Kate::TextLine textLine = m_buffer->plainLine(line); | ||||
3028 | Q_ASSERT(textLine); | ||||
3029 | const int column = fromVirtualColumn(line, virtualColumn); | ||||
3030 | KTextEditor::Range r = KTextEditor::Range(KTextEditor::Cursor(line, column), qMin(chars.length(), | ||||
3031 | textLine->length() - column)); | ||||
3032 | | ||||
3033 | // replace mode needs to know what was removed so it can be restored with backspace | ||||
3034 | if (oldCur.column() < lineLength(line)) { | ||||
3035 | QChar removed = characterAt(KTextEditor::Cursor(line, column)); | ||||
3036 | view->currentInputMode()->overwrittenChar(removed); | ||||
3035 | } | 3037 | } | ||
3036 | } | | |||
3037 | 3038 | | |||
3038 | if (multiLineBlockMode) { | 3039 | removeText(r); | ||
3039 | KTextEditor::Range selectionRange = view->selectionRange(); | | |||
3040 | const int startLine = qMax(0, selectionRange.start().line()); | | |||
3041 | const int endLine = qMin(selectionRange.end().line(), lastLine()); | | |||
3042 | const int column = toVirtualColumn(selectionRange.end()); | | |||
3043 | for (int line = endLine; line >= startLine; --line) { | | |||
3044 | editInsertText(line, fromVirtualColumn(line, column), chars); | | |||
3045 | } | | |||
3046 | int newSelectionColumn = toVirtualColumn(view->cursorPosition()); | | |||
3047 | selectionRange.setRange(KTextEditor::Cursor(selectionRange.start().line(), fromVirtualColumn(selectionRange.start().line(), newSelectionColumn)) | | |||
3048 | , KTextEditor::Cursor(selectionRange.end().line(), fromVirtualColumn(selectionRange.end().line(), newSelectionColumn))); | | |||
3049 | view->setSelection(selectionRange); | | |||
3050 | } else { | | |||
3051 | chars = eventuallyReplaceTabs(view->cursorPosition(), chars); | | |||
3052 | insertText(view->cursorPosition(), chars); | | |||
3053 | } | 3040 | } | ||
3041 | } | ||||
3054 | 3042 | | |||
3055 | /** | 3043 | if (multiLineBlockMode) { | ||
3056 | * auto bracket handling for newly inserted text | 3044 | KTextEditor::Range selectionRange = view->selectionRange(); | ||
3057 | * we inserted a bracket? | 3045 | const int startLine = qMax(0, selectionRange.start().line()); | ||
3058 | * => add the matching closing one to the view + input chars | 3046 | const int endLine = qMin(selectionRange.end().line(), lastLine()); | ||
3059 | * try to preserve the cursor position | 3047 | const int column = toVirtualColumn(selectionRange.end()); | ||
3060 | */ | 3048 | for (int line = endLine; line >= startLine; --line) { | ||
3061 | bool skipAutobrace = closingBracket == QLatin1Char('\''); | 3049 | editInsertText(line, fromVirtualColumn(line, column), chars); | ||
3062 | if ( highlight() && skipAutobrace ) { | | |||
3063 | // skip adding ' in spellchecked areas, because those are text | | |||
3064 | skipAutobrace = highlight()->spellCheckingRequiredForLocation(this, view->cursorPosition() - Cursor{0, 1}); | | |||
3065 | } | | |||
3066 | if (!closingBracket.isNull() && !skipAutobrace ) { | | |||
3067 | // add bracket to the view | | |||
3068 | const auto cursorPos(view->cursorPosition()); | | |||
3069 | const auto nextChar = view->document()->text({cursorPos, cursorPos + Cursor{0, 1}}).trimmed(); | | |||
3070 | if ( nextChar.isEmpty() || ! nextChar.at(0).isLetterOrNumber() ) { | | |||
3071 | insertText(view->cursorPosition(), QString(closingBracket)); | | |||
3072 | const auto insertedAt(view->cursorPosition()); | | |||
3073 | view->setCursorPosition(cursorPos); | | |||
3074 | m_currentAutobraceRange.reset(newMovingRange({cursorPos - Cursor{0, 1}, insertedAt}, | | |||
3075 | KTextEditor::MovingRange::DoNotExpand)); | | |||
3076 | connect(view, &View::cursorPositionChanged, | | |||
3077 | this, &DocumentPrivate::checkCursorForAutobrace, Qt::UniqueConnection); | | |||
3078 | | ||||
3079 | // add bracket to chars inserted! needed for correct signals + indent | | |||
3080 | chars.append(closingBracket); | | |||
3081 | } | | |||
3082 | m_currentAutobraceClosingChar = closingBracket; | | |||
3083 | } | 3050 | } | ||
3051 | int newSelectionColumn = toVirtualColumn(view->cursorPosition()); | ||||
3052 | selectionRange.setRange(KTextEditor::Cursor(selectionRange.start().line(), fromVirtualColumn(selectionRange.start().line(), newSelectionColumn)) | ||||
3053 | , KTextEditor::Cursor(selectionRange.end().line(), fromVirtualColumn(selectionRange.end().line(), newSelectionColumn))); | ||||
3054 | view->setSelection(selectionRange); | ||||
3055 | } else { | ||||
3056 | chars = eventuallyReplaceTabs(view->cursorPosition(), chars); | ||||
3057 | insertText(view->cursorPosition(), chars); | ||||
3058 | } | ||||
3084 | 3059 | | |||
3085 | // end edit session here, to have updated HL in userTypedChar! | 3060 | /** | ||
3086 | editEnd(); | 3061 | * auto bracket handling for newly inserted text | ||
3062 | * we inserted a bracket? | ||||
3063 | * => add the matching closing one to the view + input chars | ||||
3064 | * try to preserve the cursor position | ||||
3065 | */ | ||||
3066 | bool skipAutobrace = closingBracket == QLatin1Char('\''); | ||||
3067 | if ( highlight() && skipAutobrace ) { | ||||
3068 | // skip adding ' in spellchecked areas, because those are text | ||||
3069 | skipAutobrace = highlight()->spellCheckingRequiredForLocation(this, view->cursorPosition() - Cursor{0, 1}); | ||||
3070 | } | ||||
3071 | if (!closingBracket.isNull() && !skipAutobrace ) { | ||||
3072 | // add bracket to the view | ||||
3073 | const auto cursorPos(view->cursorPosition()); | ||||
3074 | const auto nextChar = view->document()->text({cursorPos, cursorPos + Cursor{0, 1}}).trimmed(); | ||||
3075 | if ( nextChar.isEmpty() || ! nextChar.at(0).isLetterOrNumber() ) { | ||||
3076 | insertText(view->cursorPosition(), QString(closingBracket)); | ||||
3077 | const auto insertedAt(view->cursorPosition()); | ||||
3078 | view->setCursorPosition(cursorPos); | ||||
3079 | m_currentAutobraceRange.reset(newMovingRange({cursorPos - Cursor{0, 1}, insertedAt}, | ||||
3080 | KTextEditor::MovingRange::DoNotExpand)); | ||||
3081 | connect(view, &View::cursorPositionChanged, | ||||
3082 | this, &DocumentPrivate::checkCursorForAutobrace, Qt::UniqueConnection); | ||||
3083 | | ||||
3084 | // add bracket to chars inserted! needed for correct signals + indent | ||||
3085 | chars.append(closingBracket); | ||||
3086 | } | ||||
3087 | m_currentAutobraceClosingChar = closingBracket; | ||||
3088 | } | ||||
3087 | 3089 | | |||
3088 | // trigger indentation | 3090 | // end edit session here, to have updated HL in userTypedChar! | ||
3089 | KTextEditor::Cursor b(view->cursorPosition()); | 3091 | editEnd(); | ||
3090 | m_indenter->userTypedChar(view, b, chars.isEmpty() ? QChar() : chars.at(chars.length() - 1)); | | |||
3091 | 3092 | | |||
3092 | /** | 3093 | // trigger indentation | ||
3093 | * inform the view about the original inserted chars | 3094 | KTextEditor::Cursor b(view->cursorPosition()); | ||
3094 | */ | 3095 | m_indenter->userTypedChar(view, b, chars.isEmpty() ? QChar() : chars.at(chars.length() - 1)); | ||
3095 | view->slotTextInserted(view, oldCur, chars); | | |||
3096 | } | | |||
3097 | 3096 | | |||
3098 | /** | 3097 | /** | ||
3099 | * be done | 3098 | * inform the view about the original inserted chars | ||
3100 | */ | 3099 | */ | ||
3100 | view->slotTextInserted(view, oldCur, chars); | ||||
3101 | | ||||
3101 | return true; | 3102 | return true; | ||
3102 | } | 3103 | } | ||
3103 | 3104 | | |||
3104 | void KTextEditor::DocumentPrivate::checkCursorForAutobrace(KTextEditor::View*, const KTextEditor::Cursor& newPos) { | 3105 | void KTextEditor::DocumentPrivate::checkCursorForAutobrace(KTextEditor::View*, const KTextEditor::Cursor& newPos) { | ||
3105 | if ( m_currentAutobraceRange && ! m_currentAutobraceRange->toRange().contains(newPos) ) { | 3106 | if ( m_currentAutobraceRange && ! m_currentAutobraceRange->toRange().contains(newPos) ) { | ||
3106 | m_currentAutobraceRange.clear(); | 3107 | m_currentAutobraceRange.clear(); | ||
3107 | } | 3108 | } | ||
3108 | } | 3109 | } | ||
▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines |