X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/854f487a96a07c8fe7fbbc10184e395305d8abb1..2b4e72e1d5ccecf590125c022a78a88755c779e5:/lisp/delim-col.el diff --git a/lisp/delim-col.el b/lisp/delim-col.el index 4b8bad3dda..09858ed21d 100644 --- a/lisp/delim-col.el +++ b/lisp/delim-col.el @@ -1,28 +1,28 @@ -;;; delim-col.el --- Prettify all columns in a region or rectangle. +;;; delim-col.el --- prettify all columns in a region or rectangle -;; Copyright (C) 1999 Vinicius Jose Latorre +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, +;; 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. -;; Author: Vinicius Jose Latorre -;; Time-stamp: <99/08/21 19:51:13 vinicius> -;; Version: 1.3 +;; Author: Vinicius Jose Latorre +;; Maintainer: Vinicius Jose Latorre +;; Version: 2.1 ;; Keywords: internal +;; X-URL: http://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre ;; This file is part of GNU Emacs. -;; This GNU Emacs is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published by the -;; Free Software Foundation; either version 2, or (at your option) any -;; later version. +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. -;; You should have received a copy of the GNU General Public License along -;; with GNU Emacs; see the file COPYING. If not, write to the Free -;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -;; 02111-1307, USA. +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -37,7 +37,7 @@ ;; ;; a b c d ;; aaaa bb ccc ddddd -;; aaa bbb cccc dddd +;; aaa bbb cccc dddd ;; aa bb ccccccc ddd ;; ;; And the following settings: @@ -45,7 +45,11 @@ ;; (setq delimit-columns-str-before "[ ") ;; (setq delimit-columns-str-after " ]") ;; (setq delimit-columns-str-separator ", ") +;; (setq delimit-columns-before "") +;; (setq delimit-columns-after "") ;; (setq delimit-columns-separator "\t") +;; (setq delimit-columns-format 'separator) +;; (setq delimit-columns-extra t) ;; ;; If you select the lines above and type: ;; @@ -58,7 +62,7 @@ ;; [ aaa , bbb, cccc , dddd ] ;; [ aa , bb , ccccccc, ddd ] ;; -;; But if you select start from the very first b and the very last c and type: +;; But if you select start from the very first b to the very last c and type: ;; ;; M-x delimit-columns-rectangle RET ;; @@ -69,12 +73,33 @@ ;; aaa [ bbb, cccc ] dddd ;; aa [ bb , ccccccc ] ddd ;; +;; Now, if we change settings to: +;; +;; (setq delimit-columns-before "<") +;; (setq delimit-columns-after ">") +;; +;; For the `delimit-columns-region' example above, the result is: +;; +;; [ , , , ] +;; [ , , , ] +;; [ , , , ] +;; [ , , , ] +;; +;; And for the `delimit-columns-rectangle' example above, the result is: +;; +;; a [ , ] d +;; aaaa [ , ] ddddd +;; aaa [ , ] dddd +;; aa [ , ] ddd +;; ;; Note that `delimit-columns-region' operates over all text region ;; selected, extending the region start to the beginning of line and the ;; region end to the end of line. While `delimit-columns-rectangle' ;; operates over the text rectangle selected which rectangle diagonal is ;; given by the region start and end. ;; +;; See `delimit-columns-format' variable documentation for column formating. +;; ;; `delimit-columns-region' is useful when you have columns of text that ;; are not well aligned, like: ;; @@ -88,6 +113,8 @@ ;; horse apple bus ;; dog pineapple car EXTRA ;; porcupine strawberry airplane +;; +;; Use `delimit-columns-customize' to customize delim-col package variables. ;;; Code: @@ -95,23 +122,136 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User Options: -(defvar delimit-columns-str-before "" - "*Specify a string to be inserted before all columns.") - -(defvar delimit-columns-str-separator ", " - "*Specify a string to be inserted between each column.") - -(defvar delimit-columns-str-after "" - "*Specify a string to be inserted after all columns.") - -(defvar delimit-columns-separator "\t" - "*Specify a regexp which separates each column.") +(defgroup columns nil + "Prettify columns." + :link '(emacs-library-link :tag "Source Lisp File" "delim-col.el") + :prefix "delimit-columns-" + :group 'internal) + +(defcustom delimit-columns-str-before "" + "Specify a string to be inserted before all columns." + :type '(string :tag "Before All Columns") + :group 'columns) + +(defcustom delimit-columns-str-separator ", " + "Specify a string to be inserted between each column." + :type '(string :tag "Between Each Column") + :group 'columns) + +(defcustom delimit-columns-str-after "" + "Specify a string to be inserted after all columns." + :type '(string :tag "After All Columns") + :group 'columns) + +(defcustom delimit-columns-before "" + "Specify a string to be inserted before each column." + :type '(string :tag "Before Each Column") + :group 'columns) + +(defcustom delimit-columns-after "" + "Specify a string to be inserted after each column." + :type '(string :tag "After Each Column") + :group 'columns) + +(defcustom delimit-columns-separator "\t" + "Specify a regexp which separates each column." + :type '(regexp :tag "Column Separator") + :group 'columns) + +(defcustom delimit-columns-format t + "Specify how to format columns. + +For examples below, consider: + + + columns `ccc' and `dddd', + + the maximum column length for each column is 6, + + and the following settings: + (setq delimit-columns-before \"<\") + (setq delimit-columns-after \">\") + (setq delimit-columns-separator \":\") + +Valid values are: + + nil no formating. That is, `delimit-columns-after' is followed by + `delimit-columns-separator'. + For example, the result is: \"::\" + + t align columns. That is, `delimit-columns-after' is followed by + `delimit-columns-separator' and then followed by spaces. + For example, the result is: \": : \" + + 'separator align separators. That is, `delimit-columns-after' is followed + by spaces and then followed by `delimit-columns-separator'. + For example, the result is: \" : :\" + + 'padding format column by filling with spaces before + `delimit-columns-after'. That is, spaces are followed by + `delimit-columns-after' and then followed by + `delimit-columns-separator'. + For example, the result is: \"::\" + +Any other value is treated as t." + :type '(choice :menu-tag "Column Formating" + :tag "Column Formating" + (const :tag "No Formating" nil) + (const :tag "Column Alignment" t) + (const :tag "Separator Aligment" separator) + (const :tag "Column Padding" padding)) + :group 'columns) + +(defcustom delimit-columns-extra t + "Non-nil means that lines will have the same number of columns. + +This has effect only when there are lines with different number of columns." + :type '(boolean :tag "Lines With Same Number Of Column") + :group 'columns) + +(defcustom delimit-columns-start 0 + "Specify column number to start prettifing. + +See also `delimit-columns-end' for documentation. + +The following relation must hold: + 0 <= delimit-columns-start <= delimit-columns-end + +The column number start from 0 and it's relative to the beginning of selected +region. So if you selected a text region, the first column (column 0) is +located at beginning of line. If you selected a text rectangle, the first +column (column 0) is located at left corner." + :type '(integer :tag "Column Start") + :group 'columns) + +(defcustom delimit-columns-end 1000000 + "Specify column number to end prettifing. + +See also `delimit-columns-start' for documentation. + +The following relation must hold: + 0 <= delimit-columns-start <= delimit-columns-end + +The column number start from 0 and it's relative to the beginning of selected +region. So if you selected a text region, the first column (column 0) is +located at beginning of line. If you selected a text rectangle, the first +column (column 0) is located at left corner." + :type '(integer :tag "Column End") + :group 'columns) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User Commands: +;;;###autoload +(defun delimit-columns-customize () + "Customization of `columns' group." + (interactive) + (customize-group 'columns)) + + +(defmacro delimit-columns-str (str) + `(if (stringp ,str) ,str "")) + + ;;;###autoload (defun delimit-columns-region (start end) "Prettify all columns in a text region. @@ -119,41 +259,50 @@ START and END delimits the text region." (interactive "*r") (let ((delimit-columns-str-before - (if (stringp delimit-columns-str-before) - delimit-columns-str-before - "")) + (delimit-columns-str delimit-columns-str-before)) (delimit-columns-str-separator - (if (stringp delimit-columns-str-separator) - delimit-columns-str-separator - " ")) + (delimit-columns-str delimit-columns-str-separator)) (delimit-columns-str-after - (if (stringp delimit-columns-str-after) - delimit-columns-str-after - "")) + (delimit-columns-str delimit-columns-str-after)) + (delimit-columns-before + (delimit-columns-str delimit-columns-before)) + (delimit-columns-after + (delimit-columns-str delimit-columns-after)) + (delimit-columns-start + (if (and (integerp delimit-columns-start) + (>= delimit-columns-start 0)) + delimit-columns-start + 0)) + (delimit-columns-end + (if (integerp delimit-columns-end) + delimit-columns-end + 1000000)) (delimit-columns-limit (make-marker)) (the-end (copy-marker end)) delimit-columns-max) - (save-excursion - (goto-char start) - (beginning-of-line) - ;; get maximum length for each column + (when (<= delimit-columns-start delimit-columns-end) (save-excursion + (goto-char start) + (beginning-of-line) + ;; get maximum length for each column + (and delimit-columns-format + (save-excursion + (while (< (point) the-end) + (delimit-columns-rectangle-max + (prog1 + (point) + (end-of-line))) + (forward-char 1)))) + ;; prettify columns (while (< (point) the-end) - (delimit-columns-rectangle-max + (delimit-columns-rectangle-line (prog1 (point) (end-of-line))) - (forward-char 1))) - ;; prettify columns - (while (< (point) the-end) - (delimit-columns-rectangle-line - (prog1 - (point) - (end-of-line))) - (forward-char 1)) - ;; nullify markers - (set-marker delimit-columns-limit nil) - (set-marker the-end nil)))) + (forward-char 1)) + ;; nullify markers + (set-marker delimit-columns-limit nil) + (set-marker the-end nil))))) (require 'rect) @@ -166,31 +315,40 @@ START and END delimits the text region." START and END delimits the corners of text rectangle." (interactive "*r") (let ((delimit-columns-str-before - (if (stringp delimit-columns-str-before) - delimit-columns-str-before - "")) + (delimit-columns-str delimit-columns-str-before)) (delimit-columns-str-separator - (if (stringp delimit-columns-str-separator) - delimit-columns-str-separator - " ")) + (delimit-columns-str delimit-columns-str-separator)) (delimit-columns-str-after - (if (stringp delimit-columns-str-after) - delimit-columns-str-after - "")) + (delimit-columns-str delimit-columns-str-after)) + (delimit-columns-before + (delimit-columns-str delimit-columns-before)) + (delimit-columns-after + (delimit-columns-str delimit-columns-after)) + (delimit-columns-start + (if (and (integerp delimit-columns-start) + (>= delimit-columns-start 0)) + delimit-columns-start + 0)) + (delimit-columns-end + (if (integerp delimit-columns-end) + delimit-columns-end + 1000000)) (delimit-columns-limit (make-marker)) (the-end (copy-marker end)) delimit-columns-max) - ;; get maximum length for each column - (save-excursion - (operate-on-rectangle 'delimit-columns-rectangle-max - start the-end t)) - ;; prettify columns - (save-excursion - (operate-on-rectangle 'delimit-columns-rectangle-line - start the-end t)) - ;; nullify markers - (set-marker delimit-columns-limit nil) - (set-marker the-end nil))) + (when (<= delimit-columns-start delimit-columns-end) + ;; get maximum length for each column + (and delimit-columns-format + (save-excursion + (operate-on-rectangle 'delimit-columns-rectangle-max + start the-end nil))) + ;; prettify columns + (save-excursion + (operate-on-rectangle 'delimit-columns-rectangle-line + start the-end nil)) + ;; nullify markers + (set-marker delimit-columns-limit nil) + (set-marker the-end nil)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -202,7 +360,7 @@ START and END delimits the corners of text rectangle." (defvar delimit-columns-limit nil) -(defun delimit-columns-rectangle-max (startpos &optional ignore ignore) +(defun delimit-columns-rectangle-max (startpos &optional ignore1 ignore2) (set-marker delimit-columns-limit (point)) (goto-char startpos) (let ((ncol 1) @@ -235,34 +393,82 @@ START and END delimits the corners of text rectangle." (setq values (cdr values))))) -(defun delimit-columns-rectangle-line (startpos &optional ignore ignore) - (let ((ncol 0) - (len (length delimit-columns-max)) +(defun delimit-columns-rectangle-line (startpos &optional ignore1 ignore2) + (let ((len (length delimit-columns-max)) + (ncol 0) origin) (set-marker delimit-columns-limit (point)) (goto-char startpos) - (insert delimit-columns-str-before) + ;; skip initial columns + (while (and (< ncol delimit-columns-start) + (< (point) delimit-columns-limit) + (re-search-forward delimit-columns-separator + delimit-columns-limit 'move)) + (setq ncol (1+ ncol))) + ;; insert first formating + (insert delimit-columns-str-before delimit-columns-before) ;; Adjust all columns but last one (while (progn (setq origin (current-column)) (and (< (point) delimit-columns-limit) (re-search-forward delimit-columns-separator - delimit-columns-limit 'move))) + delimit-columns-limit 'move) + (or (< ncol delimit-columns-end) + (progn + (goto-char (match-beginning 0)) + nil)))) (delete-region (match-beginning 0) (point)) - (insert (make-string (- (aref delimit-columns-max ncol) - (- (current-column) origin)) - ?\ ) - delimit-columns-str-separator) - (setq ncol (1+ ncol))) - ;; Adjust last column - (insert (make-string (- (aref delimit-columns-max ncol) + (delimit-columns-format + (and delimit-columns-format + (make-string (- (aref delimit-columns-max ncol) (- (current-column) origin)) - ?\ )) - ;; Adjust extra columns, if needed - (while (< (setq ncol (1+ ncol)) len) - (insert delimit-columns-str-separator - (make-string (aref delimit-columns-max ncol) ?\ ))) - (insert delimit-columns-str-after))) + ?\s))) + (setq ncol (1+ ncol))) + ;; Prepare last column spaces + (let ((spaces (and delimit-columns-format + (make-string (- (aref delimit-columns-max ncol) + (- (current-column) origin)) + ?\s)))) + ;; Adjust extra columns, if needed + (and delimit-columns-extra + (while (and (< (setq ncol (1+ ncol)) len) + (<= ncol delimit-columns-end)) + (delimit-columns-format spaces) + (setq spaces (and delimit-columns-format + (make-string (aref delimit-columns-max ncol) + ?\s))))) + ;; insert last formating + (cond ((null delimit-columns-format) + (insert delimit-columns-after delimit-columns-str-after)) + ((eq delimit-columns-format 'padding) + (insert spaces delimit-columns-after delimit-columns-str-after)) + (t + (insert delimit-columns-after spaces delimit-columns-str-after)) + )) + (goto-char (max (point) delimit-columns-limit)))) + + +(defun delimit-columns-format (spaces) + (cond ((null delimit-columns-format) + (insert delimit-columns-after + delimit-columns-str-separator + delimit-columns-before)) + ((eq delimit-columns-format 'separator) + (insert delimit-columns-after + spaces + delimit-columns-str-separator + delimit-columns-before)) + ((eq delimit-columns-format 'padding) + (insert spaces + delimit-columns-after + delimit-columns-str-separator + delimit-columns-before)) + (t + (insert delimit-columns-after + delimit-columns-str-separator + spaces + delimit-columns-before)) + )) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -271,4 +477,5 @@ START and END delimits the corners of text rectangle." (provide 'delim-col) +;; arch-tag: 1cc0c5c5-1b2a-43e4-9ba5-bf9441cfd1a9 ;;; delim-col.el ends here