Mercurial > vim
comparison src/popupwin.c @ 16778:eda4d65f232c v8.1.1391
patch 8.1.1391: no popup window support
commit https://github.com/vim/vim/commit/4d784b21d14fc66e98a2b07f70343cdd4acd62aa
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 25 19:51:39 2019 +0200
patch 8.1.1391: no popup window support
Problem: No popup window support.
Solution: Add initial code for popup windows. Add the 'wincolor' option.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 25 May 2019 20:00:08 +0200 |
parents | |
children | ddfa924df50d |
comparison
equal
deleted
inserted
replaced
16777:20d51e99dd6a | 16778:eda4d65f232c |
---|---|
1 /* vi:set ts=8 sts=4 sw=4 noet: | |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read a list of people who contributed. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * Implementation of popup windows. See ":help popup". | |
12 */ | |
13 | |
14 #include "vim.h" | |
15 | |
16 #ifdef FEAT_TEXT_PROP | |
17 | |
18 /* | |
19 * Go through the options in "dict" and apply them to buffer "buf" displayed in | |
20 * popup window "wp". | |
21 */ | |
22 static void | |
23 apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict) | |
24 { | |
25 wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth"); | |
26 wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight"); | |
27 wp->w_winrow = dict_get_number(dict, (char_u *)"line"); | |
28 wp->w_wincol = dict_get_number(dict, (char_u *)"col"); | |
29 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); | |
30 } | |
31 | |
32 /* | |
33 * popup_create({text}, {options}) | |
34 */ | |
35 void | |
36 f_popup_create(typval_T *argvars, typval_T *rettv) | |
37 { | |
38 win_T *wp; | |
39 buf_T *buf; | |
40 dict_T *d; | |
41 int nr; | |
42 | |
43 // Check arguments look OK. | |
44 if (!(argvars[0].v_type == VAR_STRING | |
45 && argvars[0].vval.v_string != NULL | |
46 && STRLEN(argvars[0].vval.v_string) > 0) | |
47 && !(argvars[0].v_type == VAR_LIST | |
48 && argvars[0].vval.v_list != NULL | |
49 && argvars[0].vval.v_list->lv_len > 0)) | |
50 { | |
51 emsg(_(e_listreq)); | |
52 return; | |
53 } | |
54 if (argvars[1].v_type != VAR_DICT || argvars[1].vval.v_dict == NULL) | |
55 { | |
56 emsg(_(e_dictreq)); | |
57 return; | |
58 } | |
59 d = argvars[1].vval.v_dict; | |
60 | |
61 // Create the window and buffer. | |
62 wp = win_alloc_popup_win(); | |
63 if (wp == NULL) | |
64 return; | |
65 rettv->vval.v_number = wp->w_id; | |
66 wp->w_p_wrap = TRUE; // 'wrap' is default on | |
67 | |
68 buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY); | |
69 if (buf == NULL) | |
70 return; | |
71 ml_open(buf); | |
72 curbuf = buf; | |
73 set_string_option_direct((char_u *)"buftype", -1, | |
74 (char_u *)"popup", OPT_FREE|OPT_LOCAL, 0); | |
75 set_string_option_direct((char_u *)"bufhidden", -1, | |
76 (char_u *)"hide", OPT_FREE|OPT_LOCAL, 0); | |
77 curbuf = curwin->w_buffer; | |
78 buf->b_p_ul = -1; // no undo | |
79 buf->b_p_swf = FALSE; // no swap file | |
80 buf->b_p_bl = FALSE; // unlisted buffer | |
81 | |
82 win_init_popup_win(wp, buf); | |
83 | |
84 nr = (int)dict_get_number(d, (char_u *)"tab"); | |
85 if (nr == 0) | |
86 { | |
87 // popup on current tab | |
88 wp->w_next = first_tab_popupwin; | |
89 first_tab_popupwin = wp; | |
90 } | |
91 else if (nr < 0) | |
92 { | |
93 // global popup | |
94 wp->w_next = first_popupwin; | |
95 first_popupwin = wp; | |
96 } | |
97 else | |
98 // TODO: find tab page "nr" | |
99 emsg("Not implemented yet"); | |
100 | |
101 // Add text to the buffer. | |
102 if (argvars[0].v_type == VAR_STRING) | |
103 // just a string | |
104 ml_append_buf(buf, 0, argvars[0].vval.v_string, (colnr_T)0, TRUE); | |
105 else if (argvars[0].vval.v_list->lv_first->li_tv.v_type == VAR_STRING) | |
106 { | |
107 listitem_T *li; | |
108 linenr_T lnum = 0; | |
109 char_u *p; | |
110 | |
111 // list of strings | |
112 for (li = argvars[0].vval.v_list->lv_first; li != NULL; | |
113 li = li->li_next) | |
114 if (li->li_tv.v_type == VAR_STRING) | |
115 { | |
116 p = li->li_tv.vval.v_string; | |
117 ml_append_buf(buf, lnum++, | |
118 p == NULL ? (char_u *)"" : p, (colnr_T)0, TRUE); | |
119 } | |
120 } | |
121 else | |
122 // TODO: handle a list of dictionaries | |
123 emsg("Not implemented yet"); | |
124 | |
125 // Delete the line of the empty buffer. | |
126 curbuf = buf; | |
127 ml_delete(buf->b_ml.ml_line_count, FALSE); | |
128 curbuf = curwin->w_buffer; | |
129 | |
130 // Deal with options. | |
131 apply_options(wp, buf, argvars[1].vval.v_dict); | |
132 | |
133 // set default values | |
134 if (wp->w_zindex == 0) | |
135 wp->w_zindex = 50; | |
136 | |
137 // TODO: Compute the size and position properly. | |
138 | |
139 // Default position is in middle of the screen, assuming a small popup | |
140 if (wp->w_winrow == 0) | |
141 wp->w_winrow = Rows > 5 ? Rows / 2 - 2 : 0; | |
142 else | |
143 --wp->w_winrow; // option value is one-based | |
144 if (wp->w_wincol == 0) | |
145 wp->w_wincol = Columns > 20 ? Columns / 2 - 10 : 0; | |
146 else | |
147 --wp->w_wincol; // option value is one-based | |
148 | |
149 | |
150 // TODO: set width based on longest text line and the 'wrap' option | |
151 wp->w_width = wp->w_maxwidth == 0 ? 20 : wp->w_maxwidth; | |
152 if (wp->w_maxwidth > 0 && wp->w_width > wp->w_maxwidth) | |
153 wp->w_width = wp->w_maxwidth; | |
154 if (wp->w_width > Columns - wp->w_wincol) | |
155 wp->w_width = Columns - wp->w_wincol; | |
156 | |
157 // TODO: adjust height for wrapped lines | |
158 wp->w_height = buf->b_ml.ml_line_count; | |
159 if (wp->w_maxheight > 0 && wp->w_height > wp->w_maxheight) | |
160 wp->w_height = wp->w_maxheight; | |
161 if (wp->w_height > Rows - wp->w_winrow) | |
162 wp->w_height = Rows - wp->w_winrow; | |
163 | |
164 wp->w_vsep_width = 0; | |
165 | |
166 redraw_all_later(NOT_VALID); | |
167 } | |
168 | |
169 /* | |
170 * popup_close({id}) | |
171 */ | |
172 void | |
173 f_popup_close(typval_T *argvars, typval_T *rettv UNUSED) | |
174 { | |
175 int nr = (int)tv_get_number(argvars); | |
176 | |
177 popup_close(nr); | |
178 } | |
179 | |
180 void | |
181 popup_close(int nr) | |
182 { | |
183 win_T *wp; | |
184 win_T *prev = NULL; | |
185 | |
186 for (wp = first_popupwin; wp != NULL; prev = wp, wp = wp->w_next) | |
187 if (wp->w_id == nr) | |
188 { | |
189 if (prev == NULL) | |
190 first_popupwin = wp->w_next; | |
191 else | |
192 prev->w_next = wp->w_next; | |
193 break; | |
194 } | |
195 | |
196 if (wp == NULL) | |
197 { | |
198 prev = NULL; | |
199 for (wp = first_tab_popupwin; wp != NULL; prev = wp, wp = wp->w_next) | |
200 if (wp->w_id == nr) | |
201 { | |
202 if (prev == NULL) | |
203 first_tab_popupwin = wp->w_next; | |
204 else | |
205 prev->w_next = wp->w_next; | |
206 break; | |
207 } | |
208 } | |
209 if (wp != NULL) | |
210 { | |
211 win_free_popup(wp); | |
212 redraw_all_later(NOT_VALID); | |
213 } | |
214 } | |
215 | |
216 void | |
217 close_all_popups(void) | |
218 { | |
219 while (first_popupwin != NULL) | |
220 popup_close(first_popupwin->w_id); | |
221 while (first_tab_popupwin != NULL) | |
222 popup_close(first_tab_popupwin->w_id); | |
223 } | |
224 | |
225 void | |
226 ex_popupclear(exarg_T *eap UNUSED) | |
227 { | |
228 close_all_popups(); | |
229 } | |
230 | |
231 #endif // FEAT_TEXT_PROP |