Completion in emacs mode

Mark McEahern marklists at mceahern.com
Thu Jul 25 16:54:41 EDT 2002


> Given that we are now in dodgy waters, is there an alternative to this
> route? (perhaps post a complete version of the extension here :-)

;;; new-dabbrev.el --- dynamic abbreviation package
;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.
;; Copyright (C) 1993, Lars Lindberg

;; Author: Don Morrison
;; Maintainer: Lars Lindberg <lli at sypro.cap.se>
;; Created: 16 Mar 1992
;; Version 3.0
;; Keywords: abbrev expand completion

;; This file is NOT part of GNU Emacs.

;; 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 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, 675 Mass Ave, Cambridge, MA 02139, USA.

;;; Commentary:

;; The purpose with this package is to let you write just a few
;; characters of words you've written earlier to be able to expand them.
;;
;; To expand a word, just put the point right after the word and press
;; M-/ (dabbrev-expand) or M-C-/ (dabbrev-complete).
;;
;; There are powerful things in this package that aren't turned on by
;; default. I recommend you to do the following.
;;
;; Put the following 2 lines in your .emacs file:
;; (setq-default dabbrev-always-check-other-buffers t)
;; (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
;;
;; Dabbrev will now search in all buffers with the same major mode
;; for your expansions. It will also search for complete symbols,
;; the old dabbrev package only looked half-heartedly for symbols.
;;
;; You might also consider setting
;; (setq dabbrev-upcase-means-case-search t)
;; to get automatic case se-upcase-means-case-search t)
;; to get automatic case sensitive search when your abbreviation
;; contains uppercase characters.
;;
;; Check out customization below to learn about all the features
;; of this package.

;;; Change Log
;;  3.0 1993-12-09
;;      Freshed things up for the release.
;;      'dabbrev-completion' now doesn't have to use the minibuffer.
;;      Thanks Alon Albert <al%imercury at uunet.uu.net>.
;;  2.3 1993-12-07 Lars Lindberg <lli at sypro.cap.se>
;;      'dabbrev-abbrev-char-regexp' nil means old dabbrev style of
;;      searching.
;;      Added installation and customization commentary.
;;  2.2 1993-12-04 Lars Lindberg <lli at sypro.cap.se>
;;      Added 'dabbrev-upcase-means-case-search', which makes usage of
;;      case-fold-search and case-replace customizable.
;;      Added 'dabbrev-abbrev-char-regexp' for customizing the definition
;;      of an abbreviation.
;;      Requires "picture" when compiling.
;;      Minor bug.
;;  2.1 1993-12-04 Lars Lindberg <lli at sypro.cap.se>
;;      Now doesn't consider the word that point is at, but rather
;;      the symbol, also searches for symbols.
;;      Works better with undo.
;;      Now searches as if case-fold-search was nil when the
;;      abbreviation contains at least one uppercase character.
;;      Made it faster by just putting the extra found characters
;;      in 'dabbrev--last-table', not the whole word.
;;      Corrected bugs.
;;  2.0 1993-12-02 Lars Lindberg <lli at sypro.cap.se>
;;      Searches in other buffers for the expansion.
;;      Works also for the minibuffer.
;;      Added 'dabbrev-completion'.
;;      More efficient code.
;;      Found minor bugs.
;;  1.0 converted to Emacs Lisp by Spencer Thomas.
;;      Thoroughly cleaned up by Richard Stallman.
;;  0.0
;;      DABBREVS - "Dynamic abbreviations" hack, originally written by
;;      Don Morrison for Twenex Emacs.  Converted to mlisp by Russ Fish.
;;      Supports the table feature to avoid hitting the same expansion on
;;      re-expand, and the search size limit variable.

;; Known bugs and limitations.
;; - Possible to do several levels of 'dabbrev-completion' in the
;;   minibuffer.
;;
;; Future enhancements
;;  Check the tags-files? Like tags-complete?

