&)
+ : KTextEditor::Plugin(parent),
+ m_openSelectionCommand(nullptr)
+{
+ m_openSelectionCommand = new PluginCommandKateOpenSelection(this);
+ connect(m_openSelectionCommand, &PluginCommandKateOpenSelection::openSelection, this, &PluginKateOpenSelection::slotOpenSelection);
+}
+
+PluginKateOpenSelection::~PluginKateOpenSelection()
+{
+ delete m_openSelectionCommand;
+}
+
+QObject *PluginKateOpenSelection::createView(KTextEditor::MainWindow *mainWindow)
+{
+ return new PluginViewKateOpenSelection(this, mainWindow);
+}
+
+static bool isValidChar(QChar c)
+{
+ return !c.isSpace() && c != QLatin1Char('"') && c != QLatin1Char('\'');
+}
+
+QString PluginKateOpenSelection::findPathAtCursor(KTextEditor::View* editView)
+{
+ const KTextEditor::Cursor &cursor = editView->cursorPosition();
+ const QString line = editView->document()->line(cursor.line());
+ const int lineLength = line.size();
+ if (lineLength > 0) {
+ const int col = cursor.column();
+ int start = col;
+ int end = col;
+
+ // Stop at first white space or quote (for path with space, user should select the text)
+ while (start > 0 && isValidChar(line.at(start - 1))) {
+ --start;
+ }
+ while (end+1 < lineLength && isValidChar(line.at(end + 1))) {
+ ++end;
+ }
+ return line.mid(start, end - start + 1);
+ }
+ return QString();
+}
+
+void PluginKateOpenSelection::slotOpenSelection()
+{
+ KTextEditor::Application *application = KTextEditor::Editor::instance()->application();
+ if (!application->activeMainWindow()) {
+ return;
+ }
+
+ KTextEditor::View* editView = application->activeMainWindow()->activeView();
+ if (editView) {
+ QString selection;
+
+ // Selected text
+ if (editView->selection()) {
+ selection = editView->selectionText();
+ selection = selection.trimmed();
+ }
+
+ // Try to extract path under cursor if no selected text
+ if (selection.isEmpty()) {
+ selection = findPathAtCursor(editView);
+ }
+
+ if (!selection.isEmpty() && !selection.contains(QLatin1Char('\n'))) {
+
+ // Directory of the active document
+ const QUrl currentUrl = editView->document()->url();
+ QString currentUrlDirectory;
+ if (currentUrl.isValid() && !currentUrl.isEmpty()) {
+ currentUrlDirectory = QFileInfo(currentUrl.path()).absolutePath();
+ }
+
+ // Deduction of the url type, QUrl::AssumeLocalFile to prevent remote file assumption when the local file does not exist
+ const QUrl url = QUrl::fromUserInput(selection, currentUrlDirectory, QUrl::AssumeLocalFile);
+
+ // Open the file if existing
+ if (fileExists(url)) {
+ application->activeMainWindow()->openUrl(url);
+ }
+ }
+ }
+}
+
+bool PluginKateOpenSelection::fileExists(const QUrl &url)
+{
+ if (url.isLocalFile()) {
+ return QFile::exists(url.toLocalFile());
+ }
+ // For http protocol, the file is supposed to exist (KIO::StatJob::SourceSide)
+ KIO::StatJob *job = KIO::stat(url, KIO::StatJob::SourceSide, 0, KIO::DefaultFlags);
+ KJobWidgets::setWindow(job, KTextEditor::Editor::instance()->application()->activeMainWindow()->window());
+ job->exec();
+ return !job->error();
+}
+
+PluginViewKateOpenSelection::PluginViewKateOpenSelection(PluginKateOpenSelection *plugin, KTextEditor::MainWindow *mainwindow)
+ : QObject(mainwindow),
+ KXMLGUIClient(),
+ m_mainWindow(mainwindow)
+{
+ KXMLGUIClient::setComponentName(QStringLiteral("kateopenselectionplugin"), i18n("Open Selection"));
+ setXMLFile(QStringLiteral("ui.rc"));
+ QAction *a = actionCollection()->addAction(QStringLiteral("file_openselection"));
+ a->setText(i18n("Open Selected Path"));
+ actionCollection()->setDefaultShortcut(a, QKeySequence(Qt::ALT + Qt::Key_O));
+ connect(a, &QAction::triggered, plugin, &PluginKateOpenSelection::slotOpenSelection);
+ mainwindow->guiFactory()->addClient(this);
+}
+
+PluginViewKateOpenSelection::~PluginViewKateOpenSelection()
+{
+ m_mainWindow->guiFactory()->removeClient(this);
+}
+
+PluginCommandKateOpenSelection::PluginCommandKateOpenSelection(QObject* parent)
+ : KTextEditor::Command(QStringList() << QStringLiteral("open-selection"), parent)
+{
+}
+
+PluginCommandKateOpenSelection::~PluginCommandKateOpenSelection()
+{
+}
+
+bool PluginCommandKateOpenSelection::exec(KTextEditor::View *view, const QString &cmd, QString &msg, const KTextEditor::Range &)
+{
+ Q_UNUSED(view)
+ Q_UNUSED(cmd)
+ Q_UNUSED(msg)
+
+ emit openSelection();
+ return true;
+}
+
+bool PluginCommandKateOpenSelection::help(KTextEditor::View *view, const QString &cmd, QString &msg)
+{
+ Q_UNUSED(view)
+ Q_UNUSED(cmd)
+
+ msg = i18n("open-selection — open the selected path
"
+ "usage: open-selection
"
+ "This command will open the file under the cursor (path in selection or auto-detection)
");
+
+ return true;
+}
+
+#include "plugin_kateopenselection.moc"
diff --git a/addons/openselection/rc.cpp b/addons/openselection/rc.cpp
new file mode 100644
diff --git a/addons/openselection/ui.rc b/addons/openselection/ui.rc
new file mode 100644
--- /dev/null
+++ b/addons/openselection/ui.rc
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/doc/kate/plugins.docbook b/doc/kate/plugins.docbook
--- a/doc/kate/plugins.docbook
+++ b/doc/kate/plugins.docbook
@@ -84,6 +84,10 @@
- Opens the corresponding .h/[.cpp|.c] file
+Open Selection
+- Opens the selected path
+
+
Project Plugin - Integration with Git and other source control systems
@@ -1510,6 +1514,44 @@
+
+
+Open Selection Plugin
+
+
+Using the Open Selection Plugin
+
+This command help to open files with path in a file
+
+For example, if you have a list of path in a file (address file, includes, ...), select or place the cursor in one of them, then trigger the plugin using the shortcut. The plugin will open the file
+
+
+
+
+
+
+
+