Permalink
Browse files

Merge PR #2076 'Builtin terminal emulation'

  • Loading branch information...
2 parents d2d9945 + 2aa2513 commit a6e53a3797a93fe060f807fe2e4c6361854b6c97 @tarruda tarruda committed Mar 26, 2015
Showing with 3,240 additions and 190 deletions.
  1. +0 −27 src/nvim/api/buffer.c
  2. +37 −19 src/nvim/buffer.c
  3. +41 −0 src/nvim/buffer.h
  4. +7 −0 src/nvim/buffer_defs.h
  5. +3 −2 src/nvim/diff.c
  6. +6 −0 src/nvim/edit.c
  7. +183 −29 src/nvim/eval.c
  8. +2 −2 src/nvim/ex_cmds.c
  9. +25 −0 src/nvim/ex_cmds.lua
  10. +23 −5 src/nvim/ex_docmd.c
  11. +6 −4 src/nvim/fileio.c
  12. +1 −0 src/nvim/fileio.h
  13. +5 −2 src/nvim/fold.c
  14. +6 −0 src/nvim/getchar.c
  15. +2 −0 src/nvim/macros.h
  16. +11 −0 src/nvim/main.c
  17. +8 −0 src/nvim/map.c
  18. +5 −1 src/nvim/map.h
  19. +5 −3 src/nvim/memline.c
  20. +5 −5 src/nvim/normal.c
  21. +24 −7 src/nvim/ops.c
  22. +7 −5 src/nvim/option.c
  23. +13 −5 src/nvim/os/event.c
  24. +12 −1 src/nvim/os/job.c
  25. +5 −10 src/nvim/quickfix.c
  26. +33 −3 src/nvim/screen.c
  27. +7 −2 src/nvim/syntax.c
  28. +1,129 −0 src/nvim/terminal.c
  29. +33 −0 src/nvim/terminal.h
  30. +10 −4 src/nvim/ui.c
  31. +4 −1 src/nvim/undo.c
  32. +3 −7 src/nvim/vim.h
  33. +26 −2 src/nvim/window.c
  34. +2 −12 test/functional/job/job_spec.lua
  35. +58 −30 test/functional/job/tty-test.c
  36. +158 −0 test/functional/terminal/altscreen_spec.lua
  37. +159 −0 test/functional/terminal/buffer_spec.lua
  38. +174 −0 test/functional/terminal/cursor_spec.lua
  39. +95 −0 test/functional/terminal/helpers.lua
  40. +163 −0 test/functional/terminal/highlight_spec.lua
  41. +188 −0 test/functional/terminal/mouse_spec.lua
  42. +348 −0 test/functional/terminal/scrollback_spec.lua
  43. +64 −0 test/functional/terminal/window_spec.lua
  44. +138 −0 test/functional/terminal/window_split_tab_spec.lua
  45. +6 −2 test/functional/ui/screen.lua