;;; Code:
(provide 'new-dabbrev)
(require 'cl)

;;;----------------------------------------------------------------
;;;----------------------------------------------------------------
;;; Customization variables
;;;----------------------------------------------------------------
;;;----------------------------------------------------------------
(defvar dabbrev-backward-only nil
  "*If non-NIL, `dabbrev-expand' only looks backwards.")

(defvar dabbrev-limit nil
  "*Limits region searched by `dabbrev-expand' to this many chars away.")

;; I recommend that you set this to t, at least in programming modes.
(defvar dabbrev-upcase-means-case-search nil
  "*The significance of an uppercase character in the abbreviation.

nil = Doesn't affect the search, but preserves the case when replacing.
t = The search becomes case-sensitive and the replace is exact.

This variable is buffer-local.")
(make-variable-buffer-local 'dabbrev-upcase-means-case-search)

;; I recommend that you set this to "\\sw\\|\\s_"
(defvar dabbrev-abbrev-char-regexp nil
  "*A regexp that recognizes a character in an abbreviation or an
expansion.  Will be surrounded with \\\\( ... \\\\) when used.

Set this to \"\\\\sw\" if you want ordinary words or
\"\\\\sw\\\\|\\\\s_\" if you want symbols.

You can also set it to nil if you want old-style dabbrev searching
(the abbreviation is from point to previous word-start, the
search is for symbols.

The recommended value is \"\\\\sw\\\\|\\\\s_\".")

;; I recommend that you set this to t.
(defvar dabbrev-always-check-other-buffers nil
  "*Should \\[dabbrev-expand] look in other buffers?\
nil = Don't look in other buffers.\n\
t = Look in other buffers.\n\
Otherwise ask the user if he want's to look in other buffers.

The recommended values is t.")

;; I guess setting this to a function that select all C- or C++-
;; mode buffers wouldunction that select all C- or C++-
;; mode buffers would be a good choice for a debugging buffer,
;; when debugging C- or C++-code.
(defvar dabbrev-friend-buffer-function 'dabbrev--same-major-mode-p
  "*A function that determines which buffers that should be searched.
The function should take one argument, OTHER-BUFFER, and for instance
compare it with the current buffer to decide if it's suitable for
searching in. Have a look at 'dabbrev--same-major-mode-p' for an
example.

This variable is buffer local.")
(make-variable-buffer-local 'dabbrev-friend-buffer-function)

;;;----------------------------------------------------------------
;;;----------------------------------------------------------------
;;; Internal variables
;;;----------------------------------------------------------------
;;;----------------------------------------------------------------

;; Last obarray of completions in 'dabbrev-completion'
(defvar dabbrev--last-obarray nil)

;; Table of expansions seen so far
(defvar dabbrev--last-table nil)

;; Last string we tried to expand.
(defvar dabbrev--last-abbreviation nil)

;; Location last abbreviation began
(defvar dabbrev--last-abbrev-location nil)

;; Direction of last dabbrevs search
(defvar dabbrev--last-direction 0)

;; Last expansion of an abbreviation.
(defvar dabbrev--last-expansion nil)

;; Location the last expansion was found.
(defvar dabbrev--last-expansion-location nil)

;; The list of remaining buffers with the same mode as current buffer.
(defvar dabbrev--friend-buffer-list nil)

;; The buffer we looked in last.
(defvar dabbrev--last-buffer nil)

;; The buffer we last did a completion in.
(defvar dabbrev--last-completion-buffer nil)

;; Same as dabbrev-always-check-other-buffers, but is set for every expand.
(defvar dabbrev--check-other-buffers dabbrev-always-check-other-buffers)

;;;----------------------------------------------------------------
;;;----------------------------------------------------------------
;;; Macros
;;;----------------------------------------------------------------
;;;----------------------------------------------------------------

;;; Get the buffer that mini-buffer was activated from
(defsubst dabbrev--minibuffer-origin ()
  (car (cdr (buffer-list))))

;;;----------------------------------------------------------------
;;;----------------------------------------------------------------
;;; Exported functions
;;;----------------------------------------------------------------
;;;----------------------------------------------------------------

;;;###autoload
(define-key esc-map "/" 'dabbrev-expand)
;;;###autoload
(define-key esc-map [?\C-/] 'dabbrev-completion)

;;;###autoload
(defun dabbrev-completion (&optional arg)
  "Completion on current word.

Like \\[dabbrev-expand] but finds all expansions in the current buffer
and presents suggestions for completion.

If you call this function with prefix ARG, then it searches all
buffers accepted by the function pointed out by
'dabbrev-friend-buffer-function' to find the completions.

With no prefix ARG it tries to reuse the old completion list
before making a new one."

  (interactive "*P")
  (let* ((dabbrev-always-check-other-buffers (and arg t))
	 (abbrev (dabbrev--abbrev-at-point))
	 (preserve-case-p (and case-fold-search
			       (string= abbrev (downcase abbrev))))
	 (my-obarray dabbrev--last-obarray)
	 init)
    (save-excursion
      (if (and (null arg)
	       my-obarray
	       (or (eq dabbrev--last-completion-buffer (current-buffer))
		   (and (window-minibuffer-p (selected-window))
			(eq dabbrev--last-completion-buffer (dabbrev--minibuffer-origin))))
	       dabbrev--last-abbreviation
	       (>= (length abbrev) (length dabbrev--last-abbreviation))
	       (setq init (try-completion abbrev my-obarray)))
	  ;;--------------------------------
	  ;; This is a continue.
	  ;;--------------------------------
	  (progn)
	;;--------------------------------
	;; New abbreviation to expand.
	;;--------------------------------
	(dabbrev--reset-global-variables)
	(setq dabbrev--last-abbreviation abbrev)
	(let (compl)
	(setq dabbrev--last-abbreviation abbrev)
	(let (completion-list)
	  ;; Find all expansion
	  (setq completion-list
		(dabbrev--find-all-expansions abbrev preserve-case-p))
	  ;; Make an obarray with all expansions
	  (setq my-obarray (make-vector (length completion-list) 0))
	  (or (> (length my-obarray) 0)
	      (error "No dynamic expansion for \"%s\" found%s."
		     abbrev
		     (if dabbrev--check-other-buffers "" " in this-buffer")))
	  (mapc (function (lambda (string)
			    (intern (concat abbrev string) my-obarray)))
		completion-list)
	  (setq dabbrev--last-obarray my-obarray)
	  (setq dabbrev--last-completion-buffer (current-buffer))
	  ;; Find the longest common string.
	  (setq init (try-completion abbrev my-obarray)))))
    ;;--------------------------------
    ;; Let the user choose between the expansions
    ;;--------------------------------
    (or (stringp init)
	(setq init abbrev))
    (cond
     ;; * Replace string fragment with matched common substring completion.
     ((and (not (string-equal init ""))
	   (not (string-equal (downcase init) (downcase abbrev))))
      (if (> (length (all-completions init my-obarray)) 1)
	  (message "Repeat '%s' to see all completions" this-command)
	(message "The only possible completion"))
      (and dabbrev-upcase-means-case-search
	   (setq init (substring init (length abbrev))))
      (dabbrev--substitute-expansion nil abbrev init))
     (t
      ;; * String is a common substring completion already.  Make list.
      (message "Making completion list...")
      (with-output-to-temp-buffer " *Completions*"
	(display-completion-list (all-completions abbrev my-obarray)))
      (message "Making completion list...done")))
    (and (window-minibuffer-p (selected-window))
	 (message nil))))

;;;###autoload
(defun dabbrev-expand (arg)
  "Expand previous word \"dynamically\".

Expands to the most recent, preceding word for which this is a prefix.
If no suitable preceding word is found, words following point are
considered.  If still no suitable word is found, then look in the
buffers accepted by the function pointed out by variable
'dabbrev-friend-buffer-function'.

A positive prefix argument, N, says to take the Nth backward _distinct_
possibility.  A negative argument says search forward.

If the cursor has not moved from the end of the previous expansion and
no argument is given, replace the previously-made expansion
with the next possible expansion not yet tried.

The variable 'dabbrev-backward-only' may be used to limit the
direction of search to backward if set non-nil.

To make it more powerful, make sure that
'dabbrev-always-check-other-buffers' is set to t.

Also check out 'dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
  (interactive "*P")
  (let (preserve-case-p abbrev expansion old direction loc)
    ;; abbrev -- the abbrev to expand
    ;; expansion -- the expansion found (eventually) or nil until then
    ;; old -- the text currently in the buffer
    ;;    (the abbrev, or the previously-made expansion)
    ;; loc -- place where expansion is found
    ;;    (to start search there for next expansion if requested later)
    ;; preserve-case-p -- non-nil if should transform case when
substituting.
    (save-excursion
      (if (and (null arg)
	       dabbrev--last-abbrev-location
	       (or (eq last-command this-command)
		   (and (window-minibuffer-p (selected-window))
			(= dabbrev--last-abbrev-location
			   (point)))))
	  ;;--------------------------------
	  ;; This is a redo.
	  ;;--------------------------------
	  (progn
	    (setq abbrev dabbrev--last-abbreviation)
	    (setq old dabbrev--last-expansion)
	    (setq direction dabbrev--last-direction))
	;;--------------------------------
	;; New abbreviation to expand.
	;;--------------------------------
	(dabbrev--reset-global-variables)
	(setq direction (if (null arg)
			    (if dabbrev-backward-only 1 0)
			  (prefix-numeric-value arg)))
	(setq abbrev (dabbrev--abbrev-at-point))
	(setq old nil))

      ;;--------------------------------
      ;; Find the expansion
      ;;-------------------
      ;; Find the expansion
      ;;--------------------------------
      (setq preserve-case-p
	    (and case-fold-search (string= abbrev (downcase abbrev))))
      (setq expansion (dabbrev--find-expansion abbrev direction
preserve-case-p)))
    (cond
     ((not expansion)
      (dabbrev--reset-global-variables)
      (if old
	  (save-excursion
	    (search-backward old)
	    (delete-region (match-beginning 0) (match-end 0))))
      (error "No%s dynamic expansion for \"%s\" found."
	     (if old " further" "") abbrev))
     (t
      ;; Success: stick it in and return.
      (dabbrev--substitute-expansion old abbrev expansion)
      ;; Save state for re-expand.
      (setq dabbrev--last-expansion expansion)
      (setq dabbrev--last-abbreviation abbrev)
      (setq dabbrev--last-abbrev-location (point-marker)))))
  (message nil))

;;;----------------------------------------------------------------
;;;----------------------------------------------------------------
;;; Local functions
;;;----------------------------------------------------------------
;;;----------------------------------------------------------------

;;; Checks if OTHER-BUFFER has the same major mode as current buffer.
(defun dabbrev--same-major-mode-p (other-buffer)
  (let ((orig-mode major-mode))
    (save-excursion
      (set-buffer other-buffer)
      (eq orig-mode major-mode))))

;;; Extract the symbol at point to serve as abbrevitation.
(defun dabbrev--abbrev-at-point ()
  (save-excursion
    (save-excursion
      (forward-char -1)
      (or (looking-at (concat "\\("
			      (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
			      "\\)+"))
	  (error "Not positioned immediately after a word.")))
    ;;bug in re-search-backward?
    ;;(re-search-backward (concat "\\(" dabbrev-abbrev-char-regexp "\\)+")
    ;;(setq dabbrev--last-abbrev-location (match-end 0))
    ;;(buffer-substring (match-beginning 0) (match-end 0)))
    (setq dabbrev--last-abbrev-location (point))
    (buffer-substring (point)
		      (if dabbrev-abbrev-char-regexp
			  (progn
			    (backward-sexp)
			    (while (not (looking-at dabbrev-abbrev-char-regexp))
			      (forward-char 1))
			    (point))
			(progn
			  (forward-word -1)
			  (point))))))

;;; Initializes all global variables
(defun dabbrev--reset-global-variables ()
  ;; dabbrev--last-obarray and dabbrev--last-completion-buffer
  ;; must not be reset here.
  (setq dabbrev--last-table nil
	dabbrev--last-abbreviation nil
	dabbrev--last-abbrev-location nil
	dabbrev--last-direction nil
	dabbrev--last-expansion nil
	dabbrev--last-expansion-location nil
	dabbrev--friend-buffer-list nil
	dabbrev--last-buffer nil
	dabbrev--check-other-buffers dabbrev-always-check-other-buffers))

;;; Find all buffers that are considered "friends" according to the
;;; function pointed out by dabbrev-friend-buffer-function.
(defun dabbrev--find-friend-buffers ()
  (save-excursion
    (and (window-minibuffer-p (selected-window))
	 (set-buffer (dabbrev--minibuffer-origin)))
    (let ((orig-buffer (current-buffer))
	  (orig-mode major-mode))
      (mapcan
       (function
	(lambda (buffer)
	  (and (not (eq orig-buffer buffer))
	       (funcall dabbrev-friend-buffer-function buffer)
	       (list buffer))))
       (buffer-list)))))

;;; Try to find PATTERN in REVERSE direction N times.
(defun dabbrev--try-find (pattern reverse n ignore-case)
  (save-excursion
    (let ((case-fold-search-is-local (memq 'case-fold-search
					   (buffer-local-variables)))
	  (expansion nil))
      (and dabbrev--last-expansion-location
	   (goto-char dabbrev--last-expansion-location))
      (unwind-protect
	  (progn
	    (or case-fold-search-is-local
		(make-local-variable 'case-fold-search))
	    ;; Tricky! If 'case-fold-search' isn't buffer-local, then
	    ;; this innocent let creates a buffer-local variable and
	    ;; when the let returns, it is still there!  The
	    ;; unwind-protect stuff around this makes sure that there
	    ;; exists one before the let, and removes it afterwards.
	    (let ((case-fold-search (or ignore-case
					(not dabbrev-et ((case-fold-search (or ignore-case
					(not dabbrev-upcase-means-case-search))))
	      (loop repeat n
		    while (setq expansion (dabbrev--search pattern reverse
ignore-case)))))
	(or case-fold-search-is-local
	    (kill-local-variable 'case-fold-search)))
      (and expansion
	   (setq dabbrev--last-expansion-location (point)))
      expansion)))

;;; Find all expansions of ABBREV
(defun dabbrev--find-all-expansions (abbrev ignore-case)
  (let ((all-expansions nil)
	expansion)
    (while (setq expansion (dabbrev--find-expansion abbrev 0 ignore-case))
      (setq all-expansions (cons expansion all-expansions)))
    all-expansions))

(defun dabbrev--scanning-message ()
  (message (concat "Scanning '"
		   (or buffer-file-name
		       (buffer-name (current-buffer)))
		   "'")))

;;; Find one occasion of ABBREV.
;;; DIRECTION > 0 means look that many times backwards.
;;; DIRECTION < 0 means look that many times forward.
;;; DIRECTION = 0 means try both backward and forward.
;;; IGNORE-CASE non-nil means ignore case when searching.
(defun dabbrev--find-expansion (abbrev direction ignore-case)
  (let ((pattern (concat "\\b"
			 (regexp-quote abbrev)
			 "\\(\\("
			 (or dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
			 "\\)+\\)"))
	expansion)
    (save-excursion
      (cond
       (dabbrev--last-buffer
	(set-buffer dabbrev--last-buffer)
	(dabbrev--scanning-message))
       ((window-minibuffer-p (selected-window))
	(set-buffer (dabbrev--minibuffer-origin))
	;; We don't want to be in the middle of a possible
	;; expansion, because then we will not find it.
	(re-search-forward (or dabbrev-abbrev-char-regexp
			       "\\sw\\|\\s_"))
	(dabbrev--scanning-message)))
      (cond
       ;; ------------------------------------------
       ;; Look backwards
       ;; ------------------------------------------
       ((and (>= direction 0)
	     (setq dabbrev--last-direction (min 1 direction))
	     (setq expansion (dabbrev--try-find pattern t
						(max 1 direction)
						ignore-case)))
	expansion)
       ;; ------------------------------------------
       ;; Look forward
       ;; ------------------------------------------
       ((and (<= direction 0)
	     (setq dabbrev--last-direction -1)
	     (setq expansion (dabbrev--try-find pattern nil
						(max 1 (- direction))
						ignore-case)))
	expansion)
       ;; ------------------------------------------
       ;; Look in other buffers.
       ;; Start at (point-min) and look forward.
       ;; ------------------------------------------
       (t
	(setq dabbrev--last-direction -1)
	;; Make sure that we should check other buffers
	(or dabbrev--friend-buffer-list
	    dabbrev--last-buffer
	    (not dabbrev--check-other-buffers)
	    (not (or (eq dabbrev--check-other-buffers t)
		     (progn
		       (setq dabbrev--check-other-buffers
			     (y-or-n-p "Check in other buffers this time? ")))))
	    (setq dabbrev--friend-buffer-list
		  (dabbrev--find-friend-buffers)))
	;; Walk through the buffers
	(while (and (not expansion)  (dabbrev--find-friend-buffers)))
	;; Walk through the buffers
	(while (and (not expansion) dabbrev--friend-buffer-list)
	  (setq dabbrev--last-buffer
		(car dabbrev--friend-buffer-list))
	  (setq dabbrev--friend-buffer-list
		(cdr dabbrev--friend-buffer-list))
	  (set-buffer dabbrev--last-buffer)
	  (dabbrev--scanning-message)
	  (goto-char (point-min))
	  (setq dabbrev--last-expansion-location nil)
	  (setq expansion (dabbrev--try-find pattern nil 1 ignore-case)))
	expansion)))))

(eval-when-compile (require 'picture))

(defun dabbrev--safe-replace-match (string &optional fixedcase literal)
  (if (eq major-mode 'picture-mode)
      (picture-replace-match string fixedcase literal)
    (replace-match string fixedcase literal)))

;;;----------------------------------------------------------------
;;; Substitute the current string in buffer with the expansion
;;; OLD is nil or the last expansion substring.
;;; ABBREV is the abbreviation we are working with.
;;; EXPANSION is the expansion substring.
(defun dabbrev--substitute-expansion (old abbrev expansion)
  ;.
(defun dabbrev--substitute-expansion (old abbrev expansion)
  ;;(undo-boundary)
  (and (not dabbrev-upcase-means-case-search)
       (setq old (concat abbrev (or old "")))
       (setq expansion (concat abbrev expansion)))
  (if old
      (save-excursion
	(search-backward old))
    (store-match-data (list (point-marker) (point-marker))))
  ;; Make case of replacement conform to case of abbreviation
  ;; provided (1) that kind of thing is enabled in this buffer
  ;; and (2) the replacement itself is all lower case.
  (dabbrev--safe-replace-match expansion
			       dabbrev-upcase-means-case-search
			       t))


;;;----------------------------------------------------------------
;;; Search function used by dabbrevs library.

;;; PATTERN is string to find as prefix of word. Second arg, REVERSE,
;;; is t for reverse search, nil for forward.  Variable dabbrev-limit
;;; controls the maximum search region size.  Third argment IGNORE-CASE
;;; non-nil means treat case as insignificant while looking for a match
;;; and when comparing with previous matches.  Also if that's non-nil
;;; and the match is found at the beginning of a sentence and is in
;;; lower case except for the initial then it is converted to all lower
;;; case for return.

;;; Table of expansions already seen is examined in buffer
;;; 'dabbrev--last-table' so that only distinct possibilities are found
;;; by dabbrev-re-expand.

;;; Value is the expansion, or nil if not found.

(defun dabbrev--search (pattern reverse ignore-case)
  (let ((found-string nil))
    ;; Limited search.
    (save-restriction
      (and dabbrev-limit
	   (narrow-to-region dabbrev--last-expansion-location
			     (+ (point)
				(if reverse (- dabbrev-limit) dabbrev-limit))))
      ;;--------------------------------
      ;; Look for a distinct expansion, using dabbrev--last-table.
      ;;--------------------------------
      (while (and (not found-string)
		  (if reverse
		      (re-search-backward pattern nil t)
		    (re-search-forward pattern nil t)))
	(cond
	 ((or (not dabbrev-abbrev-char-regexp)
	      (not (save-excursion
		     (goto-char (match-beginning 0))
		     (char-equal ?_ (char-syntax (preceding-char))))))
	  (setq found-string
		(buffer-substring (match-beginning 1) (match-end 1)))
	  (and ignore-case (setq found-string (downcase found-string)))
	  ;; Throw away if found in table
	  (and (some
		(function
		 (lambda (table-string) (string= found-string table-string)))
		dabbrev--last-table)
	       (setq found-string nil)))))
      (cond
       (found-string
	;;--------------------------------
	;; Put in 'dabbrev--last-table' and decide if we should return
	;; result or (downcase result)
	;;--------------------------------
	(setq dabbrev--last-table (cons found-string dabbrev--last-table))
	(let ((result (buffer-substring (match-beginning 1) (match-end 1))))
	  (if ignore-case (downcase result) result)))))))

;; nmatch-beginning 1) (match-end 1))))
	  (if ignore-case (downcase result) result)))))))





More information about the Python-list mailing list