Mercurial > vim
view runtime/pack/dist/opt/editexisting/plugin/editexisting.vim @ 33090:461541d860ac v9.0.1830
patch 9.0.1830: Vim9: crash when accessing a null object
Commit: https://github.com/vim/vim/commit/d7085a06358c22250a27186bb7d52112ed4addd1
Author: Gianmaria Bajo <mg1979.git@gmail.com>
Date: Thu Aug 31 18:15:26 2023 +0200
patch 9.0.1830: Vim9: crash when accessing a null object
Problem: Vim9: crash when accessing a null object
Solution: Check accessing a NULL object in def function
An object is NULL when the variable is declared, but the constructor
isn't called. Accessing/setting a member on the object crashed Vim.
Note: this happens inside def functions, at script level things work
differently. Accessing a NULL object member results in E1360
(correctly), while setting a value on it results in E1012 (type
mismatch) so there's still something to fix.
closes: #12973
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Gianmaria Bajo <mg1979.git@gmail.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 31 Aug 2023 18:30:03 +0200 |
parents | 75c283beb74f |
children |
line wrap: on
line source
" Vim Plugin: Edit the file with an existing Vim if possible " Maintainer: The Vim Project <https://github.com/vim/vim> " Last Change: 2023 Aug 13 " To use add ":packadd! editexisting" in your vimrc file. " This plugin serves two purposes: " 1. On startup, if we were invoked with one file name argument and the file " is not modified then try to find another Vim instance that is editing " this file. If there is one then bring it to the foreground and exit. " 2. When a file is edited and a swap file exists for it, try finding that " other Vim and bring it to the foreground. Requires Vim 7, because it " uses the SwapExists autocommand event. " Function that finds the Vim instance that is editing "filename" and brings " it to the foreground. func s:EditElsewhere(filename) let fname_esc = substitute(a:filename, "'", "''", "g") let servers = serverlist() while servers != '' " Get next server name in "servername"; remove it from "servers". let i = match(servers, "\n") if i == -1 let servername = servers let servers = '' else let servername = strpart(servers, 0, i) let servers = strpart(servers, i + 1) endif " Skip ourselves. if servername ==? v:servername continue endif " Check if this server is editing our file. try if remote_expr(servername, "bufloaded('" . fname_esc . "')") " Yes, bring it to the foreground. if has("win32") call remote_foreground(servername) endif call remote_expr(servername, "foreground()") if remote_expr(servername, "exists('*EditExisting')") " Make sure the file is visible in a window (not hidden). " If v:swapcommand exists and is set, send it to the server. if exists("v:swapcommand") let c = substitute(v:swapcommand, "'", "''", "g") call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')") else call remote_expr(servername, "EditExisting('" . fname_esc . "', '')") endif endif if !(has('vim_starting') && has('gui_running') && has('gui_win32')) " Tell the user what is happening. Not when the GUI is starting " though, it would result in a message box. echomsg "File is being edited by " . servername sleep 2 endif return 'q' endif catch /^Vim\%((\a\+)\)\=:E241:/ " Unable to send to this server, ignore it. endtry endwhile return '' endfunc " When the plugin is loaded and there is one file name argument: Find another " Vim server that is editing this file right now. if argc() == 1 && !&modified if s:EditElsewhere(expand("%:p")) == 'q' quit endif endif " Setup for handling the situation that an existing swap file is found. try au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p")) catch " Without SwapExists we don't do anything for ":edit" commands endtry " Function used on the server to make the file visible and possibly execute a " command. func! EditExisting(fname, command) " Get the window number of the file in the current tab page. let winnr = bufwinnr(a:fname) if winnr <= 0 " Not found, look in other tab pages. let bufnr = bufnr(a:fname) for i in range(tabpagenr('$')) if index(tabpagebuflist(i + 1), bufnr) >= 0 " Make this tab page the current one and find the window number. exe 'tabnext ' . (i + 1) let winnr = bufwinnr(a:fname) break endif endfor endif if winnr > 0 exe winnr . "wincmd w" elseif exists('*fnameescape') exe "split " . fnameescape(a:fname) else exe "split " . escape(a:fname, " \t\n*?[{`$\\%#'\"|!<") endif if a:command != '' exe "normal! " . a:command endif redraw endfunc