Function: sort-columns

sort-columns is an autoloaded, interactive and byte-compiled function defined in sort.el.gz.

Signature

(sort-columns REVERSE &optional BEG END)

Documentation

Sort lines in region alphabetically by a certain range of columns.

For the purpose of this command, the region BEG...END includes the entire line that point is in and the entire line the mark is in. The column positions of point and mark bound the range of columns to sort on. A prefix argument means sort into REVERSE order. The variable sort-fold-case determines whether alphabetic case affects the sort order.

Note that sort-columns rejects text that contains tabs, because tabs could be split across the specified columns and it doesn't know how to handle that. Also, when possible, it uses the sort utility program, which doesn't understand tabs. Use M-x untabify (untabify) to convert tabs to spaces before sorting.

Probably introduced at or before Emacs version 18.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/sort.el.gz
;;;###autoload
(defun sort-columns (reverse &optional beg end)
  "Sort lines in region alphabetically by a certain range of columns.
For the purpose of this command, the region BEG...END includes
the entire line that point is in and the entire line the mark is in.
The column positions of point and mark bound the range of columns to sort on.
A prefix argument means sort into REVERSE order.
The variable `sort-fold-case' determines whether alphabetic case affects
the sort order.

Note that `sort-columns' rejects text that contains tabs,
because tabs could be split across the specified columns
and it doesn't know how to handle that.  Also, when possible,
it uses the `sort' utility program, which doesn't understand tabs.
Use \\[untabify] to convert tabs to spaces before sorting."
  (interactive "P\nr")
  (save-excursion
    (let ;; To make `end-of-line' and etc. to ignore fields.
	((inhibit-field-text-motion t)
	 beg1 end1 col-beg1 col-end1 col-start col-end)
      (goto-char (min beg end))
      (setq col-beg1 (current-column))
      (beginning-of-line)
      (setq beg1 (point))
      (goto-char (max beg end))
      (setq col-end1 (current-column))
      (forward-line)
      (setq end1 (point))
      (setq col-start (min col-beg1 col-end1))
      (setq col-end (max col-beg1 col-end1))
      (if (search-backward "\t" beg1 t)
          (error (substitute-command-keys
                  "sort-columns does not work with tabs -- use \\[untabify]")))
      (if (not (or (memq system-type '(windows-nt))
		   (let ((pos beg1) plist fontified)
		     (catch 'found
		       (while (< pos end1)
			 (setq plist (text-properties-at pos))
			 (setq fontified (plist-get plist 'fontified))
			 (while (consp plist)
			   (unless (or (eq (car plist) 'fontified)
				       (and (eq (car plist) 'face)
					    fontified))
			     (throw 'found t))
			   (setq plist (cddr plist)))
			 (setq pos (next-property-change pos nil end1)))))))
	  ;; Use the sort utility if we can; it is 4 times as fast.
	  ;; Do not use it if there are any non-font-lock properties
	  ;; in the region, since the sort utility would lose the
	  ;; properties.  Tabs are used as field separator; on NetBSD,
	  ;; sort complains if "\n" is used as field separator.
	  (let ((sort-args (list (if reverse "-rt\t" "-t\t")
				 (format "-k1.%d,1.%d"
					 (1+ col-start)
					 (1+ col-end)))))
	    (when sort-fold-case
	      (push "-f" sort-args))
	    (apply #'call-process-region beg1 end1 "sort" t t nil sort-args))
	;; On ms-windows, use Emacs's own facilities.
	(save-excursion
	  (save-restriction
	    (narrow-to-region beg1 end1)
	    (goto-char beg1)
	    (sort-subr reverse 'forward-line 'end-of-line
		       #'(lambda () (move-to-column col-start) nil)
		       #'(lambda () (move-to-column col-end) nil))))))))