unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] Support for case sensitive abbrev expansion
@ 2002-07-25 19:39 Károly Lőrentey
  2002-07-26  8:30 ` Miles Bader
  0 siblings, 1 reply; 4+ messages in thread
From: Károly Lőrentey @ 2002-07-25 19:39 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2247 bytes --]


I use abbrevs while coding to expand control structure keywords to
whole statement templates.  abbrev-mode saves me huge amounts of
typing, IMHO it's an incredibly useful feature in Emacs.  But there is
one thing that has annoyed me ever since I defined my first source
code abbrev: the case-insensitivity (and, what's more,
case-preservation) of expansions.

Case-preserving is useful in text modes, but in most programming
languages, preserving the case of an abbrev expansion simply does not
make sense.  Even ignoring case differences can lead to unexpected
behavior: for example, JDE defines 'sw' as an abbrev of the Java
keyword 'switch'.  Currently this means that abbrev-mode expands all
of 'sw', 'Sw', 'sW' and 'SW', which is quite annoying while editing
source code written in a case-sensitive language.

This patch adds support for case-sensitive expansion of abbrevs.  A
new variable `abbrev-case-fold' is defined to let the user control
case behavior.  By default, case-sensitivity is inherited from
`case-fold-search'.

I implemented `abbrev-case-fold' as a new primitive buffer-local
variable.  (Buffer-locality is necessary, because IMHO most people
would want to keep the nifty case-preserving behavior in text
buffers.)  This required changes in buffer.c, buffer.h, cus-start.el
and elint.el, in addition to abbrev.c.  The patch includes
documentation updates and a NEWS entry.  If necessary, I am prepared
to sign a copyright assignment.

What do you think?  Is this the right way to do this?

-- Károly Lőrentey


2002-07-25  Károly Lőrentey <lorentey@elte.hu>
	  
	* buffer.h (struct buffer) <abbrev_case_fold>: New buffer-local
	variable.
	
	* buffer.c (Qcase_fold_search): New variable.
	(init_buffer_once): Initialize abbrev_case_fold.
	(syms_of_buffer): Initialize new vars.
	
	* abbrev.c (Qcase_fold_search): New variable.
	(Fdefine_global_abbrev, Fdefine_mode_abbrev): Do not downcase
	abbrev.
	(Fexpand_abbrev): Add support for case-sensitive expansion.
	(syms_of_abbrev): Initialize new vars.

2002-07-25  Károly Lőrentey <lorentey@elte.hu>

	* cus-start.el: Added abbrev-case-fold.

	* emacs-lisp/elint.el (elint-standard-variables): Added
	abbrev-case-fold.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Support for case sensitive abbrev expansion --]
[-- Type: text/x-patch, Size: 12588 bytes --]

Index: etc/NEWS
===================================================================
RCS file: /cvsroot/emacs/emacs/etc/NEWS,v
retrieving revision 1.718
diff -b -c -r1.718 NEWS
*** etc/NEWS	24 Jul 2002 22:14:47 -0000	1.718
--- etc/NEWS	25 Jul 2002 19:25:44 -0000
***************
*** 58,63 ****
--- 58,70 ----
  * Changes in Emacs 21.4
  
  +++
+ ** New user option `abbrev-case-fold'.  This option can be disabled to
+ avoid expanding abbrevs if their case differs from how they were
+ defined.  This is handy when the case preserving feature of abbrevs
+ doesn't make sense (e.g. in most programming modes).  The default is
+ to use the same setting as case-fold-search.
+ 
+ +++
  ** You can now customize the use of window fringes.  To control this
  for all frames, use M-x fringe-mode or the Show/Hide submenu of the
  top-level Options menu, or customize the `fringe-mode' variable.  To
Index: man/abbrevs.texi
===================================================================
RCS file: /cvsroot/emacs/emacs/man/abbrevs.texi,v
retrieving revision 1.16
diff -b -c -r1.16 abbrevs.texi
*** man/abbrevs.texi	3 Jan 2002 05:19:26 -0000	1.16
--- man/abbrevs.texi	25 Jul 2002 19:25:44 -0000
***************
*** 155,166 ****
  can be part of an abbrev.  The most common way to use an abbrev is to
  insert it and then insert a punctuation character to expand it.
  
  @vindex abbrev-all-caps
!   Abbrev expansion preserves case; thus, @samp{foo} expands into @samp{find
! outer otter}; @samp{Foo} into @samp{Find outer otter}, and @samp{FOO} into
! @samp{FIND OUTER OTTER} or @samp{Find Outer Otter} according to the
! variable @code{abbrev-all-caps} (a non-@code{nil} value chooses the first
! of the two expansions).
  
    These commands are used to control abbrev expansion:
  
--- 155,174 ----
  can be part of an abbrev.  The most common way to use an abbrev is to
  insert it and then insert a punctuation character to expand it.
  
+ @vindex abbrev-case-fold
+   Usually, abbrev expansion is case-insensitive; thus, @samp{foo},
+ @samp{Foo}, and @samp{FOO} are all expanded.  If you set the variable
+ @code{abbrev-case-fold} to @code{nil}, then all letters in the abbrev
+ must match exactly, including case.  This is a per-buffer variable;
+ altering the variable affects only the current buffer, but there is a
+ default value which you can change as well. @xref{Locals}.
+ 
  @vindex abbrev-all-caps
!   Case-insensitive abbrev expansion preserves case; thus, @samp{foo}
! expands into @samp{find outer otter}; @samp{Foo} into @samp{Find outer
! otter}, and @samp{FOO} into @samp{FIND OUTER OTTER} or @samp{Find
! Outer Otter} according to the variable @code{abbrev-all-caps} (a
! non-@code{nil} value chooses the first of the two expansions).
  
    These commands are used to control abbrev expansion:
  
Index: src/buffer.h
===================================================================
RCS file: /cvsroot/emacs/emacs/src/buffer.h,v
retrieving revision 1.85
diff -b -c -r1.85 buffer.h
*** src/buffer.h	10 Jan 2002 11:13:17 -0000	1.85
--- src/buffer.h	25 Jul 2002 19:25:45 -0000
***************
*** 639,644 ****
--- 639,646 ----
    Lisp_Object overwrite_mode;
    /* non-nil means abbrev mode is on.  Expand abbrevs automatically.  */
    Lisp_Object abbrev_mode;
+   /* Control whether ignore case when expanding abbreviations. */
+   Lisp_Object abbrev_case_fold;
    /* Display table to use for text in this buffer.  */
    Lisp_Object display_table;
    /* t means the mark and region are currently active.  */
Index: src/buffer.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/buffer.c,v
retrieving revision 1.398
diff -b -c -r1.398 buffer.c
*** src/buffer.c	21 Jul 2002 20:25:32 -0000	1.398
--- src/buffer.c	25 Jul 2002 19:25:48 -0000
***************
*** 4867,4872 ****
--- 4867,4873 ----
    buffer_defaults.abbrev_mode = Qnil;
    buffer_defaults.overwrite_mode = Qnil;
    buffer_defaults.case_fold_search = Qt;
+   buffer_defaults.abbrev_case_fold = intern ("case-fold-search");
    buffer_defaults.auto_fill_function = Qnil;
    buffer_defaults.selective_display = Qnil;
  #ifndef old
***************
*** 4936,4941 ****
--- 4937,4943 ----
    XSETFASTINT (buffer_local_flags.abbrev_mode, idx); ++idx;
    XSETFASTINT (buffer_local_flags.overwrite_mode, idx); ++idx;
    XSETFASTINT (buffer_local_flags.case_fold_search, idx); ++idx;
+   XSETFASTINT (buffer_local_flags.abbrev_case_fold, idx); ++idx;
    XSETFASTINT (buffer_local_flags.auto_fill_function, idx); ++idx;
    XSETFASTINT (buffer_local_flags.selective_display, idx); ++idx;
  #ifndef old
***************
*** 5196,5201 ****
--- 5198,5208 ----
  		     doc: /* Default value of `case-fold-search' for buffers that don't override it.
  This is the same as (default-value 'case-fold-search).  */);
  
