Closed OsKaR31415 closed 1 month ago
Thanks for opening a new issue :)
Could you replace that last line with exec '/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim' --headless --cmd "let g:firenvim_config={'globalSettings':{},'localSettings':{'.*':{}}}" --cmd 'let g:started_by_firenvim = v:true' -c 'call firenvim#run()'
and then attempt running the script again with echo 'abcde{}' | ${XDG_DATA_HOME:-${HOME}/.local/share}/firenvim/firenvim
?
After replacing the last line with the one you gave, the script still outputs nothing : no error, no data.
Does /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim --version
work at all?
Does /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim --version work at all? It does, and returns :
NVIM v0.9.5 Build type: Release LuaJIT 2.1.1713773202
fichier vimrc système : "$VIM/sysinit.vim"
$VIM par défaut : "/opt/homebrew/Cellar/neovim/0.9.5/share/nvim
"
Run :checkhealth for more info
Okay, let's bring in the big guns then. Could you reset .local/share/firenvim/firenvim to how it was (either by undoing the changes I asked you to make or re-running call firenvim#install()
), then replace the file named firenvim.vim in your plugin installation directory with this one:
let s:firenvim_done = 0 let s:script_dir = expand(':p:h:h') function! firenvim#get_chan() abort if (exists('g:last_focused_firenvim_channel')) return g:last_focused_firenvim_channel endif let l:uis = filter(nvim_list_uis(), \ {i, ui -> nvim_get_chan_info(ui.chan).client.name ==? 'Firenvim'}) if len(l:uis) != 1 if len(l:uis) == 0 throw 'firenvim#focus_page(): No firenvim ui found!' endif throw 'firenvim#focus_page(): Too many UIs found!' endif return uis[0].chan endfunction function! firenvim#eval_js(js, ...) abort let callback_name = get(a:, 1, '') call rpcnotify(firenvim#get_chan(), 'firenvim_eval_js', a:js, callback_name) endfunction " Asks the browser extension to release focus from the frame and focus the " page instead function! firenvim#focus_input() abort call rpcnotify(firenvim#get_chan(), 'firenvim_focus_input') endfunction " Asks the browser extension to release focus from the frame and focus the " page instead function! firenvim#focus_page() abort call rpcnotify(firenvim#get_chan(), 'firenvim_focus_page') endfunction " Asks the browser extension to release focus from the frame and focus the " next page element, matching the behavior of pressing ` ` in the page. function! firenvim#focus_next() abort call rpcnotify(firenvim#get_chan(), 'firenvim_focus_next') endfunction " Asks the browser extension to release focus from the frame and focus the " next page element, matching the behavior of pressing ` ` in the page. function! firenvim#focus_prev() abort call rpcnotify(firenvim#get_chan(), 'firenvim_focus_prev') endfunction " Asks the browser extension to hide the firenvim frame function! firenvim#hide_frame() abort call rpcnotify(firenvim#get_chan(), 'firenvim_hide_frame') endfunction " Asks the browser extension to write to the text area. Either two or no " arguments. " 1st arg: list of strings to write, one string per line, empty strings for " empty lines " 2nd arg: position of the cursor function! firenvim#write(...) abort let l:text = '' let l:cursor = [0, 0] if a:0 == 0 let l:text = nvim_buf_get_lines(0, 0, -1, 0) let l:cursor = nvim_win_get_cursor(0) elseif a:0 == 2 let l:text = a:1 let l:cursor = a:2 if type(l:text) != v:t_list || (len(l:text) > 0 && type(l:text[0]) != v:t_string) throw "firenvim#write's first argument must be a list of strings" endif if type(l:text) != v:t_list \ || len(l:cursor) != 2 \ || type(l:cursor[0]) != v:t_number \ || type(l:cursor[1]) != v:t_number throw "firenvim#write's second argument must be a list of two numbers" endif else throw 'firenvim#write should be called either with 0 or 2 arguments' endif call rpcnotify(firenvim#get_chan(), 'firenvim_bufwrite', {'text': l:text, 'cursor': l:cursor}) endfunction " Asks the browser extension to send one or multiple key events to the " underlying input field. function! firenvim#press_keys(...) abort if a:0 < 1 throw 'firenvim#press_keys expects at least one argument' endif let l:keys = copy(a:000) if type(l:keys[0]) == type([]) if a:0 > 1 throw 'firenvim#press_keys expects a single list argument' endif let l:keys = l:keys[0] endif if len(filter(copy(l:keys), { key, value -> type(value) == type("") })) != len(l:keys) throw 'Key symbols must be strings.' endif call rpcnotify(firenvim#get_chan(), 'firenvim_press_keys', l:keys) endfunction " Turns a wsl path (forward slashes) into a windows one (backslashes) function! s:to_windows_path(path) abort if a:path[0] !=# '/' return a:path endif let l:path_components = split(a:path, '/') return join([toupper(l:path_components[1]) . ':'] + path_components[2:-1], '\') endfunction " Turns a windows path (backslashes) into a wsl one (forward slashes) function! s:to_wsl_path(path) abort if a:path[0] ==# '/' return a:path endif if executable('wslpath') try " 0:-2 because we need to remove the \r\n return system(['wslpath', '-a', '-u', a:path])[0:-2] catch endtry endif let l:path_components = split(a:path, '\\') return join(['/mnt', tolower(path_components[0][0:-2])] + l:path_components[1:-1], '/') endfunction " Simple helper to build the right path depending on the platform. function! s:build_path(list) abort let l:path_separator = '/' if has('win32') let l:path_separator = "\\" endif if s:is_wsl let a:list[0] = s:to_wsl_path(a:list[0]) endif return join(a:list, l:path_separator) endfunction " Retrieves a windows env var from wsl. Retrieves a windows path (with " backslashes!) function! s:get_windows_env_path(env) abort if has('win32') let l:env = a:env if l:env[0] ==# '%' let l:env = '$' . l:env[1:-2] endif return expand(l:env) endif if s:is_wsl let l:env = a:env if l:env[0] ==# '$' let l:env = '%' . l:env[1:-1] . '%' endif try let l:cmd_output = system(['cmd.exe', '/c', 'echo', l:env]) catch /E475:.*cmd.exe' is not executable/ try let l:cmd_output = system(['/mnt/c/Windows/System32/cmd.exe', '/c', 'echo', l:env]) catch /E475:.*cmd.exe' is not executable/ throw 'Error: Firenvim could not find cmd.exe from WSL on your system. Please report this issue.' endtry endtry return cmd_output[match(l:cmd_output, 'C:\\'):-3] endif throw 'Used get_windows_env_path on non-windows platform!' endfunction " Entry point of the vim-side of the extension. " This function does the following things: " - Get a security token from neovim's stdin " - Bind itself to a TCP port " - Write the security token + tcp port number to stdout() " - Take care of forwarding messages received on the TCP port to neovim function! firenvim#run() abort call writefile(["176"], "/tmp/firenvim.log", "a") " Write messages to stdout according to the format expected by " Firefox's native messaging protocol function! WriteStdout(id, data) abort call writefile(["180"], "/tmp/firenvim.log", "a") " The native messaging protocol expects the message's length " to precede the message. It has to use native endianness. We " assume big endian. let l:len = strlen(a:data) call writefile(["185"], "/tmp/firenvim.log", "a") let l:lenstr = luaeval('string.char(bit.band(' . l:len . ', 255))' \. '.. string.char(bit.band(bit.rshift(' . l:len . ', 8), 255))' \. '.. string.char(bit.band(bit.rshift(' . l:len . ', 16), 255))' \. '.. string.char(bit.band(bit.rshift(' . l:len . ', 24), 255))') call writefile(["190"], "/tmp/firenvim.log", "a") " https://github.com/neovim/neovim/pull/15211 " Neovim 0.6 breaking change. try call writefile(["194"], "/tmp/firenvim.log", "a") call chansend(a:id, [join(l:lenstr['_VAL']) . a:data]) call writefile(["196"], "/tmp/firenvim.log", "a") catch call writefile(["198"], "/tmp/firenvim.log", "a") call chansend(a:id, l:lenstr) call writefile(["200"], "/tmp/firenvim.log", "a") call chansend(a:id, a:data) call writefile(["202"], "/tmp/firenvim.log", "a") endtry call writefile(["204"], "/tmp/firenvim.log", "a") endfunction call writefile(["206"], "/tmp/firenvim.log", "a") let s:accumulated_data = '' call writefile(["208"], "/tmp/firenvim.log", "a") function! OnStdin(id, data, event) abort call writefile(["210"], "/tmp/firenvim.log", "a") " `:h channel-stdio`: empty a:data means FD closed? if a:data == [''] call writefile(["213"], "/tmp/firenvim.log", "a") qall! end call writefile(["216"], "/tmp/firenvim.log", "a") if s:firenvim_done call writefile(["218"], "/tmp/firenvim.log", "a") return endif call writefile(["221"], "/tmp/firenvim.log", "a") let l:data = s:accumulated_data . a:data[0] call writefile(["223"], "/tmp/firenvim.log", "a") try call writefile(["225"], "/tmp/firenvim.log", "a") let l:params = json_decode(matchstr(l:data[4:], '{[^}]*}')) call writefile(["227"], "/tmp/firenvim.log", "a") catch call writefile(["229"], "/tmp/firenvim.log", "a") let s:accumulated_data = l:data call writefile(["231"], "/tmp/firenvim.log", "a") return endtry call writefile(["234"], "/tmp/firenvim.log", "a") let s:firenvim_done = v:true call writefile(["236"], "/tmp/firenvim.log", "a") let l:package_json = s:build_path([s:script_dir, 'package.json']) call writefile(["239"], "/tmp/firenvim.log", "a") let l:version = json_decode(join(readfile(l:package_json), "\n"))['version'] call writefile(["241"], "/tmp/firenvim.log", "a") let l:result = { 'version': l:version } call writefile(["243"], "/tmp/firenvim.log", "a") if exists('g:firenvim_config') call writefile(["246"], "/tmp/firenvim.log", "a") let l:result['settings'] = g:firenvim_config call writefile(["248"], "/tmp/firenvim.log", "a") endif call writefile(["251"], "/tmp/firenvim.log", "a") if exists('g:firenvim_o') call writefile(["253"], "/tmp/firenvim.log", "a") let l:result['messages'] = g:firenvim_o call writefile(["255"], "/tmp/firenvim.log", "a") endif call writefile(["258"], "/tmp/firenvim.log", "a") if has_key(l:params, 'newInstance') && l:params['newInstance'] call writefile(["260"], "/tmp/firenvim.log", "a") let l:port = luaeval("require('firenvim').start_server('" . \ l:params['password'] . \ "')") call writefile(["264"], "/tmp/firenvim.log", "a") let l:result['port'] = l:port call writefile(["266"], "/tmp/firenvim.log", "a") endif let l:response = '' call writefile(["270"], "/tmp/firenvim.log", "a") try call writefile(["272"], "/tmp/firenvim.log", "a") let l:response = json_encode(result) call writefile(["274"], "/tmp/firenvim.log", "a") catch /E474/ call writefile(["276"], "/tmp/firenvim.log", "a") call remove(result, 'settings') call writefile(["278"], "/tmp/firenvim.log", "a") if !has_key(result, 'messages') call writefile(["280"], "/tmp/firenvim.log", "a") let result['messages'] = [] call writefile(["282"], "/tmp/firenvim.log", "a") endif call writefile(["284"], "/tmp/firenvim.log", "a") call add(result['messages'], 'Error serializing settings:' . v:exception) call writefile(["286"], "/tmp/firenvim.log", "a") let l:response = json_encode(result) call writefile(["288"], "/tmp/firenvim.log", "a") endtry call writefile(["290"], "/tmp/firenvim.log", "a") call WriteStdout(a:id, l:response) call writefile(["292"], "/tmp/firenvim.log", "a") endfunction " g:firenvim_c might not exist for firenvim installations dating back " to 2021 and earlier. " call writefile(["296"], "/tmp/firenvim.log", "a") if exists('g:firenvim_c') call writefile(["298"], "/tmp/firenvim.log", "a") for data in g:firenvim_i call writefile(["300"], "/tmp/firenvim.log", "a") call OnStdin(g:firenvim_c, data, 'stdin') call writefile(["302"], "/tmp/firenvim.log", "a") endfor call writefile(["304"], "/tmp/firenvim.log", "a") let g:Firenvim_oi = funcref('OnStdin') call writefile(["306"], "/tmp/firenvim.log", "a") else call writefile(["308"], "/tmp/firenvim.log", "a") let l:chanid = stdioopen({ 'on_stdin': 'OnStdin' }) call writefile(["310"], "/tmp/firenvim.log", "a") endif call writefile(["312"], "/tmp/firenvim.log", "a") endfunction " Wrapper function that executes funcname(...args) if a $DRY_RUN env variable " isn't defined and just echoes `funcname(...args)` if it is. function! s:maybe_execute(funcname, ...) abort let l:result = '' if !empty($DRY_RUN) echo a:funcname . '(' . string(a:000)[1:-2] . ')' else let l:result = call(a:funcname, a:000) end return l:result endfunction " Returns the name of the script that should be executed by the browser. function! s:get_executable_name() abort if has('win32') || s:is_wsl return 'firenvim.bat' endif return 'firenvim' endfunction " Returns the path of the directory in which firenvim will run when the " browser launches it. " On wsl, this is a path living on the linux side. function! s:get_runtime_dir_path() abort let l:xdg_runtime_dir = $XDG_RUNTIME_DIR if l:xdg_runtime_dir ==# '' if has('win32') || s:is_wsl let l:xdg_runtime_dir = s:get_windows_env_path('$TEMP') if l:xdg_runtime_dir ==# '' let l:xdg_runtime_dir = s:get_windows_env_path('$TMP') endif if l:xdg_runtime_dir ==# '' let l:xdg_runtime_dir = s:get_windows_env_path('$USERPROFILE') if l:xdg_runtime_dir ==# '' let l:xdg_runtime_dir = fnamemodify(stdpath('data'), ':h') else let l:xdg_runtime_dir = l:xdg_runtime_dir . '\AppData\Local\Temp' endif endif else let l:xdg_runtime_dir = $TMPDIR if l:xdg_runtime_dir ==# '' let l:xdg_runtime_dir = '/tmp/' endif endif endif return s:build_path([l:xdg_runtime_dir, 'firenvim']) endfunction " Returns the directory in which the firenvim script is written. function! s:get_data_dir_path() abort let l:xdg_data_home = $XDG_DATA_HOME if s:is_wsl let l:xdg_data_home = s:get_windows_env_path('%LOCALAPPDATA%') elseif l:xdg_data_home ==# '' let l:xdg_data_home = fnamemodify(stdpath('data'), ':h') endif return s:build_path([l:xdg_data_home, 'firenvim']) endfunction function! s:firefox_config_exists() abort let l:p = [$HOME, '.mozilla'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Mozilla'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Roaming', 'Mozilla', 'Firefox'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%APPDATA%'), 'Mozilla', 'Firefox'] endif return isdirectory(s:build_path(l:p)) 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']) endfunction function! s:librewolf_config_exists() abort let l:p = [$HOME, '.librewolf'] if has('win32') || s:is_wsl let l:p = [s:get_windows_env_path('%USERPROFILE%'), '.librewolf'] endif return isdirectory(s:build_path(l:p)) endfunction function! s:get_librewolf_manifest_dir_path() abort if has('win32') || s:is_wsl return s:get_data_dir_path() end return s:build_path([$HOME, '.librewolf', 'native-messaging-hosts']) endfunction function! s:arc_config_exists() abort let l:p = [$HOME, '.config', 'Arc'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Arc'] end return isdirectory(s:build_path(l:p)) endfunction function! s:brave_config_exists() abort let l:p = [$HOME, '.config', 'BraveSoftware'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'BraveSoftware'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'BraveSoftware'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'BraveSoftware'] elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'BraveSoftware'] end return isdirectory(s:build_path(l:p)) endfunction function! s:opera_config_exists() abort let l:p = [$HOME, '.config', 'opera'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'com.operasoftware.Opera'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'Opera Software'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'Opera Software'] elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'opera'] end return isdirectory(s:build_path(l:p)) endfunction function! s:vivaldi_config_exists() abort let l:p = [$HOME, '.config', 'vivaldi'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Vivaldi'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'Vivaldi'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'Vivaldi'] elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'vivaldi'] end return isdirectory(s:build_path(l:p)) endfunction function! s:chrome_config_exists() abort let l:p = [$HOME, '.config', 'google-chrome'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Google', 'Chrome'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'Google', 'Chrome'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'Google', 'Chrome'] elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'google-chrome'] end return isdirectory(s:build_path(l:p)) endfunction function! s:ungoogled_chromium_config_exists() abort let l:p = [$HOME, '.config', 'ungoogled-chromium'] if has('mac') " According to #1007, on macos, things work when using the " regular chrome dir. return v:false elseif has('win32') || s:is_wsl " Don't know what should be used here. Wait for somebody to " complain. return v:false elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'ungoogled-chromium'] end return isdirectory(s:build_path(l:p)) endfunction function! s:edge_config_exists() abort let l:p = [$HOME, '.config', 'microsoft-edge'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Microsoft', 'Edge'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'Microsoft', 'Edge'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'Microsoft', 'Edge'] elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'microsoft-edge'] end return isdirectory(s:build_path(l:p)) endfunction function! s:chrome_dev_config_exists() abort let l:p = [$HOME, '.config', 'google-chrome-unstable'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Google', 'Chrome Dev'] elseif !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'google-chrome-unstable'] end return isdirectory(s:build_path(l:p)) endfunction function! s:get_chrome_manifest_dir_path() abort if has('mac') return s:build_path([$HOME, 'Library', 'Application Support', 'Google', 'Chrome', 'NativeMessagingHosts']) elseif has('win32') || s:is_wsl return s:get_data_dir_path() end if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'google-chrome', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'google-chrome', 'NativeMessagingHosts']) endfunction function! s:get_vivaldi_manifest_dir_path() abort if has('mac') return s:get_chrome_manifest_dir_path() elseif has('win32') || s:is_wsl return s:get_chrome_manifest_dir_path() end " https://github.com/glacambre/firenvim/issues/1433 if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'vivaldi', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'vivaldi', 'NativeMessagingHosts']) endfunction function! s:get_ungoogled_chromium_manifest_dir_path() abort if has('mac') || has('win32') || s:is_wsl throw "Ungoogled chromium isn't supported. Please open an issue to add support." end if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'ungoogled-chromium', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'ungoogled-chromium', 'NativeMessagingHosts']) endfunction function! s:get_edge_manifest_dir_path() abort if has('mac') return s:build_path([$HOME, 'Library', 'Application Support', 'Microsoft', 'Edge', 'NativeMessagingHosts']) elseif has('win32') || s:is_wsl return s:get_data_dir_path() end if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'microsoft-edge', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'microsoft-edge', 'NativeMessagingHosts']) endfunction function! s:get_chrome_dev_manifest_dir_path() abort if has('mac') return s:build_path([$HOME, 'Library', 'Application Support', 'Google', 'Chrome Dev', 'NativeMessagingHosts']) elseif has('win32') || s:is_wsl throw 'No chrome dev on win32.' end if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'google-chrome-unstable', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'google-chrome-unstable', 'NativeMessagingHosts']) endfunction function! s:get_brave_manifest_dir_path() abort if has('mac') return s:get_chrome_manifest_dir_path() elseif has('win32') || s:is_wsl return s:get_chrome_manifest_dir_path() end if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'BraveSoftware', 'Brave-Browser', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'BraveSoftware', 'Brave-Browser', 'NativeMessagingHosts']) endfunction function! s:canary_config_exists() abort if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Google', 'Chrome Canary'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'Google', 'Chrome SxS'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'Google', 'Chrome SxS'] else " Chrome canary doesn't exist on linux return v:false end return isdirectory(s:build_path(l:p)) endfunction function! s:get_canary_manifest_dir_path() abort if has('mac') return s:build_path([$HOME, 'Library', 'Application Support', 'Google', 'Chrome Canary', 'NativeMessagingHosts']) elseif has('win32') || s:is_wsl return s:get_data_dir_path() end throw "Chrome Canary doesn't exist on Linux" endfunction function! s:chromium_config_exists() abort let l:p = [$HOME, '.config', 'chromium'] if has('mac') let l:p = [$HOME, 'Library', 'Application Support', 'Chromium'] elseif has('win32') let l:p = [$HOME, 'AppData', 'Local', 'Chromium'] elseif s:is_wsl let l:p = [s:get_windows_env_path('%LOCALAPPDATA%'), 'Chromium'] end if !empty($XDG_CONFIG_HOME) let l:p = [$XDG_CONFIG_HOME, 'chromium', 'NativeMessagingHosts'] end return isdirectory(s:build_path(l:p)) endfunction function! s:get_chromium_manifest_dir_path() abort if has('mac') return s:build_path([$HOME, 'Library', 'Application Support', 'Chromium', 'NativeMessagingHosts']) elseif has('win32') || s:is_wsl return s:get_data_dir_path() end if !empty($XDG_CONFIG_HOME) return s:build_path([$XDG_CONFIG_HOME, 'chromium', 'NativeMessagingHosts']) end return s:build_path([$HOME, '.config', 'chromium', 'NativeMessagingHosts']) endfunction function! s:get_progpath() abort let l:result = v:progpath if $APPIMAGE !=# '' " v:progpath is different every time you run neovim appimages let l:result = $APPIMAGE endif " Some package managers will install neovim in a version-specific path " that v:progpath will point to. This is an issue because the path may " break when neovim is updated. Try to detect these cases, work around " them if possible and warn the user. let l:specific_installs = { \ 'homebrew': { \ 'pattern': '^/usr/local/Cellar/', \ 'constant_paths': ['/usr/local/opt/nvim'] \ }, \ 'nix': { \ 'pattern': '^/nix/store/', \ 'constant_paths': [ \ expand('$HOME/.nix-profile/bin/nvim'), \ expand('/etc/profiles/per-user/$USER/bin/nvim'), \ '/run/current-system/sw/bin/nvim' \ ] \ } \ } for l:package_manager in keys(l:specific_installs) let l:install = l:specific_installs[l:package_manager] if match(l:result, l:install['pattern']) == 0 let l:warning = 'Warning: ' . l:package_manager . ' path detected. ' let l:alternative_found = v:false for l:constant_path in l:install['constant_paths'] if executable(l:constant_path) let l:warning = l:warning . \ "Using '" . l:constant_path . "'" . \ "' instead of '" . l:result . "'" let l:result = l:constant_path let l:alternative_found = v:true break endif endfor if !l:alternative_found let l:warning = l:warning . \ 'Firenvim may break next time you update neovim.' endif echo l:warning endif endfor return l:result endfunction function! s:capture_env_var(var) abort let l:value = eval('$' . a:var) if l:value ==? '' return '' endif return 'if [ ! -n "$' . a:var . '" ]; then' . "\n" . \' ' . a:var . "='" . l:value . "'\n" . \' export ' . a:var . "\n" . \"fi\n" endfunction function! s:get_executable_content(data_dir, prolog) abort let l:stdioopen = '' if api_info().version.major > 0 || api_info().version.minor > 6 let l:stdioopen = '--cmd "' . \"let g:firenvim_config={'globalSettings':{},'localSettings':{'.*':{}}}|" . \'let g:firenvim_i=[]|' . \'let g:firenvim_o=[]|' . \'let g:Firenvim_oi={i,d,e->add(g:firenvim_i,d)}|' . \'let g:Firenvim_oo={t->[chansend(2,t)]+add(g:firenvim_o,t)}|' . \"let g:firenvim_c=stdioopen({'on_stdin':{i,d,e->g:Firenvim_oi(i,d,e)},'on_print':{t->g:Firenvim_oo(t)}})". \'"' endif if s:is_wsl " Get path of firenvim script on the linux side, execute that " from the windows batch script let s:is_wsl = v:false let l:script_path = s:get_firenvim_script_path() let s:is_wsl = v:true return "@echo off\r\nwsl \"" . l:script_path . '"' endif if has('win32') || s:is_wsl let l:wsl_prefix = '' if s:is_wsl let l:wsl_prefix = 'wsl' endif let l:dir = s:to_windows_path(a:data_dir) return "@echo off\r\n" . \ "mkdir \"" . l:dir . "\" 2>nul\r\n" . \ "cd \"" . l:dir . "\"\r\n" . \ a:prolog . "\r\n" . \ l:wsl_prefix . ' "' . s:get_progpath() . '" --headless ' . l:stdioopen . ' --cmd "let g:started_by_firenvim = v:true" -c "call firenvim#run()"' . "\r\n" endif return "#!/bin/sh\n" . \ 'mkdir -p ' . a:data_dir . "\n" . \ 'chmod 700 ' . a:data_dir . "\n" . \ 'cd ' . a:data_dir . "\n" . \ 'export PATH="$PATH:' . $PATH . "\"\n" . \ "unset NVIM_LISTEN_ADDRESS\n" . \ 'if [ -n "$VIM" ] && [ ! -d "$VIM" ]; then' . "\n" . \ " unset VIM\n" . \ "fi\n" . \ 'if [ -n "$VIMRUNTIME" ] && [ ! -d "$VIMRUNTIME" ]; then' . "\n" . \ " unset VIMRUNTIME\n" . \ "fi\n" . \ s:capture_env_var('XDG_DATA_HOME') . \ s:capture_env_var('XDG_CONFIG_HOME') . \ s:capture_env_var('XDG_STATE_HOME') . \ s:capture_env_var('XDG_DATA_DIRS') . \ s:capture_env_var('XDG_CONFIG_DIRS') . \ s:capture_env_var('XDG_CACHE_HOME') . \ s:capture_env_var('XDG_RUNTIME_DIR') . \ s:capture_env_var('NVIM_APPNAME') . \ a:prolog . "\n" . \ "exec '" . s:get_progpath() . \ "' --headless " . l:stdioopen . \ " --cmd 'let g:started_by_firenvim = v:true' " . \ "-c 'try|" . \ 'call firenvim#run()|' . \ 'catch /Unknown function/|' . \ "call chansend(g:firenvim_c,[\"f\\n\\n\\n\"..json_encode({\"messages\":[\"Your plugin manager did not load the Firenvim plugin for neovim.\"],\"version\":\"0.0.0\"})])|" . \ "call chansend(2,[\"Firenvim not in runtime path. &rtp=\"..&rtp])|" . \ 'qall!|' . \ 'catch|' . \ "call chansend(g:firenvim_c,[\"l\\n\\n\\n\"..json_encode({\"messages\": [\"Something went wrong when running firenvim. See troubleshooting guide.\"],\"version\":\"0.0.0\"})])|" . \ 'call chansend(2,[v:exception])|' . \ 'qall!|' . \ "endtry'\n" endfunction function! s:get_manifest_beginning(execute_nvim_path) abort return '{ \ "name": "firenvim", \ "description": "Turn your browser into a Neovim GUI.", \ "path": "' . substitute(a:execute_nvim_path, '\', '\\\\', 'g') . '", \ "type": "stdio", \' endfunction function! s:get_chrome_manifest(execute_nvim_path) abort return s:get_manifest_beginning(a:execute_nvim_path) . \' "allowed_origins": [ \ "chrome-extension://egpjdkipkomnmjhjmdamaniclmdlobbo/" \ ] \}' endfunction function! s:get_firefox_manifest(execute_nvim_path) abort return s:get_manifest_beginning(a:execute_nvim_path) . \' "allowed_extensions": ["firenvim@lacamb.re"] \}' endfunction function! s:key_to_ps1_str(key, manifest_path) abort let l:ps1_content = '' let l:key_arr = split(a:key, '\') let l:i = 0 for l:i in range(2, len(l:key_arr) - 1) let l:ps1_content = l:ps1_content . "\nNew-Item -Path \"" . join(key_arr[0:i], '\') . '"' endfor " Then, assign a value to it return l:ps1_content . "\nSet-Item -Path \"" . \ a:key . \ '\" -Value "' . s:to_windows_path(a:manifest_path) . '"' endfunction function! s:get_browser_configuration() abort " Brave, Opera and Vivaldi all rely on Chrome's native messenger let l:browsers = { \'arc': { \ 'has_config': s:arc_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_chrome_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \}, \'brave': { \ 'has_config': s:brave_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_brave_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \}, \'chrome': { \ 'has_config': s:chrome_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_chrome_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \}, \'chrome-canary': { \ 'has_config': s:canary_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_canary_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \}, \'chrome-dev': { \ 'has_config': s:chrome_dev_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_chrome_dev_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \}, \'chromium': { \ 'has_config': s:chromium_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_chromium_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Chromium\NativeMessagingHosts\firenvim', \}, \'edge': { \ 'has_config': s:edge_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_edge_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Microsoft\Edge\NativeMessagingHosts\firenvim', \}, \'firefox': { \ 'has_config': s:firefox_config_exists(), \ 'manifest_content': function('s:get_firefox_manifest'), \ 'manifest_dir_path': function('s:get_firefox_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Mozilla\NativeMessagingHosts\firenvim', \}, \'librewolf': { \ 'has_config': s:librewolf_config_exists(), \ 'manifest_content': function('s:get_firefox_manifest'), \ 'manifest_dir_path': function('s:get_librewolf_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\LibreWolf\NativeMessagingHosts\firenvim', \}, \'opera': { \ 'has_config': s:opera_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_chrome_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \}, \'ungoogled-chromium': { \ 'has_config': s:ungoogled_chromium_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_ungoogled_chromium_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Chromium\NativeMessagingHosts\firenvim', \}, \'vivaldi': { \ 'has_config': s:vivaldi_config_exists(), \ 'manifest_content': function('s:get_chrome_manifest'), \ 'manifest_dir_path': function('s:get_vivaldi_manifest_dir_path'), \ 'registry_key': 'HKCU:\Software\Google\Chrome\NativeMessagingHosts\firenvim', \} \} if $TESTING == 1 call remove(l:browsers, 'librewolf') call remove(l:browsers, 'brave') call remove(l:browsers, 'chrome-dev') call remove(l:browsers, 'opera') call remove(l:browsers, 'ungoogled-chromium') call remove(l:browsers, 'vivaldi') endif return l:browsers endfunction function! s:get_firenvim_script_path() abort return s:build_path([s:get_data_dir_path(), s:get_executable_name()]) endfunction " At first, is_wsl is set to false, even on WSL. This lets us install firenvim " on the wsl side, in case people want to use a wsl browser. " Then, we set is_wsl to true if we're on wsl and launch firenvim#install " again, installing things on the host side. let s:is_wsl = v:false " Installing firenvim requires several steps: " - Create a batch/shell script that takes care of starting neovim with the " right arguments. This is needed because the webextension api doesn't let " users specify what arguments programs should be started with " - Create a manifest file that lets the browser know where the script created " can be found " - On windows, also create a registry key that points to the native manifest " " Manifest paths & registry stuff are specified here: " https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#Manifest_location " " firenvim#install accepts the following optional arguments: " a:1: 0 to let firenvim detect what browsers the user wants to use or 1 to " force install for every browser. " a:2: A prologue that should be inserted in the shell/batch script and " executed before neovim is ran. function! firenvim#install(...) abort if !has('nvim-0.6.0') echoerr 'Error: nvim version >= 0.6.0 required. Aborting.' return endif try lua require("bit") catch echoerr 'Error: Lua package "bit" unavailable. Install it or switch to LuaJIT.' return endtry let l:force_install = 0 let l:script_prolog = '' if a:0 > 0 let l:force_install = a:1 if a:0 > 1 let l:script_prolog = a:2 endif endif let l:execute_nvim_path = s:get_firenvim_script_path() let l:execute_nvim = s:get_executable_content(s:get_runtime_dir_path(), l:script_prolog) call s:maybe_execute('mkdir', s:get_data_dir_path(), 'p', 0700) if s:is_wsl let l:execute_nvim_path = s:to_wsl_path(l:execute_nvim_path) endif call s:maybe_execute('writefile', split(l:execute_nvim, "\n"), l:execute_nvim_path) if s:is_wsl let l:execute_nvim_path = s:to_windows_path(l:execute_nvim_path) endif call s:maybe_execute('setfperm', l:execute_nvim_path, 'rwx------') let l:browsers = s:get_browser_configuration() let l:powershell_script = '' for l:name in keys(l:browsers) let l:cur_browser = l:browsers[l:name] if !l:cur_browser['has_config'] && !l:force_install echo 'No config detected for ' . l:name . '. Skipping.' 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']) 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 let s:is_wsl = has('wsl') || !empty($WSL_DISTRO_NAME) || !empty ($WSL_INTEROP) if s:is_wsl echo 'Installation complete on the wsl side. Performing install on the windows side.' call firenvim#install(l:force_install, l:script_prolog) endif endif if luaeval('lvim~=nil') echo 'WARNING: Lunarvim is not supported. Do not open issues if you use Lunarvim.' endif endfunction " Removes files created by Firenvim during its installation process " The uninstallation logic is similar to `firenvim#install`: " > At first, is_wsl is set to false, even on WSL. This lets us uninstall " firenvim on the wsl side. " > Then, we set is_wsl to true if we're on wsl and launch " firenvim#uninstall again, uninstalling things on the host side. function! firenvim#uninstall() abort let l:data_dir = s:get_data_dir_path() call delete(l:data_dir, 'rf') echo 'Removed firenvim data directory.' let l:browsers = s:get_browser_configuration() for l:name in keys(l:browsers) let l:cur_browser = l:browsers[l:name] if !l:cur_browser['has_config'] continue 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']) if has('win32') let l:manifest_path = s:build_path([l:manifest_dir_path, 'firenvim-' . l:name . '.json']) endif if has('win32') || s:is_wsl echo 'Removing registry key for ' . l:name . '. This may take a while.' let l:ps1_content = 'Remove-Item -Path "' . l:cur_browser['registry_key'] . '" -Recurse' let o = system(['powershell.exe', '-NonInteractive', '-Command', '-'], [l:ps1_content]) if v:shell_error echo o endif echo 'Removed registry key for ' . l:name . '.' endif call delete(l:manifest_path) echo 'Removed native manifest for ' . l:name . '.' endfor if !s:is_wsl let s:is_wsl = has('wsl') || !empty($WSL_DISTRO_NAME) || !empty ($WSL_INTEROP) if s:is_wsl echo 'Uninstallation complete on the wsl side. Performing uninstall on the windows side.' call firenvim#uninstall() endif endif endfunction function! firenvim#onUIEnter(event) abort let l:ui = nvim_get_chan_info(a:event.chan) if has_key(l:ui, 'client') && has_key(l:ui.client, 'name') && \ l:ui.client.name =~? 'Firenvim' call map(nvim_list_bufs(), {key, val -> firenvimft#detect(val)}) augroup FirenvimFtdetectAugroup autocmd! autocmd BufRead,BufNewFile *.txt call firenvimft#detect(str2nr(expand(' '))) augroup END endif endfunction
And then run echo "abcde{}" | ~/.local/share/firenvim/firenvim
from your shell? This should create a file named /tmp/firenvim.log
whose contents I would need you to upload here.
Does /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim --version work at all?
It does and returns this :
NVIM v0.9.5
Build type: Release
LuaJIT 2.1.1713773202
fichier vimrc système : "$VIM/sysinit.vim"
$VIM par défaut : "/opt/homebrew/Cellar/neovim/0.9.5/share/nvim
"
Run :checkhealth for more info
run
echo "abcde{}" | ~/.local/share/firenvim/firenvim
from your shell? This should create a file named /tmp/firenvim.log whose contents I would need you to upload here.
After executing call firenvim#install()
and copying your version of firenvim.vim
, running echo "abcde{}" | ~/.local/share/firenvim/firenvim
returns nothing, and the /tmp/firenvim.log
file isn't created.
Okay, so for some reason neovim seems to work but there's no input/output from it... What does /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim --headless -c 'call stdioopen({})| call chansend(1, [string(exists("g:firenvim_loaded"))]) | qall!'
print?
What does /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim --headless -c 'call stdioopen({})| call chansend(1, [string(exists("g:firenvim_loaded"))]) | qall!' print?
It prints 1
without any line break.
So now we know that the plugin is loaded and that firenvim is able to write to stdout with stdioopen/chansend, that's good... But why isn't it writing to stdout???
At this point I'm running out of ideas. Let's start with a clean set up that doesn't have anything. Please run this script:
rm -rf "${XDG_DATA_HOME:-${HOME}/.local/share}/firenvim/"
DIR=~/.config/nvim
mv "$DIR" "$DIR.bak"
mkdir "$DIR"
git clone "https://github.com/glacambre/firenvim" "$DIR/firenivm"
echo "set rtp+=$DIR/firenvim" > $DIR/init.vim
/opt/homebrew/Cellar/neovim/0.9.5/bin/nvim --headless "+call firenvim#install(0) | q"
And then run echo 'abcde{}' | "${XDG_DATA_HOME:-${HOME}/.local/share}/firenvim/firenvim"
. Let's hope this prints something because I don't know what else we can try...
The script executes fine except that neovim doesn't know the firenvim#install(0)
function.
I investigated a bit, and it happends that my default nvim
is /opt/homebrew/nvim
, and not /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim
. The second one must be the one used by firenvim, and doesn't have any plugin loaded or anything : when it starts, it's just vanilla neovim.
So the problem is that firenvim is not using the right neovim.
This doesn't make sense to me - regardless of whether you're using /opt/homebrew/nvim
or /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim
, the same config, and so same set of plugins should be loaded, and so the behavior of nvim -c 'call firenvim#run()'
should be the same (firenvim's only version requirement nvim>0.7.0).
What are /opt/homebrew/nvim
and /opt/homebrew/Cellar/neovim/0.9.5/bin/nvim
? Are they scripts or binaries?
So the problem is that firenvim is not using the right neovim.
Ah, yes, it seems that the existing kludge to deal with homebrew is not sufficient because yours is installed in /opt
and not /usr
:
https://github.com/glacambre/firenvim/blob/cf4ff99033640b5ec33890bcdc892ddc436ed8e5/autoload/firenvim.vim#L583-L591
I'll implement a fix.
@OsKaR31415 I think I fixed the problem with #1617 - could you update your firenvim neovim plugin, run firenvim#install()
again and let me know if everything works as expected?
What happens
Firenvim is not starting. When clicking on the addon button, The error message is :
Debugging
I tried running
echo 'abcde{}' | .local/share/firenvim/firenvim
, and it runs with no error but also no output.Here is the content of my
.local/share/firenvim/firenvim
: