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 を変数に退避しておけばいいだけなので、制御コードをハードコーディングする必要もないのだった。