comparison src/popupmnu.c @ 12566:33a900199c25 v8.0.1161

patch 8.0.1161: popup menu drawing problem when resizing terminal commit https://github.com/vim/vim/commit/a5e6621aadadf78c7b344e93a4b328788076f14c Author: Bram Moolenaar <Bram@vim.org> Date: Fri Sep 29 22:42:33 2017 +0200 patch 8.0.1161: popup menu drawing problem when resizing terminal Problem: Popup menu drawing problem when resizing terminal. Solution: Redraw after resizing also when a popup menu is visible. (Ozaki Kiichi, closes #2110)
author Christian Brabandt <cb@256bit.org>
date Fri, 29 Sep 2017 22:45:03 +0200
parents 972ea22c946f
children fad36581f788
comparison
equal deleted inserted replaced
12565:657abf4f50ba 12566:33a900199c25
62 int redo_count = 0; 62 int redo_count = 0;
63 #if defined(FEAT_QUICKFIX) 63 #if defined(FEAT_QUICKFIX)
64 win_T *pvwin; 64 win_T *pvwin;
65 #endif 65 #endif
66 66
67 redo: 67 do
68 def_width = PUM_DEF_WIDTH; 68 {
69 max_width = 0; 69 def_width = PUM_DEF_WIDTH;
70 kind_width = 0; 70 max_width = 0;
71 extra_width = 0; 71 kind_width = 0;
72 above_row = 0; 72 extra_width = 0;
73 below_row = cmdline_row; 73 above_row = 0;
74 74 below_row = cmdline_row;
75 /* Pretend the pum is already there to avoid that must_redraw is set when 75
76 * 'cuc' is on. */ 76 /* Pretend the pum is already there to avoid that must_redraw is set
77 pum_array = (pumitem_T *)1; 77 * when 'cuc' is on. */
78 validate_cursor_col(); 78 pum_array = (pumitem_T *)1;
79 pum_array = NULL; 79 validate_cursor_col();
80 80 pum_array = NULL;
81 row = curwin->w_wrow + W_WINROW(curwin); 81
82 row = curwin->w_wrow + W_WINROW(curwin);
82 83
83 #if defined(FEAT_QUICKFIX) 84 #if defined(FEAT_QUICKFIX)
84 FOR_ALL_WINDOWS(pvwin) 85 FOR_ALL_WINDOWS(pvwin)
85 if (pvwin->w_p_pvw) 86 if (pvwin->w_p_pvw)
86 break; 87 break;
87 if (pvwin != NULL) 88 if (pvwin != NULL)
88 { 89 {
89 if (W_WINROW(pvwin) < W_WINROW(curwin)) 90 if (W_WINROW(pvwin) < W_WINROW(curwin))
90 above_row = W_WINROW(pvwin) + pvwin->w_height; 91 above_row = W_WINROW(pvwin) + pvwin->w_height;
91 else if (W_WINROW(pvwin) > W_WINROW(curwin) + curwin->w_height) 92 else if (W_WINROW(pvwin) > W_WINROW(curwin) + curwin->w_height)
92 below_row = W_WINROW(pvwin); 93 below_row = W_WINROW(pvwin);
93 } 94 }
94 #endif 95 #endif
95 96
96 /* 97 /*
97 * Figure out the size and position of the pum. 98 * Figure out the size and position of the pum.
98 */ 99 */
99 if (size < PUM_DEF_HEIGHT) 100 if (size < PUM_DEF_HEIGHT)
100 pum_height = size; 101 pum_height = size;
101 else
102 pum_height = PUM_DEF_HEIGHT;
103 if (p_ph > 0 && pum_height > p_ph)
104 pum_height = p_ph;
105
106 /* Put the pum below "row" if possible. If there are few lines decide on
107 * where there is more room. */
108 if (row + 2 >= below_row - pum_height
109 && row - above_row > (below_row - above_row) / 2)
110 {
111 /* pum above "row" */
112
113 /* Leave two lines of context if possible */
114 if (curwin->w_wrow - curwin->w_cline_row >= 2)
115 context_lines = 2;
116 else 102 else
117 context_lines = curwin->w_wrow - curwin->w_cline_row; 103 pum_height = PUM_DEF_HEIGHT;
118
119 if (row >= size + context_lines)
120 {
121 pum_row = row - size - context_lines;
122 pum_height = size;
123 }
124 else
125 {
126 pum_row = 0;
127 pum_height = row - context_lines;
128 }
129 if (p_ph > 0 && pum_height > p_ph)
130 {
131 pum_row += pum_height - p_ph;
132 pum_height = p_ph;
133 }
134 }
135 else
136 {
137 /* pum below "row" */
138
139 /* Leave two lines of context if possible */
140 if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3)
141 context_lines = 3;
142 else
143 context_lines = curwin->w_cline_row
144 + curwin->w_cline_height - curwin->w_wrow;
145
146 pum_row = row + context_lines;
147 if (size > below_row - pum_row)
148 pum_height = below_row - pum_row;
149 else
150 pum_height = size;
151 if (p_ph > 0 && pum_height > p_ph) 104 if (p_ph > 0 && pum_height > p_ph)
152 pum_height = p_ph; 105 pum_height = p_ph;
153 } 106
154 107 /* Put the pum below "row" if possible. If there are few lines decide
155 /* don't display when we only have room for one line */ 108 * on where there is more room. */
156 if (pum_height < 1 || (pum_height == 1 && size > 1)) 109 if (row + 2 >= below_row - pum_height
157 return; 110 && row - above_row > (below_row - above_row) / 2)
111 {
112 /* pum above "row" */
113
114 /* Leave two lines of context if possible */
115 if (curwin->w_wrow - curwin->w_cline_row >= 2)
116 context_lines = 2;
117 else
118 context_lines = curwin->w_wrow - curwin->w_cline_row;
119
120 if (row >= size + context_lines)
121 {
122 pum_row = row - size - context_lines;
123 pum_height = size;
124 }
125 else
126 {
127 pum_row = 0;
128 pum_height = row - context_lines;
129 }
130 if (p_ph > 0 && pum_height > p_ph)
131 {
132 pum_row += pum_height - p_ph;
133 pum_height = p_ph;
134 }
135 }
136 else
137 {
138 /* pum below "row" */
139
140 /* Leave two lines of context if possible */
141 if (curwin->w_cline_row
142 + curwin->w_cline_height - curwin->w_wrow >= 3)
143 context_lines = 3;
144 else
145 context_lines = curwin->w_cline_row
146 + curwin->w_cline_height - curwin->w_wrow;
147
148 pum_row = row + context_lines;
149 if (size > below_row - pum_row)
150 pum_height = below_row - pum_row;
151 else
152 pum_height = size;
153 if (p_ph > 0 && pum_height > p_ph)
154 pum_height = p_ph;
155 }
156
157 /* don't display when we only have room for one line */
158 if (pum_height < 1 || (pum_height == 1 && size > 1))
159 return;
158 160
159 #if defined(FEAT_QUICKFIX) 161 #if defined(FEAT_QUICKFIX)
160 /* If there is a preview window at the above avoid drawing over it. */ 162 /* If there is a preview window at the above avoid drawing over it. */
161 if (pvwin != NULL && pum_row < above_row && pum_height > above_row) 163 if (pvwin != NULL && pum_row < above_row && pum_height > above_row)
162 { 164 {
163 pum_row += above_row; 165 pum_row += above_row;
164 pum_height -= above_row; 166 pum_height -= above_row;
165 } 167 }
166 #endif 168 #endif
167 169
168 /* Compute the width of the widest match and the widest extra. */ 170 /* Compute the width of the widest match and the widest extra. */
169 for (i = 0; i < size; ++i) 171 for (i = 0; i < size; ++i)
170 { 172 {
171 w = vim_strsize(array[i].pum_text); 173 w = vim_strsize(array[i].pum_text);
172 if (max_width < w) 174 if (max_width < w)
173 max_width = w; 175 max_width = w;
174 if (array[i].pum_kind != NULL) 176 if (array[i].pum_kind != NULL)
175 { 177 {
176 w = vim_strsize(array[i].pum_kind) + 1; 178 w = vim_strsize(array[i].pum_kind) + 1;
177 if (kind_width < w) 179 if (kind_width < w)
178 kind_width = w; 180 kind_width = w;
179 } 181 }
180 if (array[i].pum_extra != NULL) 182 if (array[i].pum_extra != NULL)
181 { 183 {
182 w = vim_strsize(array[i].pum_extra) + 1; 184 w = vim_strsize(array[i].pum_extra) + 1;
183 if (extra_width < w) 185 if (extra_width < w)
184 extra_width = w; 186 extra_width = w;
185 } 187 }
186 } 188 }
187 pum_base_width = max_width; 189 pum_base_width = max_width;
188 pum_kind_width = kind_width; 190 pum_kind_width = kind_width;
189 191
190 /* Calculate column */ 192 /* Calculate column */
191 #ifdef FEAT_RIGHTLEFT
192 if (curwin->w_p_rl)
193 col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1;
194 else
195 #endif
196 col = curwin->w_wincol + curwin->w_wcol;
197
198 /* if there are more items than room we need a scrollbar */
199 if (pum_height < size)
200 {
201 pum_scrollbar = 1;
202 ++max_width;
203 }
204 else
205 pum_scrollbar = 0;
206
207 if (def_width < max_width)
208 def_width = max_width;
209
210 if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
211 #ifdef FEAT_RIGHTLEFT
212 && !curwin->w_p_rl)
213 || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)
214 #endif
215 ))
216 {
217 /* align pum column with "col" */
218 pum_col = col;
219
220 #ifdef FEAT_RIGHTLEFT 193 #ifdef FEAT_RIGHTLEFT
221 if (curwin->w_p_rl) 194 if (curwin->w_p_rl)
222 pum_width = pum_col - pum_scrollbar + 1; 195 col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1;
223 else 196 else
224 #endif 197 #endif
225 pum_width = Columns - pum_col - pum_scrollbar; 198 col = curwin->w_wincol + curwin->w_wcol;
226 199
227 if (pum_width > max_width + kind_width + extra_width + 1 200 /* if there are more items than room we need a scrollbar */
228 && pum_width > PUM_DEF_WIDTH) 201 if (pum_height < size)
229 { 202 {
230 pum_width = max_width + kind_width + extra_width + 1; 203 pum_scrollbar = 1;
231 if (pum_width < PUM_DEF_WIDTH) 204 ++max_width;
232 pum_width = PUM_DEF_WIDTH; 205 }
233 }
234 }
235 else if (Columns < def_width)
236 {
237 /* not enough room, will use what we have */
238 #ifdef FEAT_RIGHTLEFT
239 if (curwin->w_p_rl)
240 pum_col = Columns - 1;
241 else 206 else
242 #endif 207 pum_scrollbar = 0;
243 pum_col = 0; 208
244 pum_width = Columns - 1; 209 if (def_width < max_width)
245 } 210 def_width = max_width;
246 else 211
247 { 212 if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
248 if (max_width > PUM_DEF_WIDTH) 213 #ifdef FEAT_RIGHTLEFT
249 max_width = PUM_DEF_WIDTH; /* truncate */ 214 && !curwin->w_p_rl)
250 #ifdef FEAT_RIGHTLEFT 215 || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)
251 if (curwin->w_p_rl) 216 #endif
252 pum_col = max_width - 1; 217 ))
218 {
219 /* align pum column with "col" */
220 pum_col = col;
221
222 #ifdef FEAT_RIGHTLEFT
223 if (curwin->w_p_rl)
224 pum_width = pum_col - pum_scrollbar + 1;
225 else
226 #endif
227 pum_width = Columns - pum_col - pum_scrollbar;
228
229 if (pum_width > max_width + kind_width + extra_width + 1
230 && pum_width > PUM_DEF_WIDTH)
231 {
232 pum_width = max_width + kind_width + extra_width + 1;
233 if (pum_width < PUM_DEF_WIDTH)
234 pum_width = PUM_DEF_WIDTH;
235 }
236 }
237 else if (Columns < def_width)
238 {
239 /* not enough room, will use what we have */
240 #ifdef FEAT_RIGHTLEFT
241 if (curwin->w_p_rl)
242 pum_col = Columns - 1;
243 else
244 #endif
245 pum_col = 0;
246 pum_width = Columns - 1;
247 }
253 else 248 else
254 #endif 249 {
255 pum_col = Columns - max_width; 250 if (max_width > PUM_DEF_WIDTH)
256 pum_width = max_width - pum_scrollbar; 251 max_width = PUM_DEF_WIDTH; /* truncate */
257 } 252 #ifdef FEAT_RIGHTLEFT
258 253 if (curwin->w_p_rl)
259 pum_array = array; 254 pum_col = max_width - 1;
260 pum_size = size; 255 else
261 256 #endif
262 /* Set selected item and redraw. If the window size changed need to redo 257 pum_col = Columns - max_width;
263 * the positioning. Limit this to two times, when there is not much 258 pum_width = max_width - pum_scrollbar;
264 * room the window size will keep changing. */ 259 }
265 if (pum_set_selected(selected, redo_count) && ++redo_count <= 2) 260
266 goto redo; 261 pum_array = array;
262 pum_size = size;
263
264 /* Set selected item and redraw. If the window size changed need to
265 * redo the positioning. Limit this to two times, when there is not
266 * much room the window size will keep changing. */
267 } while (pum_set_selected(selected, redo_count) && ++redo_count <= 2);
267 } 268 }
268 269
269 /* 270 /*
270 * Redraw the popup menu, using "pum_first" and "pum_selected". 271 * Redraw the popup menu, using "pum_first" and "pum_selected".
271 */ 272 */