Git commit e78c5f95d8127aa13d117a6d3f2cb59570ec80ba by Christoph Cullmann, on behalf of Patrick Northon. Committed on 01/12/2022 at 19:55. Pushed by cullmann into branch 'master'.
Some changes and fixes to projects. - Fix exclude_patterns in the example. - Remove canonization of paths so that symbolic links are left intact. - Document exclude_patterns and new hidden option. For directories not under version control: - Will now follow symbolic links. These will be treated like normal directories transparently. Removal of canonization of paths is necessary for this. - Add an option to include or exclude hidden files. - Fetch files and directories, so that empty directories can be listed. M +5 -10 addons/project/kateproject.cpp M +5 -2 addons/project/kateproject.example M +2 -2 addons/project/kateprojectinfoview.cpp M +7 -6 addons/project/kateprojectplugin.cpp M +1 -2 addons/project/kateprojectplugin.h M +24 -16 addons/project/kateprojectworker.cpp M +1 -1 addons/project/kateprojectworker.h M +1 -1 apps/lib/katedocmanager.cpp M +9 -1 doc/kate/plugins.docbook https://invent.kde.org/utilities/kate/commit/e78c5f95d8127aa13d117a6d3f2cb59570ec80ba diff --git a/addons/project/kateproject.cpp b/addons/project/kateproject.cpp index 0ea51b229..f2b371170 100644 --- a/addons/project/kateproject.cpp +++ b/addons/project/kateproject.cpp @@ -117,14 +117,9 @@ KateProject::KateProject(QThreadPool &threadPool, KateProjectPlugin *plugin, con : m_threadPool(threadPool) , m_plugin(plugin) , m_fileBacked(true) - , m_fileName(QFileInfo(fileName).canonicalFilePath()) - , m_baseDir(QFileInfo(fileName).canonicalPath()) + , m_fileName(QFileInfo(fileName).absoluteFilePath()) + , m_baseDir(QFileInfo(fileName).absolutePath()) { - // if canonicalFilePath already returned empty string, no need to try to load this - if (m_fileName.isEmpty()) { - return; - } - // ensure we get notified for project file changes connect(&m_plugin->fileWatcher(), &QFileSystemWatcher::fileChanged, this, &KateProject::slotFileChanged); m_plugin->fileWatcher().addPath(m_fileName); @@ -139,8 +134,8 @@ KateProject::KateProject(QThreadPool &threadPool, KateProjectPlugin *plugin, con : m_threadPool(threadPool) , m_plugin(plugin) , m_fileBacked(false) - , m_fileName(QDir(QDir(directory).canonicalPath()).filePath(QStringLiteral(".kateproject"))) - , m_baseDir(QDir(directory).canonicalPath()) + , m_fileName(QDir(QDir(directory).absolutePath()).filePath(QStringLiteral(".kateproject"))) + , m_baseDir(QDir(directory).absolutePath()) , m_globalProject(globalProject) { // try to load the project map, will start worker thread, too @@ -294,7 +289,7 @@ bool KateProject::load(const QVariantMap &globalProject, bool force) */ const auto baseDir = globalProject[QStringLiteral("directory")].toString(); if (!baseDir.isEmpty()) { - m_baseDir = QFileInfo(QFileInfo(m_fileName).dir(), baseDir).canonicalFilePath(); + m_baseDir = QFileInfo(QFileInfo(m_fileName).dir(), baseDir).absoluteFilePath(); } /** diff --git a/addons/project/kateproject.example b/addons/project/kateproject.example index 869ffff1d..f27f0b25f 100644 --- a/addons/project/kateproject.example +++ b/addons/project/kateproject.example @@ -11,6 +11,9 @@ struct /// If set, the directory given here is used as the base directory for the project. /// Otherwise, the directory in which the project file is located as the base directory. string directory; + + /// "exclude_patterns" is a list of regex patterns than can be used to exclude folders and files from the project tree + vector< string > exclude_patterns; /// The "files" struct describes which files belong to the project. /// There are five miutually exclusive methods to do this. @@ -43,8 +46,8 @@ struct /// If "recursive" is set to 1, the globbing expressions in filters are executed recursively in the directory tree. bool recursive; - /// "exclude_patterns" is a list of regex patterns than can be used to exclude folders and files from the project tree - vector< string > exclude_patterns; + /// If "hidden" is set to 1, hidden files will be retrieved. Only affects directories not managed by version control. + bool hidden; }; /// The "build" structure is optional. diff --git a/addons/project/kateprojectinfoview.cpp b/addons/project/kateprojectinfoview.cpp index ce3ff7026..0b50d670d 100644 --- a/addons/project/kateprojectinfoview.cpp +++ b/addons/project/kateprojectinfoview.cpp @@ -29,7 +29,7 @@ KateProjectInfoView::KateProjectInfoView(KateProjectPluginView *pluginView, Kate /** * terminal for the directory with the .kateproject file inside */ - const QString projectPath = QFileInfo(QFileInfo(m_project->fileName()).path()).canonicalFilePath(); + const QString projectPath = QFileInfo(QFileInfo(m_project->fileName()).path()).absoluteFilePath(); if (!projectPath.isEmpty()) { m_terminal = new KateProjectInfoViewTerminal(pluginView, projectPath); addTab(m_terminal, i18n("Terminal (.kateproject)")); @@ -38,7 +38,7 @@ KateProjectInfoView::KateProjectInfoView(KateProjectPluginView *pluginView, Kate /** * terminal for the base directory, if different to directory of .kateproject */ - const QString basePath = QFileInfo(m_project->baseDir()).canonicalFilePath(); + const QString basePath = QFileInfo(m_project->baseDir()).absoluteFilePath(); if (!basePath.isEmpty() && projectPath != basePath) { addTab(new KateProjectInfoViewTerminal(pluginView, basePath), i18n("Terminal (Base)")); } diff --git a/addons/project/kateprojectplugin.cpp b/addons/project/kateprojectplugin.cpp index 22f0f58f9..33d4b56d8 100644 --- a/addons/project/kateprojectplugin.cpp +++ b/addons/project/kateprojectplugin.cpp @@ -132,10 +132,11 @@ KateProject *KateProjectPlugin::createProjectForFileName(const QString &fileName KateProject *KateProjectPlugin::openProjectForDirectory(const QDir &dir) { // check for project and load it if found - const QString canonicalPath = dir.canonicalPath(); - const QString canonicalFileName = dir.filePath(ProjectFileName); + const QDir absDir(dir.absolutePath()); + const QString absolutePath = absDir.path(); + const QString projectFileName = absDir.filePath(ProjectFileName); for (KateProject *project : qAsConst(m_projects)) { - if (project->baseDir() == canonicalPath || project->fileName() == canonicalFileName) { + if (project->baseDir() == absolutePath || project->fileName() == projectFileName) { return project; } } @@ -346,7 +347,7 @@ KateProject *KateProjectPlugin::createProjectForRepository(const QString &type, cnf[QStringLiteral("name")] = dir.dirName(); cnf[QStringLiteral("files")] = (QVariantList() << files); - KateProject *project = new KateProject(m_threadPool, this, cnf, dir.canonicalPath()); + KateProject *project = new KateProject(m_threadPool, this, cnf, dir.absolutePath()); m_projects.append(project); @@ -366,7 +367,7 @@ KateProject *KateProjectPlugin::createProjectForDirectory(const QDir &dir) cnf[QStringLiteral("name")] = dir.dirName(); cnf[QStringLiteral("files")] = (QVariantList() << files); - KateProject *project = new KateProject(m_threadPool, this, cnf, dir.canonicalPath()); + KateProject *project = new KateProject(m_threadPool, this, cnf, dir.absolutePath()); m_projects.append(project); @@ -381,7 +382,7 @@ KateProject *KateProjectPlugin::createProjectForDirectory(const QDir &dir, const return project; } - KateProject *project = new KateProject(m_threadPool, this, projectMap, dir.canonicalPath()); + KateProject *project = new KateProject(m_threadPool, this, projectMap, dir.absolutePath()); if (!project->isValid()) { delete project; return nullptr; diff --git a/addons/project/kateprojectplugin.h b/addons/project/kateprojectplugin.h index 10aa40cd9..7935c8348 100644 --- a/addons/project/kateprojectplugin.h +++ b/addons/project/kateprojectplugin.h @@ -48,8 +48,7 @@ public: /** * Create new project for given project filename. * Null pointer if no project can be opened. - * File name will be canonicalized! - * @param fileName canonicalized file name for the project + * @param fileName file name for the project * @return project or null if not openable */ KateProject *createProjectForFileName(const QString &fileName); diff --git a/addons/project/kateprojectworker.cpp b/addons/project/kateprojectworker.cpp index d40730eae..a22c8e96c 100644 --- a/addons/project/kateprojectworker.cpp +++ b/addons/project/kateprojectworker.cpp @@ -310,7 +310,7 @@ void KateProjectWorker::loadFilesEntry(QStandardItem *parent, preparedItems.reserve(files.size()); for (const auto &item : files) preparedItems.emplace_back(item, QString(), nullptr); - QtConcurrent::blockingMap(preparedItems, [excludeFolderPatterns, dirPath, excludeRegexps](std::tuple<QString, QString, KateProjectItem *> &item) { + QtConcurrent::blockingMap(preparedItems, [dirPath, excludeRegexps](std::tuple<QString, QString, KateProjectItem *> &item) { /** * cheap file name computation * we do this A LOT, QFileInfo is very expensive just for this operation @@ -329,18 +329,19 @@ void KateProjectWorker::loadFilesEntry(QStandardItem *parent, const QString fileName = (slashIndex < 0) ? filePath : filePath.mid(slashIndex + 1); filePath = (slashIndex < 0) ? QString() : filePath.left(slashIndex); - /** - * don't create a KateProjectItem object if no file! - */ - if (!QFileInfo(fullFilePath).isFile()) { - return; - } - /** * construct the item with info about filename + full file path */ - projectItem = new KateProjectItem(KateProjectItem::File, fileName); - projectItem->setData(fullFilePath, Qt::UserRole); + const QFileInfo info(fullFilePath); + if (info.isFile()) { + projectItem = new KateProjectItem(KateProjectItem::File, fileName); + projectItem->setData(fullFilePath, Qt::UserRole); + } + else if(info.isDir() && QDir(fullFilePath).isEmpty()) + { + projectItem = new KateProjectItem(KateProjectItem::Directory, fileName); + projectItem->setData(fullFilePath, Qt::UserRole); + } }); /** @@ -424,11 +425,16 @@ QVector<QString> KateProjectWorker::findFiles(const QDir &dir, const QVariantMap return userGivenFilesList.toVector(); } + /** + * shall we collect hidden files or not? + */ + const bool hidden = filesEntry.contains(QLatin1String("hidden")) && filesEntry[QStringLiteral("hidden")].toBool(); + /** * if nothing found for that, try to use filters to scan the directory * here we only get files */ - return filesFromDirectory(dir, recursive, filesEntry[QStringLiteral("filters")].toStringList()); + return filesFromDirectory(dir, recursive, hidden, filesEntry[QStringLiteral("filters")].toStringList()); } QVector<QString> KateProjectWorker::filesFromGit(const QDir &dir, bool recursive) @@ -688,13 +694,15 @@ QVector<QString> KateProjectWorker::filesFromFossil(const QDir &dir, bool recurs return files; } -QVector<QString> KateProjectWorker::filesFromDirectory(const QDir &_dir, bool recursive, const QStringList &filters) +QVector<QString> KateProjectWorker::filesFromDirectory(QDir dir, bool recursive, bool hidden, const QStringList &filters) { /** - * setup our filters, we only want files! + * setup our filters */ - QDir dir(_dir); - dir.setFilter(QDir::Files); + QDir::Filters filterFlags = QDir::Files | QDir::Dirs | QDir::NoDot | QDir::NoDotDot; + if(hidden) + filterFlags |= QDir::Hidden; + dir.setFilter(filterFlags); if (!filters.isEmpty()) { dir.setNameFilters(filters); } @@ -704,7 +712,7 @@ QVector<QString> KateProjectWorker::filesFromDirectory(const QDir &_dir, bool re */ QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags; if (recursive) { - flags = flags | QDirIterator::Subdirectories; + flags = flags | QDirIterator::Subdirectories | QDirIterator::FollowSymlinks; } /** diff --git a/addons/project/kateprojectworker.h b/addons/project/kateprojectworker.h index c22cb1c75..fc501e79f 100644 --- a/addons/project/kateprojectworker.h +++ b/addons/project/kateprojectworker.h @@ -65,7 +65,7 @@ private: static QVector<QString> filesFromSubversion(const QDir &dir, bool recursive); static QVector<QString> filesFromDarcs(const QDir &dir, bool recursive); static QVector<QString> filesFromFossil(const QDir &dir, bool recursive); - static QVector<QString> filesFromDirectory(const QDir &dir, bool recursive, const QStringList &filters); + static QVector<QString> filesFromDirectory(QDir dir, bool recursive, bool hidden, const QStringList &filters); static QVector<QString> gitFiles(const QDir &dir, bool recursive, const QStringList &args); diff --git a/apps/lib/katedocmanager.cpp b/apps/lib/katedocmanager.cpp index f5b15119b..027ff8c11 100644 --- a/apps/lib/katedocmanager.cpp +++ b/apps/lib/katedocmanager.cpp @@ -103,7 +103,7 @@ static QUrl normalizeUrl(const QUrl &url) { // Resolve symbolic links for local files (done anyway in KTextEditor) if (url.isLocalFile() && !KNetworkMounts::self()->isOptionEnabledForPath(url.toLocalFile(), KNetworkMounts::StrongSideEffectsOptimizations)) { - QString normalizedUrl = QFileInfo(url.toLocalFile()).canonicalFilePath(); + QString normalizedUrl = QFileInfo(url.toLocalFile()).absoluteFilePath(); if (!normalizedUrl.isEmpty()) { return QUrl::fromLocalFile(normalizedUrl); } diff --git a/doc/kate/plugins.docbook b/doc/kate/plugins.docbook index bb9ce7d81..043341f3a 100644 --- a/doc/kate/plugins.docbook +++ b/doc/kate/plugins.docbook @@ -2031,8 +2031,12 @@ or you can tell it to recursively load files from directories as follows: "CMakeLists.txt", "Find*.cmake" ], - "recursive": 1 + "recursive": 1, + "hidden": 1 } + ], + "exclude_patterns" : [ + "^build/.*" ] } </screen> @@ -2040,6 +2044,10 @@ or you can tell it to recursively load files from directories as follows: <para> Here, subfolders and filters define what’s part of the project. You can also mix version control and files based on filters. +Hidden files will not be retrieved if the option <code>"hidden"</code> is 0. +<code>"exclude_patterns"</code> is a list of regex patterns than can be used +to exclude folders and files from the project tree. In this example, All files +and folders in a directory <filename>build</filename> from the root will be excluded. </para> <para id="projects-build-support">If you want to add support for the building, you can write a
