From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: Inserting output from a program into a buffer Date: Tue, 23 Feb 2010 00:23:58 +0100 Organization: Informatimago Message-ID: <87iq9ozwfl.fsf@galatea.lan.informatimago.com> References: <87zl324774.fsf@lion.rapttech.com.au> <87k4u66nhh.fsf@galatea.lan.informatimago.com> <87zl316218.fsf@galatea.lan.informatimago.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1266882175 20663 80.91.229.12 (22 Feb 2010 23:42:55 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 22 Feb 2010 23:42:55 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Tue Feb 23 00:42:51 2010 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1NjhvO-00083E-Sl for geh-help-gnu-emacs@m.gmane.org; Tue, 23 Feb 2010 00:42:51 +0100 Original-Received: from localhost ([127.0.0.1]:47752 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NjhvO-0004Y5-FK for geh-help-gnu-emacs@m.gmane.org; Mon, 22 Feb 2010 18:42:50 -0500 Original-Path: news.stanford.edu!usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 105 Original-X-Trace: individual.net L5AEmqkOryig/AdzIEex+wteRSn8lqp/4yFiaxGVazgg1Fy4Cn Cancel-Lock: sha1:MWMwMmIwODRmYzk3YjhjNGRiYTA0NTVhNDQ4ZTA0ZmYxYWM2MDRlNg== sha1:icuLJWLoUwDtgEin/cCmnL9FvkQ= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (darwin) Original-Xref: news.stanford.edu gnu.emacs.help:177003 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:72041 Archived-At: Tim Johnson writes: > On 2010-02-22, Pascal J. Bourguignon wrote: > <...> >> In general, functions don't modify variables. This would be a bad case >> of side effect. In emacs lisp it would be somewhat possible, since all >> var)))) >> >> (Notice that this effect is a design bug in LISP that was detected in >> 1960 and corrected in the following years by the introduction of lexical >> variables. emacs lisp is somewhat retrograde (or at least conservator) >> on this point). >> >> >> Anyways, it is a bad idea to try to modify variables from called >> functions. >> >> >> What you really need is to BIND the RESULT of buffer-string and other >> functions TO a variable. This is done with LET: >> >> (let ((string (buffer-substring (point-min) (+ 10 (point-min))))) >> (string= "Newsgroups" string)) >> >> --> t > Pascal, the total of what you have written is valuable to me in > understand programming elisp. I don't fully follow all of what you say, > but I hope that it will soak in. > I've now written a function that copies a delimited 'form' (sexp or > other data structure) > I submit it here for your comments. Your comments will no doubt further > enlighten me on your insights. > ;; code follows > (defun tj-copy-previous-region() > "Grab a symmetrically delimited data structure beginning on the same line > as the cursor" > (interactive) > (let ((boundary(point))found end success (origin (point))) > (beginning-of-line-text) > (if (member (char-after) '(40 91 123)) > (progn > (setq found (point))) > (progn > (setq found(re-search-forward "(\\|\\[\\|{" boundary t)) > (if found > (progn > (backward-char 1) > (setq found (point))) > (message "*** No Opening delimiter found on this line ***")))) > (when found > (forward-sexp) > (setq end (point)) > (setq success (buffer-substring found end)) > (message "** RESULT: %s ***" success) > (goto-char origin)) > success)) > ;; needs a little more factoring and I note some redundant bindings... >> But who I am to say such things, I'm not RMS... > :) We all owe RMS a great debt for his contributions and his > passionate opinions are well known.... > thanks You could write it like this: (defun tj-copy-previous-region () "Save a list surrounding or before the cursor into the kill-ring." (interactive) (save-excursion (let ((boundary (point))) (beginning-of-line-text) (if (re-search-forward "[([{]" boundary t) (let ((start (match-beginning 0))) (goto-char (1- start)) (forward-sexp) (kill-ring-save start (point))) (error "No Opening delimiter found on this line"))))) aaaa (1 2 3 4 5 6 7 8 9) zzzz ^ M-x tj-copy-previous-region RET C-n C-n C-y inserts: (1 2 3 4 5 6 7 8 9) Notice: - spaces before opening parentheses not preceded by an opening parenthesis. - indentation done automatically by emacs. - avoidance of setf or setq. - do actually what was documented (by the function name), ie. use kill-ring-save instead of buffer-substring. - use of save-excursion to save the excursion - use of error to deal with exceptional cases instead of just message. error will do the right thing depending on the local circumstances (ie. it will message the error in interactive use, but enter the debugger or have the error otherwise handled if the programmer asks it to). -- __Pascal Bourguignon__