home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.emacs.help
- Path: sparky!uunet!cis.ohio-state.edu!src.bae.co.UK!moore
- From: moore@src.bae.co.UK (Chris Moore)
- Subject: adding new functions
- Message-ID: <9207241243.AA29061@sun19.src.bae.co.uk>
- Sender: daemon@cis.ohio-state.edu
- Organization: Gatewayed from the GNU Project mailing list help-gnu-emacs@prep.ai.mit.edu
- References: <Jul23.203033.61716@yuma.ACNS.ColoState.EDU>
- Date: Fri, 24 Jul 1992 12:43:26 GMT
- Lines: 79
-
-
- ryanr@lamar.colostate.edu (Richard Ryan) said:
-
- > (defun gt-indent-region ()
- > (shell-command-on-region 4 "sed -e '/^\(.\)/s//> \1/'"))
-
- You need to say the function is interactive before it becomes available to
- the user via the M-x way of calling functions. That's why you were seeing
- 'no match'. Adding the interactive will now let you call the function.
-
- ie.
-
- (defun gt-indent-region ()
- (interactive)
- (shell-command-on-region 4 "sed -e '/^\(.\)/s//> \1/'"))
-
- It won't work, since shell-command-on-region needs at least 3 arguments -
- the beginning and end of the region and the command to execute. I can't
- quite see what the 4 is supposed to mean in your function. Fortunately,
- interactive provides a way of automatically passing the beginning and end
- of the current region to a function. (See C-h f interactive RET for
- details).
-
- (defun gt-indent-region (start end)
- (interactive "r")
- (shell-command-on-region start end "sed -e '/^\(.\)/s//> \1/'"))
-
- This now calls sed on the region with the expression you give. I don't
- know enough sed to understand what this means, but it seems to me that it
- just copies input to output. Emacs puts the output from sed in a "*Shell
- Command Output*" buffer. Giving shell-command-on-region an extra true
- argument will cause emacs to replace the region in the original buffer with
- the output of sed:
-
- (defun gt-indent-region (start end)
- (interactive "r")
- (shell-command-on-region start end "sed -e '/^\(.\)/s//> \1/'" t))
-
- Another problem: When you write a string in emacs lisp, backslashes are
- used to create certain characters in the string, like the familiar \n, \t
- etc of C. So if you really want a backslash in your string you have to
- type two backslashes. Now your function becomes the following:
-
- (defun gt-indent-region (start end)
- (interactive "r")
- (shell-command-on-region start end "sed -e '/^\\(.\\)/s//> \\1/'" t))
-
- And now it actually works!
-
- > Also, what I'm trying to do with this command is put a "> "
- > in the left margin. If you've got a better function, please
- > send me a copy.
-
- Probably something using replace-regexp instead of forking a shell would be
- quicker. Unfortunately, it appears that replace-regexp doesn't work on
- regions. It works from point to end-of-buffer. One solution to this is to
- narrow the buffer to the region of interest before calling replace-regexp.
-
- [later, after much hacking] try this:
-
- (defun gt-indent-region (start end)
- (interactive "r")
- (save-excursion
- ;; Point could currently be at end of region. We want it at the
- ;; beginning.
- (goto-char start)
- ;; Without this it's possible to insert the '>' halfway along a line.
- (beginning-of-line)
- (save-restriction
- (narrow-to-region (point) end)
- (replace-regexp "^" "> "))))
-
- The save-excursion is used to ensure that point is not moved by the function.
- The save-restriction is used to ensure that the buffer is restricted in the
- same way after the function returns as it was before it was called.
- Although longer, this function is much quicker than forking a shell to run
- sed, since all the work's done by lisp.
-
- Chris.
-