terminal: absolute CWD in term:// URI #11289

This makes it possible to restore the working directory of :terminal
buffers when reading those buffers from a session file.

Fixes #11288

Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
This commit is contained in:
Chris LaRose 2020-01-26 00:24:42 -08:00 committed by Justin M. Keyes
parent 451af7f087
commit c6ff23d7a0
6 changed files with 42 additions and 11 deletions

View File

@ -321,7 +321,7 @@ function vim.trim(s)
return s:match('^%s*(.*%S)') or ''
end
--- Escapes magic chars in a Lua pattern string.
--- Escapes magic chars in a Lua pattern.
---
--@see https://github.com/rxi/lume
--@param s String to escape

View File

@ -234,7 +234,8 @@ get_vimpatch() {
msg_ok "Saved patch to '${NVIM_SOURCE_DIR}/${patch_file}'."
}
# shellcheck disable=SC2015 # "Note that A && B || C is not if-then-else."
# shellcheck disable=SC2015
# ^ "Note that A && B || C is not if-then-else."
stage_patch() {
get_vimpatch "$1"
local try_apply="${2:-}"
@ -305,7 +306,8 @@ git_hub_pr() {
git hub pull new -m "$1"
}
# shellcheck disable=SC2015 # "Note that A && B || C is not if-then-else."
# shellcheck disable=SC2015
# ^ "Note that A && B || C is not if-then-else."
submit_pr() {
require_executable git
local push_first

View File

@ -18383,13 +18383,17 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
int pid = chan->stream.pty.process.pid;
char buf[1024];
// format the title with the pid to conform with the term:// URI
snprintf(buf, sizeof(buf), "term://%s//%d:%s", cwd, pid, cmd);
// "./…" => "/home/foo/…"
vim_FullName(cwd, (char *)NameBuff, sizeof(NameBuff), false);
// "/home/foo/…" => "~/…"
home_replace(NULL, NameBuff, IObuff, sizeof(IObuff), true);
// Terminal URI: "term://$CWD//$PID:$CMD"
snprintf((char *)NameBuff, sizeof(NameBuff), "term://%s//%d:%s",
(char *)IObuff, pid, cmd);
// at this point the buffer has no terminal instance associated yet, so unset
// the 'swapfile' option to ensure no swap file will be created
curbuf->b_p_swf = false;
(void)setfname(curbuf, (char_u *)buf, NULL, true);
(void)setfname(curbuf, NameBuff, NULL, true);
// Save the job id and pid in b:terminal_job_{id,pid}
Error err = ERROR_INIT;
// deprecated: use 'channel' buffer option

View File

@ -339,8 +339,8 @@ int main(int argc, char **argv)
"matchstr(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
// capture the working directory
"{'cwd': get(matchlist(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})"
"{'cwd': expand(get(matchlist(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, ''))})"
"|endif");
do_cmdline_cmd("augroup END");
#undef PROTO

View File

@ -6,6 +6,8 @@ local command = helpers.command
local get_pathsep = helpers.get_pathsep
local eq = helpers.eq
local funcs = helpers.funcs
local matches = helpers.matches
local pesc = helpers.pesc
local rmdir = helpers.rmdir
local file_prefix = 'Xtest-functional-ex_cmds-mksession_spec'
@ -48,7 +50,7 @@ describe(':mksession', function()
eq(cwd_dir .. get_pathsep() .. tab_dir, funcs.getcwd())
end)
it('restores buffers when using tab-local working directories', function()
it('restores buffers with tab-local CWD', function()
local tmpfile_base = file_prefix .. '-tmpfile'
local cwd_dir = funcs.getcwd()
local session_path = cwd_dir .. get_pathsep() .. session_file
@ -70,4 +72,23 @@ describe(':mksession', function()
command('tabnext 2')
eq(cwd_dir .. get_pathsep() .. tmpfile_base .. '2', funcs.expand('%:p'))
end)
it('restores CWD for :terminal buffers #11288', function()
local cwd_dir = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
local session_path = cwd_dir..get_pathsep()..session_file
command('cd '..tab_dir)
command('terminal echo $PWD')
command('cd '..cwd_dir)
command('mksession '..session_path)
command('qall!')
-- Create a new test instance of Nvim.
clear()
command('silent source '..session_path)
local expected_cwd = cwd_dir..get_pathsep()..tab_dir
matches('^term://'..pesc(expected_cwd)..'//%d+:', funcs.expand('%'))
command('qall!')
end)
end)

View File

@ -5,9 +5,12 @@ local curbufmeths = helpers.curbufmeths
local curwinmeths = helpers.curwinmeths
local nvim_dir = helpers.nvim_dir
local command = helpers.command
local funcs = helpers.funcs
local meths = helpers.meths
local clear = helpers.clear
local eq = helpers.eq
local matches = helpers.matches
local pesc = helpers.pesc
describe(':edit term://*', function()
local get_screen = function(columns, lines)
@ -28,7 +31,8 @@ describe(':edit term://*', function()
command('edit term://')
local termopen_runs = meths.get_var('termopen_runs')
eq(1, #termopen_runs)
eq(termopen_runs[1], termopen_runs[1]:match('^term://.//%d+:$'))
local cwd = funcs.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
matches('^term://'..pesc(cwd)..'//%d+:$', termopen_runs[1])
end)
it("runs TermOpen early enough to set buffer-local 'scrollback'", function()