View
@@ -516,33 +516,6 @@ ArrayOf(Integer, 2) buffer_get_mark(Buffer buffer, String name, Error *err)
return rv;
}
-// Find a window that contains "buf" and switch to it.
-// If there is no such window, use the current window and change "curbuf".
-// Caller must initialize save_curbuf to NULL.
-// restore_win_for_buf() MUST be called later!
-static void switch_to_win_for_buf(buf_T *buf,
- win_T **save_curwinp,
- tabpage_T **save_curtabp,
- buf_T **save_curbufp)
-{
- win_T *wp;
- tabpage_T *tp;
-
- if (!find_win_for_buf(buf, &wp, &tp)
- || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL)
- switch_buffer(save_curbufp, buf);
-}
-
-static void restore_win_for_buf(win_T *save_curwin,
- tabpage_T *save_curtab,
- buf_T *save_curbuf)
-{
- if (save_curbuf == NULL) {
- restore_win(save_curwin, save_curtab, true);
- } else {
- restore_buffer(save_curbuf);
- }
-}
// Check if deleting lines made the cursor position invalid.
// Changed the lines from "lo" to "hi" and added "extra" lines (negative if
View
@@ -68,6 +68,7 @@
#include "nvim/spell.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
+#include "nvim/terminal.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
@@ -307,20 +308,28 @@ close_buffer (
bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);
bool wipe_buf = (action == DOBUF_WIPE);
- /*
- * Force unloading or deleting when 'bufhidden' says so.
- * The caller must take care of NOT deleting/freeing when 'bufhidden' is
- * "hide" (otherwise we could never free or delete a buffer).
- */
- if (buf->b_p_bh[0] == 'd') { /* 'bufhidden' == "delete" */
- del_buf = true;
+ // Force unloading or deleting when 'bufhidden' says so, but not for terminal
+ // buffers.
+ // The caller must take care of NOT deleting/freeing when 'bufhidden' is
+ // "hide" (otherwise we could never free or delete a buffer).
+ if (!buf->terminal) {
+ if (buf->b_p_bh[0] == 'd') { // 'bufhidden' == "delete"
+ del_buf = true;
+ unload_buf = true;
+ } else if (buf->b_p_bh[0] == 'w') { // 'bufhidden' == "wipe"
+ del_buf = true;
+ unload_buf = true;
+ wipe_buf = true;
+ } else if (buf->b_p_bh[0] == 'u') // 'bufhidden' == "unload"
+ unload_buf = true;
+ }
+
+ if (buf->terminal && (unload_buf || del_buf || wipe_buf)) {
+ // terminal buffers can only be wiped
unload_buf = true;
- } else if (buf->b_p_bh[0] == 'w') { /* 'bufhidden' == "wipe" */
del_buf = true;
- unload_buf = true;
wipe_buf = true;
- } else if (buf->b_p_bh[0] == 'u') /* 'bufhidden' == "unload" */
- unload_buf = true;
+ }
if (win_valid(win)) {
/* Set b_last_cursor when closing the last window for the buffer.
@@ -383,6 +392,10 @@ close_buffer (
if (buf->b_nwindows > 0 || !unload_buf)
return;
+ if (buf->terminal) {
+ terminal_close(buf->terminal, NULL);
+ }
+
/* Always remove the buffer when there is no file name. */
if (buf->b_ffname == NULL)
del_buf = TRUE;
@@ -925,8 +938,8 @@ do_buffer (
if (action != DOBUF_WIPE && buf->b_ml.ml_mfp == NULL && !buf->b_p_bl)
return FAIL;
- if (!forceit && bufIsChanged(buf)) {
- if ((p_confirm || cmdmod.confirm) && p_write) {
+ if (!forceit && (buf->terminal || bufIsChanged(buf))) {
+ if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
dialog_changed(buf, FALSE);
if (!buf_valid(buf))
/* Autocommand deleted buffer, oops! It's not changed
@@ -937,9 +950,14 @@ do_buffer (
if (bufIsChanged(buf))
return FAIL;
} else {
- EMSGN(_("E89: No write since last change for buffer %" PRId64
- " (add ! to override)"),
- buf->b_fnum);
+ if (buf->terminal) {
+ EMSG2(_("E89: %s will be killed(add ! to override)"),
+ (char *)buf->b_fname);
+ } else {
+ EMSGN(_("E89: No write since last change for buffer %" PRId64
+ " (add ! to override)"),
+ buf->b_fnum);
+ }
return FAIL;
}
}
@@ -2145,7 +2163,7 @@ void buflist_list(exarg_T *eap)
(curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
buf->b_ml.ml_mfp == NULL ? ' ' :
(buf->b_nwindows == 0 ? 'h' : 'a'),
- !buf->b_p_ma ? '-' : (buf->b_p_ro ? '=' : ' '),
+ !MODIFIABLE(buf) ? '-' : (buf->b_p_ro ? '=' : ' '),
(buf->b_flags & BF_READERR) ? 'x'
: (bufIsChanged(buf) ? '+' : ' '),
NameBuff);
@@ -2623,7 +2641,7 @@ void maketitle(void)
switch (bufIsChanged(curbuf)
+ (curbuf->b_p_ro * 2)
- + (!curbuf->b_p_ma * 4)) {
+ + (!MODIFIABLE(curbuf) * 4)) {
case 1: STRCAT(buf, " +"); break;
case 2: STRCAT(buf, " ="); break;
case 3: STRCAT(buf, " =+"); break;
@@ -3250,7 +3268,7 @@ build_stl_str_hl (
itemisflag = TRUE;
switch ((opt == STL_MODIFIED_ALT)
+ bufIsChanged(wp->w_buffer) * 2
- + (!wp->w_buffer->b_p_ma) * 4) {
+ + (!MODIFIABLE(wp->w_buffer)) * 4) {
case 2: str = (char_u *)"[+]"; break;
case 3: str = (char_u *)",+"; break;
case 4: str = (char_u *)"[-]"; break;
View
@@ -1,6 +1,7 @@
#ifndef NVIM_BUFFER_H
#define NVIM_BUFFER_H
+#include "nvim/window.h"
#include "nvim/pos.h" // for linenr_T
#include "nvim/ex_cmds_defs.h" // for exarg_T
@@ -45,4 +46,44 @@ enum bfa_values {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "buffer.h.generated.h"
#endif
+
+// Find a window that contains "buf" and switch to it.
+// If there is no such window, use the current window and change "curbuf".
+// Caller must initialize save_curbuf to NULL.
+// restore_win_for_buf() MUST be called later!
+static inline void switch_to_win_for_buf(buf_T *buf,
+ win_T **save_curwinp,
+ tabpage_T **save_curtabp,
+ buf_T **save_curbufp)
+{
+ win_T *wp;
+ tabpage_T *tp;
+
+ if (!find_win_for_buf(buf, &wp, &tp)
+ || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL)
+ switch_buffer(save_curbufp, buf);
+}
+
+static inline void restore_win_for_buf(win_T *save_curwin,
+ tabpage_T *save_curtab,
+ buf_T *save_curbuf)
+{
+ if (save_curbuf == NULL) {
+ restore_win(save_curwin, save_curtab, true);
+ } else {
+ restore_buffer(save_curbuf);
+ }
+}
+
+#define WITH_BUFFER(b, code) \
+ do { \
+ buf_T *save_curbuf = NULL; \
+ win_T *save_curwin = NULL; \
+ tabpage_T *save_curtab = NULL; \
+ switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
+ code; \
+ restore_win_for_buf(save_curwin, save_curtab, save_curbuf); \
+ } while (0)
+
+
#endif // NVIM_BUFFER_H
@@ -27,6 +27,8 @@
// for String
#include "nvim/api/private/defs.h"
+#define MODIFIABLE(buf) (!buf->terminal && buf->b_p_ma)
+
/*
* Flags for w_valid.
* These are set when something in a window structure becomes invalid, except
@@ -101,6 +103,9 @@ typedef struct file_buffer buf_T; /* forward declaration */
// for FileID
#include "nvim/os/fs_defs.h"
+// for Terminal
+#include "nvim/terminal.h"
+
/*
* The taggy struct is used to store the information about a :tag command.
*/
@@ -749,6 +754,8 @@ struct file_buffer {
* may use a different synblock_T. */
signlist_T *b_signlist; /* list of signs to draw */
+
+ Terminal *terminal; // Terminal instance associated with the buffer
};
/*
View
@@ -2078,7 +2078,7 @@ void ex_diffgetput(exarg_T *eap)
if ((curtab->tp_diffbuf[idx_other] != curbuf)
&& (curtab->tp_diffbuf[idx_other] != NULL)) {
if ((eap->cmdidx != CMD_diffput)
- || curtab->tp_diffbuf[idx_other]->b_p_ma) {
+ || MODIFIABLE(curtab->tp_diffbuf[idx_other])) {
break;
}
found_not_ma = TRUE;
@@ -2098,7 +2098,8 @@ void ex_diffgetput(exarg_T *eap)
for (i = idx_other + 1; i < DB_COUNT; ++i) {
if ((curtab->tp_diffbuf[i] != curbuf)
&& (curtab->tp_diffbuf[i] != NULL)
- && ((eap->cmdidx != CMD_diffput) || curtab->tp_diffbuf[i]->b_p_ma)) {
+ && ((eap->cmdidx != CMD_diffput)
+ || MODIFIABLE(curtab->tp_diffbuf[i]))) {
EMSG(_("E101: More than two buffers in diff mode, don't know "
"which one to use"));
return;
View
@@ -56,6 +56,7 @@
#include "nvim/tag.h"
#include "nvim/ui.h"
#include "nvim/mouse.h"
+#include "nvim/terminal.h"
#include "nvim/undo.h"
#include "nvim/window.h"
#include "nvim/os/event.h"
@@ -244,6 +245,11 @@ edit (
long count
)
{
+ if (curbuf->terminal) {
+ terminal_enter(curbuf->terminal, true);
+ return false;
+ }
+
int c = 0;
char_u *ptr;
int lastc;
Oops, something went wrong.

0 comments on commit a6e53a3

Please sign in to comment.