aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1995-04-08 18:03:38 +0000
committerRichard M. Stallman1995-04-08 18:03:38 +0000
commitc412c8081c8365f77ffcc50862bf4a79c28386c8 (patch)
tree7e5027c09f98a394bdc2da3b13fab096ead79d04
parent41bf6a06459d0f62219a92aedbf9ca182c870b4f (diff)
downloademacs-c412c8081c8365f77ffcc50862bf4a79c28386c8.tar.gz
emacs-c412c8081c8365f77ffcc50862bf4a79c28386c8.zip
(string_width): New function.
(vmotion): Compute the width of minibuf_prompt if it isn't already known.
-rw-r--r--src/indent.c88
1 files changed, 87 insertions, 1 deletions
diff --git a/src/indent.c b/src/indent.c
index ef30c10aaad..fa757f97676 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -274,6 +274,84 @@ current_column ()
274 return col; 274 return col;
275} 275}
276 276
277/* Return the width in columns of the part of STRING from BEG to END.
278 If BEG is nil, that stands for the beginning of STRING.
279 If END is nil, that stands for the end of STRING. */
280
281static int
282string_width (string, beg, end)
283 Lisp_Object string, beg, end;
284{
285 register int col;
286 register unsigned char *ptr, *stop;
287 register int tab_seen;
288 int post_tab;
289 register int c;
290 register int tab_width = XINT (current_buffer->tab_width);
291 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
292 register struct Lisp_Vector *dp = buffer_display_table ();
293 int b, e;
294
295 if (NILP (end))
296 e = XSTRING (string)->size;
297 else
298 {
299 CHECK_NUMBER (end, 0);
300 e = XINT (end);
301 }
302
303 if (NILP (beg))
304 b = 0;
305 else
306 {
307 CHECK_NUMBER (beg, 0);
308 b = XINT (beg);
309 }
310
311 /* Make a pointer for decrementing through the chars before point. */
312 ptr = XSTRING (string)->data + e;
313 /* Make a pointer to where consecutive chars leave off,
314 going backwards from point. */
315 stop = XSTRING (string)->data + b;
316
317 if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
318
319 col = 0, tab_seen = 0, post_tab = 0;
320
321 while (1)
322 {
323 if (ptr == stop)
324 break;
325
326 c = *--ptr;
327 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
328 col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
329 else if (c >= 040 && c < 0177)
330 col++;
331 else if (c == '\n')
332 break;
333 else if (c == '\t')
334 {
335 if (tab_seen)
336 col = ((col + tab_width) / tab_width) * tab_width;
337
338 post_tab += col;
339 col = 0;
340 tab_seen = 1;
341 }
342 else
343 col += (ctl_arrow && c < 0200) ? 2 : 4;
344 }
345
346 if (tab_seen)
347 {
348 col = ((col + tab_width) / tab_width) * tab_width;
349 col += post_tab;
350 }
351
352 return col;
353}
354
277DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ", 355DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
278 "Indent from point with tabs and spaces until COLUMN is reached.\n\ 356 "Indent from point with tabs and spaces until COLUMN is reached.\n\
279Optional second argument MIN says always do at least MIN spaces\n\ 357Optional second argument MIN says always do at least MIN spaces\n\
@@ -1009,7 +1087,15 @@ vmotion (from, vtarget, width, hscroll, window)
1009 && marker_position (XWINDOW (window)->start) == BEG 1087 && marker_position (XWINDOW (window)->start) == BEG
1010 here is deliberate; I think we want to measure from the prompt 1088 here is deliberate; I think we want to measure from the prompt
1011 position even if the minibuffer window has scrolled. */ 1089 position even if the minibuffer window has scrolled. */
1012 int start_hpos = (EQ (window, minibuf_window) ? minibuf_prompt_width : 0); 1090 int start_hpos = 0;
1091
1092 if (EQ (window, minibuf_window))
1093 {
1094 if (minibuf_prompt_width == 0)
1095 minibuf_prompt_width = string_width (minibuf_prompt, Qnil, Qnil);
1096
1097 start_hpos = minibuf_prompt_width;
1098 }
1013 1099
1014 retry: 1100 retry:
1015 if (vtarget > vpos) 1101 if (vtarget > vpos)