Last active
August 12, 2016 18:00
-
-
Save saitoha/a013bdfebe368cf1e0306a66b75621f4 to your computer and use it in GitHub Desktop.
vim: focus event tracking - version 3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt | |
index 1eea20f..016b8f6 100644 | |
--- a/runtime/doc/term.txt | |
+++ b/runtime/doc/term.txt | |
@@ -306,6 +306,10 @@ Added by Vim (there are no standard codes for these): | |
|xterm-true-color| | |
t_8b set background color (R, G, B) *t_8b* *'t_8b'* | |
|xterm-true-color| | |
+ t_fe enable focus-event tracking *t_fe* *'t_fe'* | |
+ |xterm-focus-event| | |
+ t_fd disable focus-event tracking *t_fd* *'t_fd'* | |
+ |xterm-focus-event| | |
KEY CODES | |
Note: Use the <> form if possible | |
@@ -457,6 +461,16 @@ And run "xrdb -merge .Xresources" to make it effective. You can check the | |
value with the context menu (right mouse button while CTRL key is pressed), | |
there should be a tick at allow-window-ops. | |
+ *xterm-focus-event* | |
+Some terminals including xterm support focus event tracking feature. | |
+If this feature is enabled by 't_fe' sequence, special key sequences are sent | |
+from the terminal to Vim every time the terminal gains or loses the focus. Vim | |
+fires focus events (|FocusGained|/|FocusLost|) by handling them. focus event | |
+tracking is disabled by 't_fd' sequence when exit "raw" mode. If you wouldn't | |
+like to use this feature, add the following code to your .vimrc: | |
+ `set t_fe=` | |
+ `set t_fd=` | |
+ | |
*termcap-colors* | |
Note about colors: The 't_Co' option tells Vim the number of colors available. | |
When it is non-zero, the 't_AB' and 't_AF' options are used to set the color. | |
diff --git a/src/option.c b/src/option.c | |
index ff7973f..18ab19f 100644 | |
--- a/src/option.c | |
+++ b/src/option.c | |
@@ -3018,6 +3018,8 @@ static struct vimoption options[] = | |
p_term("t_ZR", T_CZR) | |
p_term("t_8f", T_8F) | |
p_term("t_8b", T_8B) | |
+ p_term("t_fe", T_FE) | |
+ p_term("t_fd", T_FD) | |
/* terminal key codes are not in here */ | |
diff --git a/src/term.c b/src/term.c | |
index 344fabc..af6ab11 100644 | |
--- a/src/term.c | |
+++ b/src/term.c | |
@@ -162,6 +162,10 @@ static char_u *vim_tgetstr(char *s, char_u **pp); | |
#endif /* HAVE_TGETENT */ | |
static int detected_8bit = FALSE; /* detected 8-bit terminal */ | |
+#if defined(FEAT_AUTOCMD) && (defined(UNIX) || defined(VMS)) | |
+static int focus_mode = FALSE; /* xterm's "focus reporting" availability */ | |
+static int focus_state = FALSE; /* TRUE if the terminal window gains focus */ | |
+#endif | |
static struct builtin_term builtin_termcaps[] = | |
{ | |
@@ -860,6 +864,10 @@ static struct builtin_term builtin_termcaps[] = | |
{(int)KS_8F, IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")}, | |
{(int)KS_8B, IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")}, | |
# endif | |
+# if defined(FEAT_AUTOCMD) && (defined(UNIX) || defined(VMS)) | |
+ {(int)KS_FE, IF_EB("\033[?1004h", ESC_STR "[?1004h")}, | |
+ {(int)KS_FD, IF_EB("\033[?1004l", ESC_STR "[?1004l")}, | |
+# endif | |
{K_UP, IF_EB("\033O*A", ESC_STR "O*A")}, | |
{K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, | |
@@ -1825,6 +1833,28 @@ set_termname(char_u *term) | |
# endif | |
#endif /* FEAT_MOUSE */ | |
+#if defined(FEAT_AUTOCMD) && (defined(UNIX) || defined(VMS)) | |
+ /* focus reporting is supported by xterm compatible terminals and tmux. */ | |
+ if (use_xterm_like_mouse(term)) | |
+ { | |
+ char_u name[3]; | |
+ | |
+ name[0] = (int)KS_EXTRA; | |
+ name[2] = NUL; | |
+ | |
+ /* handle focus in event */ | |
+ name[1] = (int)KE_FOCUSGAINED; | |
+ add_termcode(name, (char_u *)"\033[I", FALSE); | |
+ | |
+ /* handle focus out event */ | |
+ name[1] = (int)KE_FOCUSLOST; | |
+ add_termcode(name, (char_u *)"\033[O", FALSE); | |
+ | |
+ focus_mode = TRUE; | |
+ focus_state = TRUE; | |
+ } | |
+#endif | |
+ | |
#ifdef USE_TERM_CONSOLE | |
/* DEFAULT_TERM indicates that it is the machine console. */ | |
if (STRCMP(term, DEFAULT_TERM) != 0) | |
@@ -3142,6 +3172,11 @@ starttermcap(void) | |
{ | |
out_str(T_TI); /* start termcap mode */ | |
out_str(T_KS); /* start "keypad transmit" mode */ | |
+#if defined(FEAT_AUTOCMD) && (defined(UNIX) || defined(VMS)) | |
+ /* enable xterm's forcus reporting mode */ | |
+ if (focus_mode && T_FE != NUL) | |
+ out_str(T_FE); | |
+#endif | |
out_flush(); | |
termcap_active = TRUE; | |
screen_start(); /* don't know where cursor is now */ | |
@@ -3191,6 +3226,11 @@ stoptermcap(void) | |
check_for_codes_from_term(); | |
} | |
#endif | |
+#if defined(FEAT_AUTOCMD) && (defined(UNIX) || defined(VMS)) | |
+ /* disable xterm's forcus reporting mode */ | |
+ if (focus_mode && T_FD != NUL) | |
+ out_str(T_FD); | |
+#endif | |
out_str(T_KE); /* stop "keypad transmit" mode */ | |
out_flush(); | |
termcap_active = FALSE; | |
@@ -5234,6 +5274,35 @@ check_termcode( | |
# endif /* !USE_ON_FLY_SCROLL */ | |
#endif /* FEAT_GUI */ | |
+#if defined(FEAT_AUTOCMD) && (defined(UNIX) || defined(VMS)) | |
+ /* | |
+ * Handle FocusIn/FocusOut event sequences reported by XTerm. | |
+ * (CSI I/CSI O) | |
+ */ | |
+ if (focus_mode | |
+# ifdef FEAT_GUI | |
+ && !gui.in_use | |
+# endif | |
+ && key_name[0] == KS_EXTRA | |
+ ) | |
+ { | |
+ if (key_name[1] == KE_FOCUSGAINED && !focus_state) | |
+ { | |
+ apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, FALSE, curbuf); | |
+ did_cursorhold = TRUE; | |
+ focus_state = TRUE; | |
+ key_name[1] = (int)KE_IGNORE; | |
+ } | |
+ else if (key_name[1] == KE_FOCUSLOST && focus_state) | |
+ { | |
+ apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf); | |
+ did_cursorhold = TRUE; | |
+ focus_state = FALSE; | |
+ key_name[1] = (int)KE_IGNORE; | |
+ } | |
+ } | |
+#endif | |
+ | |
/* | |
* Change <xHome> to <Home>, <xUp> to <Up>, etc. | |
*/ | |
diff --git a/src/term.h b/src/term.h | |
index 4a7391c..608e385 100644 | |
--- a/src/term.h | |
+++ b/src/term.h | |
@@ -89,10 +89,12 @@ enum SpecialKey | |
KS_OP, /* original color pair */ | |
KS_U7, /* request cursor position */ | |
KS_8F, /* set foreground color (RGB) */ | |
- KS_8B /* set background color (RGB) */ | |
+ KS_8B, /* set background color (RGB) */ | |
+ KS_FE, /* enable focus event tracking */ | |
+ KS_FD /* disable focus event tracking */ | |
}; | |
-#define KS_LAST KS_8B | |
+#define KS_LAST KS_FD | |
/* | |
* the terminal capabilities are stored in this array | |
@@ -170,6 +172,8 @@ extern char_u *(term_strings[]); /* current terminal strings */ | |
#define T_U7 (term_str(KS_U7)) /* request cursor position */ | |
#define T_8F (term_str(KS_8F)) /* set foreground color (RGB) */ | |
#define T_8B (term_str(KS_8B)) /* set background color (RGB) */ | |
+#define T_FE (term_str(KS_FE)) /* enable focus event tracking */ | |
+#define T_FD (term_str(KS_FD)) /* disable focus event tracking */ | |
#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */ | |
#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 23: every time the terminal gains or loses focus