equalsraf / neovim-qt

Neovim client library and GUI, in Qt5.
https://github.com/equalsraf/neovim-qt/wiki
ISC License
1.85k stars 171 forks source link

Is it possible to pass cli positional arguments to `nvim-qt --server xxx` to open file directly? #610

Open luochen1990 opened 4 years ago

luochen1990 commented 4 years ago

I'm using Windows with WSL Ubuntu, my current usage is use nvim inside WSL as the server, and use Windows nvim-qt.exe as the client:

alias gv='f(){ nvim --listen 127.0.0.1:10710 --headless "$@" & /mnt/c/dev/Neovim/bin/nvim-qt.exe --server 127.0.0.1:10710 }; f'

I'm using the above alias to mimic a gvim command which can accept positional arguments and open the file directly.

But the above solution have some limitation, first, we cannot use gv command a second time until the first process is closed; second, it looks stupid to restart a new nvim process every time we start a client.

So I'm trying to keep a daemon nvim process alive, and always connect to the same server for different client instance, but I don't know how to pass the positional arguments to nvim-qt.exe so that it can open the file directly, just like the gvim command. Can you help?

justinmk commented 4 years ago

https://github.com/neovim/neovim/pull/11326 and related work will enable this kind of thing.

equalsraf commented 4 years ago

Currently we disallow positional arguments when called with --server. If we assume they are allowed with --server and expected to be treated as files to be open, then we need a way to convey this to the running instance of neovim.

The closest thing we have to this is drag and drop (or file open on mac OS) that opens files using the nvim drop command. Quickest thing I can think of is a patch for --server

diff --git a/src/gui/app.cpp b/src/gui/app.cpp
index ccf1d92..42ff461 100644
--- a/src/gui/app.cpp
+++ b/src/gui/app.cpp
@@ -134,6 +134,11 @@ void App::showUi(NeovimConnector *c, const QCommandLineParser& parser)
    } else {
        win->delayedShow();
    }
+
+   auto files = openFiles(parser);
+   if (!files.isEmpty()) {
+       emit openFilesTriggered(files);
+   }
 #endif
 }

@@ -207,9 +212,8 @@ void App::processCliOptions(QCommandLineParser &parser, const QStringList& argum
        ::exit(-1);
    }

-   if (!parser.positionalArguments().isEmpty() &&
-           (parser.isSet("embed") || parser.isSet("server"))) {
-       qWarning() << "--embed and --server do not accept positional arguments\n";
+   if (!parser.positionalArguments().isEmpty() && parser.isSet("embed")) {
+       qWarning() << "--embed does not accept positional arguments\n";
        ::exit(-1);
    }

@@ -226,6 +230,22 @@ void App::processCliOptions(QCommandLineParser &parser, const QStringList& argum
    }
 }

+/// Return a list of URLs that should be open in Neovim.
+///
+/// This only makes sense in invocations where arguments are clearly filenames.
+QList<QUrl> App::openFiles(const QCommandLineParser& parser)
+{
+   if (parser.isSet("server")) {
+       auto result = QList<QUrl>();
+       foreach(const QString& filepath, parser.positionalArguments()) {
+           result.append(QUrl::fromLocalFile(filepath));
+       }
+       return result;
+   } else {
+       return QList<QUrl>();
+   }
+}
+
 NeovimConnector* App::createConnector(const QCommandLineParser& parser)
 {
    if (parser.isSet("embed")) {
diff --git a/src/gui/app.h b/src/gui/app.h
index 174c80b..1db1cfe 100644
--- a/src/gui/app.h
+++ b/src/gui/app.h
@@ -20,6 +20,7 @@ public:
    void showUi(NeovimConnector *c, const QCommandLineParser&);
    static void processCliOptions(QCommandLineParser& p, const QStringList& arguments);
    static NeovimConnector* createConnector(const QCommandLineParser& p);
+   static QList<QUrl> openFiles(const QCommandLineParser& p);

 private:
    static ShellOptions GetShellOptionsFromQSettings();