-
-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle firefox flatpak installation #1597
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that most of the code in the 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 manifest for ' . l:name . '.'
if s:browser_has_flatpak_installed(l:cur_browser)
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"])])
endif
if has('win32') || s:is_wsl
... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That does actually make the most sense yes |
||
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']) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thinking: this effectively breaks flatpak's sandboxing. A compromised firefox will be able to append malicious code to the user's init.lua, which will be executed outside the sandbox the next time the user runs neovim from their terminal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only way around it would be to copy the directories instead of symlinking them, but then you'd have to re-run it any time your config changed or you updated a plugin.
I have pondered that perhaps this PR would be better as purely documentation rather than any changes the plugin makes, then the setup is up to the user.