diff --git a/docs/PLAN.md b/docs/PLAN.md index 77b4611..cc1daa6 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -346,7 +346,11 @@ Kate flow through the real plumber rules. selection, else `Document::wordAt(cursorPosition)`, with the active doc's dir as `wdir`; on send failure it falls back to an internal resolver (URL → `QDesktopServices`, path[:line] → open here). Incoming `edit` messages are - opened via `MainWindow::openUrl` + `activateView` + `setCursorPosition`. + opened via `MainWindow::openUrl` + `activateView` + `setCursorPosition`; a + plumbed path that resolves to a **directory** opens as a folder in Kate + instead (relaunches the hosting kate binary on the dir — Kate is + single-instance, so it opens in the running window; no in-process folder-open + API exists, so this is the documented command-line path). - **Verification**: `test_plumbmsg` + `test_plumbresolve` run headless; `test_plumb_live` does a **real round-trip** against a running plumber (send `:2` → rules → edit port → `edit()` signal) and **skips+passes** when no diff --git a/src/plugin/ollieplugin.cpp b/src/plugin/ollieplugin.cpp index a1dd747..dbfa21d 100644 --- a/src/plugin/ollieplugin.cpp +++ b/src/plugin/ollieplugin.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -895,6 +897,23 @@ void OllieView::onPlumbEdit(const QString &file, const QString &addr, const QStr fi = QFileInfo(QDir(wdir).absoluteFilePath(path)); } + // A plumbed directory opens as a folder in Kate (like acme opening a + // directory listing). Kate accepts a directory URL on its command line and, + // being single-instance, opens it in the running window. We relaunch the + // very binary hosting us so it is unambiguously "this Kate". There is no + // in-process public API to open a folder as a project, so this is the + // documented path, not a guessed one. + if (fi.exists() && fi.isDir()) { + QString kate = QCoreApplication::applicationFilePath(); + if (kate.isEmpty() || !QFileInfo(kate).fileName().contains(QLatin1String("kate"))) { + kate = QStandardPaths::findExecutable(QStringLiteral("kate")); + } + if (!kate.isEmpty()) { + QProcess::startDetached(kate, {fi.absoluteFilePath()}); + } + return; + } + const QUrl url = QUrl::fromLocalFile(fi.absoluteFilePath()); KTextEditor::View *view = m_mainWindow->openUrl(url); if (!view) {