unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Colin Walters <walters@verbum.org>
Cc: emacs-devel@gnu.org, xemacs-design@xemacs.org
Subject: Re: API changes
Date: 18 May 2002 15:54:53 -0400	[thread overview]
Message-ID: <1021751693.16292.1954.camel@space-ghost> (raw)
In-Reply-To: <013e01c1fd9e$af600450$772efea9@neeeeeee>

[-- Attachment #1: Type: text/plain, Size: 731 bytes --]

> OK, i agree with the change and I made it.  I'm attaching the new code.  

Well, I was about halfway through implementing it myself, so I just went
ahead and finished my implementation.  Along the way, there were enough
different cases to worry about that I wrote a little test suite; please
find it attached, along with my implementation.

Try typing M-C-x on the test suite; your implementation seems to behave
differently when the string is truncated, but too small to contain the
ellipsis.  In that case I just returned the truncated string.  On the
other test suite entries we agreed on the output.

(Incidentally, something is strange with your mail; your comments came
*after* the ----- Original Message ----- delimiter)


[-- Attachment #2: tstw-test.el --]
[-- Type: text/x-emacs-lisp, Size: 5098 bytes --]

;; -*- mode: emacs-lisp; coding: iso-2022-7bit -*-

;;;###autoload
(defun truncate-string-to-width (str end-column
				     &optional start-column padding ellipsis)
  "Truncate string STR to end at column END-COLUMN.
The optional 3rd arg START-COLUMN, if non-nil, specifies the starting
column; that means to return the characters occupying columns
START-COLUMN ... END-COLUMN of STR.  Both END-COLUMN and START-COLUMN
are specified in terms of character display width in the current
buffer; see also `char-width'.

The optional 4th arg PADDING, if non-nil, specifies a padding
character (which should have a display width of 1) to add at the end
of the result if STR doesn't reach column END-COLUMN, or if END-COLUMN
comes in the middle of a character in STR.  PADDING is also added at
the beginning of the result if column START-COLUMN appears in the
middle of a character in STR.

If PADDING is nil, no padding is added in these cases, so
the resulting string may be narrower than END-COLUMN.

If ELLIPSIS is non-nil, it should be a string which will replace the
end of STR (including any padding) if it extends beyond END-COLUMN,
unless the display width of STR is equal to or less than the display
width of ELLIPSIS.  If it is non-nil and not a string, then ELLIPSIS
defaults to \"...\"."
  (or start-column
      (setq start-column 0))
  (when (and ellipsis (not (stringp ellipsis)))
    (setq ellipsis "..."))
  (let ((str-len (length str))
	(str-width (string-width str))
	(ellipsis-len (if ellipsis (length ellipsis) 0))
	(ellipsis-width (if ellipsis (string-width ellipsis) 0))
	(idx 0)
	(column 0)
	(head-padding "") (tail-padding "")
	ch last-column last-idx from-idx)
    (condition-case nil
	(while (< column start-column)
	  (setq ch (aref str idx)
		column (+ column (char-width ch))
		idx (1+ idx)))
      (args-out-of-range (setq idx str-len)))
    (if (< column start-column)
	(if padding (make-string end-column padding) "")
      (when (and padding (> column start-column))
	(setq head-padding (make-string (- column start-column) padding)))
      (setq from-idx idx)
      (when (>= end-column column)
	(if (and (< end-column str-width)
		 (> str-width ellipsis-width))
	    (setq end-column (- end-column ellipsis-width))
	  (setq ellipsis ""))
	(condition-case nil
	    (while (< column end-column)
	      (setq last-column column
		    last-idx idx
		    ch (aref str idx)
		    column (+ column (char-width ch))
		    idx (1+ idx)))
	  (args-out-of-range (setq idx str-len)))
	(when (> column end-column)
	  (setq column last-column
		idx last-idx))
	(when (and padding (< column end-column))
	  (setq tail-padding (make-string (- end-column column) padding))))
      (concat head-padding (substring str from-idx idx)
	      tail-padding ellipsis))))

(dolist (test '(
		(("" 0) . "")
		(("x" 1) . "x")
		(("xy" 1) . "x")
		(("xy" 2 1) . "y")
		(("xy" 0) . "")
		(("xy" 3) . "xy")
		(("^[$AVP^[(B" 0) . "")
		(("^[$AVP^[(B" 1) . "")
		(("^[$AVP^[(B" 2) . "^[$AVP^[(B")
		(("^[$AVP^[(B" 1 nil ? ) . " ")
		(("^[$AVPND^[(B" 3 1 ? ) . "  ")
		(("x^[$AVP^[(Bx" 2) . "x")
		(("x^[$AVP^[(Bx" 3) . "x^[$AVP^[(B")
		(("x^[$AVP^[(Bx" 3) . "x^[$AVP^[(B")
		(("x^[$AVP^[(Bx" 4 1) . "^[$AVP^[(Bx")
		(("kor^[$(CGQ^[(Be^[$(C1[^[(Ban" 8 1 ? ) . "or^[$(CGQ^[(Be^[$(C1[^[(B")
		(("kor^[$(CGQ^[(Be^[$(C1[^[(Ban" 7 2 ? ) . "r^[$(CGQ^[(Be ")
		(("" 0 nil nil "...") . "")
		(("x" 3 nil nil "...") . "x")
		(("^[$AVP^[(B" 3 nil nil "...") . "^[$AVP^[(B")
		(("foo" 3 nil nil "...") . "foo")
		(("foo" 2 nil nil "...") . "fo") ;; XEmacs failure?
		(("foobar" 6 0 nil "...") . "foobar")
		(("foobarbaz" 6 nil nil "...") . "foo...")
		(("foobarbaz" 7 2 nil "...") . "ob...")
		(("foobarbaz" 9 3 nil "...") . "barbaz")
		(("^[$B$3^[(Bh^[$B$s^[(Be^[$B$K^[(Bl^[$B$A^[(Bl^[$B$O^[(Bo" 15 1 ?  t) . " h^[$B$s^[(Be^[$B$K^[(Bl^[$B$A^[(Bl^[$B$O^[(Bo")
		(("^[$B$3^[(Bh^[$B$s^[(Be^[$B$K^[(Bl^[$B$A^[(Bl^[$B$O^[(Bo" 14 1 ?  t) . " h^[$B$s^[(Be^[$B$K^[(Bl^[$B$A^[(B...")
		(("x" 3 nil nil "^[$(0GnM$^[(B") . "x")
		(("^[$AVP^[(B" 2 nil nil "^[$(0GnM$^[(B") . "^[$AVP^[(B")
		(("^[$AVP^[(B" 1 nil ?x "^[$(0GnM$^[(B") . "x") ;; XEmacs error
		(("^[$AVPND^[(B" 3 nil ?  "^[$(0GnM$^[(B") . "^[$AVP^[(B ") ;; XEmacs error
		(("foobarbaz" 4 nil nil  "^[$(0GnM$^[(B") . "^[$(0GnM$^[(B")
		(("foobarbaz" 5 nil nil  "^[$(0GnM$^[(B") . "f^[$(0GnM$^[(B")
		(("foobarbaz" 6 nil nil  "^[$(0GnM$^[(B") . "fo^[$(0GnM$^[(B")
		(("foobarbaz" 8 3 nil "^[$(0GnM$^[(B") . "b^[$(0GnM$^[(B")
		(("^[$B$3^[(Bh^[$B$s^[(Be^[$B$K^[(Bl^[$B$A^[(Bl^[$B$O^[(Bo" 14 4 ?x "^[$BF|K\8l^[(B") . "xe^[$B$KF|K\8l^[(B")
		(("^[$B$3^[(Bh^[$B$s^[(Be^[$B$K^[(Bl^[$B$A^[(Bl^[$B$O^[(Bo" 13 4 ?x "^[$BF|K\8l^[(B") . "xex^[$BF|K\8l^[(B")
		))
  (let (ret)
    (condition-case e 
	(setq ret (apply #'truncate-string-to-width (car test)))
      (error (setq ret e)))
    (unless (equal ret (cdr test))
      (error "%s: expected %s, got %s"
	     (prin1-to-string (cons 'truncate-string-to-width (car test)))
	     (prin1-to-string (cdr test))
	     (if (consp ret)
		 (format "error: %s: %s" (car ret)
			 (prin1-to-string (cdr ret)))
	       (prin1-to-string ret))))))

  parent reply	other threads:[~2002-05-18 19:54 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <3CCAA9FF.4000905@666.com>
2002-04-28  0:58 ` API changes Daniel Pittman
2002-04-28  5:48 ` Colin Walters
2002-04-28 23:45 ` Stefan Monnier
2002-04-29  5:05 ` Richard Stallman
2002-05-04  6:26   ` Colin Walters
     [not found]   ` <1020493576.5286.5.camel@space-ghost>
2002-05-17 12:30     ` Ben Wing
2002-05-18 18:49       ` Richard Stallman
2002-05-18 19:54       ` Colin Walters [this message]
     [not found]         ` <200205191940.g4JJeij24049@aztec.santafe.edu>
2002-05-19 20:09           ` Colin Walters
2002-05-20  3:07             ` Stephen J. Turnbull
     [not found] ` <1019972901.27106.63.camel@space-ghost>
2002-04-29  5:05   ` Richard Stallman
2002-04-29  6:25     ` Colin Walters
2002-04-27 13:39 Ben Wing

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1021751693.16292.1954.camel@space-ghost \
    --to=walters@verbum.org \
    --cc=emacs-devel@gnu.org \
    --cc=xemacs-design@xemacs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).