File indexing completed on 2024-05-05 04:36:48
0001 /* This file is part of KDevelop 0002 * 0003 * Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 #include <completion/items/keyworditem.h> 0020 0021 #include <KTextEditor/Document> 0022 #include <KTextEditor/View> 0023 0024 #include <language/codecompletion/codecompletionmodel.h> 0025 #include <language/duchain/ducontext.h> 0026 0027 #include <completion/helpers.h> 0028 0029 using namespace KTextEditor; 0030 using namespace KDevelop; 0031 0032 namespace ruby { 0033 0034 KeywordItem::KeywordItem(CodeCompletionContext::Ptr ctx, 0035 const QString &keyword, 0036 const QString &customReplacement, 0037 bool line) 0038 : NormalDeclarationCompletionItem(DeclarationPointer(), ctx) 0039 , m_keyword(keyword) 0040 , m_replacement(customReplacement) 0041 , m_wholeLine(line) 0042 { 0043 } 0044 0045 void KeywordItem::execute(View *view, const Range &word) 0046 { 0047 auto document = view->document(); 0048 0049 if (!m_replacement.isEmpty()) { 0050 QString replacement = m_replacement; 0051 replacement = replacement.replace("%END%", getIndendation(document->line(word.start().line())) + "end"); 0052 bool shouldUnindent = replacement.indexOf("%UNINDENT%") != -1; 0053 replacement.remove("%UNINDENT%"); 0054 if (shouldUnindent) 0055 replacement = replacement.replace('\n', '\n' + getIndendation(document->line(word.start().line()))); 0056 int cursor = replacement.indexOf("%CURSOR%"); 0057 int selectionEnd = -1; 0058 0059 if (cursor != -1) { 0060 const QString ind = indentString(document); 0061 replacement = replacement.replace("%INDENT%", ind); 0062 cursor -= 8 - ind.size(); // "%INDENT%" -> 8 0063 replacement.remove("%CURSOR%"); 0064 } else { 0065 cursor = replacement.indexOf("%SELECT%"); 0066 if (cursor != -1) { 0067 replacement.remove("%SELECT%"); 0068 selectionEnd = replacement.indexOf("%ENDSELECT%", cursor + 1); 0069 if (selectionEnd == -1) 0070 selectionEnd = replacement.length(); 0071 replacement.remove("%ENDSELECT%"); 0072 } 0073 } 0074 0075 if (m_wholeLine) { 0076 Range newRange(Cursor(word.start().line(), 0), word.end()); 0077 document->replaceText(newRange, m_keyword); 0078 } else 0079 document->replaceText(word, replacement); 0080 0081 if (shouldUnindent) { 0082 int iWidth = indentString(document).size(); 0083 if (word.start().column() >= iWidth) { 0084 Range unindent(Cursor(word.start().line(), 0), Cursor(word.end().line(), iWidth)); 0085 document->removeText(unindent); 0086 cursor -= iWidth; 0087 selectionEnd -= iWidth; 0088 } 0089 } 0090 0091 if (cursor != -1) { 0092 replacement = replacement.left(cursor); 0093 KTextEditor::Cursor newPos( 0094 word.start().line() + replacement.count('\n'), 0095 word.start().column() + replacement.length() - replacement.lastIndexOf('\n') - 1 0096 ); 0097 view->setCursorPosition(newPos); 0098 if (selectionEnd != -1) { 0099 view->setSelection( 0100 KTextEditor::Range( 0101 newPos, 0102 KTextEditor::Cursor( 0103 newPos.line(), 0104 newPos.column() + selectionEnd - cursor 0105 ) 0106 ) 0107 ); 0108 } 0109 } 0110 } else { 0111 document->replaceText(word, m_keyword); 0112 } 0113 } 0114 0115 QVariant KeywordItem::data(const QModelIndex &index, int role, const KDevelop::CodeCompletionModel *model) const 0116 { 0117 switch (role) { 0118 case KDevelop::CodeCompletionModel::IsExpandable: 0119 return QVariant(false); 0120 case Qt::DisplayRole: 0121 if (index.column() == KTextEditor::CodeCompletionModel::Name) { 0122 return QVariant(m_keyword); 0123 } else if (m_wholeLine && index.column() == KTextEditor::CodeCompletionModel::Prefix) { 0124 return QVariant(m_replacement); 0125 } 0126 return QVariant(); 0127 case KTextEditor::CodeCompletionModel::ItemSelected: 0128 return QVariant(""); 0129 case KTextEditor::CodeCompletionModel::InheritanceDepth: 0130 return QVariant(0); 0131 default: 0132 break; 0133 } 0134 0135 return NormalDeclarationCompletionItem::data(index, role, model); 0136 } 0137 0138 } 0139