File indexing completed on 2024-03-24 04:38:27
0001 /* 0002 * This file is part of KDevelop 0003 * 0004 * Copyright 2007-2010 Alexander Dymo <adymo@kdevelop.org> 0005 * Copyright (C) 2014-2015 Miquel Sabaté Solà <mikisabate@gmail.com> 0006 * 0007 * This program is free software; you can redistribute it and/or modify 0008 * it under the terms of the GNU Library General Public License as 0009 * published by the Free Software Foundation; either version 2 of the 0010 * License, or (at your option) any later version. 0011 * 0012 * This program is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public 0018 * License along with this program; if not, write to the 0019 * Free Software Foundation, Inc., 0020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include <QtCore/QDir> 0024 #include <QtCore/QFileInfo> 0025 0026 #include <KLocalizedString> 0027 0028 #include <interfaces/icore.h> 0029 #include <interfaces/idocumentcontroller.h> 0030 #include <interfaces/iplugincontroller.h> 0031 #include <language/interfaces/iquickopen.h> 0032 0033 #include <languagesupport.h> 0034 #include <rails/switchers.h> 0035 #include <rails/helpers.h> 0036 0037 using namespace KDevelop; 0038 using namespace ruby::rails; 0039 0040 namespace { 0041 0042 bool isViewExtension(const QString &extension) 0043 { 0044 return (extension == QStringLiteral("rjs") || 0045 extension == QStringLiteral("rxml") || 0046 extension == QStringLiteral("rhtml") || 0047 extension == QStringLiteral("js.rjs") || 0048 extension == QStringLiteral("xml.builder") || 0049 extension == QStringLiteral("html.erb") || 0050 extension == QStringLiteral("erb") || 0051 extension == QStringLiteral("haml")); 0052 } 0053 0054 } 0055 0056 Switchers::Switchers(ruby::LanguageSupport *language) 0057 : QObject(language) 0058 { 0059 } 0060 0061 QVector<Path> Switchers::viewsToSwitch() 0062 { 0063 QVector<Path> urls; 0064 0065 auto doc = ICore::self()->documentController()->activeDocument(); 0066 if (!doc) { 0067 return urls; 0068 } 0069 0070 const QUrl &url = doc->url(); 0071 QFileInfo file(url.toLocalFile()); 0072 if (!file.exists()) { 0073 return urls; 0074 } 0075 0076 const QString &ext = file.completeSuffix(); 0077 QString name = file.baseName(); 0078 QString switchTo = ""; 0079 0080 if (isViewExtension(ext)) { 0081 switchTo = file.dir().dirName(); 0082 } else if (ext == "rb") { 0083 switchTo = name.remove(QRegExp("_controller$")); 0084 switchTo = switchTo.remove(QRegExp("_controller_test$")); 0085 switchTo = switchTo.remove(QRegExp("_test$")); 0086 } 0087 0088 if (switchTo.isEmpty()) { 0089 return urls; 0090 } 0091 if (switchTo.endsWith("s")) { 0092 switchTo = switchTo.mid(0, switchTo.length() - 1); 0093 } 0094 0095 Path root = Helpers::findRailsRoot(url); 0096 if (!root.isValid()) { 0097 return urls; 0098 } 0099 0100 Path viewsUrl(root, QStringLiteral("app/views")); 0101 Path viewsUrlS(viewsUrl, switchTo); 0102 Path viewsUrlP(viewsUrl, switchTo + "s"); 0103 0104 if (QFile::exists(viewsUrlS.toLocalFile())) { 0105 viewsUrl = viewsUrlS; 0106 } else if (QFile::exists(viewsUrlP.toLocalFile())) { 0107 viewsUrl = viewsUrlP; 0108 } else { 0109 return urls; 0110 } 0111 0112 QDir viewsDir(viewsUrl.toLocalFile()); 0113 const QStringList &views = viewsDir.entryList(); 0114 const Path base(viewsDir.absolutePath()); 0115 0116 foreach (const QString &name, views) { 0117 if (!(name.endsWith("~") || name == "." || name == "..")) { 0118 urls << KDevelop::Path(base, name); 0119 } 0120 } 0121 return urls; 0122 } 0123 0124 QVector<Path> Switchers::testsToSwitch() 0125 { 0126 QVector<KDevelop::Path> urls; 0127 0128 auto doc = KDevelop::ICore::self()->documentController()->activeDocument(); 0129 if (!doc) { 0130 return urls; 0131 } 0132 0133 QFileInfo file(doc->url().toLocalFile()); 0134 if (!file.exists()) { 0135 return urls; 0136 } 0137 0138 const QString &ext = file.completeSuffix(); 0139 QString name = file.baseName(); 0140 QString switchTo = ""; 0141 0142 if (isViewExtension(ext)) { 0143 switchTo = file.dir().dirName(); 0144 } else if (ext == "rb") { 0145 switchTo = name.remove(QRegExp("_controller$")). 0146 remove(QRegExp("_controller_test$")).remove(QRegExp("_test$")); 0147 } 0148 if (switchTo.isEmpty()) { 0149 return urls; 0150 } 0151 if (switchTo.endsWith("s")) { 0152 switchTo = switchTo.mid(0, switchTo.length() - 1); 0153 } 0154 0155 Path testsUrl(Helpers::findRailsRoot(doc->url()), "test"); 0156 Path functionalTestsUrlS(testsUrl, "functional/" + switchTo + 0157 "_controller_test.rb"); 0158 if (QFile::exists(functionalTestsUrlS.toLocalFile())) { 0159 urls << functionalTestsUrlS; 0160 } 0161 0162 Path functionalTestsUrlP(testsUrl, "functional/" + switchTo + 0163 "s_controller_test.rb"); 0164 if (QFile::exists(functionalTestsUrlP.toLocalFile())) { 0165 urls << functionalTestsUrlP; 0166 } 0167 0168 Path integrationTestsUrlS(testsUrl, "integration/" + switchTo + "_test.rb"); 0169 if (QFile::exists(integrationTestsUrlS.toLocalFile())) { 0170 urls << integrationTestsUrlS; 0171 } 0172 0173 Path integrationTestsUrlP(testsUrl, "integration/" + switchTo + "s_test.rb"); 0174 if (QFile::exists(integrationTestsUrlP.toLocalFile())) { 0175 urls << integrationTestsUrlP; 0176 } 0177 0178 Path unitTestsUrlS(testsUrl, "unit/" + switchTo + "_test.rb"); 0179 if (QFile::exists(unitTestsUrlS.toLocalFile())) { 0180 urls << unitTestsUrlS; 0181 } 0182 0183 Path unitTestsUrlP(testsUrl, "unit/" + switchTo + "s_test.rb"); 0184 if (QFile::exists(unitTestsUrlP.toLocalFile())) { 0185 urls << unitTestsUrlP; 0186 } 0187 0188 return urls; 0189 } 0190 0191 void Switchers::switchToController() 0192 { 0193 auto doc = KDevelop::ICore::self()->documentController()->activeDocument(); 0194 if (!doc) { 0195 return; 0196 } 0197 0198 QFileInfo file(doc->url().toLocalFile()); 0199 if (!file.exists()) { 0200 return; 0201 } 0202 0203 const QString &ext = file.completeSuffix(); 0204 QString name = file.baseName(); 0205 QString switchTo = ""; 0206 Path root = Helpers::findRailsRoot(doc->url()); 0207 if (!root.isValid()) { 0208 return; 0209 } 0210 0211 if (ext == QStringLiteral("rb") && 0212 !name.endsWith(QStringLiteral("_controller"))) { 0213 0214 if (name.endsWith("_test")) { 0215 switchTo = name.remove(QRegExp("_test$")); 0216 switchTo = name.remove(QRegExp("_controller$")); 0217 } else { 0218 switchTo = name; 0219 } 0220 } else if (isViewExtension(ext)) { 0221 switchTo = file.dir().dirName(); 0222 } 0223 0224 if (!switchTo.isEmpty()) { 0225 Path url(root, "app/controllers"); 0226 0227 if (switchTo.endsWith("s")) { 0228 switchTo = switchTo.mid(0, switchTo.length() - 1); 0229 } 0230 Path singular(url, switchTo + "_controller.rb"); 0231 Path plural(url, switchTo + "s_controller.rb"); 0232 0233 QUrl docUrl; 0234 if (QFile::exists(singular.toLocalFile())) { 0235 docUrl = singular.toUrl(); 0236 } else { 0237 docUrl = plural.toUrl(); 0238 } 0239 ICore::self()->documentController()->openDocument(docUrl); 0240 } 0241 } 0242 0243 void Switchers::switchToModel() 0244 { 0245 auto doc = ICore::self()->documentController()->activeDocument(); 0246 if (!doc) { 0247 return; 0248 } 0249 0250 QFileInfo file(doc->url().toLocalFile()); 0251 if (!file.exists()) { 0252 return; 0253 } 0254 0255 const QString &ext = file.completeSuffix(); 0256 QString name = file.baseName(); 0257 QString switchTo = ""; 0258 0259 Path root = Helpers::findRailsRoot(doc->url()); 0260 if (!root.isValid()) { 0261 return; 0262 } 0263 0264 if (isViewExtension(ext)) { 0265 switchTo = file.dir().dirName(); 0266 } else if (ext == QStringLiteral("rb") && 0267 (name.endsWith(QStringLiteral("_controller")) || 0268 name.endsWith(QStringLiteral("_test")))) { 0269 0270 switchTo = name.remove(QRegExp("_controller$")); 0271 switchTo = switchTo.remove(QRegExp("_controller_test$")); 0272 switchTo = switchTo.remove(QRegExp("_test$")); 0273 } 0274 if (switchTo.isEmpty()) { 0275 return; 0276 } 0277 0278 Path url(root, QStringLiteral("app/models")); 0279 if (switchTo.endsWith("s")) { 0280 switchTo = switchTo.mid(0, switchTo.length() - 1); 0281 } 0282 url.addPath(switchTo + ".rb"); 0283 ICore::self()->documentController()->openDocument(url.toUrl()); 0284 } 0285 0286 void Switchers::switchToView() 0287 { 0288 if (viewsToSwitch().isEmpty()) { 0289 return; 0290 } 0291 0292 auto quickOpen = ICore::self()->pluginController()-> 0293 extensionForPlugin<IQuickOpen>("org.kdevelop.IQuickOpen"); 0294 0295 Q_ASSERT(quickOpen); 0296 quickOpen->showQuickOpen(QStringList{ i18n("Rails Views") }); 0297 } 0298 0299 void Switchers::switchToTest() 0300 { 0301 if (testsToSwitch().isEmpty()) { 0302 return; 0303 } 0304 0305 auto quickOpen = ICore::self()->pluginController()-> 0306 extensionForPlugin<IQuickOpen>("org.kdevelop.IQuickOpen"); 0307 0308 Q_ASSERT(quickOpen); 0309 quickOpen->showQuickOpen(QStringList{ i18n("Rails Tests") }); 0310 } 0311