+   DEFVAR_LISP_NOPRO ("default-abbrev-case-fold",
+ 		     &buffer_defaults.abbrev_case_fold,
+ 		     doc: /* Default value of `abbrev-case-fold' for buffers that don't override it.
+ This is the same as (default-value 'abbrev-case-fold').  */);
+   
  #ifdef DOS_NT
    DEFVAR_LISP_NOPRO ("default-buffer-file-type", 
  		     &buffer_defaults.buffer_file_type,
Index: src/abbrev.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/abbrev.c,v
retrieving revision 1.55
diff -b -c -r1.55 abbrev.c
*** src/abbrev.c	15 Jul 2002 00:00:35 -0000	1.55
--- src/abbrev.c	25 Jul 2002 19:25:49 -0000
***************
*** 84,89 ****
--- 84,90 ----
  Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
  
  Lisp_Object Qsystem_type, Qcount;
+ Lisp_Object Qcase_fold_search;
  \f
  DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
         doc: /* Create a new, empty abbrev table object.  */)
***************
*** 166,172 ****
       (abbrev, expansion)
       Lisp_Object abbrev, expansion;
  {
!   Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
--- 167,173 ----
       (abbrev, expansion)
       Lisp_Object abbrev, expansion;
  {
!   Fdefine_abbrev (Vglobal_abbrev_table, abbrev,
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
***************
*** 180,186 ****
    if (NILP (current_buffer->abbrev_table))
      error ("Major mode has no abbrev table");
  
!   Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
--- 181,187 ----
    if (NILP (current_buffer->abbrev_table))
      error ("Major mode has no abbrev table");
  
!   Fdefine_abbrev (current_buffer->abbrev_table, abbrev,
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
***************
*** 244,254 ****
--- 245,264 ----
    register Lisp_Object sym;
    Lisp_Object expansion, hook, tem;
    Lisp_Object value;
+   int case_fold;
  
    value = Qnil;
  
    Frun_hooks (1, &Qpre_abbrev_expand_hook);
  
+   if (SYMBOLP (current_buffer->abbrev_case_fold)
+       && EQ (current_buffer->abbrev_case_fold, Qcase_fold_search))
+     {
+       case_fold = !NILP (current_buffer->case_fold_search);
+     }
+   else
+     case_fold = !NILP (current_buffer->abbrev_case_fold);
+   
    wordstart = 0;
    if (!(BUFFERP (Vabbrev_start_location_buffer)
  	&& XBUFFER (Vabbrev_start_location_buffer) == current_buffer))
***************
*** 294,300 ****
        /* ??? This loop needs to go by characters!  */
        register int c = FETCH_BYTE (idx);
        if (UPPERCASEP (c))
! 	c = DOWNCASE (c), uccount++;
        else if (! NOCASEP (c))
  	lccount++;
        *p++ = c;
--- 304,314 ----
        /* ??? This loop needs to go by characters!  */
        register int c = FETCH_BYTE (idx);
        if (UPPERCASEP (c))
!         {
!           if (case_fold)
!             c = DOWNCASE (c);
!           uccount++;
!         }
        else if (! NOCASEP (c))
          lccount++;
        *p++ = c;
***************
*** 348,356 ****
  			  SBYTES (expansion), 1);
        SET_PT (PT + whitecnt);
  
!       if (uccount && !lccount)
  	{
! 	  /* Abbrev was all caps */
  	  /* If expansion is multiple words, normally capitalize each word */
  	  /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
  	     but Megatest 68000 compiler can't handle that */
--- 362,370 ----
  			  SBYTES (expansion), 1);
        SET_PT (PT + whitecnt);
  
!       if (case_fold && uccount && !lccount)
  	{
! 	  /* Abbrev was all caps with case insensitive expansion */
  	  /* If expansion is multiple words, normally capitalize each word */
  	  /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
  	     but Megatest 68000 compiler can't handle that */
***************
*** 365,371 ****
  	  Fupcase_region (make_number (wordstart), make_number (PT));
  	caped: ;
  	}
!       else if (uccount)
  	{
  	  /* Abbrev included some caps.  Cap first initial of expansion */
  	  int pos = wordstart_byte;
--- 379,385 ----
  	  Fupcase_region (make_number (wordstart), make_number (PT));
  	caped: ;
  	}
!       else if (case_fold && uccount)
  	{
  	  /* Abbrev included some caps.  Cap first initial of expansion */
  	  int pos = wordstart_byte;
***************
*** 600,605 ****
--- 614,622 ----
    Qcount = intern ("count");
    staticpro (&Qcount);
  
+   Qcase_fold_search = intern ("case-fold-search");
+   staticpro (&Qcase_fold_search);
+ 
    DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list,
  	       doc: /* List of symbols whose values are abbrev tables.  */);
    Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"),
***************
*** 647,652 ****
--- 664,682 ----
    DEFVAR_PER_BUFFER ("local-abbrev-table", &current_buffer->abbrev_table, Qnil,
  		     doc: /* Local (mode-specific) abbrev table of current buffer.  */);
  
+   DEFVAR_PER_BUFFER ("abbrev-case-fold", &current_buffer->abbrev_case_fold, Qcase_fold_search,
+                      doc: /* *Control whether ignore case when expanding abbreviations.
+ A value of nil means case is significant, and abbrevs must
+ be typed exactly the same as they were defined in order to
+ be recognized.
+ A value of `case-fold-search' (the default) means case is
+ significant if `case-fold-search' is nil.
+ Any other non-nil value means case is not significant.
+ 
+ Note that if you define abbrevs containing uppercase
+ characters, then they will not be available if the
+ expansion is case-insensitive. */);
+                              
    DEFVAR_BOOL ("abbrevs-changed", &abbrevs_changed,
  	       doc: /* Set non-nil by defining or altering any word abbrevs.
  This causes `save-some-buffers' to offer to save the abbrevs.  */);
Index: lisp/cus-start.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/cus-start.el,v
retrieving revision 1.51
diff -b -c -r1.51 cus-start.el
*** lisp/cus-start.el	22 Jul 2002 15:22:49 -0000	1.51
--- lisp/cus-start.el	25 Jul 2002 19:25:49 -0000
***************
*** 57,62 ****
--- 57,68 ----
  	     (indicate-empty-lines display boolean "21.1")
  	     (scroll-up-aggressively windows boolean "21.1")
  	     (scroll-down-aggressively windows boolean "21.1")
+ 	     (abbrev-case-fold 
+ 	      abbrev-mode 
+ 	      (choice (const :tag "Don't ignore case" nil)
+ 		      (const :tag "Ignore case" t)
+ 		      (const :tag "Same as case-fold-search" case-fold-search))
+ 	      "21.4")
  	     ;; callint.c
  	     (mark-even-if-inactive editing-basics boolean)
  	     ;; callproc.c
Index: lisp/emacs-lisp/elint.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emacs-lisp/elint.el,v
retrieving revision 1.5
diff -b -c -r1.5 elint.el
*** lisp/emacs-lisp/elint.el	22 Dec 2001 13:37:30 -0000	1.5
--- lisp/emacs-lisp/elint.el	25 Jul 2002 19:25:50 -0000
***************
*** 728,734 ****
  ;;;
  
  (defconst elint-standard-variables
!   '(abbrev-mode auto-fill-function buffer-auto-save-file-name
       buffer-backed-up buffer-display-table buffer-file-format
       buffer-file-name buffer-file-number buffer-file-truename
       buffer-file-type buffer-invisibility-spec buffer-offer-save
--- 728,734 ----
  ;;;
  
  (defconst elint-standard-variables
!   '(abbrev-case-fold abbrev-mode auto-fill-function buffer-auto-save-file-name
       buffer-backed-up buffer-display-table buffer-file-format
       buffer-file-name buffer-file-number buffer-file-truename
       buffer-file-type buffer-invisibility-spec buffer-offer-save

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Support for case sensitive abbrev expansion
  2002-07-25 19:39 [PATCH] Support for case sensitive abbrev expansion Károly Lőrentey
@ 2002-07-26  8:30 ` Miles Bader
  2002-07-26 16:21   ` Károly Lőrentey
  2002-07-27 18:52   ` Richard Stallman
  0 siblings, 2 replies; 4+ messages in thread
From: Miles Bader @ 2002-07-26  8:30 UTC (permalink / raw)
  Cc: emacs-devel

Just some technical comments:

There's no need to add a new field to `struct buffer' for the
`abbrev-case-fold' variable, you can just declare a normal variable
Vabbrev_case_fold using DEFVAR_LISP, and emacs will do the right thing
if a mode makes it buffer-local.  [There are obviously trade-offs, but I
think for something minor like this you shouldn't extend the buffer
structure]

The feature that makes it track `case-fold-search' probably isn't useful
-- I expect that in most cases people will want to retain
case-insensitive searching, even in situations where case-sensitive
abbrevs would be appropriate.  I think you should just initialize the
global value to `nil' for compatibility, and leave it to individual
language modes to set a different buffer-local value.

-Miles
-- 
[|nurgle|]  ddt- demonic? so quake will have an evil kinda setting? one that 
            will  make every christian in the world foamm at the mouth? 
[iddt]      nurg, that's the goal 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Support for case sensitive abbrev expansion
  2002-07-26  8:30 ` Miles Bader
@ 2002-07-26 16:21   ` Károly Lőrentey
  2002-07-27 18:52   ` Richard Stallman
  1 sibling, 0 replies; 4+ messages in thread
From: Károly Lőrentey @ 2002-07-26 16:21 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 935 bytes --]

Miles Bader <miles@lsi.nec.co.jp> writes:
> There's no need to add a new field to `struct buffer' for the
> `abbrev-case-fold' variable, you can just declare a normal variable
> Vabbrev_case_fold using DEFVAR_LISP, and emacs will do the right thing
> if a mode makes it buffer-local.  [There are obviously trade-offs, but I
> think for something minor like this you shouldn't extend the buffer
> structure]

You are right, and I was hoping for a solution that was simpler than
that. :-)

> The feature that makes it track `case-fold-search' probably isn't useful
> -- I expect that in most cases people will want to retain
> case-insensitive searching, even in situations where case-sensitive
> abbrevs would be appropriate.  I think you should just initialize the
> global value to `nil' for compatibility, and leave it to individual
> language modes to set a different buffer-local value.

All right.  Here is a much cleaner patch:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Case-sensitive abbrev expansion, v2 --]
[-- Type: text/x-patch, Size: 7561 bytes --]

Index: etc/NEWS
===================================================================
RCS file: /cvsroot/emacs/emacs/etc/NEWS,v
retrieving revision 1.719
diff -b -c -r1.719 NEWS
*** etc/NEWS	25 Jul 2002 11:10:38 -0000	1.719
--- etc/NEWS	26 Jul 2002 16:06:58 -0000
***************
*** 58,63 ****
--- 58,69 ----
  * Changes in Emacs 21.4
  
  +++
+ ** New user option `abbrev-case-fold'.  This option can be disabled to
+ avoid expanding abbrevs if their case differs from how they were
+ defined.  This is handy when the case preserving feature of abbrevs
+ doesn't make sense (e.g. in most programming modes).
+ 
+ +++
  ** You can now customize the use of window fringes.  To control this
  for all frames, use M-x fringe-mode or the Show/Hide submenu of the
  top-level Options menu, or customize the `fringe-mode' variable.  To
Index: man/abbrevs.texi
===================================================================
RCS file: /cvsroot/emacs/emacs/man/abbrevs.texi,v
retrieving revision 1.16
diff -b -c -r1.16 abbrevs.texi
*** man/abbrevs.texi	3 Jan 2002 05:19:26 -0000	1.16
--- man/abbrevs.texi	26 Jul 2002 16:06:58 -0000
***************
*** 155,166 ****
  can be part of an abbrev.  The most common way to use an abbrev is to
  insert it and then insert a punctuation character to expand it.
  
  @vindex abbrev-all-caps
!   Abbrev expansion preserves case; thus, @samp{foo} expands into @samp{find
! outer otter}; @samp{Foo} into @samp{Find outer otter}, and @samp{FOO} into
! @samp{FIND OUTER OTTER} or @samp{Find Outer Otter} according to the
! variable @code{abbrev-all-caps} (a non-@code{nil} value chooses the first
! of the two expansions).
  
    These commands are used to control abbrev expansion:
  
--- 155,172 ----
  can be part of an abbrev.  The most common way to use an abbrev is to
  insert it and then insert a punctuation character to expand it.
  
+ @vindex abbrev-case-fold
+   Usually, abbrev expansion is case-insensitive; thus, @samp{foo},
+ @samp{Foo}, and @samp{FOO} are all expanded.  If you set the variable
+ @code{abbrev-case-fold} to @code{nil}, then all letters in the abbrev
+ must match exactly, including case.
+ 
  @vindex abbrev-all-caps
!   Case-insensitive abbrev expansion preserves case; thus, @samp{foo}
! expands into @samp{find outer otter}; @samp{Foo} into @samp{Find outer
! otter}, and @samp{FOO} into @samp{FIND OUTER OTTER} or @samp{Find
! Outer Otter} according to the variable @code{abbrev-all-caps} (a
! non-@code{nil} value chooses the first of the two expansions).
  
    These commands are used to control abbrev expansion:
  
Index: src/abbrev.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/abbrev.c,v
retrieving revision 1.55
diff -b -c -r1.55 abbrev.c
*** src/abbrev.c	15 Jul 2002 00:00:35 -0000	1.55
--- src/abbrev.c	26 Jul 2002 16:06:58 -0000
***************
*** 83,88 ****
--- 83,91 ----
  
  Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook;
  
+ /* Control whether ignore case when expanding abbreviations. */
+ Lisp_Object Vabbrev_case_fold;
+ 
  Lisp_Object Qsystem_type, Qcount;
  \f
  DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0,
***************
*** 166,172 ****
       (abbrev, expansion)
       Lisp_Object abbrev, expansion;
  {
!   Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev),
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
--- 169,175 ----
       (abbrev, expansion)
       Lisp_Object abbrev, expansion;
  {
!   Fdefine_abbrev (Vglobal_abbrev_table, abbrev,
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
***************
*** 180,186 ****
    if (NILP (current_buffer->abbrev_table))
      error ("Major mode has no abbrev table");
  
!   Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev),
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
--- 183,189 ----
    if (NILP (current_buffer->abbrev_table))
      error ("Major mode has no abbrev table");
  
!   Fdefine_abbrev (current_buffer->abbrev_table, abbrev,
  		  expansion, Qnil, make_number (0), Qnil);
    return abbrev;
  }
***************
*** 294,300 ****
        /* ??? This loop needs to go by characters!  */
        register int c = FETCH_BYTE (idx);
        if (UPPERCASEP (c))
! 	c = DOWNCASE (c), uccount++;
        else if (! NOCASEP (c))
  	lccount++;
        *p++ = c;
--- 297,307 ----
        /* ??? This loop needs to go by characters!  */
        register int c = FETCH_BYTE (idx);
        if (UPPERCASEP (c))
!         {
!           if (!NILP (Vabbrev_case_fold))
!             c = DOWNCASE (c);
!           uccount++;
!         }
        else if (! NOCASEP (c))
          lccount++;
        *p++ = c;
***************
*** 348,356 ****
  			  SBYTES (expansion), 1);
        SET_PT (PT + whitecnt);
  
!       if (uccount && !lccount)
  	{
! 	  /* Abbrev was all caps */
  	  /* If expansion is multiple words, normally capitalize each word */
  	  /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
  	     but Megatest 68000 compiler can't handle that */
--- 355,363 ----
  			  SBYTES (expansion), 1);
        SET_PT (PT + whitecnt);
  
!       if (!NILP (Vabbrev_case_fold) && uccount && !lccount)
  	{
! 	  /* Abbrev was all caps with case insensitive expansion */
  	  /* If expansion is multiple words, normally capitalize each word */
  	  /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase
  	     but Megatest 68000 compiler can't handle that */
***************
*** 365,371 ****
  	  Fupcase_region (make_number (wordstart), make_number (PT));
  	caped: ;
  	}
!       else if (uccount)
  	{
  	  /* Abbrev included some caps.  Cap first initial of expansion */
  	  int pos = wordstart_byte;
--- 372,378 ----
  	  Fupcase_region (make_number (wordstart), make_number (PT));
  	caped: ;
  	}
!       else if (!NILP (Vabbrev_case_fold) && uccount)
  	{
  	  /* Abbrev included some caps.  Cap first initial of expansion */
  	  int pos = wordstart_byte;
***************
*** 647,652 ****
--- 654,670 ----
    DEFVAR_PER_BUFFER ("local-abbrev-table", &current_buffer->abbrev_table, Qnil,
  		     doc: /* Local (mode-specific) abbrev table of current buffer.  */);
  
+   DEFVAR_LISP ("abbrev-case-fold", &Vabbrev_case_fold,
+                doc: /* *Non-nil means ignore case when expanding abbreviations.
+ A value of nil means case is significant, and abbrevs must
+ be typed exactly the same as they were defined in order to
+ be recognized.
+ 
+ Note that if you define abbrevs containing uppercase
+ characters, then they will not be available if the
+ expansion is case-insensitive. */);
+   Vabbrev_case_fold = Qt;
+                              
    DEFVAR_BOOL ("abbrevs-changed", &abbrevs_changed,
  	       doc: /* Set non-nil by defining or altering any word abbrevs.
  This causes `save-some-buffers' to offer to save the abbrevs.  */);
Index: lisp/cus-start.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/cus-start.el,v
retrieving revision 1.51
diff -b -c -r1.51 cus-start.el
*** lisp/cus-start.el	22 Jul 2002 15:22:49 -0000	1.51
--- lisp/cus-start.el	26 Jul 2002 16:06:58 -0000
***************
*** 37,42 ****
--- 37,43 ----
  (let ((all '(;; abbrev.c 
  	     (abbrev-all-caps abbrev-mode boolean)
  	     (pre-abbrev-expand-hook abbrev-mode hook)
+ 	     (abbrev-case-fold abbrev-mode boolean "21.4")
  	     ;; alloc.c
  	     (gc-cons-threshold alloc integer)
  	     (undo-limit undo integer)

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]


2002-07-26  Károly Lőrentey <lorentey@elte.hu>
	  
	* abbrev.c (Vabbrev_case_fold): New variable.
	(Fexpand_abbrev): Use it.
	(Fdefine_global_abbrev, Fdefine_mode_abbrev): Do not downcase
	abbrev.
	(syms_of_abbrev): Initialize Vabbrev_case_fold.

2002-07-26  Károly Lőrentey <lorentey@elte.hu>

	* cus-start.el: Added abbrev-case-fold.

-- 
Lőrentey Károly

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Support for case sensitive abbrev expansion
  2002-07-26  8:30 ` Miles Bader
  2002-07-26 16:21   ` Károly Lőrentey
@ 2002-07-27 18:52   ` Richard Stallman
  1 sibling, 0 replies; 4+ messages in thread
From: Richard Stallman @ 2002-07-27 18:52 UTC (permalink / raw)
  Cc: lorentey, emacs-devel

    The feature that makes it track `case-fold-search' probably isn't useful
    -- I expect that in most cases people will want to retain
    case-insensitive searching, even in situations where case-sensitive
    abbrevs would be appropriate.  I think you should just initialize the
    global value to `nil' for compatibility, and leave it to individual
    language modes to set a different buffer-local value.

Neither one is the right way to implement such a feature.  It would be
wrong for any mode to make all abbrev definitions case-sensitive.

All programming languages allow comments, which are written in human
languages, normally with mixed case.  Therefore, abbrevs for
human-language text are useful in all modes, and the current
case-adaptation features of abbrevs are useful in all modes.

The only kind of case-sensitive abbrev feature that would be
acceptable is one that allows individual abbrevs to be case-sensitive.
That feature would do no harm.  However, I don't think it is worth
implementing.  If you make your abbrevs three characters instead of
two, you can easily make them unobtrusive so that they don't get
in your way when you don't want them.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2002-07-27 18:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-25 19:39 [PATCH] Support for case sensitive abbrev expansion Károly Lőrentey
2002-07-26  8:30 ` Miles Bader
2002-07-26 16:21   ` Károly Lőrentey
2002-07-27 18:52   ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).