Function: org-table-sort-lines

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

Signature

(org-table-sort-lines &optional WITH-CASE SORTING-TYPE GETKEY-FUNC COMPARE-FUNC INTERACTIVE\?)

Documentation

Sort table lines according to the column at point.

The position of point indicates the column to be used for sorting, and the range of lines is the range between the nearest horizontal separator lines, or the entire table of no such lines exist. If point is before the first column, you will be prompted for the sorting column. If there is an active region, the mark specifies the first line and the sorting column, while point should be in the last line to be included into the sorting.

The command then prompts for the sorting type which can be alphabetically, numerically, or by time (as given in a time stamp in the field, or as a HH:MM value). Sorting in reverse order is also possible.

With prefix argument WITH-CASE, alphabetic sorting will be case-sensitive if the locale allows for it.

If SORTING-TYPE is specified when this function is called from a Lisp program, no prompting will take place. SORTING-TYPE must be a character, any of (?a ?A ?n ?N ?t ?T ?f ?F) where the capital letters indicate that sorting should be done in reverse order.

If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies a function to be called to extract the key. It must return a value that is compatible with COMPARE-FUNC, the function used to compare entries.

A non-nil value for INTERACTIVE? is used to signal that this function is being called interactively.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-table.el.gz
;;;###autoload
(defun org-table-sort-lines
    (&optional with-case sorting-type getkey-func compare-func interactive?)
  "Sort table lines according to the column at point.

The position of point indicates the column to be used for
sorting, and the range of lines is the range between the nearest
horizontal separator lines, or the entire table of no such lines
exist.  If point is before the first column, you will be prompted
for the sorting column.  If there is an active region, the mark
specifies the first line and the sorting column, while point
should be in the last line to be included into the sorting.

The command then prompts for the sorting type which can be
alphabetically, numerically, or by time (as given in a time stamp
in the field, or as a HH:MM value).  Sorting in reverse order is
also possible.

With prefix argument WITH-CASE, alphabetic sorting will be case-sensitive
if the locale allows for it.

If SORTING-TYPE is specified when this function is called from a Lisp
program, no prompting will take place.  SORTING-TYPE must be a character,
any of (?a ?A ?n ?N ?t ?T ?f ?F) where the capital letters indicate that
sorting should be done in reverse order.

If the SORTING-TYPE is ?f or ?F, then GETKEY-FUNC specifies
a function to be called to extract the key.  It must return a value
that is compatible with COMPARE-FUNC, the function used to compare
entries.

A non-nil value for INTERACTIVE? is used to signal that this
function is being called interactively."
  (interactive (list current-prefix-arg nil nil nil t))
  (when (org-region-active-p) (goto-char (region-beginning)))
  ;; Point must be either within a field or before a data line.
  (save-excursion
    (skip-chars-backward " \t")
    (when (bolp) (search-forward "|" (line-end-position) t))
    (org-table-check-inside-data-field))
  ;; Set appropriate case sensitivity and column used for sorting.
  (let ((column (let ((c (org-table-current-column)))
		  (cond ((> c 0) c)
			(interactive?
			 (read-number "Use column N for sorting: "))
			(t 1))))
	(sorting-type
	 (or sorting-type
	     (read-char-exclusive "Sort Table: [a]lphabetic, [n]umeric, \
\[t]ime, [f]unc.  A/N/T/F means reversed: ")))
	(start (org-table-begin))
	(end (org-table-end)))
    (save-restriction
      ;; Narrow buffer to appropriate sorting area.
      (if (org-region-active-p)
	  (progn (goto-char (region-beginning))
		 (narrow-to-region
		  (point)
		  (save-excursion (goto-char (region-end))
				  (line-beginning-position 2))))
	(narrow-to-region
	 (save-excursion
	   (if (re-search-backward org-table-hline-regexp start t)
	       (line-beginning-position 2)
	     start))
	 (if (save-excursion (re-search-forward org-table-hline-regexp end t))
	     (match-beginning 0)
	   end)))
      ;; Determine arguments for `sort-subr'.  Also record original
      ;; position.  `org-table-save-field' cannot help here since
      ;; sorting is too much destructive.
      (let* ((coordinates
	      (cons (count-lines (point-min) (line-beginning-position))
		    (current-column)))
	     (extract-key-from-field
	      ;; Function to be called on the contents of the field
	      ;; used for sorting in the current row.
	      (cl-case sorting-type
		((?n ?N) #'string-to-number)
		((?a ?A) #'org-sort-remove-invisible)
		((?t ?T)
		 (lambda (f)
		   (cond ((string-match org-ts-regexp-both f)
			  (float-time
			   (org-time-string-to-time (match-string 0 f))))
			 ((org-duration-p f) (org-duration-to-minutes f))
			 ((string-match "\\<[0-9]+:[0-9]\\{2\\}\\>" f)
			  (org-duration-to-minutes (match-string 0 f)))
			 (t 0))))
		((?f ?F)
		 (or getkey-func
		     (and interactive?
			  (org-read-function "Function for extracting keys: "))
		     (error "Missing key extractor to sort rows")))
		(t (user-error "Invalid sorting type `%c'" sorting-type))))
	     (predicate
	      (cl-case sorting-type
		((?n ?N ?t ?T) #'<)
		((?a ?A) (if with-case #'org-string-collate-lessp
			   (lambda (s1 s2) (org-string-collate-lessp s1 s2 nil t))))
		((?f ?F)
		 (or compare-func
		     (and interactive?
			  (org-read-function
			   "Function for comparing keys (empty for default \
`sort-subr' predicate): "
			   'allow-empty))))))
	     (shrunk-columns (remq column (org-table--list-shrunk-columns))))
	(goto-char (point-min))
	(sort-subr (memq sorting-type '(?A ?N ?T ?F))
		   (lambda ()
		     (forward-line)
		     (while (and (not (eobp))
				 (not (looking-at org-table-dataline-regexp)))
		       (forward-line)))
		   #'end-of-line
		   (lambda ()
		     (funcall extract-key-from-field
			      (org-trim (org-table-get-field column))))
		   nil
		   predicate)
	;; Hide all columns but the one being sorted.
	(org-table--shrink-columns shrunk-columns start end)
	;; Move back to initial field.
	(forward-line (car coordinates))
	(move-to-column (cdr coordinates))))))