diff --git a/README.md b/README.md index 21440401..35e9f0db 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,25 @@ Before installing anything please read [SECURITY.md](SECURITY.md) and make sure 2. Install the Firenvim addon for your browser from [Mozilla's store](https://addons.mozilla.org/en-US/firefox/addon/firenvim/) or [Google's](https://chrome.google.com/webstore/detail/firenvim/egpjdkipkomnmjhjmdamaniclmdlobbo). +3. If you're not using a flatpak browser, you can skip this + +While support for flatpaks was [recently](https://github.com/glacambre/firenvim/pull/1597) added for Firefox, other changes are still needed on the user's end. + +The following folders all need to be overridden in the flatpak config for the browser: + +- Whatever `:echo stdpath("config")` resolves to for you (normally `~/.config/nvim`) +- Whatever `:echo stdpath("data")` resolves to for you (normall `~/.local/share/nvim`) +- `~/.local/share/firenvim` +- The path to `nvim` if it's installed using something like homebrew (if you're using your distro's package manager you should be able to ignore) +- `/run/user/1000/firenvim` by default, or whichever path you've configured as the base for the files being edited + +You can do this using [flatseal](https://flathub.org/apps/com.github.tchx84.Flatseal) (recommended) or create/amend the file in `~/.local/share/flatpak/overrides/org.mozilla.firefox` to look something similar to the below: + +```conf +[Context] +filesystems=/run/user/1000/firenvim;~/.local/share/firenvim;~/.local/share/nvim;~/.config/nvim +``` + If you would rather build and install Firenvim from source, check [CONTRIBUTING.md](CONTRIBUTING.md). #### Other browsers diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index c55c40f6..6781d3a1 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -4,13 +4,22 @@ If you're having issues with Firenvim, here are the steps you can take in order ## Make sure Flatpak and Snap are not preventing Firenvim from working -If your browser is installed through Snap or Flatpak, sandboxing mechanisms might be preventing the browser from starting Neovim. You can confirm this by running: +If your browser is installed through Snap, sandboxing mechanisms might be preventing the browser from starting Neovim. You can confirm this by running: ``` flatpak permissions webextensions ``` -If the output of this command shows that Snap/Flatpak are preventing Firenvim from running, you need to run `flatpak permission-set webextensions firenvim snap.firefox yes` to change that. +If the output of this command shows that Snap are preventing Firenvim from running, you need to run `flatpak permission-set webextensions firenvim snap.firefox yes` to change that. + +In the case of Flatpak installs, verify that you've performed the steps in the [README](https://github.com/glacambre/firenvim?tab=readme-ov-file#installing) and that the `~/.local/share/flatpak/overrides/org.mozilla.firefox` file looks something similar to the below: + +```conf +[Context] +filesystems=/run/user/1000/firenvim;~/.local/share/firenvim;~/.local/share/nvim;~/.config/nvim +``` + +Those directories may change depending on your setup, consult the guidelines in the [README](https://github.com/glacambre/firenvim?tab=readme-ov-file#installing). Also ensure that the directory that `$ which nvim` resolves to shows up (eg if you've installed via homebrew, you'll have to add `/home/linuxbrew/.linuxbrew`) ## Make sure the neovim plugin is installed diff --git a/autoload/firenvim.vim b/autoload/firenvim.vim index cbcb9f2d..4a1432fd 100644 --- a/autoload/firenvim.vim +++ b/autoload/firenvim.vim @@ -273,6 +273,23 @@ function! s:get_data_dir_path() abort return s:build_path([l:xdg_data_home, 'firenvim']) endfunction +function! s:browser_has_flatpak_installed(browser) abort + if has('linux') && has_key(a:browser, 'flatpak_name') + let l:cmd_output = system(['flatpak', 'info', a:browser['flatpak_name']]) + if l:cmd_output =~ 'error:.*not installed' + return 0 + else + return 1 + endif + endif + + return 0 +endfunction + +function! s:firefox_flatpak_config_exists() abort + return isdirectory(s:build_path([$HOME, '.var', 'app', 'org.mozilla.firefox', '.mozilla'])) +endfunction + function! s:firefox_config_exists() abort let l:p = [$HOME, '.mozilla'] if has('mac') @@ -285,13 +302,17 @@ function! s:firefox_config_exists() abort return isdirectory(s:build_path(l:p)) endfunction +function! s:get_firefox_flatpak_manifest_dir_path() abort + return s:build_path([$HOME, '.var', 'app', 'org.mozilla.firefox', '.mozilla', 'native-messaging-hosts']) +endfunction + function! s:get_firefox_manifest_dir_path() abort - if has('mac') - return s:build_path([$HOME, 'Library', 'Application Support', 'Mozilla', 'NativeMessagingHosts']) - elseif has('win32') || s:is_wsl - return s:get_data_dir_path() - end - return s:build_path([$HOME, '.mozilla', 'native-messaging-hosts']) + if has('mac') + return s:build_path([$HOME, 'Library', 'Application Support', 'Mozilla', 'NativeMessagingHosts']) + elseif has('win32') || s:is_wsl + return s:get_data_dir_path() + end + return s:build_path([$HOME, '.mozilla', 'native-messaging-hosts']) endfunction function! s:librewolf_config_exists() abort @@ -750,6 +771,12 @@ function! s:get_browser_configuration() abort \ 'manifest_dir_path': function('s:get_firefox_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Mozilla\NativeMessagingHosts\firenvim', \}, + \'firefox-flatpak': { + \ 'has_config': s:firefox_flatpak_config_exists(), + \ 'manifest_content': function('s:get_firefox_manifest'), + \ 'manifest_dir_path': function('s:get_firefox_flatpak_manifest_dir_path'), + \ 'flatpak_name': 'org.mozilla.firefox', + \}, \'librewolf': { \ 'has_config': s:librewolf_config_exists(), \ 'manifest_content': function('s:get_firefox_manifest'), @@ -857,64 +884,86 @@ function! firenvim#install(...) abort continue endif - try - let l:manifest_content = l:cur_browser['manifest_content'](l:execute_nvim_path) - let l:manifest_dir_path = l:cur_browser['manifest_dir_path']() - let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim.json']) - catch /.*/ - echo 'Aborting installation for ' . l:name . '. ' . v:exception - continue - endtry - - if has('win32') || s:is_wsl - let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim-' . l:name . '.json']) + let l:flatpak_result = s:browser_has_flatpak_installed(l:cur_browser) + if l:flatpak_result == 1 + try + let l:manifest_content = l:cur_browser['manifest_content'](l:execute_nvim_path) + let l:manifest_dir_path = l:cur_browser['manifest_dir_path']() + let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim.json']) + catch /.*/ + echo 'Aborting installation for ' . l:name . ' flatpak. ' . v:exception + continue + endtry + + call s:maybe_execute('mkdir', l:manifest_dir_path, 'p', 0700) + call s:maybe_execute('writefile', [l:manifest_content], l:manifest_path) + call s:maybe_execute('setfperm', l:manifest_path, 'rw-------') + + echo 'Installed flatpak manifest for ' . l:name . '.' + + call s:maybe_execute('system', ['ln', '-nsf', stdpath("config"), s:build_path([$HOME, '.var', 'app', l:cur_browser['flatpak_name'], "config", "nvim"])]) + call s:maybe_execute('system', ['ln', '-nsf', stdpath("data"), s:build_path([$HOME, '.var', 'app', l:cur_browser['flatpak_name'], "data", "nvim"])]) + else + try + let l:manifest_content = l:cur_browser['manifest_content'](l:execute_nvim_path) + let l:manifest_dir_path = l:cur_browser['manifest_dir_path']() + let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim.json']) + catch /.*/ + echo 'Aborting installation for ' . l:name . '. ' . v:exception + continue + endtry + + if has('win32') || s:is_wsl + let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim-' . l:name . '.json']) + endif + + call s:maybe_execute('mkdir', l:manifest_dir_path, 'p', 0700) + call s:maybe_execute('writefile', [l:manifest_content], l:manifest_path) + call s:maybe_execute('setfperm', l:manifest_path, 'rw-------') + + echo 'Installed native manifest for ' . l:name . '.' + + if has('win32') || s:is_wsl + " On windows, also create a registry key. We do this + " by writing a powershell script to a file and + " executing it. + let l:ps1_content = s:key_to_ps1_str(l:cur_browser['registry_key'], + \ l:manifest_path) + let l:ps1_path = s:build_path([l:manifest_dir_path, l:name . '.ps1']) + echo 'Creating registry key for ' . l:name . '. This may take a while. Script: ' . l:ps1_path + call s:maybe_execute('writefile', split(l:ps1_content, "\n"), l:ps1_path) + call s:maybe_execute('setfperm', l:ps1_path, 'rwx------') + try + let o = s:maybe_execute('system', ['powershell.exe', '-NonInteractive', '-Command', '-'], readfile(l:ps1_path)) + catch /powershell.exe' is not executable/ + let l:failure = v:true + let l:msg = 'Error: Firenvim could not find powershell.exe' + " If the failure happened on wsl, try to use + " an absolute path + if s:is_wsl + let l:msg += ' from WSL' + try + let o = s:maybe_execute('system', ['/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe', '-Command', '-'], readfile(l:ps1_path)) + let l:failure = v:false + catch /powershell.exe' is not executable/ + let l:failure = v:true + endtry + endif + let l:msg += ' on your system. Please report this issue.' + if l:failure + echomsg 'Note: created ' . l:ps1_path . " . You may try to run it manually by right-clicking from your file browser to complete Firenvim's installation." + throw l:msg + endif + endtry + + if v:shell_error + echo o + endif + + echo 'Created registry key for ' . l:name . '.' + endif endif - call s:maybe_execute('mkdir', l:manifest_dir_path, 'p', 0700) - call s:maybe_execute('writefile', [l:manifest_content], l:manifest_path) - call s:maybe_execute('setfperm', l:manifest_path, 'rw-------') - - echo 'Installed native manifest for ' . l:name . '.' - - if has('win32') || s:is_wsl - " On windows, also create a registry key. We do this - " by writing a powershell script to a file and - " executing it. - let l:ps1_content = s:key_to_ps1_str(l:cur_browser['registry_key'], - \ l:manifest_path) - let l:ps1_path = s:build_path([l:manifest_dir_path, l:name . '.ps1']) - echo 'Creating registry key for ' . l:name . '. This may take a while. Script: ' . l:ps1_path - call s:maybe_execute('writefile', split(l:ps1_content, "\n"), l:ps1_path) - call s:maybe_execute('setfperm', l:ps1_path, 'rwx------') - try - let o = s:maybe_execute('system', ['powershell.exe', '-NonInteractive', '-Command', '-'], readfile(l:ps1_path)) - catch /powershell.exe' is not executable/ - let l:failure = v:true - let l:msg = 'Error: Firenvim could not find powershell.exe' - " If the failure happened on wsl, try to use - " an absolute path - if s:is_wsl - let l:msg += ' from WSL' - try - let o = s:maybe_execute('system', ['/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe', '-Command', '-'], readfile(l:ps1_path)) - let l:failure = v:false - catch /powershell.exe' is not executable/ - let l:failure = v:true - endtry - endif - let l:msg += ' on your system. Please report this issue.' - if l:failure - echomsg 'Note: created ' . l:ps1_path . " . You may try to run it manually by right-clicking from your file browser to complete Firenvim's installation." - throw l:msg - endif - endtry - - if v:shell_error - echo o - endif - - echo 'Created registry key for ' . l:name . '.' - endif endfor if !s:is_wsl @@ -951,6 +1000,18 @@ function! firenvim#uninstall() abort continue endif + let l:flatpak_result = s:browser_has_flatpak_installed(l:cur_browser) + if l:flatpak_result == 1 + let l:manifest_content = l:cur_browser['manifest_content'](l:execute_nvim_path) + let l:manifest_dir_path = l:cur_browser['manifest_dir_path'](1) + let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim.json']) + + call delete(l:manifest_path) + call delete(s:build_path([$HOME, '.var', 'app', l:cur_browser['flatpak_name'], 'config', 'nvim'])) + call delete(s:build_path([$HOME, '.var', 'app', l:cur_browser['flatpak_name'], 'data', 'nvim'])) + echo 'Removed flatpak manifest for ' . l:name . '.' + endif + let l:manifest_dir_path = l:cur_browser['manifest_dir_path']() let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim.json'])