home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / misc / thing.el < prev    next >
Encoding:
Text File  |  1990-03-21  |  5.5 KB  |  176 lines

  1. ;From: guttman@mitre.org (Joshua D. Guttman)
  2. ;Newsgroups: comp.emacs,gnu.emacs
  3. ;Subject: thing commands, also work under X
  4. ;Message-ID: <GUTTMAN.89Aug7201146@darjeeling.mitre.org>
  5. ;Date: 8 Aug 89 00:11:47 GMT
  6. ;Distribution: comp
  7. ;Organization: Mitre Corporation, Bedford, MA.
  8. ;Lines: 166
  9. ;
  10. ;I'm enclosing some code that simplifies and adapts the "thing commands"
  11. ;previously offered under emacstool, based on an idea from zmacs.  The syntax
  12. ;tables are used to construct the "thing" at a particular place in a buffer.
  13. ;For instance, at a left-paren, the thing is the following sexp, while at a
  14. ;right paren it is the preceding sexp.  The association between character syntax
  15. ;and "things" is fixed by an alist, so that behavior can be easily tailored.  I
  16. ;have also included two functions that connect with X windows.  I bind them to
  17. ;mouse events, and find them very useful.  Bindings I use are:
  18. ;
  19. ;(define-key mouse-map x-button-s-middle 'x-mouse-kill-thing)
  20. ;(define-key mouse-map x-button-s-right 'x-mouse-copy-thing)
  21. ;
  22. ;The other main commands are:
  23. ;
  24. ;(global-set-key "\C-ck" 'kill-thing-at-point)
  25. ;(global-set-key "\C-cw" 'copy-thing-at-point)
  26. ;
  27. ;No bindings are made by the code below, so you can do as you please.
  28. ;
  29. ;    Joshua Guttman
  30. ;
  31. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  32. ;; Thing.el
  33. ;; adapted from sun-fns.el by Joshua Guttman, MITRE.  
  34. ;; Comments appreciated: guttman@mitre.org
  35.  
  36.  
  37. (provide 'thing)
  38.  
  39. (defun thing-boundaries (here)
  40.   "Return start and end of text object at HERE using syntax table and thing-boundary-alist.  
  41. Thing-boundary-alist is a list of pairs of the form (SYNTAX-CHAR FUNCTION)
  42. where FUNCTION takes a single position argument and returns a cons of places
  43.  (start end) representing boundaries of the thing at that position.  
  44. Typically:
  45.  Left or right Paren syntax indicates an s-expression.    
  46.  The end of a line marks the line including a trailing newline. 
  47.  Word syntax indicates current word. 
  48.  Symbol syntax indicates symbol.
  49.  If it doesn't recognize one of these it selects just the character HERE."
  50.   (interactive "d")
  51.   (if (save-excursion
  52.     (goto-char here)
  53.     (eolp))
  54.       (thing-get-line here)
  55.     (let* ((syntax
  56.         (char-syntax (char-after here)))
  57.        (pair
  58.         (assq syntax thing-boundary-alist)))
  59.     
  60.       (if pair
  61.       (funcall (car (cdr pair)) here)
  62.     (cons here (1+ here))))))  
  63.  
  64.  
  65. (defvar thing-boundary-alist
  66.   '((?w thing-word)
  67.     (?_ thing-symbol)
  68.     (?\( thing-sexp-start)
  69.     (?\$ thing-sexp-start)
  70.     (?' thing-sexp-start)
  71.     (?\" thing-sexp-start)
  72.     (?\) thing-sexp-end)
  73.     (?  thing-whitespace))
  74.   "*List of pairs of the form (SYNTAX-CHAR FUNCTION) used by THING-BOUNDARIES.")
  75.   
  76. (defun thing-get-line (here)
  77.   "Return whole of line HERE is in, with newline unless at eob."
  78.   (save-excursion
  79.     (goto-char here)
  80.     (let* ((start (progn (beginning-of-line 1)
  81.              (point)))
  82.        (end (progn (forward-line 1)
  83.                (point))))
  84.       (cons start end))))
  85.  
  86. (defun thing-word (here)
  87.   "Return start and end of word at HERE."
  88.   (save-excursion
  89.     (goto-char here)
  90.     (forward-word 1)
  91.     (let ((end (point)))
  92.       (forward-word -1)
  93.       (cons (point) end))))
  94.  
  95. (defun thing-symbol (here)
  96.   "Return start and end of symbol at HERE."
  97.   (let ((end (scan-sexps here 1)))
  98.     (cons (min here (scan-sexps end -1))
  99.       end)))
  100.  
  101. (defun thing-sexp-start (here)
  102.   "Return start and end of sexp starting HERE."
  103.   (cons here (scan-sexps here 1)))
  104.  
  105. (defun thing-sexp-end (here)
  106.   "Return start and end of sexp ending HERE."
  107.   (cons (scan-sexps (1+ here) -1)
  108.     (1+ here)))
  109.  
  110. (defun thing-whitespace (here)
  111.   "Return start to end of all but one char of whitespace HERE, unless 
  112. there's only one char of whitespace.  Then return start to end of it."
  113.   (save-excursion
  114.     (let ((start (progn
  115.            (skip-chars-backward " \t") (1+ (point))))
  116.       (end (progn 
  117.          (skip-chars-forward " \t") (point))))
  118.       (if (= start end)
  119.       (cons (1- start) end)
  120.     (cons start end)))))
  121.  
  122.  
  123.  
  124.  
  125.  
  126. (defun mark-thing-at-point (here)
  127.   "Set point at beginning and mark at end of text object using syntax table.
  128. See thing-boundaries for definition of text objects"
  129.   (interactive "d")
  130.   (let ((bounds (thing-boundaries here)))
  131.     (goto-char (cdr bounds))
  132.     (set-mark-command nil)
  133.     (goto-char (car bounds))))
  134.  
  135. (defun kill-thing-at-point (here)
  136.   "Kill text object using syntax table.
  137. See thing-boundaries for definition of text objects"
  138.   (interactive "d")
  139.   (let ((bounds (thing-boundaries here)))
  140.     (kill-region (car bounds) (cdr bounds))))
  141.  
  142.  
  143. (defun copy-thing-at-point (here)
  144.   "Copy text object using syntax table.
  145. See thing-boundaries for definition of text objects"
  146.   (interactive "d")
  147.   (let ((bounds (thing-boundaries here)))
  148.     (copy-region-as-kill (car bounds) (cdr bounds))))
  149.  
  150. ;;; Two X-related fns.      
  151.         
  152. (defun x-mouse-kill-thing (arg)
  153.   "Kill text object at point or mouse position and insert into window system cut buffer.
  154. Save in Emacs kill ring also."
  155.   (interactive "d")
  156.   (setq last-command nil)
  157.   (x-mouse-set-point arg)
  158.   (let* ((bounds (thing-boundaries (point)))
  159.      (start (car bounds))
  160.      (end (cdr bounds)))
  161.     (x-store-cut-buffer (buffer-substring start end))
  162.     (kill-region start end)))
  163.  
  164. (defun x-mouse-copy-thing (arg)
  165.   "Copy text object at point or mouse position into window system cut buffer.
  166. Save in Emacs kill ring also."
  167.   (save-excursion
  168.     (save-window-excursion
  169.       (setq last-command nil)
  170.       (x-mouse-set-point arg)
  171.       (let* ((bounds (thing-boundaries (point)))
  172.          (start (car bounds))
  173.          (end (cdr bounds)))
  174.     (x-store-cut-buffer (buffer-substring start end))
  175.     (copy-region-as-kill start end)))))
  176.