Mercurial > vim
comparison src/popupwin.c @ 16855:19162ff4eacd v8.1.1429
patch 8.1.1429: "pos" option of popup window not supported yet
commit https://github.com/vim/vim/commit/ac1f1bc222b7de3cb2d3f1f2aa076f11c75e69de
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu May 30 21:24:26 2019 +0200
patch 8.1.1429: "pos" option of popup window not supported yet
Problem: "pos" option of popup window not supported yet.
Solution: Implement the option. Rename popup_getposition() to
popup_getpos().
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 30 May 2019 21:30:04 +0200 |
parents | e6bcccccbf7b |
children | 4de94f6161f2 |
comparison
equal
deleted
inserted
replaced
16854:a84036f2d3ec | 16855:19162ff4eacd |
---|---|
13 | 13 |
14 #include "vim.h" | 14 #include "vim.h" |
15 | 15 |
16 #ifdef FEAT_TEXT_PROP | 16 #ifdef FEAT_TEXT_PROP |
17 | 17 |
18 typedef struct { | |
19 char *pp_name; | |
20 poppos_T pp_val; | |
21 } poppos_entry_T; | |
22 | |
23 static poppos_entry_T poppos_entries[] = { | |
24 {"botleft", POPPOS_BOTLEFT}, | |
25 {"topleft", POPPOS_TOPLEFT}, | |
26 {"botright", POPPOS_BOTRIGHT}, | |
27 {"topright", POPPOS_TOPRIGHT}, | |
28 {"center", POPPOS_CENTER} | |
29 }; | |
30 | |
18 /* | 31 /* |
19 * Get option value for"key", which is "line" or "col". | 32 * Get option value for"key", which is "line" or "col". |
20 * Handles "cursor+N" and "cursor-N". | 33 * Handles "cursor+N" and "cursor-N". |
21 */ | 34 */ |
22 static int | 35 static int |
23 popup_options_pos(dict_T *dict, char_u *key) | 36 popup_options_one(dict_T *dict, char_u *key) |
24 { | 37 { |
25 dictitem_T *di; | 38 dictitem_T *di; |
26 char_u *val; | 39 char_u *val; |
27 char_u *s; | 40 char_u *s; |
28 char_u *endp; | 41 char_u *endp; |
56 if (n < 1) | 69 if (n < 1) |
57 n = 1; | 70 n = 1; |
58 return n; | 71 return n; |
59 } | 72 } |
60 | 73 |
74 static void | |
75 get_pos_options(win_T *wp, dict_T *dict) | |
76 { | |
77 char_u *str; | |
78 int nr; | |
79 | |
80 nr = popup_options_one(dict, (char_u *)"line"); | |
81 if (nr > 0) | |
82 wp->w_wantline = nr; | |
83 nr = popup_options_one(dict, (char_u *)"col"); | |
84 if (nr > 0) | |
85 wp->w_wantcol = nr; | |
86 | |
87 str = dict_get_string(dict, (char_u *)"pos", FALSE); | |
88 if (str != NULL) | |
89 { | |
90 for (nr = 0; | |
91 nr < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T)); | |
92 ++nr) | |
93 if (STRCMP(str, poppos_entries[nr].pp_name) == 0) | |
94 { | |
95 wp->w_popup_pos = poppos_entries[nr].pp_val; | |
96 nr = -1; | |
97 break; | |
98 } | |
99 if (nr != -1) | |
100 semsg(_(e_invarg2), str); | |
101 } | |
102 } | |
103 | |
61 /* | 104 /* |
62 * Go through the options in "dict" and apply them to buffer "buf" displayed in | 105 * Go through the options in "dict" and apply them to buffer "buf" displayed in |
63 * popup window "wp". | 106 * popup window "wp". |
64 * When called from f_popup_atcursor() "atcursor" is TRUE. | 107 * When called from f_popup_atcursor() "atcursor" is TRUE. |
65 */ | 108 */ |
66 static void | 109 static void |
67 apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor) | 110 apply_options(win_T *wp, buf_T *buf UNUSED, dict_T *dict, int atcursor) |
68 { | 111 { |
112 #if defined(FEAT_TIMERS) | |
69 int nr; | 113 int nr; |
114 #endif | |
70 char_u *str; | 115 char_u *str; |
71 | 116 |
72 wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth"); | 117 wp->w_minwidth = dict_get_number(dict, (char_u *)"minwidth"); |
73 wp->w_minheight = dict_get_number(dict, (char_u *)"minheight"); | 118 wp->w_minheight = dict_get_number(dict, (char_u *)"minheight"); |
74 wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth"); | 119 wp->w_maxwidth = dict_get_number(dict, (char_u *)"maxwidth"); |
75 wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight"); | 120 wp->w_maxheight = dict_get_number(dict, (char_u *)"maxheight"); |
76 | 121 |
77 if (atcursor) | 122 if (atcursor) |
78 { | 123 { |
124 wp->w_popup_pos = POPPOS_BOTLEFT; | |
79 setcursor_mayforce(TRUE); | 125 setcursor_mayforce(TRUE); |
80 wp->w_wantline = screen_screenrow(); | 126 wp->w_wantline = screen_screenrow(); |
127 if (wp->w_wantline == 0) // cursor in first line | |
128 { | |
129 wp->w_wantline = 2; | |
130 wp->w_popup_pos = POPPOS_TOPLEFT; | |
131 } | |
81 wp->w_wantcol = screen_screencol() + 1; | 132 wp->w_wantcol = screen_screencol() + 1; |
82 } | 133 } |
83 | 134 |
84 nr = popup_options_pos(dict, (char_u *)"line"); | 135 get_pos_options(wp, dict); |
85 if (nr > 0) | |
86 wp->w_wantline = nr; | |
87 nr = popup_options_pos(dict, (char_u *)"col"); | |
88 if (nr > 0) | |
89 wp->w_wantcol = nr; | |
90 | 136 |
91 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); | 137 wp->w_zindex = dict_get_number(dict, (char_u *)"zindex"); |
92 | 138 |
93 #if defined(FEAT_TIMERS) | 139 #if defined(FEAT_TIMERS) |
94 // Add timer to close the popup after some time. | 140 // Add timer to close the popup after some time. |
210 popup_adjust_position(win_T *wp) | 256 popup_adjust_position(win_T *wp) |
211 { | 257 { |
212 linenr_T lnum; | 258 linenr_T lnum; |
213 int wrapped = 0; | 259 int wrapped = 0; |
214 int maxwidth; | 260 int maxwidth; |
215 | 261 int center_vert = FALSE; |
216 // TODO: Compute the size and position properly. | 262 int center_hor = FALSE; |
217 if (wp->w_wantline > 0) | 263 |
218 wp->w_winrow = wp->w_wantline - 1; | 264 wp->w_winrow = 0; |
265 wp->w_wincol = 0; | |
266 if (wp->w_popup_pos == POPPOS_CENTER) | |
267 { | |
268 // center after computing the size | |
269 center_vert = TRUE; | |
270 center_hor = TRUE; | |
271 } | |
219 else | 272 else |
220 // TODO: better default | 273 { |
221 wp->w_winrow = Rows > 5 ? Rows / 2 - 2 : 0; | 274 if (wp->w_wantline == 0) |
222 if (wp->w_winrow >= Rows) | 275 center_vert = TRUE; |
223 wp->w_winrow = Rows - 1; | 276 else if (wp->w_popup_pos == POPPOS_TOPLEFT |
224 | 277 || wp->w_popup_pos == POPPOS_TOPRIGHT) |
225 if (wp->w_wantcol > 0) | 278 { |
226 wp->w_wincol = wp->w_wantcol - 1; | 279 wp->w_winrow = wp->w_wantline - 1; |
227 else | 280 if (wp->w_winrow >= Rows) |
228 // TODO: better default | 281 wp->w_winrow = Rows - 1; |
229 wp->w_wincol = Columns > 20 ? Columns / 2 - 10 : 0; | 282 } |
230 if (wp->w_wincol >= Columns - 3) | 283 |
231 wp->w_wincol = Columns - 3; | 284 if (wp->w_wantcol == 0) |
232 | 285 center_hor = TRUE; |
286 else if (wp->w_popup_pos == POPPOS_TOPLEFT | |
287 || wp->w_popup_pos == POPPOS_BOTLEFT) | |
288 { | |
289 wp->w_wincol = wp->w_wantcol - 1; | |
290 if (wp->w_wincol >= Columns - 3) | |
291 wp->w_wincol = Columns - 3; | |
292 } | |
293 } | |
294 | |
295 // When centering or right aligned, use maximum width. | |
296 // When left aligned use the space available. | |
233 maxwidth = Columns - wp->w_wincol; | 297 maxwidth = Columns - wp->w_wincol; |
234 if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) | 298 if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) |
235 maxwidth = wp->w_maxwidth; | 299 maxwidth = wp->w_maxwidth; |
236 | 300 |
237 // Compute width based on longest text line and the 'wrap' option. | 301 // Compute width based on longest text line and the 'wrap' option. |
253 | 317 |
254 if (wp->w_minwidth > 0 && wp->w_width < wp->w_minwidth) | 318 if (wp->w_minwidth > 0 && wp->w_width < wp->w_minwidth) |
255 wp->w_width = wp->w_minwidth; | 319 wp->w_width = wp->w_minwidth; |
256 if (wp->w_width > maxwidth) | 320 if (wp->w_width > maxwidth) |
257 wp->w_width = maxwidth; | 321 wp->w_width = maxwidth; |
322 if (center_hor) | |
323 wp->w_wincol = (Columns - wp->w_width) / 2; | |
324 else if (wp->w_popup_pos == POPPOS_BOTRIGHT | |
325 || wp->w_popup_pos == POPPOS_TOPRIGHT) | |
326 { | |
327 // Right aligned: move to the right if needed. | |
328 // No truncation, because that would change the height. | |
329 if (wp->w_width < wp->w_wantcol) | |
330 wp->w_wincol = wp->w_wantcol - wp->w_width; | |
331 } | |
258 | 332 |
259 if (wp->w_height <= 1) | 333 if (wp->w_height <= 1) |
260 wp->w_height = wp->w_buffer->b_ml.ml_line_count + wrapped; | 334 wp->w_height = wp->w_buffer->b_ml.ml_line_count + wrapped; |
261 if (wp->w_minheight > 0 && wp->w_height < wp->w_minheight) | 335 if (wp->w_minheight > 0 && wp->w_height < wp->w_minheight) |
262 wp->w_height = wp->w_minheight; | 336 wp->w_height = wp->w_minheight; |
263 if (wp->w_maxheight > 0 && wp->w_height > wp->w_maxheight) | 337 if (wp->w_maxheight > 0 && wp->w_height > wp->w_maxheight) |
264 wp->w_height = wp->w_maxheight; | 338 wp->w_height = wp->w_maxheight; |
265 if (wp->w_height > Rows - wp->w_winrow) | 339 if (wp->w_height > Rows - wp->w_winrow) |
266 wp->w_height = Rows - wp->w_winrow; | 340 wp->w_height = Rows - wp->w_winrow; |
267 | 341 |
342 if (center_vert) | |
343 wp->w_winrow = (Rows - wp->w_height) / 2; | |
344 else if (wp->w_popup_pos == POPPOS_BOTRIGHT | |
345 || wp->w_popup_pos == POPPOS_BOTLEFT) | |
346 { | |
347 if (wp->w_height <= wp->w_wantline) | |
348 // bottom aligned: may move down | |
349 wp->w_winrow = wp->w_wantline - wp->w_height; | |
350 else | |
351 // not enough space, make top aligned | |
352 wp->w_winrow = wp->w_wantline + 1; | |
353 } | |
354 | |
268 wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer); | 355 wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer); |
269 } | 356 } |
270 | 357 |
271 /* | 358 /* |
272 * popup_create({text}, {options}) | 359 * popup_create({text}, {options}) |
302 // Create the window and buffer. | 389 // Create the window and buffer. |
303 wp = win_alloc_popup_win(); | 390 wp = win_alloc_popup_win(); |
304 if (wp == NULL) | 391 if (wp == NULL) |
305 return; | 392 return; |
306 rettv->vval.v_number = wp->w_id; | 393 rettv->vval.v_number = wp->w_id; |
307 wp->w_p_wrap = TRUE; // 'wrap' is default on | 394 wp->w_popup_pos = POPPOS_TOPLEFT; |
308 | 395 |
309 buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY); | 396 buf = buflist_new(NULL, NULL, (linenr_T)0, BLN_NEW|BLN_LISTED|BLN_DUMMY); |
310 if (buf == NULL) | 397 if (buf == NULL) |
311 return; | 398 return; |
312 ml_open(buf); | 399 ml_open(buf); |
320 (char_u *)"hide", OPT_FREE|OPT_LOCAL, 0); | 407 (char_u *)"hide", OPT_FREE|OPT_LOCAL, 0); |
321 buf->b_p_ul = -1; // no undo | 408 buf->b_p_ul = -1; // no undo |
322 buf->b_p_swf = FALSE; // no swap file | 409 buf->b_p_swf = FALSE; // no swap file |
323 buf->b_p_bl = FALSE; // unlisted buffer | 410 buf->b_p_bl = FALSE; // unlisted buffer |
324 buf->b_locked = TRUE; | 411 buf->b_locked = TRUE; |
412 wp->w_p_wrap = TRUE; // 'wrap' is default on | |
413 | |
325 // Avoid that 'buftype' is reset when this buffer is entered. | 414 // Avoid that 'buftype' is reset when this buffer is entered. |
326 buf->b_p_initialized = TRUE; | 415 buf->b_p_initialized = TRUE; |
327 | 416 |
328 nr = (int)dict_get_number(d, (char_u *)"tab"); | 417 nr = (int)dict_get_number(d, (char_u *)"tab"); |
329 if (nr == 0) | 418 if (nr == 0) |
576 wp->w_minheight = nr; | 665 wp->w_minheight = nr; |
577 if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0) | 666 if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0) |
578 wp->w_maxwidth = nr; | 667 wp->w_maxwidth = nr; |
579 if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0) | 668 if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0) |
580 wp->w_maxheight = nr; | 669 wp->w_maxheight = nr; |
581 if ((nr = dict_get_number(d, (char_u *)"line")) > 0) | 670 get_pos_options(wp, d); |
582 wp->w_wantline = nr; | |
583 if ((nr = dict_get_number(d, (char_u *)"col")) > 0) | |
584 wp->w_wantcol = nr; | |
585 // TODO: "pos" | |
586 | 671 |
587 if (wp->w_winrow + wp->w_height >= cmdline_row) | 672 if (wp->w_winrow + wp->w_height >= cmdline_row) |
588 clear_cmdline = TRUE; | 673 clear_cmdline = TRUE; |
589 popup_adjust_position(wp); | 674 popup_adjust_position(wp); |
590 redraw_all_later(NOT_VALID); | 675 redraw_all_later(NOT_VALID); |
591 } | 676 } |
592 | 677 |
593 /* | 678 /* |
594 * popup_getposition({id}) | 679 * popup_getpos({id}) |
595 */ | 680 */ |
596 void | 681 void |
597 f_popup_getposition(typval_T *argvars, typval_T *rettv) | 682 f_popup_getpos(typval_T *argvars, typval_T *rettv) |
598 { | 683 { |
599 dict_T *dict; | 684 dict_T *dict; |
600 int id = (int)tv_get_number(argvars); | 685 int id = (int)tv_get_number(argvars); |
601 win_T *wp = find_popup_win(id); | 686 win_T *wp = find_popup_win(id); |
602 | 687 |
621 f_popup_getoptions(typval_T *argvars, typval_T *rettv) | 706 f_popup_getoptions(typval_T *argvars, typval_T *rettv) |
622 { | 707 { |
623 dict_T *dict; | 708 dict_T *dict; |
624 int id = (int)tv_get_number(argvars); | 709 int id = (int)tv_get_number(argvars); |
625 win_T *wp = find_popup_win(id); | 710 win_T *wp = find_popup_win(id); |
711 int i; | |
626 | 712 |
627 if (rettv_dict_alloc(rettv) == OK) | 713 if (rettv_dict_alloc(rettv) == OK) |
628 { | 714 { |
629 if (wp == NULL) | 715 if (wp == NULL) |
630 return; | 716 return; |
635 dict_add_number(dict, "minwidth", wp->w_minwidth); | 721 dict_add_number(dict, "minwidth", wp->w_minwidth); |
636 dict_add_number(dict, "minheight", wp->w_minheight); | 722 dict_add_number(dict, "minheight", wp->w_minheight); |
637 dict_add_number(dict, "maxheight", wp->w_maxheight); | 723 dict_add_number(dict, "maxheight", wp->w_maxheight); |
638 dict_add_number(dict, "maxwidth", wp->w_maxwidth); | 724 dict_add_number(dict, "maxwidth", wp->w_maxwidth); |
639 dict_add_number(dict, "zindex", wp->w_zindex); | 725 dict_add_number(dict, "zindex", wp->w_zindex); |
726 | |
727 for (i = 0; i < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T)); | |
728 ++i) | |
729 if (wp->w_popup_pos == poppos_entries[i].pp_val) | |
730 { | |
731 dict_add_string(dict, "pos", | |
732 (char_u *)poppos_entries[i].pp_name); | |
733 break; | |
734 } | |
735 | |
640 # if defined(FEAT_TIMERS) | 736 # if defined(FEAT_TIMERS) |
641 dict_add_number(dict, "time", wp->w_popup_timer != NULL | 737 dict_add_number(dict, "time", wp->w_popup_timer != NULL |
642 ? (long)wp->w_popup_timer->tr_interval : 0L); | 738 ? (long)wp->w_popup_timer->tr_interval : 0L); |
643 # endif | 739 # endif |
644 } | 740 } |