diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index e4ca2617512..958ae4c0a15 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -419,6 +419,15 @@ Split @var{string} into a list of strings on newline boundaries. If @var{omit-nulls}, remove empty lines from the results. @end defun +@defun string-pad string length &optional padding +Pad @var{string} to the be of @var{length} using @var{padding} as the +padding character (defaulting to the space character). If +@var{string} is shorter than @var{length}, no padding is done. If +@var{length} is positive, the padding is done to the end of the +string, and if it's negative, to the start of the string (using the +absolute value). +@end defun + @node Modifying Strings @section Modifying Strings @cindex modifying strings diff --git a/etc/NEWS b/etc/NEWS index 17c6ce61f94..9b4fcd92fc1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1443,7 +1443,7 @@ that makes it a valid button. +++ *** A number of new string manipulation functions have been added. 'string-clean-whitespace', 'string-fill', 'string-limit', -'string-limit' and 'slice-string'. +'string-limit', 'string-pad' and 'slice-string'. +++ *** New variable 'current-minibuffer-command'. diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 8b11b57ff7f..3e1476adfc1 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -131,6 +131,10 @@ There can be any number of :example/:result elements." (mapconcat :eval (mapconcat (lambda (a) (concat "[" a "]")) '("foo" "bar" "zot") " ")) + (string-pad + :eval (string-pad "foo" 5) + :eval (string-pad "foobar" 5) + :eval (string-pad "foo" -5 ?-)) (mapcar :eval (mapcar #'identity "123")) (format diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 41a20795378..250ba6e6fa2 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -317,6 +317,26 @@ The boundaries that match REGEXP are not omitted from the results." (push (substring string start-substring) result) (nreverse result)))) +(defun string-pad (string length &optional padding) + "Pad STRING to LENGTH using PADDING. +If PADDING is nil, the space character is used. If not nil, it +should be a character. + +If STRING is longer than the absolute value of LENGTH, no padding +is done. + +If LENGTH is positive, the padding is done to the end of the +string, and if it's negative, padding is done to the start of the +string." + (if (> (length string) (abs length)) + string + (let ((pad-length (- (abs length) (length string)))) + (concat (and (< length 0) + (make-string pad-length (or padding ?\s))) + string + (and (> length 0) + (make-string pad-length (or padding ?\s))))))) + (defun replace-region-contents (beg end replace-fn &optional max-secs max-costs) "Replace the region between BEG and END using REPLACE-FN. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index 949bbb163eb..94ff459869c 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -608,5 +608,11 @@ (should (equal (slice-string "-foo-bar-" "-") '("-foo" "-bar" "-"))) (should (equal (slice-string "ooo" "lala") '("ooo")))) +(ert-deftest subr-string-pad () + (should (equal (string-pad "foo" 5) "foo ")) + (should (equal (string-pad "foo" 5 ?-) "foo--")) + (should (equal (string-pad "foo" -5 ?-) "--foo")) + (should (equal (string-pad "foo" 2 ?-) "foo"))) + (provide 'subr-x-tests) ;;; subr-x-tests.el ends here