summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2015-10-08 16:15:17 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2015-10-08 16:15:17 +0200
commit44cb8b16565f3a8f8d7472c2a7a779de8afacc27 (patch)
treecda55d5a6a23d94ccff32569db8fc3dac831edc8
parentd2ac2545294b4ac0f53b89010fc152cef56f654d (diff)
downloadorg-mode-44cb8b16565f3a8f8d7472c2a7a779de8afacc27.tar.gz
Remove maximum indentation without untabifying
* lisp/org.el (org-remove-indentation): (org-do-remove-indentation): Change algorithm so as not to untabify string or buffer. Only <tab> characters used for indentation may be removed. Reported-by: "Charles C. Berry" <ccberry@ucsd.edu> <http://permalink.gmane.org/gmane.emacs.orgmode/101768>
-rwxr-xr-xlisp/org.el48
1 files changed, 29 insertions, 19 deletions
diff --git a/lisp/org.el b/lisp/org.el
index 3645d5d..2f2f87e 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -22268,29 +22268,39 @@ leave it alone. If it is larger than ind, set it to the target."
l)))
(defun org-remove-indentation (code &optional n)
- "Remove the maximum common indentation from the lines in CODE.
-N may optionally be the number of spaces to remove."
+ "Remove maximum common indentation in string CODE and return it.
+N may optionally be the number of columns to remove. Return CODE
+as-is if removal failed."
(with-temp-buffer
(insert code)
- (org-do-remove-indentation n)
- (buffer-string)))
+ (if (org-do-remove-indentation n) (buffer-string) code)))
(defun org-do-remove-indentation (&optional n)
- "Remove the maximum common indentation from the buffer."
- (untabify (point-min) (point-max))
- (let ((min 10000) re)
- (if n
- (setq min n)
- (goto-char (point-min))
- (while (re-search-forward "^ *[^ \n]" nil t)
- (setq min (min min (1- (- (match-end 0) (match-beginning 0)))))))
- (unless (or (= min 0) (= min 10000))
- (setq re (format "^ \\{%d\\}" min))
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (replace-match "")
- (end-of-line 1))
- min)))
+ "Remove the maximum common indentation from the buffer.
+When optional argument N is a positive integer, remove exactly
+that much characters from indentation, if possible. Return nil
+if it fails."
+ (catch :exit
+ (goto-char (point-min))
+ ;; Find maximum common indentation, if not specified.
+ (let ((n (or n
+ (let ((min-ind (point-max)))
+ (save-excursion
+ (while (re-search-forward "^[ \t]*\\S-" nil t)
+ (let ((ind (1- (current-column))))
+ (if (zerop ind) (throw :exit nil)
+ (setq min-ind (min min-ind ind))))))
+ min-ind))))
+ (if (zerop n) (throw :exit nil)
+ ;; Remove exactly N indentation, but give up if not possible.
+ (while (not (eobp))
+ (let ((ind (progn (skip-chars-forward " \t") (current-column))))
+ (cond ((eolp) (delete-region (line-beginning-position) (point)))
+ ((< ind n) (throw :exit nil))
+ (t (org-indent-line-to (- ind n))))
+ (forward-line)))
+ ;; Signal success.
+ t))))
(defun org-fill-template (template alist)
"Find each %key of ALIST in TEMPLATE and replace it."