commit e42a63a96004e2a5865dd3bc48f78f16a879e918 (HEAD, refs/remotes/origin/master) Author: Basil L. Contovounesios Date: Tue Dec 22 09:01:47 2020 +0000 ; Fix docstrings in last change to subr-x.el diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index dc046c3d76..09c4649817 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -293,7 +293,7 @@ is returned unchanged. If STRING is longer than LENGTH, return a substring consisting of the first LENGTH characters of STRING. If END is non-nil, return -the last LENTGH characters instead." +the last LENGTH characters instead." (unless (natnump length) (signal 'wrong-type-argument (list 'natnump length))) (cond @@ -331,8 +331,8 @@ If STRING is longer than the absolute value of LENGTH, no padding is done. If START is nil (or not present), the padding is done to the end -of the string, and non-nil, padding is done to the start of the -string." +of the string, and if non-nil, padding is done to the start of +the string." (unless (natnump length) (signal 'wrong-type-argument (list 'natnump length))) (let ((pad-length (- length (length string)))) commit 901532967873ab82d948024105b5736b622f518b Author: Daniel Martín Date: Tue Dec 22 07:36:41 2020 +0100 Fix wdired-get-filename when ls -F marks symlinks * lisp/wdired.el (wdired-get-filename): In some systems like BSD or macOS, "ls -F" marks symlinks with a trailing "@". Add logic accounting for this so that wdired-get-filename returns the correct filename. This change also fixes test "wdired-test-bug34915" on macOS and BSD systems (bug#34915). diff --git a/lisp/wdired.el b/lisp/wdired.el index b7dd4ee949..c2e1d0cafc 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -355,7 +355,10 @@ non-nil means return old filename." dired-permission-flags-regexp nil t) (goto-char (match-beginning 0)) (looking-at "l") - (search-forward " -> " (line-end-position) t))) + (if (and used-F + dired-ls-F-marks-symlinks) + (re-search-forward "@? -> " (line-end-position) t) + (search-forward " -> " (line-end-position) t)))) (goto-char (match-beginning 0)) (setq end (point))) (when (and used-F commit 051d8f75350e54009180cc2fa5e5f86c92db1e13 Author: Lars Ingebrigtsen Date: Tue Dec 22 06:59:25 2020 +0100 Make string-pad take an optional START parameter * lisp/emacs-lisp/subr-x.el (string-pad): Alter the calling convention. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 80e936e974..ef848ac510 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -418,13 +418,13 @@ 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 +@defun string-pad string length &optional padding start 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). +@var{start} is @code{nil} (or not present), the padding is done to the +end of the string, and if it's non-@code{nil}, to the start of the +string. @end defun @defun string-chop-newline string diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index eb57e70660..e9e1be1d55 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -134,7 +134,7 @@ There can be any number of :example/:result elements." (string-pad :eval (string-pad "foo" 5) :eval (string-pad "foobar" 5) - :eval (string-pad "foo" -5 ?-)) + :eval (string-pad "foo" 5 ?- t)) (mapcar :eval (mapcar #'identity "123")) (format diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index b79482fd4b..dc046c3d76 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -322,7 +322,7 @@ The boundaries that match REGEXP are included in the result." (push (substring string start-substring) result) (nreverse result)))) -(defun string-pad (string length &optional padding) +(defun string-pad (string length &optional padding start) "Pad STRING to LENGTH using PADDING. If PADDING is nil, the space character is used. If not nil, it should be a character. @@ -330,16 +330,18 @@ 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 +If START is nil (or not present), the padding is done to the end +of the string, and non-nil, padding is done to the start of the string." - (let ((pad-length (- (abs length) (length string)))) + (unless (natnump length) + (signal 'wrong-type-argument (list 'natnump length))) + (let ((pad-length (- length (length string)))) (if (< pad-length 0) string - (concat (and (< length 0) + (concat (and start (make-string pad-length (or padding ?\s))) string - (and (> length 0) + (and (not start) (make-string pad-length (or padding ?\s))))))) (defun string-chop-newline (string) diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index 52b4809514..854d61ed28 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -613,7 +613,7 @@ (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" 5 ?- t) "--foo")) (should (equal (string-pad "foo" 2 ?-) "foo"))) (ert-deftest subr-string-chop-newline () commit 9480169f1b8a27ed61db0913989c9a81339ccd9d Author: Lars Ingebrigtsen Date: Tue Dec 22 06:54:32 2020 +0100 Change the string-limit parameter semantics * lisp/emacs-lisp/subr-x.el (string-limit): Alter the calling convention. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 17cc1a4712..80e936e974 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -405,13 +405,12 @@ there are individual words that are longer than @var{length}, these will not be shortened. @end defun -@defun string-limit string length -Return a string that's shorter than @var{length}. If @var{string} is -shorter than @var{length}, @var{string} is returned as is. If -@var{length} is positive, return a substring of @var{string} -consisting of the first @var{length} characters. If @var{length} is -negative, return a string of the @var{-length} last characters -instead. +@defun string-limit string length &optional end +If @var{string} is shorter than @var{length}, @var{string} is returned +as is. Otherwise, return a substring of @var{string} consisting of +the first @var{length} characters. If the optional @var{end} +parameter is given, return a string of the @var{length} last +characters instead. @end defun @defun string-lines string &optional omit-nulls diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 7bb7d233b4..eb57e70660 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -145,7 +145,7 @@ There can be any number of :example/:result elements." :eval (substring "foobar" 3)) (string-limit :eval (string-limit "foobar" 3) - :eval (string-limit "foobar" -3) + :eval (string-limit "foobar" 3 t) :eval (string-limit "foobar" 10)) (split-string :eval (split-string "foo bar") diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 6f4f7ed5dc..b79482fd4b 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -286,17 +286,20 @@ result will have lines that are longer than LENGTH." (fill-region (point-min) (point-max))) (buffer-string))) -(defun string-limit (string length) +(defun string-limit (string length &optional end) "Return (up to) a LENGTH substring of STRING. If STRING is shorter than or equal to LENGTH, the entire string -is returned unchanged. If STRING is longer than LENGTH, and -LENGTH is a positive number, return a substring consisting of the -first LENGTH characters of STRING. If LENGTH is negative, return -a substring consisting of the last LENGTH characters of STRING." +is returned unchanged. + +If STRING is longer than LENGTH, return a substring consisting of +the first LENGTH characters of STRING. If END is non-nil, return +the last LENTGH characters instead." + (unless (natnump length) + (signal 'wrong-type-argument (list 'natnump length))) (cond - ((<= (length string) (abs length)) string) - ((>= length 0) (substring string 0 length)) - ((substring string length)))) + ((<= (length string) length) string) + (end (substring string (- (length string) length))) + (t (substring string 0 length)))) (defun string-lines (string &optional omit-nulls) "Split STRING into a list of lines. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index 2e16cd0f30..52b4809514 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -595,9 +595,10 @@ (ert-deftest subr-string-limit () (should (equal (string-limit "foo" 10) "foo")) (should (equal (string-limit "foo" 2) "fo")) - (should (equal (string-limit "foo" -2) "oo")) - (should (equal (string-limit "abc" -10) "abc")) - (should (equal (string-limit "foo" 0) ""))) + (should (equal (string-limit "foo" 2 t) "oo")) + (should (equal (string-limit "abc" 10 t) "abc")) + (should (equal (string-limit "foo" 0) "")) + (should-error (string-limit "foo" -1))) (ert-deftest subr-string-lines () (should (equal (string-lines "foo") '("foo"))) commit d2b86118629562600c07dbc5befa78ac8b860b68 Author: Lars Ingebrigtsen Date: Tue Dec 22 04:24:25 2020 +0100 Further string-clean-whitespace tweaks * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Put \r back, which was mistakenly removed. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index aa39fc1538..6f4f7ed5dc 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -269,7 +269,7 @@ carriage return." All sequences of whitespaces in STRING are collapsed into a single space character, and leading/trailing whitespace is removed." - (let ((blank "[[:blank:]\n]+")) + (let ((blank "[[:blank:]\r\n]+")) (string-trim (replace-regexp-in-string blank " " string t t) blank blank))) diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index ab5a5bfa64..2e16cd0f30 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -584,7 +584,7 @@ (ert-deftest subr-clean-whitespace () (should (equal (string-clean-whitespace " foo ") "foo")) - (should (equal (string-clean-whitespace " foo \n\t Bar") "foo Bar"))) + (should (equal (string-clean-whitespace " foo \r\n\t  Bar") "foo Bar"))) (ert-deftest subr-string-fill () (should (equal (string-fill "foo" 10) "foo")) commit c69c65676dbca582dc6c2e59b7e19baf5da4caf0 Author: Dmitry Gutov Date: Tue Dec 22 03:15:45 2020 +0200 (ruby-mode-set-encoding): Use 'save-restriction' * lisp/progmodes/ruby-mode.el (ruby-mode-set-encoding): Use 'save-restriction' (bug#45349). diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 8cb0350dc0..45b0f84e33 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el @@ -780,24 +780,25 @@ The style of the comment is controlled by `ruby-encoding-magic-comment-style'." (defun ruby-mode-set-encoding () "Insert a magic comment header with the proper encoding if necessary." (save-excursion - (widen) - (goto-char (point-min)) - (when (ruby--encoding-comment-required-p) + (save-restriction + (widen) (goto-char (point-min)) - (let ((coding-system (ruby--detect-encoding))) - (when coding-system - (if (looking-at "^#!") (beginning-of-line 2)) - (cond ((looking-at "\\s *#.*\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)") - ;; update existing encoding comment if necessary - (unless (string= (match-string 2) coding-system) - (goto-char (match-beginning 2)) - (delete-region (point) (match-end 2)) - (insert coding-system))) - ((looking-at "\\s *#.*coding\\s *[:=]")) - (t (when ruby-insert-encoding-magic-comment - (ruby--insert-coding-comment coding-system)))) - (when (buffer-modified-p) - (basic-save-buffer-1))))))) + (when (ruby--encoding-comment-required-p) + (goto-char (point-min)) + (let ((coding-system (ruby--detect-encoding))) + (when coding-system + (if (looking-at "^#!") (beginning-of-line 2)) + (cond ((looking-at "\\s *#.*\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)") + ;; update existing encoding comment if necessary + (unless (string= (match-string 2) coding-system) + (goto-char (match-beginning 2)) + (delete-region (point) (match-end 2)) + (insert coding-system))) + ((looking-at "\\s *#.*coding\\s *[:=]")) + (t (when ruby-insert-encoding-magic-comment + (ruby--insert-coding-comment coding-system)))) + (when (buffer-modified-p) + (basic-save-buffer-1)))))))) (defvar ruby--electric-indent-chars '(?. ?\) ?} ?\])) commit 27fab4b140c57a82fac6864bbae0fd9ae1ef363c Author: Basil L. Contovounesios Date: Mon Dec 21 22:34:33 2020 +0000 Tiny string-clean-whitespace simplification * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Streamline by treating replacement string as being literal and having fixed case. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 1c8e1d6293..aa39fc1538 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -270,7 +270,7 @@ All sequences of whitespaces in STRING are collapsed into a single space character, and leading/trailing whitespace is removed." (let ((blank "[[:blank:]\n]+")) - (string-trim (replace-regexp-in-string blank " " string) + (string-trim (replace-regexp-in-string blank " " string t t) blank blank))) (defun string-fill (string length) commit 7e86d3bb9b61e3e2c2389e66370df037bd8a8f43 Author: Lars Ingebrigtsen Date: Mon Dec 21 23:18:05 2020 +0100 Make string-chop-newline more efficient * lisp/emacs-lisp/subr-x.el (string-chop-newline): Make more efficient. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 4d1a73a251..1c8e1d6293 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -341,7 +341,7 @@ string." (defun string-chop-newline (string) "Remove the final newline (if any) from STRING." - (replace-regexp-in-string "\n\\'" "" string)) + (string-remove-suffix "\n" string)) (defun replace-region-contents (beg end replace-fn &optional max-secs max-costs) commit 768522750ddbf68eb86b336fb41df9ec2fae6988 Author: Lars Ingebrigtsen Date: Mon Dec 21 22:41:37 2020 +0100 Make string-clean-whitespace work on non-ASCII whitespace, too * lisp/emacs-lisp/subr-x.el (string-clean-whitespace): Also clean up non-ASCII whitespace. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 80d4cb9b65..4d1a73a251 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -269,7 +269,9 @@ carriage return." All sequences of whitespaces in STRING are collapsed into a single space character, and leading/trailing whitespace is removed." - (string-trim (replace-regexp-in-string "[ \t\n\r]+" " " string))) + (let ((blank "[[:blank:]\n]+")) + (string-trim (replace-regexp-in-string blank " " string) + blank blank))) (defun string-fill (string length) "Try to word-wrap STRING so that no lines are longer than LENGTH. commit c9a95237a8e5d2c2e8ca3d6c97de8c7b5c1daaac Author: Lars Ingebrigtsen Date: Mon Dec 21 22:08:56 2020 +0100 Add try-completion to the string shortdoc * lisp/emacs-lisp/shortdoc.el (string): Mention try-completion here. diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 9bd06636f4..7bb7d233b4 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -192,6 +192,8 @@ There can be any number of :example/:result elements." :eval (reverse "foo")) (substring-no-properties :eval (substring-no-properties (propertize "foobar" 'face 'bold) 0 3)) + (try-completion + :eval (try-completion "foo" '("foobar" "foozot" "gazonk"))) "Predicates for Strings" (string-equal :eval (string-equal "foo" "foo")) commit f329a3180ead740bb85e1edfc48ae360a56f7ffd Author: Lars Ingebrigtsen Date: Mon Dec 21 22:05:37 2020 +0100 Add string-chop-newline * doc/lispref/strings.texi (Creating Strings): Document it. * lisp/emacs-lisp/subr-x.el (string-chop-newline): Add new function. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index c65d839a02..17cc1a4712 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -428,6 +428,10 @@ string, and if it's negative, to the start of the string (using the absolute value). @end defun +@defun string-chop-newline string +Remove the final newline, if any, from @var{string}. +@end defun + @node Modifying Strings @section Modifying Strings @cindex modifying strings diff --git a/etc/NEWS b/etc/NEWS index a6774be8f7..46b8435a14 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-lines', 'string-pad' and 'string-slice'. +'string-lines', 'string-pad', 'string-chop-newline' and 'string-slice'. +++ *** New variable 'current-minibuffer-command'. diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index df31b0aaf1..9bd06636f4 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -181,6 +181,8 @@ There can be any number of :example/:result elements." (string-remove-prefix :no-manual t :eval (string-remove-prefix "foo" "foobar")) + (string-chop-newline + :eval (string-chop-newline "foo\n")) (string-clean-whitespace :eval (string-clean-whitespace " foo bar ")) (string-fill diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 78d0b054b3..80d4cb9b65 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -337,6 +337,10 @@ string." (and (> length 0) (make-string pad-length (or padding ?\s))))))) +(defun string-chop-newline (string) + "Remove the final newline (if any) from STRING." + (replace-regexp-in-string "\n\\'" "" string)) + (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 c655fcf6ea..ab5a5bfa64 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -615,5 +615,10 @@ (should (equal (string-pad "foo" -5 ?-) "--foo")) (should (equal (string-pad "foo" 2 ?-) "foo"))) +(ert-deftest subr-string-chop-newline () + (should (equal (string-chop-newline "foo\n") "foo")) + (should (equal (string-chop-newline "foo\nbar\n") "foo\nbar")) + (should (equal (string-chop-newline "foo\nbar") "foo\nbar"))) + (provide 'subr-x-tests) ;;; subr-x-tests.el ends here commit e967ba301857edd15778a018ae716e4e98fa2fa9 Author: Basil L. Contovounesios Date: Mon Dec 21 20:40:12 2020 +0000 ; Fix recent string utility additions * etc/NEWS: Fix typo. * lisp/emacs-lisp/subr-x.el (string-limit): Fix typos in docstring. Simplify. (string-slice): Improve docstring wording. (string-pad): Simplify. diff --git a/etc/NEWS b/etc/NEWS index 1d50555c8e..a6774be8f7 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', 'string-pad' and 'string-slice'. +'string-lines', 'string-pad' and 'string-slice'. +++ *** New variable 'current-minibuffer-command'. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 05fa16da49..78d0b054b3 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -286,15 +286,15 @@ result will have lines that are longer than LENGTH." (defun string-limit (string length) "Return (up to) a LENGTH substring of STRING. -If STRING is shorter or equal to LENGTH, the entire string is -returned unchanged. If STRING is longer than LENGTH, and LENGTH -is a positive number, return a a substring consisting of the +If STRING is shorter than or equal to LENGTH, the entire string +is returned unchanged. If STRING is longer than LENGTH, and +LENGTH is a positive number, return a substring consisting of the first LENGTH characters of STRING. If LENGTH is negative, return -a substring consisitng of thelast LENGTH characters of STRING." +a substring consisting of the last LENGTH characters of STRING." (cond ((<= (length string) (abs length)) string) ((>= length 0) (substring string 0 length)) - (t (substring string (+ (length string) length))))) + ((substring string length)))) (defun string-lines (string &optional omit-nulls) "Split STRING into a list of lines. @@ -303,7 +303,7 @@ If OMIT-NULLS, empty lines will be removed from the results." (defun string-slice (string regexp) "Split STRING at REGEXP boundaries and return a list of slices. -The boundaries that match REGEXP are not omitted from the results." +The boundaries that match REGEXP are included in the result." (let ((start-substring 0) (start-search 0) (result nil)) @@ -328,9 +328,9 @@ 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)))) + (let ((pad-length (- (abs length) (length string)))) + (if (< pad-length 0) + string (concat (and (< length 0) (make-string pad-length (or padding ?\s))) string commit fd9431dde443471f17ffeebf9628fd9aee154e1b Author: Lars Ingebrigtsen Date: Mon Dec 21 20:42:17 2020 +0100 Fix shorter-than-length case for string-limit * lisp/emacs-lisp/subr-x.el (string-limit): Fix shorter-than-length case. diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index db7e75dfd2..05fa16da49 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -292,7 +292,7 @@ is a positive number, return a a substring consisting of the first LENGTH characters of STRING. If LENGTH is negative, return a substring consisitng of thelast LENGTH characters of STRING." (cond - ((<= (length string) length) string) + ((<= (length string) (abs length)) string) ((>= length 0) (substring string 0 length)) (t (substring string (+ (length string) length))))) diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index 6ed06d4ce4..c655fcf6ea 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -596,6 +596,7 @@ (should (equal (string-limit "foo" 10) "foo")) (should (equal (string-limit "foo" 2) "fo")) (should (equal (string-limit "foo" -2) "oo")) + (should (equal (string-limit "abc" -10) "abc")) (should (equal (string-limit "foo" 0) ""))) (ert-deftest subr-string-lines () commit cf2e8321850f81d9eb0ebc23a4887f12dc3dbfac Author: Lars Ingebrigtsen Date: Mon Dec 21 20:18:57 2020 +0100 Rename slice-string to string-slice * lisp/emacs-lisp/subr-x.el (string-slice): Rename from slice-string. * doc/lispref/strings.texi (Creating Strings): Ditto. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 958ae4c0a1..c65d839a02 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -381,13 +381,13 @@ The default value of @var{separators} for @code{split-string}. Its usual value is @w{@code{"[ \f\t\n\r\v]+"}}. @end defvar -@defun slice-string string regexp +@defun string-slice string regexp Split @var{string} into a list of strings on @var{regexp} boundaries. As opposed to @code{split-string}, the boundaries are included in the result set: @example -(slice-string " two words " " +") +(string-slice " two words " " +") @result{} (" two" " words" " ") @end example @end defun diff --git a/etc/NEWS b/etc/NEWS index 9b4fcd92fc..1d50555c8e 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', 'string-pad' and 'slice-string'. +'string-limit', 'string-pad' and 'string-slice'. +++ *** New variable 'current-minibuffer-command'. diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 3e1476adfc..df31b0aaf1 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -151,9 +151,9 @@ There can be any number of :example/:result elements." :eval (split-string "foo bar") :eval (split-string "|foo|bar|" "|") :eval (split-string "|foo|bar|" "|" t)) - (slice-string - :eval (slice-string "foo-bar" "-") - :eval (slice-string "foo-bar--zot-" "-+")) + (string-slice + :eval (string-slice "foo-bar" "-") + :eval (string-slice "foo-bar--zot-" "-+")) (string-lines :eval (string-lines "foo\n\nbar") :eval (string-lines "foo\n\nbar" t)) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 250ba6e6fa..db7e75dfd2 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -301,7 +301,7 @@ a substring consisitng of thelast LENGTH characters of STRING." If OMIT-NULLS, empty lines will be removed from the results." (split-string string "\n" omit-nulls)) -(defun slice-string (string regexp) +(defun string-slice (string regexp) "Split STRING at REGEXP boundaries and return a list of slices. The boundaries that match REGEXP are not omitted from the results." (let ((start-substring 0) diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index 94ff459869..6ed06d4ce4 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -602,11 +602,11 @@ (should (equal (string-lines "foo") '("foo"))) (should (equal (string-lines "foo \nbar") '("foo " "bar")))) -(ert-deftest subr-slice-string () - (should (equal (slice-string "foo-bar" "-") '("foo" "-bar"))) - (should (equal (slice-string "foo-bar-" "-") '("foo" "-bar" "-"))) - (should (equal (slice-string "-foo-bar-" "-") '("-foo" "-bar" "-"))) - (should (equal (slice-string "ooo" "lala") '("ooo")))) +(ert-deftest subr-string-slice () + (should (equal (string-slice "foo-bar" "-") '("foo" "-bar"))) + (should (equal (string-slice "foo-bar-" "-") '("foo" "-bar" "-"))) + (should (equal (string-slice "-foo-bar-" "-") '("-foo" "-bar" "-"))) + (should (equal (string-slice "ooo" "lala") '("ooo")))) (ert-deftest subr-string-pad () (should (equal (string-pad "foo" 5) "foo ")) commit b3dec3176673fa99e57e3916b36ea4367d47c0fa Author: Lars Ingebrigtsen Date: Mon Dec 21 20:01:28 2020 +0100 Add `string-pad' * doc/lispref/strings.texi (Creating Strings): Document it. * lisp/emacs-lisp/shortdoc.el (string): Add example. * lisp/emacs-lisp/subr-x.el (string-pad): New function. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index e4ca261751..958ae4c0a1 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 17c6ce61f9..9b4fcd92fc 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 8b11b57ff7..3e1476adfc 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 41a2079537..250ba6e6fa 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 949bbb163e..94ff459869 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 commit 87e422f1044068a4d27e5e4bfdbc664d9e4bbc43 Author: Lars Ingebrigtsen Date: Mon Dec 21 18:53:32 2020 +0100 Beef up the Emacs string utility set a bit * doc/lispref/strings.texi (Modifying Strings): Document them. * lisp/emacs-lisp/shortdoc.el (string): Add examples. * lisp/emacs-lisp/subr-x.el (string-clean-whitespace) (string-fill, string-limit, string-lines, slice-string): New functions. diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 0f157c39d6..e4ca261751 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -381,6 +381,44 @@ The default value of @var{separators} for @code{split-string}. Its usual value is @w{@code{"[ \f\t\n\r\v]+"}}. @end defvar +@defun slice-string string regexp +Split @var{string} into a list of strings on @var{regexp} boundaries. +As opposed to @code{split-string}, the boundaries are included in the +result set: + +@example +(slice-string " two words " " +") + @result{} (" two" " words" " ") +@end example +@end defun + +@defun string-clean-whitespace string +Clean up the whitespace in @var{string} by collapsing stretches of +whitespace to a single space character, as well as removing all +whitespace from the start and the end of @var{string}. +@end defun + +@defun string-fill string length +Attempt to Word-wrap @var{string} so that no lines are longer than +@var{length}. Filling is done on whitespace boundaries only. If +there are individual words that are longer than @var{length}, these +will not be shortened. +@end defun + +@defun string-limit string length +Return a string that's shorter than @var{length}. If @var{string} is +shorter than @var{length}, @var{string} is returned as is. If +@var{length} is positive, return a substring of @var{string} +consisting of the first @var{length} characters. If @var{length} is +negative, return a string of the @var{-length} last characters +instead. +@end defun + +@defun string-lines string &optional omit-nulls +Split @var{string} into a list of strings on newline boundaries. If +@var{omit-nulls}, remove empty lines from the results. +@end defun + @node Modifying Strings @section Modifying Strings @cindex modifying strings diff --git a/etc/NEWS b/etc/NEWS index 7411295e1b..17c6ce61f9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1440,6 +1440,11 @@ that makes it a valid button. ** Miscellaneous ++++ +*** A number of new string manipulation functions have been added. +'string-clean-whitespace', 'string-fill', 'string-limit', +'string-limit' and 'slice-string'. + +++ *** New variable 'current-minibuffer-command'. This is like 'this-command', but it is bound recursively when entering diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 37d6170fee..8b11b57ff7 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -139,10 +139,20 @@ There can be any number of :example/:result elements." (substring :eval (substring "foobar" 0 3) :eval (substring "foobar" 3)) + (string-limit + :eval (string-limit "foobar" 3) + :eval (string-limit "foobar" -3) + :eval (string-limit "foobar" 10)) (split-string :eval (split-string "foo bar") :eval (split-string "|foo|bar|" "|") :eval (split-string "|foo|bar|" "|" t)) + (slice-string + :eval (slice-string "foo-bar" "-") + :eval (slice-string "foo-bar--zot-" "-+")) + (string-lines + :eval (string-lines "foo\n\nbar") + :eval (string-lines "foo\n\nbar" t)) (string-replace :eval (string-replace "foo" "bar" "foozot")) (replace-regexp-in-string @@ -167,6 +177,11 @@ There can be any number of :example/:result elements." (string-remove-prefix :no-manual t :eval (string-remove-prefix "foo" "foobar")) + (string-clean-whitespace + :eval (string-clean-whitespace " foo bar ")) + (string-fill + :eval (string-fill "Three short words" 12) + :eval (string-fill "Long-word" 3)) (reverse :eval (reverse "foo")) (substring-no-properties diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index e6abb39ddc..41a2079537 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -264,6 +264,59 @@ carriage return." (substring string 0 (- (length string) (length suffix))) string)) +(defun string-clean-whitespace (string) + "Clean up whitespace in STRING. +All sequences of whitespaces in STRING are collapsed into a +single space character, and leading/trailing whitespace is +removed." + (string-trim (replace-regexp-in-string "[ \t\n\r]+" " " string))) + +(defun string-fill (string length) + "Try to word-wrap STRING so that no lines are longer than LENGTH. +Wrapping is done where there is whitespace. If there are +individual words in STRING that are longer than LENGTH, the +result will have lines that are longer than LENGTH." + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (let ((fill-column length) + (adaptive-fill-mode nil)) + (fill-region (point-min) (point-max))) + (buffer-string))) + +(defun string-limit (string length) + "Return (up to) a LENGTH substring of STRING. +If STRING is shorter or equal to LENGTH, the entire string is +returned unchanged. If STRING is longer than LENGTH, and LENGTH +is a positive number, return a a substring consisting of the +first LENGTH characters of STRING. If LENGTH is negative, return +a substring consisitng of thelast LENGTH characters of STRING." + (cond + ((<= (length string) length) string) + ((>= length 0) (substring string 0 length)) + (t (substring string (+ (length string) length))))) + +(defun string-lines (string &optional omit-nulls) + "Split STRING into a list of lines. +If OMIT-NULLS, empty lines will be removed from the results." + (split-string string "\n" omit-nulls)) + +(defun slice-string (string regexp) + "Split STRING at REGEXP boundaries and return a list of slices. +The boundaries that match REGEXP are not omitted from the results." + (let ((start-substring 0) + (start-search 0) + (result nil)) + (save-match-data + (while (string-match regexp string start-search) + (if (zerop (match-beginning 0)) + (setq start-search (match-end 0)) + (push (substring string start-substring (match-beginning 0)) result) + (setq start-substring (match-beginning 0) + start-search (match-end 0)))) + (push (substring string start-substring) result) + (nreverse result)))) + (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 9d14a5ab7e..949bbb163e 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -582,5 +582,31 @@ (should (equal (string-remove-suffix "a" "aa") "a")) (should (equal (string-remove-suffix "a" "ba") "b"))) +(ert-deftest subr-clean-whitespace () + (should (equal (string-clean-whitespace " foo ") "foo")) + (should (equal (string-clean-whitespace " foo \n\t Bar") "foo Bar"))) + +(ert-deftest subr-string-fill () + (should (equal (string-fill "foo" 10) "foo")) + (should (equal (string-fill "foobar" 5) "foobar")) + (should (equal (string-fill "foo bar zot" 5) "foo\nbar\nzot")) + (should (equal (string-fill "foo bar zot" 7) "foo bar\nzot"))) + +(ert-deftest subr-string-limit () + (should (equal (string-limit "foo" 10) "foo")) + (should (equal (string-limit "foo" 2) "fo")) + (should (equal (string-limit "foo" -2) "oo")) + (should (equal (string-limit "foo" 0) ""))) + +(ert-deftest subr-string-lines () + (should (equal (string-lines "foo") '("foo"))) + (should (equal (string-lines "foo \nbar") '("foo " "bar")))) + +(ert-deftest subr-slice-string () + (should (equal (slice-string "foo-bar" "-") '("foo" "-bar"))) + (should (equal (slice-string "foo-bar-" "-") '("foo" "-bar" "-"))) + (should (equal (slice-string "-foo-bar-" "-") '("-foo" "-bar" "-"))) + (should (equal (slice-string "ooo" "lala") '("ooo")))) + (provide 'subr-x-tests) ;;; subr-x-tests.el ends here commit e352abeac16725c226c1246e3c83f71b8d3fa689 Author: Eli Zaretskii Date: Mon Dec 21 19:27:02 2020 +0200 Fix frame creation on X when tool bar is disabled * src/xterm.c (handle_one_xevent): Restrict the fix for bug#44002 to situations when we are asked by the WM to create a window with bogus 1x1 dimensions. (Bug#44794) diff --git a/src/xterm.c b/src/xterm.c index 3de0d2e73c..7f8728e47c 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -8947,7 +8947,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!f && (f = any) && configureEvent.xconfigure.window == FRAME_X_WINDOW (f) - && FRAME_VISIBLE_P(f)) + && (FRAME_VISIBLE_P(f) + || !(configureEvent.xconfigure.width <= 1 + && configureEvent.xconfigure.height <= 1))) { block_input (); if (FRAME_X_DOUBLE_BUFFERED_P (f)) @@ -8962,7 +8964,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, f = 0; } #endif - if (f && FRAME_VISIBLE_P(f)) + if (f + && (FRAME_VISIBLE_P(f) + || !(configureEvent.xconfigure.width <= 1 + && configureEvent.xconfigure.height <= 1))) { #ifdef USE_GTK /* For GTK+ don't call x_net_wm_state for the scroll bar commit 2d19dbdd522feec8dde5c3339357b32f040a29dd Author: Michael Albinus Date: Mon Dec 21 16:37:29 2020 +0100 Fix permission problem in Tramp's copy-file * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-directly): Take care of PRESERVE-UID-GID. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index e6e718ebe3..0dbcb83536 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2234,7 +2234,7 @@ the uid and gid from FILENAME." (file-writable-p (concat prefix localname2)))) (tramp-do-copy-or-rename-file-directly op (concat prefix localname1) (concat prefix localname2) - ok-if-already-exists keep-date t) + ok-if-already-exists keep-date preserve-uid-gid) ;; We must change the ownership to the local user. (tramp-set-file-uid-gid (concat prefix localname2) commit faf3613cba8571eaef2709bd7bb6f11a956b9262 Author: Mattias Engdegård Date: Mon Dec 21 11:24:46 2020 +0100 ; * src/nsfns.m (all_nonzero_ascii): comment correction diff --git a/src/nsfns.m b/src/nsfns.m index 1deddb0d38..f3c5a9ef67 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -3010,7 +3010,7 @@ - (NSString *)panel: (id)sender userEnteredFilename: (NSString *)filename #endif -/* Whether N bytes at STR are in the [0,127] range. */ +/* Whether N bytes at STR are in the [1,127] range. */ static bool all_nonzero_ascii (unsigned char *str, ptrdiff_t n) { commit e470881a423bf43044cb65661772425fd3a24fff Author: Stefan Kangas Date: Mon Dec 21 16:22:42 2020 +0100 Drop XEmacs support for EDE ELisp projects * lisp/cedet/ede/proj-elisp.el (ede-proj-target-elisp): Remove XEmacs support. (ede-xemacs-compiler): Make obsolete. diff --git a/lisp/cedet/ede/proj-elisp.el b/lisp/cedet/ede/proj-elisp.el index bcd672133d..9847a36746 100644 --- a/lisp/cedet/ede/proj-elisp.el +++ b/lisp/cedet/ede/proj-elisp.el @@ -36,7 +36,7 @@ (keybindings :initform nil) (phony :initform t) (sourcetype :initform '(ede-source-emacs)) - (availablecompilers :initform '(ede-emacs-compiler ede-xemacs-compiler)) + (availablecompilers :initform '(ede-emacs-compiler)) (aux-packages :initarg :aux-packages :initform nil :type list @@ -104,6 +104,7 @@ For Emacs Lisp, return addsuffix command on source files." :name "xemacs" :variables '(("EMACS" . "xemacs"))) "Compile Emacs Lisp programs with XEmacs.") +(make-obsolete-variable 'ede-xemacs-compiler 'ede-emacs-compiler "28.1") ;;; Claiming files (cl-defmethod ede-buffer-mine ((this ede-proj-target-elisp) buffer)