summaryrefslogtreecommitdiff
path: root/elisp/erbot/contrib/lines.el
diff options
context:
space:
mode:
Diffstat (limited to 'elisp/erbot/contrib/lines.el')
-rw-r--r--elisp/erbot/contrib/lines.el586
1 files changed, 586 insertions, 0 deletions
diff --git a/elisp/erbot/contrib/lines.el b/elisp/erbot/contrib/lines.el
new file mode 100644
index 0000000..f938c49
--- /dev/null
+++ b/elisp/erbot/contrib/lines.el
@@ -0,0 +1,586 @@
+;;; Lines.el -- help deal with data-files. OLDER VERSIONS SECURITY RISK
+;;General Public License.
+;; Time-stamp: <2004-11-21 11:11:45 deego>
+;; GPL'ed under GNU'S public license..
+;; Copyright (C) Deepak Goel 2000
+;; Emacs Lisp Archive entry
+;; Filename: lines.el
+;; Author: Deepak Goel <deego@glue.umd.edu>
+;; Version: 0.3alpha
+
+;; OLDER VERSIONS OF LINES.EL AREx A SECURITY RISK. IF YOU USE THEM
+;; TO FETCH FIELD FROM SOME ONE ELSE'S FILE , CRAFTY EXPRESSIONS CAN
+;; MAKE YOUR EMACS EVALUATE ANYTHING, INCLUDING (SHELL-COMMAND "RM
+;; -RF")). WE JUST THINK SO, WE HAVEN'T BEEN ABLE TO ACTUALLY COME UP
+;; WITH AN EXPLOIT. SO USE version > 0.3 only
+
+;; EVEN THIS LIBRARY IS A POSSIBLE SECURITY RISK TOO IF YOU DISABLE
+;; LINES-SAFE-P.
+
+
+
+(defvar lines-version "0.3alpha")
+
+;;; See also: forms.el (just saw it.. maybe it does all that lines.el
+;; does ?)
+
+
+;;;COMMENTARY: lines functions to help deal with data-files..
+
+;;; Sometimes you want to use lines- functions instead of point-
+;;; functions, even though it is slower. Particularly if u r dealing with
+;;; parsing/editing a data-file, with, say data arranged in columns.
+;;; lines.el defines most lines- counterparts of (point-max) (point-min)
+;;; (point) (kill-region) etc. [for instance, emacs' default lines-what
+;;; does not return an integer, which is what u may want during
+;;; programming]
+
+;;; Lines.el also defines functions such as lines-get-fields (which gets
+;;; all fields on this line, assuming they are lisp-expressions).
+
+
+;;; BEFORE DOING ANYTHING WITH A BUFFER, please do not forget to call
+;;;; lines-narrow-initial..
+
+
+
+;;; CODE:
+(eval-when-compile (require 'cl))
+
+;;;###autoload
+(defmacro lines-ignore-errors (&rest body)
+ "Copied from utils.el
+
+Like ignore-errors, but returns a list of body, and the
+error... Improved for me by Kalle on 7/3/01: * used backquote:
+something i was too lazy to convert my macro to.. * removed the
+progn: condition-case automatically has one.. * made sure that
+the return is nil.. just as it is in ignore-errors. "
+ (let ((err (gensym)))
+ `(condition-case ,err (list (progn ,@body) nil)
+ (error
+ (list nil ,err)))))
+
+
+(defmacro lines-with-string (string &rest body)
+ "This macro treats the string as a buffer... basically, it
+temporarily puts the string into a temp-buffer and runs body on it...
+Note that when the body is being run, the point is (initially) at the
+end of the buffer... "
+ `(with-temp-buffer
+ (insert ,string)
+ ,@body))
+
+
+(defun lines-empty-error ()
+ ""
+ (error "Empty buffer. NOTE: M-x lines-warning.")
+)
+
+(defun lines-warning ()
+ ""
+ (let ((lines-loudness 1))
+ (lines-message
+ "THIS program assumes that the proper form of the (data-) file you
+ examine ends in \\n. Anything in your file after the last \\n
+ will be ignored."))
+)
+
+;;;Mon Jan 15 04:09:30 2001
+;;;###autoload
+(defun lines-widen ()
+ (widen)
+)
+
+;;;Mon Jan 15 03:32:05 2001
+;;;###autoload
+(defun lines-narrow-initial (&optional ERR)
+ "Narrows such that the last char is a \\n
+If the buffer survives, returns the size of the buffer, else nil.
+Optional arg ERR results in ERR upon empty buffer.
+FOR FUTURE EDITS: NEVER CALL OTHER LINES FUNCTIONS WITHIN THIS
+FUNCTION, THIS ONE IS CALLED BY ALL OTHERS!
+
+"
+ (interactive)
+ (save-excursion
+ (let
+ ((lastn
+ (progn
+ (goto-char (point-max))
+ (if
+ (search-backward "\n" nil t)
+ (+ (point) 1)
+ (point-min)))))
+ (narrow-to-region (point-min) lastn))
+ (if (> (point-max) (point-min))
+ (point-max)
+ nil))
+)
+
+
+(defvar lines-loudness 0.6 "Tells you how noisy lines will be..
+Between 0 and 1 are meaningful values")
+
+(defun lines-message (&optional args)
+ (if (> lines-loudness 0.5) (apply 'message args))
+)
+
+
+;;;###autoload
+(defalias 'lines-what-line 'lines-what)
+
+;;;Wed Jan 17 00:11:38 2001
+;;;###autoload
+(defun lines-what-narrowed (&optional given-point )
+ " Like lines-what-line, except assumes a narrowed buffer.
+Mostly like what-line, except: returns integer!
+Tells you the current line.. If narrowed, assumes that the first
+visible line is number 1.. As if the buffer were the entire buffer..
+Respects narrowing..
+
+If DONTNARROW is t, assume that lines has already been narrowed..
+"
+ (interactive)
+ (let ((opoint (if given-point given-point (point)))
+ start)
+ (save-excursion
+ (goto-char (point-min))
+ (beginning-of-line)
+ (setq start (point))
+ (goto-char opoint)
+ (beginning-of-line)
+ (let
+ ((result
+ (if (/= start 1)
+ (1+ (count-lines start (point)))
+ (1+ (count-lines start (point))))))
+ (if (interactive-p)
+ (message (format "%S" result)))
+ result)))
+ )
+
+;;;Wed Jan 17 00:11:38 2001
+;;;###autoload
+(defun lines-what(&optional given-point )
+ " Mostly like what-line, except: returns integer!
+Tells you the current line.. Ignores any narrowing when counting
+lines, but does not disrupt the narrowing..
+
+Hacked from the code of what-line, and i still don't understand some
+stuff about the relevance of start here..
+
+Thus, even if the buffer has been narrowed, lines-what will try to
+return the true line-number.. Agreed this may slow things down for
+large files, but makes sense to me.. if u don't like this, please
+consider using lines-what-narrowed..
+
+In the new emacsen, see also `line-at-pos'.
+"
+ (interactive)
+ (let ((opoint (if given-point given-point (point)))
+ start)
+ (save-excursion
+ (goto-char (point-min))
+ (beginning-of-line)
+ (setq start (point))
+ (goto-char opoint)
+ (beginning-of-line)
+ (let
+ ((result
+ (if (/= start 1)
+ (1+ (count-lines 1 (point)))
+ (1+ (count-lines 1 (point))))))
+ (if (interactive-p)
+ (message (format "%S" result)))
+ result)))
+ )
+
+
+;;;###autoload
+(defalias 'lines-line-difference 'lines-difference)
+
+;;;###autoload
+(defun lines-difference (start end )
+ "Nothing more than the difference between the line at start and the
+one at end. start and end are points.. See also the default
+count-lines..
+If DONTNARROW is t, assume that lines has already been narrowed..
+
+"
+ (save-excursion
+ (- (lines-what-line end )
+ (lines-what-line start )))
+ )
+
+
+;;;###autoload
+(defalias 'lines-last-line-p 'lines-last-p)
+
+;;;###autoload
+(defun lines-last-p ()
+" Tells if we are on the last line. "
+ (interactive)
+ (save-excursion
+ (end-of-line)
+ (equal (point) (point-max)))
+ )
+
+;;;###autoload
+(defalias 'lines-first-line-p 'lines-first-p)
+
+;;;###autoload
+(defun lines-first-p ()
+"If DONTNARROW is t, assume that lines has already been narrowed.."
+ (interactive)
+ (save-excursion
+ (beginning-of-line)
+ (equal (point) (point-min)))
+)
+
+;;;###autoload
+(defalias 'lines-line-min 'lines-min)
+
+;;;###autoload
+(defun lines-min ()
+ "Like point-min..
+If DONTNARROW is t, assume that lines has already been narrowed..
+
+"
+ (interactive)
+ (save-excursion
+ (goto-char (point-min))
+ (lines-what-line (point) ))
+)
+
+;;;###autoload
+(defalias 'lines-line-max 'lines-max)
+
+(defun lines-max ()
+ "Like point-max
+If DONTNARROW is t, assume that lines has already been narrowed..
+"
+ (interactive)
+ (save-excursion
+ (goto-char (point-max))
+ (lines-what-line (point) ))
+)
+
+
+;;;Tue Jan 16 11:26:30 2001
+;;;###autoload
+(defalias 'lines-kill-this 'lines-kill-one)
+
+;;;Tue Jan 16 11:26:26 2001
+;;;###autoload
+(defun lines-kill-one (&optional pt1 )
+ (interactive)
+ (if (null pt1)
+ (setq pt1 (point)))
+ (lines-kill pt1 pt1 ))
+
+
+;;;Tue Jan 16 11:50:55 2001
+;;;###autoload
+(defun lines-kill-by-lines (&optional l1 l2 )
+ "Kills from line1 to line2. If l1 or l2 is not specified, passes nil to
+lines-kill..
+
+Use this function only if necessary..
+This function calls line-kill.. which is the one to be preferred for
+speed..
+
+"
+ (save-excursion
+ (let
+ ((pt1
+ (if (null l1) nil
+ (progn
+ (goto-line l1)
+ (point))))
+ (pt2
+ (if (null l2) nil
+ (progn
+ (goto-line l2)
+ (point)))))
+ (lines-kill pt1 pt2 )))
+ )
+
+
+
+
+;;;Tue Jan 16 11:26:22 2001
+;;;###autoload
+(defalias 'lines-kill-line 'lines-kill-one)
+
+
+;;;###autoload
+(defun lines-kill (&optional pt1 pt2 )
+ "Kills this line completely.
+
+If PT1 and PT2 are specified, kills all lines through the line on PT1
+to line on PT2, inclusive.
+
+If neither PT1 is not specified, kills between point and mark.
+
+If only PT1 is specified, and PT2 is nil, takes PT2 to be PT1,
+viz. kills the line on PT1.
+
+
+If DONTNARROW is t, assume that buffer has already been narrowed
+initially.
+
+If the second point to be killed is point-max, viz. is at a line we
+don't consider to be on the buffer, this function appropriately
+subtracts 1 from it so as to make it a part of the last legal line.
+
+"
+ (interactive)
+ (when (null pt1)
+ (setq pt1 (mark))
+ (setq pt2 (point)))
+ (when (null pt1) ;;if mark is undefined..
+ (setq pt1 pt2))
+ (lines-swap-if-necc 'pt1 'pt2) ;;;ensure pt1 <= pt2.
+ (if (= pt2 (point-max)) (setq pt2 (- pt2 1)))
+ (if (= pt1 (point-max)) (setq pt1 (- pt1 1)))
+ (save-excursion
+ (let ((a1
+ (progn
+ (goto-char pt1)
+ (beginning-of-line)
+ (point)))
+ (a2
+ (progn
+ (goto-char pt2)
+ (end-of-line)
+ (+ (point) 1))))
+ (kill-region a1 a2)))
+ )
+
+
+
+
+
+(defun lines-backward-char ()
+ "Moves one point back. Returns point if succeeds, else nil.
+Never gives error!
+Actually, i don't think we need this function..
+"
+ (interactive)
+ (let ((pt (point)))
+ (ignore-errors (backward-char 1))
+ (if (/= (point) pt)
+ pt
+ nil))
+ )
+
+;;;Tue Jan 16 17:35:29 2001
+;;;###autoload
+(defun lines-get-fields-by-lines (&optional line)
+ "Gets the field on the given line"
+ (lines-get-fields (lines-point-for-line line))
+)
+
+
+;;;Thu Feb 8 14:48:47 2001
+;;;###autoload
+(defun lines-point-for-line (line)
+ (save-excursion
+ (goto-line line)
+ (point)))
+
+(defcustom lines-safe-p t
+ "Set to t to revert to an unsafe, older but faster method of using
+ lines. ")
+
+;;;Mon Jan 15 02:42:19 2001
+;;;###autoload
+(defun lines-get-fields (&optional pt )
+ "Gets the fields if any on the current line, as a list.
+Uses scan-sexps==>
+will be affected by the value of parse-sexp-ignore-comments..
+
+I think this needs to be totally rewritten.. to give the same results,
+but much more efficiently..
+"
+ (interactive)
+ (let (fields fld buf fld-err err)
+ (if (null pt) (setq pt (point)))
+ (if (= pt (point-max))
+ (goto-char (- pt 1)))
+ (save-excursion
+ (goto-char pt)
+ (let ((expr (lines-at-point ))
+ fields)
+ (cond
+ (lines-safe-p
+ (with-temp-buffer
+ (setq buf (current-buffer))
+ (insert expr)
+ (goto-char (point-min))
+ (while
+ (progn
+ (setq fld-err
+ (lines-ignore-errors (read buf)))
+ (setq fld (car fld-err))
+ (setq err (cadr fld-err))
+ (not err))
+ (push fld fields)))
+ (setq fields (reverse fields)))
+ (t
+ (if (null expr)
+ (error "Attempt to get fields beyond the last RET "))
+ (with-temp-buffer
+ (insert "(setq fields (quote (")
+ (insert expr)
+ (insert " \n)))")
+ (eval-buffer))))
+ (if (interactive-p) (message "%S" fields))
+ fields))))
+;;; (let ((doing (point-min)))
+;;; (while doing
+;;; (setq doing (scan-sexps doing 1))
+;;; (when doing
+;;; (goto-char doing)
+;;; (setq fields (cons (format "%S" (sexp-at-point)) fields))))))
+;;; (reverse fields))
+;;; )
+
+
+;;;Mon Jan 15 16:29:12 2001
+;;;###autoload
+(defalias 'lines-line-at-point-verbatim 'lines-at-point-verbatim)
+
+;;;Mon Jan 15 03:02:17 2001
+;;;###autoload
+(defun lines-at-point-verbatim ( )
+ "Gives you just this one line at tthe current point.
+this returns you the line along with the trailing \\n. Thus, if the
+buffer ended up empty upon line-narrowing, this will return \"\".
+If DONTNARROW is t, assume that lines has already been narrowed..
+"
+ (interactive)
+ (buffer-substring
+ (save-excursion
+ (beginning-of-line)
+ (point))
+ (save-excursion
+ (forward-line 1)
+ (point)))
+ )
+
+;;;Mon Jan 15 16:29:40 2001
+;;;###autoload
+(defalias 'lines-line-at-point 'lines-at-point)
+
+;;;Mon Jan 15 03:55:05 2001
+;;;###autoload
+(defun lines-at-point ()
+ "Returns the line at this point, without the trailing \\newline.
+If the buffer is empty, returns nil.
+If DONTNARROW is t, assume that lines has already been narrowed..
+"
+ (interactive)
+ (let ((string (lines-at-point-verbatim )))
+ (let ((len (length string)))
+ (if (> len 0)
+ (substring string 0 (- len 1))
+ nil)))
+)
+
+
+
+
+
+;;;Tue Jan 16 11:35:20 2001
+(defun lines-swap-if-necc (sym1 sym2)
+ "INTERNAL..
+Ensures that the value of symbol SYM1 if less than that of SYM2"
+ (when (> (eval sym1) (eval sym2))
+ (let ((v2 (eval sym2)))
+ (set sym2 (eval sym1))
+ (set sym1 v2)))
+)
+
+
+
+;;;Tue Jan 16 15:50:31 2001
+;;;###autoload
+(defun lines-narrow (&optional pt1 pt2 )
+ "If called with no arguments, will assume point mark. If pt2 is
+undefined, will take it to be the same as pt1.
+
+Will narrow buffer from the line starting pt1 to the line ending
+pt2, inclusive. If pt1 is > pt2, will be swapped.. "
+ (interactive)
+ (if (null pt1)
+ (progn
+ (setq pt1 (mark))
+ (setq pt2 (point))))
+ (if (null pt2)
+ (setq pt2 pt1))
+ (lines-swap-if-necc 'pt1 'pt2)
+ (save-excursion
+ (narrow-to-region
+ (progn
+ (goto-char pt1)
+ (beginning-of-line)
+ (point))
+ (progn
+ (goto-char pt2)
+ (end-of-line)
+ (if (not (= (point-max) (point)))
+ (forward-char 1))
+ (point))))
+)
+
+;;;Tue Jan 16 17:33:51 2001
+;;;###autoload
+(defun lines-for-point (&optional pt)
+ "Line number on the point"
+ (interactive)
+ (if (null pt) (setq pt (point)))
+ (save-excursion
+ (goto-char pt)
+ (lines-what)))
+
+;;; 2002-05-14 T15:24:21-0400 (Tuesday) D. Goel
+;;;###autoload
+(defun lines-what-string (string)
+ (lines-with-string string
+ (lines-what)))
+
+
+
+;;; 2002-11-27 T15:21:04-0500 (Wednesday) D. Goel
+;;;###autoload
+(defun lines-get-fields-file (filename)
+ "Get fields from a file. A list per line. A list of such lists.
+problem: barfs in the middle of comments..."
+
+ (interactive "F")
+ (save-window-excursion
+ (let ((fields nil))
+ (find-file filename)
+ (lines-narrow-initial)
+ (goto-char (point-min))
+ (while (not (lines-last-p))
+ (add-to-list 'fields (lines-get-fields))
+ (next-line 1))
+ (reverse fields))))
+
+(defun lines-write-fields-file (fields filename)
+ (with-temp-file filename
+ (let ((left fields))
+ (while left
+ (insert
+ (mapconcat
+ '(lambda (arg) (format "%S" arg))
+ (car left)
+ "\t") "\n")
+ (pop left)))))
+
+(provide 'lines)
+
+;;;lines.el ends here..