altscreen ハック
サスペンドしたときは vim の画面がそのまま残り、vim を終了したときは起動前の画面を復元してほしい。
vim は C-z にもマッピングできるので、そこで t_ti と t_te を空にして、さらに au VimLeavePre などで終了前に t_te を復元すればいいのだが、制御コードを .vimrc にハードコーディングするのが嫌だったのでハックしてみた。
いつにも増してダーティハック。
--- ../src.orig/ex_docmd.c Sat May 6 01:33:19 2006 +++ ex_docmd.c Wed Nov 29 00:40:07 2006 @@ -13,6 +13,8 @@ #include "vim.h" +int suspend_start; + #ifdef HAVE_FCNTL_H # include <fcntl.h> /* for chdir() */ #endif @@ -6487,6 +6489,7 @@ windgoto((int)Rows - 1, 0); out_char('\n'); out_flush(); + suspend_start = 1; stoptermcap(); out_flush(); /* needed for SUN to restore xterm buffer */ #ifdef FEAT_TITLE @@ -6501,6 +6504,7 @@ scroll_start(); /* scroll screen before redrawing */ redraw_later_clear(); shell_resized(); /* may have resized window */ + suspend_start = 0; } } --- ../src.orig/term.c Thu May 4 02:34:57 2006 +++ term.c Wed Nov 29 00:38:13 2006 @@ -25,6 +25,8 @@ #define tgetstr tgetstr_defined_wrong #include "vim.h" +extern int suspend_start; + #ifdef HAVE_TGETENT # ifdef HAVE_TERMIOS_H # include <termios.h> /* seems to be required for some Linux */ @@ -3220,7 +3222,9 @@ { if (full_screen && !termcap_active) { - out_str(T_TI); /* start termcap mode */ + if (!suspend_start) { + out_str(T_TI); /* start termcap mode */ + } out_str(T_KS); /* start "keypad transmit" mode */ out_flush(); termcap_active = TRUE; @@ -3253,7 +3257,9 @@ out_flush(); termcap_active = FALSE; cursor_on(); /* just in case it is still off */ - out_str(T_TE); /* stop termcap mode */ + if (!suspend_start) { + out_str(T_TE); /* stop termcap mode */ + } screen_start(); /* don't know where cursor is now */ out_flush(); }
さらによく考えたら、t_te を変数に退避しておけばいいだけなので、制御コードをハードコーディングする必要もないのだった。