5

I have a bunch of keywords:

  • set
  • write
  • quit

which each can be shortened down to one letter:

  • s se set
  • w wr wri writ write
  • q qu qui quit

Further, these keywords are case-insensitive, so the following are added to the mix:

  • s S se sE Se SE ...
  • w W wr wR Wr WR ...
  • q Q qu qU Qu QU ...

Given a list of the basic keywords ("set" "write" "quit"), how can I create a regular expression that will match them as I describe?


I've approached it by providing a list to regexp-opt, but the case-insensitivity list is proving hard to write. Here is what I have so far:

(defun mumps--command-variants (command &optional stack)
  "Returns the possible abbreviations of COMMAND.
For example, input of \"set\" would yield the list
  \(\"s\" \"se\" \"set\")"
  (let ((case-insensitive-command-list
         (mumps--case-insensitize command))))
  (if (= 1 (length command))
      (cons command stack)
    (mumps--command-variants
     (substring command 0 (1- (length command)))
     (cons command stack))))

Note on use-case

This is going to be used to create font-lock keywords for a major mode for editing MUMPS code. MUMPS is an... interesting language: command names are case-insensitive (and can be abbreviated like this), but everything else in the language is case-sensitive (and cannot be abbreviated). Furthermore, there is no syntactical difference between a expression which uses a command and that which uses a function (a subroutine of commands), but one is case-insensitive/abbreviated and the other is not.

  • Can you please specify the use context for the regexp? Is this for regexp search (C-M-s)? Is it for completion? Etc. As @Dan indicates, there can be different variables for controlling case-sensitivity, depending on the context. – Drew Feb 9 '15 at 22:08
  • @Drew As the function name implies, this is for a major-mode for editing MUMPS code, a syntactically absurd language. The regexp will be used to construct the mumps-font-lock-keywords to be used for highlighting. Some keywords are case-insensitive, some are case-sensitive. I really think the question as it is written would be the solution, but I provided some context to avoid the X/Y problem (which I seem to have fallen into in reverse...). – Sean Allred Feb 9 '15 at 22:12
  • ;-) Sorry if I muddied the waters instead of helping clear things up. – Drew Feb 9 '15 at 22:16
  • @Drew Not at all :) I'll try to edit the question to make the context clearer. – Sean Allred Feb 9 '15 at 22:17
  • I assume you're already aware of lorikeem, an existing set of tools for editing MUMPS code in Emacs. – wasamasa Feb 10 '15 at 8:57
4

After reading the comments in a previous answer, it appears that you would like to write a font-lock rule which would match one regexp without case, whereas the others would still be matched with a case.

The easiest way to do this is to break out the matcher of the font-lock rule to a function, for example:

Before:

 ...
 (MY-REGEXP
  (0 font-lock-variable-name-face)
  (1 another-face)
  ...)
 ...

After:

 (defun my-match-the-regexp (limit)
   (let ((case-fold-search t))
     (re-search-forward MY-REGEXP limit t)))

 (my-match-the-regexp
  (0 font-lock-variable-name-face)
  (1 another-face)
  ...)
1

The docstring for re-search-forward says:

Search case-sensitivity is determined by the value of the variable case-fold-search, which see.

Hence, you can set case-fold-search to t:

Documentation: Non-nil if searches and matches should ignore case.

EDIT For font locking, you can set font-lock-keywords-case-fold-search to t:

Documentation: Non-nil means the patterns in font-lock-keywords are case-insensitive. This is set via the function font-lock-set-defaults, based on the CASE-FOLD argument of font-lock-defaults.

  • 1
    Will this be effective when using the regular expression in font-lock keywords? – Sean Allred Feb 9 '15 at 21:17
  • @SeanAllred: see edit. It looks like you can set font-lock-keywords-case-fold-search. – Dan Feb 9 '15 at 21:20
  • 1
    Sorry, but only these words are case insensitive. MUMPS is an absurd language -- commands are case insensitive, but everything else is case-sensitive. Interesting that font-lock-mode provides this, though. – Sean Allred Feb 9 '15 at 21:21
  • Are you using your regexp within a function used as part of a font-lock-keywords FUNCTION? If so, perhaps you can use an ANCHOR or another means to control the scope of what you want to be case-sensitive. IOW, perhaps you can use a function that can (at that point) know just how far to search case-insensitively. If this suggestion doesn't help, ignore. But it sounds like the problem (use case) might be underspecified. – Drew Feb 9 '15 at 22:12
  • @Drew sorry for not providing enough detail. I don't think anchors will help in this case (for this language) since there is no specific scope reserved for commands (e.g. functions are case-sensitive, but have the same exact syntax). – Sean Allred Feb 9 '15 at 22:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.