mirror of
https://github.com/neovim/neovim.git
synced 2025-10-17 07:16:09 +00:00
terminal: New module that implements a terminal emulator
This commit integrates libvterm with Neovim and implements a terminal emulator with nvim buffers as the display mechanism. Terminal buffers can be created using any of the following methods: - Opening a file with name following the "term://[${cwd}//[${pid}:]]${cmd}" URI pattern where: - cwd is the working directory of the process - pid is the process id. This is just for use in session files where a pid would have been assigned to the saved buffer title. - cmd is the command to run - Invoking the `:terminal` ex command - Invoking the `termopen` function which returns a job id for automating the terminal window. Some extra changes were also implemented to adapt with terminal buffers. Here's an overview: - The `main` function now sets a BufReadCmd autocmd to intercept the term:// URI and spawn the terminal buffer instead of reading the file. - terminal buffers behave as if the following local buffer options were set: - `nomodifiable` - `swapfile` - `undolevels=-1` - `bufhidden=hide` - All commands that delete buffers(`:bun`, `:bd` and `:bw`) behave the same for terminal buffers, but only work when bang is passed(eg: `:bwipeout!`) - A new "terminal" mode was added. A consequence is that a new set of mapping commands were implemented with the "t" prefix(tmap, tunmap, tnoremap...) - The `edit` function(which enters insert mode) will actually enter terminal mode if the current buffer is a terminal - The `put` operator was adapted to send data to the terminal instead of modifying the buffer directly. - A window being resized will also trigger a terminal resize if the window displays the terminal.
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/syntax.h"
|
||||
#include "nvim/terminal.h"
|
||||
#include "nvim/undo.h"
|
||||
#include "nvim/os/os.h"
|
||||
|
||||
@@ -1765,6 +1766,12 @@ static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_c
|
||||
}
|
||||
buf_T *old_curbuf = curbuf;
|
||||
|
||||
Terminal *term = win->w_buffer->terminal;
|
||||
if (term) {
|
||||
// Don't free terminal buffers
|
||||
free_buf = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Closing the last window in a tab page. First go to another tab
|
||||
* page and then close the window and the tab page. This avoids that
|
||||
@@ -1789,6 +1796,13 @@ static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_c
|
||||
if (h != tabline_height())
|
||||
shell_new_rows();
|
||||
}
|
||||
|
||||
if (term) {
|
||||
// When a window containing a terminal buffer is closed, recalculate its
|
||||
// size
|
||||
terminal_resize(term, 0, 0);
|
||||
}
|
||||
|
||||
/* Since goto_tabpage_tp above did not trigger *Enter autocommands, do
|
||||
* that now. */
|
||||
apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, FALSE, curbuf);
|
||||
@@ -1907,6 +1921,8 @@ int win_close(win_T *win, int free_buf)
|
||||
|| close_last_window_tabpage(win, free_buf, prev_curtab))
|
||||
return FAIL;
|
||||
|
||||
// let terminal buffers know that this window dimensions may be ignored
|
||||
win->w_closing = true;
|
||||
/* Free the memory used for the window and get the window that received
|
||||
* the screen space. */
|
||||
wp = win_free_mem(win, &dir, NULL);
|
||||
@@ -1963,7 +1979,6 @@ int win_close(win_T *win, int free_buf)
|
||||
if (help_window)
|
||||
restore_snapshot(SNAP_HELP_IDX, close_curwin);
|
||||
|
||||
|
||||
redraw_all_later(NOT_VALID);
|
||||
return OK;
|
||||
}
|
||||
@@ -4689,6 +4704,11 @@ void win_new_height(win_T *wp, int height)
|
||||
redraw_win_later(wp, SOME_VALID);
|
||||
wp->w_redr_status = TRUE;
|
||||
invalidate_botline_win(wp);
|
||||
|
||||
if (wp->w_buffer->terminal) {
|
||||
terminal_resize(wp->w_buffer->terminal, 0, wp->w_height);
|
||||
redraw_win_later(wp, CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4706,6 +4726,11 @@ void win_new_width(win_T *wp, int width)
|
||||
}
|
||||
redraw_win_later(wp, NOT_VALID);
|
||||
wp->w_redr_status = TRUE;
|
||||
|
||||
if (wp->w_buffer->terminal) {
|
||||
terminal_resize(wp->w_buffer->terminal, wp->w_width, 0);
|
||||
redraw_win_later(wp, CLEAR);
|
||||
}
|
||||
}
|
||||
|
||||
void win_comp_scroll(win_T *wp)
|
||||
@@ -5570,4 +5595,3 @@ static int frame_check_width(frame_T *topfrp, int width)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user