0

I have the following function

(defun fphp/find-unimported-classes ()
  (interactive)
  (mapcar (lambda (classentry)
            (ov-clear (classentry-overlay classentry))
            )
          classentries)
  (setq classentries '())
  (save-excursion
    (goto-char (point-min))
    (while (re-search-forward "$[A-Z]+" nil t)
      (backward-word)
      (backward-word)
      (setq word (current-word))
      (setq wordpoint (point))
      (forward-word)
      (setq endwordpoint (point))
      (forward-word)
      (if (string= (capitalize word) word)
          (add-to-list 'classentries (make-classentry :word word))))
    (mapcar (lambda (classentry)
              (goto-char (point-max))
              (setq word (classentry-word classentry))
              (message word)
              (setq classregexp (concat "\\(" (substring word 0 1) "\\)"
                                        (substring word 1) "\s"))
              (if (buffer-contains-string (concat "use [A-Z+\\]+" word ";"))
                  (ov-set classregexp 'face 'class-defined-face '(classentry-overlay classentry) t)
                (ov-set classregexp 'face 'class-undefined-face '(classentry-overlay classentry) t)
                )
              )
            classentries)
    ))

It's purpose is to match all unimported classes in the php code and it works quite well, however it matches also variable names, like:

$className

I want to modify it to match only capitalized words. The regexp is built here:

(setq classregexp (concat "\\(" (substring word 0 1) "\\)" 
(substring word 1) "\s"))

How can I achieve it? Now it matches all cases of the first character.

Tobias
  • 32,569
  • 1
  • 34
  • 75
Filip Górny
  • 101
  • 3
  • Please consider indenting your code in the usual way. Thx. – Drew Jul 02 '18 at 15:00
  • `[:upper:]` matches uppercase characters when `case-fold-search` is non-`nil`. Also, you're using `$` in your regular expression without escaping it, and in that case it matches end of the line, which probably isn't what you're looking for. –  Jul 02 '18 at 17:00
  • @DoMiNeLa10 The character `$` has its special meaning [only at the end of a regexp or before `\)` or `\|`](https://emacs.stackexchange.com/questions/10591/why-doesnt-j-match-a-new-line-character-after-another-line). – Tobias Jul 03 '18 at 00:03
  • @DoMiNeLa10 You can write an answer based on your comment on `[:upper:]`. But you should write: "**even** when `case-fold-search` is non-nil" in your answer to stress that that version works with `case-fold-search` set to `t` **or** `nil`, i.e. that regexp is independent from the setting of `case-fold-search`. – Tobias Jul 03 '18 at 00:37

2 Answers2

1

The matching of upper/lower case letters is controlled by the option case-fold-search. A non-nil value of case-fold-search implies that matches ignore case.

If you want to match upper/lower case letters at specific places in your elisp code you need to put your matching-operation into a let with case-fold-search bound to nil.

Example:

(let ((case-fold-search nil))
  (re-search-forward "$[A-Z]+" nil t))

Note that the explicit value in the binding is just syntactic sugar to make clear what you mean. You could also write shorter as follows:

(let (case-fold-search)
  (re-search-forward "$[A-Z]+" nil t))

At the time of writing of that answer there is a page on emacswiki about case-fold-search and there is of course a man page for case-fold-search.

Related answer here on emacs.se: How to perform case-sensitive query-replace? Please see also the comments on case-replace there for case-related problems with emacs regexps in a more general context.

Tobias
  • 32,569
  • 1
  • 34
  • 75
0

You can use [:upper:] to match uppercase characters in your regular expression. Make sure case-fold-search is set to nil when you're using case sensitive regular expressions. For instance, a regexp that matches symbols which consist only of letters and start with a capital one (including ones that are just a capital letter):

"\\_<[[:upper:]][[:upper:][:lower:]]*\\_>"