0
(defun pretty-add-keywords (mode keywords)
      (font-lock-add-keywords
       mode (mapcar (lambda (kw) `(,(car kw)
                                   (0 (prog1 nil
                                        (compose-region (match-beginning 0)
                                                        (match-end 0)
                                                        ,(cdr kw))))))
                    keywords)))

This function currently lets me match a regexp and replace it with a single char. I've been trying to modify it so that instead of just replacing it with a fixed char it replaces it with a group from the regex.

Would anybody be able to help me out.

Thanks

  • Could you post an example of the end result, and also how you all the function today. – Lindydancer Oct 27 '16 at 8:44
  • Here is what it looks like before I call the function. This is what it looks like after. – Wolfe Oct 27 '16 at 13:08
  • Ok, so far so good. Could you give an example of what want to accomplish, which doesn't work today? – Lindydancer Oct 27 '16 at 18:53
  • Basically instead of just replacing a static char I wanted to be able to extract a group. So for example if I had array[x] I would want to be able to replace (visually) that with just x. I know font lock uses regexps internally but I haven't found a way to access the groups. – Wolfe Oct 27 '16 at 18:56
1

The following code will hide the "array[" and "]" parts using the invisible text property. It is a different approach compared to using compose-region, as suggested in the question.

(defun my-hide-array ()
  (make-variable-buffer-local 'font-lock-extra-managed-props)
  (add-to-list 'font-lock-extra-managed-props 'invisible)
  (font-lock-add-keywords nil
                          '(("\\(\\_<array\\_>\\[\\)[a-zA-Z0-9_]+\\(\\]\\)"
                             (1 '(face nil invisible t))
                             (2 '(face nil invisible t))))))

You can add this function to a suitable major mode hook.

Using compose-region would probably not be a good idea -- the replacement text would probably not be editable, so you would have to disable the font-lock rule from time to time to edit your source code.

Note that the function matched only simple cases, where the array is indexed by a simple variable or constant. If you would like to handle the case with complex expression (maybe even nested occurrences of array), you would need to replace the regexp with an elisp function to do the match (using tools like forward-sexp). It can either apply the invisible text property itself or set up a "fake" match data structure and continue using the font-lock rule as is.

  • What does the \\_< and the \\_> part do? \< allegedly denotes the beginning of a word, but what is \\_<? And what is the underscore after 9 for? – lo tolmencre Dec 11 '17 at 19:44
  • It denotes the beginning of a symbol. For example, take the symbol this_is_a_symbol. The regexp \\<this\\> will match it, whereas \\_<this\\_> won't. – Lindydancer Dec 11 '17 at 22:16
  • 1
    @lotolmencre see C-h i g (elisp)Regexp Backslash – phils Dec 23 '17 at 1:59

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.