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
  • 33,167
  • 1
  • 37
  • 77
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 \|. – 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
  • 33,167
  • 1
  • 37
  • 77
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:]]*\\_>"