daa84 / neovim-gtk

gtk ui for neovim
GNU General Public License v3.0
716 stars 57 forks source link

Won't Run Properly From Anywhere But the Build Directory #209

Open ewhac opened 4 years ago

ewhac commented 4 years ago

After building, nvim-gtk won't run properly from anywhere except the directory in which it was built.

After successfully building and installing to $HOME/.cargo/bin, when run from the build directory, nvim-gtk behaves properly and comes up nearly identically to nvim-qt:

However, the moment I change to any other directory and try to run the program, I get a window with the error text:

Can't initialize nvim: 0 - Vim:E492: Not an editor command: GuiFont ProFontWindows:h9

The file $HOME/.config/nvim/ginit.vim exists, and works perfectly fine for nvim-qt launched from anywhere.

The difference appears to be the presence of the runtime directory. If it's present in the current directory, nvim-gtk runs fine; if not, it complains.

While writing up this report, I decided to grep for PREFIX in the code, and found this in src/nvim/mod.rs:

    if let Ok(runtime_path) = env::var("NVIM_GTK_RUNTIME_PATH") {
        cmd.arg("--cmd")
            .arg(format!("let &rtp.=',{}'", runtime_path));
    } else if let Some(prefix) = option_env!("PREFIX") {
        cmd.arg("--cmd")
            .arg(format!("let &rtp.=',{}/share/nvim-gtk/runtime'", prefix));
    } else {
        cmd.arg("--cmd").arg("let &rtp.=',runtime'");
    }

I see nvim-qt does effectively the same thing. This is arguably incorrect behavior. I think you should be using the FreeDesktop.org standards for fishing stuff out of "common" directories as outlined here. Basically, the search order appears to be:

With that in mind, your code should probably look something like:

    // Tack on all potential locations for our runtime, if they exist.
    if let Ok(runtime_path) = env::var("NVIM_GTK_RUNTIME_PATH") {
        if path::Path::new (&runtime_path).exists() {
            cmd.arg("--cmd")
                .arg(format!("let &rtp.=',{}'", runtime_path));
            found_runtime = true;
        }
    }
    if let Some(prefix) = option_env!("PREFIX") {
        if path::Path::new (&prefix).exists() {
            cmd.arg("--cmd")
                .arg(format!("let &rtp.=',{}/share/nvim-gtk/runtime'", prefix));
            found_runtime = true;
        }
    }
    if let Some(mut data_dir) = dirs::data_dir() {
        data_dir.push ("nvim-gtk");
        data_dir.push ("runtime");

        if data_dir.exists() {
            if let Some(pth) = data_dir.to_str() {
                cmd.arg("--cmd")
                    .arg(format!("let &rtp.=',{}'", pth));
                found_runtime = true;
            }
        }
    }
    // While /usr/share, /usr/local/share, etc. are already in the standard
    // runtime path, an nvim-gtk specific flavor is not.  Nevertheless,
    // this loop is of questionable wisdom.
    if let Ok(xdg_dirs) = env::var ("XDG_DATA_DIRS") {
        for mut ent in env::split_paths (&xdg_dirs) {
            ent.push ("nvim-gtk");
            ent.push ("runtime");
            if ent.exists() {
                if let Some(pth) = ent.to_str() {
                    cmd.arg("--cmd")
                        .arg(format!("let &rtp.=',{}'", pth));
                    found_runtime = true;
                }
            }
        }
    }
    if !found_runtime {
        // Fallback: Look in the current directory.
        cmd.arg("--cmd").arg("let &rtp.=',runtime'");
    }

The above kluge seems to work for me. I'm sure that someone with more than a week's exposure to Rust would be able to do a better job.