help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fancy C/C++ Code Coloring: Useable but too slow for large buffers. Want


From: Nordlöw
Subject: Fancy C/C++ Code Coloring: Useable but too slow for large buffers. Wanted: Optimization!
Date: Mon, 17 Mar 2008 05:43:00 -0700 (PDT)
User-agent: G2/1.0

To increase readabily for C/C++ code I have extended my font-locking
with font-lock-add-keywords() to also colorize function calls, number
literals, operators and more. But the performance is really bad when
viewing large buffers with long lines of code. Can I speed up my code
anyway? If have missed a file or function let me now and I will give
it to you. Note that the face defintions are not complete for light
backgrounds.

Thanks in advance,
Nordlöw

CODE FOLLOWS:

;; Lisp Utils

(defun regexp-quote-alt-list (list)
  "Return a regexp string which exactly matches any of the
elements (alternatives) in the LIST of strings."
  (interactive)
  (mapconcat 'regexp-quote list "\\|"))
;;(regexp-quote-alt-list '("*a" "*b" "*c"))

;; Lisp Utils ends here



;;; pnw-cc-patterns.el --- language patterns for C, C++, etc.

;; Copyright (C) 2007 Per Nordlöw

;; Author: Per Nordlöw <per.nordlow@gmail.com>
;; Keywords: unix files

;; This file is NOT part of GNU Emacs.

;;
============================================================================

;; C Programming Language Patterns

(defconst c-cpp-statement-regexp
  (concat
   "^[ \\t]*" "#" "[ \\t]*" "include" "[ \\t]*"
   "[<\"]" "\\([^>\"]+\\)" "[>\"]")
  "Matches C PreProcessor statements such as #ifdef, #include,
#define, etc.")

(defconst c-operators-assignment
  (list "+=" "-="                       ;Assignment Additive
        "*=" "/=" "%="                  ;Assignment Multiplicative
        "=" "^=" "&=" "|="              ;Assignment Shift
        "<<=" ">>="
        "=")
  "C Assignment Operators.")

(defconst c-operators-inc-dec
  (list "++" "--"                       ;Increase, Decrease
        )
  "C Assignment Operators Inc Dec.")

(defconst c-operators-member
  (list "->" "."                        ;Member
        )
  "C Member Operators.")

(defconst c-operators-others
  (list "-" "+"                         ;Add, Subtract
        "&&" "||" "!"                   ;Logical AND, OR, NOT
        "&" "|" "~"                     ;Bitwise AND, OR, NOT
        "^"                             ;Bitwise XOR

        "<<" ">>"                       ;Bitwise Shift

        "*" "/" "%"                     ;Multiplicative

        "<" ">"                         ;Less/Great Than Comparison
        "==" "!="                       ;Comparison: Equal or Not Equal
        "<=" ">="              ;Less/Great Then or Equal To Comparison

        ;;","                           ;Skip Comma
        )
  "C Other Operators.")

(defconst c-operators-all
  (append c-operators-assignment
          c-operators-inc-dec
          c-operators-member
          c-operators-others
          )
  "C All Operators.")

(defconst c-parenthesises
  (list "(" ")"
        )
  "C Parenthesises.")

(defconst c-braces
  (list "[" "]"                         ;Array Indexing
        "{" "}"                         ;Curly Braces
        )
  "C Braces.")

(defconst c-separators
  (list "," ";"                         ;Statement Separator
        )
  "C Statement Separators.")

;; The reserved words of C++ may be conveniently placed into several
groups. In the first group we put those that were also present in the
C programming language and have been carried over into C++. There are
32 of these, and here they are:
(defconst c-reserved-words
  (list
   "auto" "const" "double" "float" "int" "short" "struct" "unsigned"
   "break" "continue" "else" "for" "long" "signed" "switch" "void"
   "case" "default" "enum" "goto" "register" "sizeof" "typedef"
"volatile"
   "char" "do" "extern" "if" "return" "static" "union" "while")
  "C Reserved Words.")

;;
============================================================================

;; C++ Programming Language Patterns

;; There are another 30 reserved words that were not in C, are
therefore new to C++, and here they are:
(defconst c++-reserved-words
  (list
   "asm" "dynamic_cast" "namespace" "reinterpret_cast" "try"
   "bool" "explicit" "new" "static_cast" "typeid"
   "catch" "false" "operator" "template" "typename"
   "class" "friend" "private" "this" "using"
   "const_cast" "inline" "public" "throw" "virtual"
   "delete" "mutable" "protected" "true" "wchar_t"
   )
  "C++ Reserved Words.")

;; The following 11 C++ reserved words are not essential when the
standard ASCII character set is being used, but they have been added
to provide more readable alternatives for some of the C++ operators,
and also to facilitate programming with character sets that lack
characters needed by C++.
(defconst c++-reserved-words-extra
  (list
   "and" "bitand" "compl" "not_eq" "or_eq" "xor_eq"
   "and_eq" "bitor" "not" "or" "xor"
   )
  "C++ Extra Reserved Words.")

(defconst c++-operators-members
  (list ".*" "->*" "::")
  "C++ Mebmer Operators (not in C).")

(defconst c++-string-operators
  '("and" "or" "not" "bitand" "bitor" "bitnot")
  "C/C++ Logic and Bitwise Operators.")

(provide 'pnw-cc-patterns)

;;; pnw-cc-patterns.el ends here




;;; pnw-regexps --- Various useful regular expressions
;;; -*-unibyte: t;-*-

;; Author: Per Nordlöw <per.nordlow@gmail.com>
;; Created: 14 Mars 2005
;; Version: $Revision: 0.2 $
;; Keywords: regular expression(s), regexp(s), patterns

;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of
;; the License, or (at your option) any later version.

;; This program is distributed in the hope that it will be
;; useful, but WITHOUT ANY WARRANTY; without even the implied
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;; PURPOSE.  See the GNU General Public License for more details.

;; You should have received a copy of the GNU General Public
;; License along with this program; if not, write to the Free
;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
;; MA 02111-1307 USA

;;; Commentary:

;; Useful Regular Expressions

;;; Code:

;;
============================================================================

;;; Faces

(defface number-hex-face
  '((t (:foreground "Green" :background "Black")))
  "*Face used to highlight a Hexadecimal Integer."
  :group 'pnw-regexps)
(defvar number-hex-face 'number-hex-face)

;;
============================================================================

;;; Number Literal

(defconst number-dec-regexp
  (concat "\\<"
          "[0-9]+"                      ;digits
          "\\>")
  "Regular expression matching a Decimal Integer.")

(defconst number-hex-regexp
  (concat "\\<"
          "0x"                          ;prefix
          "[0-9a-fA-F]+"                ;digits
          "\\>")
  "Regular expression matching a Hexadecimal Integer.")

;;
============================================================================

;;; C-language Number Decimal Literal

(defconst c-number-dec-regexp
  (concat "\\<"
          "\\(" "[0-9]+" "\\)"                       ;digits (1)
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer.")

(defconst c-number-dec-4to6-regexp
  (concat "\\<"
          "\\(" "[0-9]" "\\{" "1,3" "\\}" "\\)" ;1-to-3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer with 4 to 6
digits.")

(defconst c-number-dec-7to9-regexp
  (concat "\\<"
          "\\(" "[0-9]" "\\{" "1,3" "\\}" "\\)" ;1-to-3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer with 7 to 9
digits.")

(defconst c-number-dec-10to12-regexp
  (concat "\\<"
          "\\(" "[0-9]" "\\{" "1,3" "\\}" "\\)" ;1-to-3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer with 10 to 12
digits.")

(defconst c-number-dec-13to15-regexp
  (concat "\\<"
          "\\(" "[0-9]" "\\{" "1,3" "\\}" "\\)" ;1-to-3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer with 13 to 15
digits.")

(defconst c-number-dec-16to18-regexp
  (concat "\\<"
          "\\(" "[0-9]" "\\{" "1,3" "\\}" "\\)" ;1-to-3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer with 16 to 18
digits.")

(defconst c-number-dec-19to21-regexp
  (concat "\\<"
          "\\(" "[0-9]" "\\{" "1,3" "\\}" "\\)" ;1-to-3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[0-9]" "\\{"   "3" "\\}" "\\)" ;3-digit group
          "\\(" "[U]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (2)
          "\\>")
  "Regular expression matching a C Decimal Integer with 19 to 21
digits.")

;;
============================================================================

;;; C-language Number HexaDecimal Literal

(defconst c-number-hex-regexp
  (concat "\\<"
          "\\(" "0x" "\\)"              ;prefix (1)
          "\\(" "[0-9a-fA-F]+" "\\)"    ;digits (2)
          "\\(" "[UI]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long (3)
          "\\>")
  "Regular expression matching a C Hexadecimal Integer.")

(defconst c-number-hex-fancy-regexp
  (concat "\\<"
          "\\(" "0x" "\\)"              ;prefix (1)
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[0-9a-fA-F]" "\\{1,2\\}?" "\\)"
          "\\(" "[UI]?" "[L]" "\\{" "0,2" "\\}" "\\)" ;unsigned long long
(10)
          "\\>"
          )
  "Regular expression matching a C Fancy Hexadecimal Integer.")

;;
============================================================================

;;; C-language Number Floating Point Literal

(defconst c-number-float-regexp
  (concat "\\<"
          "\\("
          "[\\+-]?"
          "\\(?:"
          "\\(?:" "[0-9]+" "\\(?:" "\\." "[0-9]*" "\\)?" "\\)"
          "\\|"
          "\\(?:" "[0-9]*" "\\(?:" "\\." "[0-9]+" "\\)" "\\)"
          "\\)"
          "\\(?:" "[eE]" "[\\+-]?" "[0-9]+" "\\)?"
          "\\)"
          "\\(" "[dDFf]?" "\\)"         ;precision (2)
          "\\>")
  "Regular expression matching a C Floating Point Literal.")

;;
============================================================================

;; Phone Numbers

(defface swedish-phone-number-face
  '((t (:foreground "PaleGoldenrod" :background "MidnightBlue")))
  "*Face used to highlight a swedish phone number."
  :group 'pnw-regexps)
(defvar swedish-phone-number-face 'swedish-phone-number-face)

(defconst swedish-phone-number-regexp
  (concat "[0-9]" "\\{" "2,4" "\\}"     ;area number (1)
          "-"                           ;separator (2)
          "[0-9]" "\\{" "5,8" "\\}"     ;local number (3)
          )
  "Regular expression matching a swedish phone number.")

;;; Date

(defconst swedish-date-regexp
  (concat "[0-9]" "\\{" "2,4" "\\}"
          "-"
          "[0-9]" "\\{" "2" "\\}"
          "-"
          "[0-9]" "\\{" "2" "\\}"
          )
  "Regular expression matching a swedish date.")

;;
============================================================================

;;; Time

(defconst swedish-time-regexp
  (concat "[0-2][0-9]"
          ":" "[0-5][0-9]"
          "\\(?:" ":[0-9][0-9]" "\\)" "?"
          )
  "Regular expression matching a swedish time.")

;;
============================================================================

;;; Numbers

(defconst dec-1-to-3-regexp
  (concat "[0-9]" "\\{" "1,3" "\\}"
          )
  "Regular expression matching 1 to 3 decimal digits.")

(defconst dec-u8-regexp
  (concat "\\(?:"
          "\\(?:" "[0-9]" "\\)" "\\|"
          "\\(?:" "[1-9]" "[0-9]" "\\)" "\\|"
          "\\(?:" "[1]"   "[0-9]" "[0-9]" "\\)" "\\|"
          "\\(?:" "[2]"   "[0-4]" "[0-9]" "\\)" "\\|"
          "\\(?:" "[2]"   "[5]"   "[0-5]" "\\)"
          "\\)"
          )
  "Regular expression matching a decimal unsigned 8-bit char
[0...255].")

;;
============================================================================

;;; File and Path

(defconst ascii-name-regexp
  (concat "[A-Za-z_]"
          "[A-Za-z_0-9]*"
          )
  "Regular expression matching a C-style identifier.")

(defconst line-nr-regexp
  (concat "[1-9][0-9]*"
          )
  "Regular expression matching the line number location in a (source)
file.")

(defconst ascii-path-regexp
  (concat "\\(?:" "~?" "/" ascii-name-regexp "\\)"
          "\\(?:" "/" ascii-name-regexp "\\)" "*"
          )
  "Regular expression matching file path part of URL.")

;;
============================================================================

;;; URLs

(defconst url-protocol-regexp
  (concat "\\(?:"
          "file" "\\|"
          "s?ftp" "\\|"
          "s?http"
          "\\)"
          "://"
          )
  "Regular expression matching protocol prefix of URL.")

(defconst url-hostname-regexp
  (concat "[\\sw-]+"                    ;first part
          "\\(?:" "\\." "[\\sw-]+" "\\)" "+" ;resting parts
          )
  "Regular expression matching hostname part of URL.")

(defconst url-port-regexp
  (concat "\\(?:" ":[0-9]" "\\{" "1,5" "\\}" "\\)" "?"
          )
  "Regular expression matching port specification part of URL.")

(defconst url-path-regexp
  (concat "\\(?:" "/" "~?" "[\\sw-]+" "\\)"
          "\\(?:" "/" "[\\sw-]+" "\\)" "*"
          )
  "Regular expression matching file path part of URL.")

(defconst url-regexp
  (concat url-protocol-regexp
          url-hostname-regexp
          url-port-regexp
          "\\(?:" url-path-regexp "\\)?"
          )
  "Regular expression matching URLs.")

;;
============================================================================

;;; Emails

(defconst email-name-regexp
  (concat "[A-Za-z0-9_.-]+"
          )
  "Regular expression matching the name part of an email.")

(defconst email-regexp
  (concat email-name-regexp
          "@"
          "[A-Za-z0-9_.-]+"
          )
  "Regular expression matching emails.")

;;; Commands and Programs

(defconst sh-builtin-list
  (list "echo" "set" "setenv" "export")
  "Names of builtin commands in common UNIX shells.")
(defconst sh-builtin-regexp
  (concat "\\<\\(" (mapconcat 'identity sh-builtin-list "\\.") "\\)\
\>")
  "Regular expression matching builtin commands in common UNIX
shells.")

;;
============================================================================

;;; Common UNIX Programs

(defconst unix-programs-list
  (list "ls" "cp" "rm" "mv"
        "cat" "zcat"
        "zip" "unzip"
        "gzip" "gunzip"
        "bzip2" "bunzip2"
        "grep"
        "modprobe" "lsmod" "inmod" "rmmod"
        "awk" "gawk" "sed"
        "df" "du" "hdparm"
        "passwd" "su" "id"
        "mkfs" "mke2fs" "mkreiserfs"
        "sshd" "crond"                  ;daemons
        "gcc" "pkgadd"
        "configure")
  "Names of common Linux programs.")
(defconst unix-programs-regexp
  (concat "\\<\\(" (mapconcat 'identity unix-programs-list "\\.") "\\)\
\>")
  "Regular expression matching common Linux programs.")

;;
============================================================================

;;; File System Types

;;; (pnw-install-file "pnw-regexps.el")
(defconst fs-types-list
  (list "ext2" "ext3" "reiserfs"
        "swap" "xfs" "vfat" "minix" "cramfs" "bfs" "jfs")
  "Names of common UNIX file systems.")
(defconst fs-types-regexp
  (concat "\\<\\(" (mapconcat 'identity fs-types-list "\\.") "\\)\\>")
  "Regular expression matching common UNIX file systems.")

;;
============================================================================

;;; Shell Commands

(defconst sh-cmd-regexp
  (concat "^" "\\s-*" "[\\$#] .*$")
  "Regular expression matching a shell command line interface (CLI)
call.")

;;
============================================================================

;;; Valgrind

(defconst valgrind-process-nr-regexp
  (concat "^==\\([0-9]+\\)== "
          )
  "Regular expression matching process number part of a Valgrind line
prefix.")

;;
============================================================================

;;; Web-related

(defconst pnw-font-lock-extra-list
  (list
   (list (concat
          "\\(?:" "[^0-9a-fA-F]" "\\|" "^" "\\)"
          "\\("
          number-hex-regexp
          "\\)")
         1 font-lock-constant-face)
   (list swedish-phone-number-regexp
         0 swedish-phone-number-face)
   (list swedish-date-regexp
         0 font-lock-constant-face)
   (list swedish-time-regexp
         0 font-lock-constant-face)
   ;; IP Literals
   (list (concat
          ;;"[^0-9.]"
          "\\<\\("
          (mapconcat 'identity (make-list 4 dec-u8-regexp) "\\.") ;IPv4 quads
          "\\|"
          (mapconcat 'identity (make-list 16 dec-u8-regexp) "\\.") ;IPv6
          "\\)\\>"
          ;;"[^0-9.]"
          )
         1 font-lock-constant-face)
   ;; Shell Commands
   (list sh-cmd-regexp
         '(0 font-lock-warning-face))
   ;; Shell Builtins
   (list sh-builtin-regexp
         0 font-lock-builtin-face)
   ;; Shell Programs
   (list unix-programs-regexp
         0 font-lock-function-name-face)
   ;; File Systems
   (list fs-types-regexp
         0 font-lock-constant-face)
   ;; Alone Paths
   (list (concat
          "\\("
          ascii-path-regexp
          "\\)"
          )
         1 font-lock-constant-face)
   ;; Valgrind address and source function
   (list (concat
          "\\(" number-hex-regexp "\\)"
          ": "
          "\\(" ascii-name-regexp "\\)"
          )
         '(1 number-hex-face)
         '(2 font-lock-function-name-face)
         )
   ;; Valgrind process number
   (list (concat
          valgrind-process-nr-regexp
          )
         1 font-lock-builtin-face)
   ;; Valgrind Name and Line
   (list (concat "("
                 "\\(" ascii-name-regexp "\\)"
                 ":"
                 "\\(" line-nr-regexp "\\)"
                 ")$"
                 )
         '(1 font-lock-warning-face)
         '(2 font-lock-variable-name-face)
         )
   ;; URL starts
   (list (concat
          "[^0-9.]"
          "\\("
          url-regexp
          "\\)"
          )
         1 font-lock-variable-name-face)
   ;; Emails
   (list email-regexp
         0 font-lock-variable-name-face)
   )
  "Extra expressions to font-lock in Text mode(s).")

(defconst pnw-font-lock-extra
  (progn
    (require 'font-lock)
    pnw-font-lock-extra-list)
  "Extra expressions to font-lock in Text mode(s).")

(provide 'pnw-regexps)

;;; pnw-regexps.el ends here





;;; pnw-faces.el --- Extra general faces (may come part of font-
lock...)

;; Copyright (C) 2007 Per Nordlöw

;; Author: Per Nordlöw <per.nordlow@gmail.com>
;; Keywords: unix files

;; This file is NOT part of GNU Emacs.

;;;
===========================================================================
;;; Faces: Operators

(defface font-lock-operator-face        ;operator
  '((((class color)) (:inherit font-lock-builtin-face :bold nil)))
  "Font Lock mode face used to highlight operators."
  :group 'pnw-faces)

(defface font-lock-operator-member-face ;operator-member
  '((((class color)) (:inherit font-lock-operator-face :bold t)))
  "Font Lock mode face used to highlight member operators."
  :group 'pnw-faces)

(defface font-lock-operator-assignment-face ;operator-assignment
  '((((class color)) (:inherit font-lock-operator-face :bold t)))
  "Font Lock mode face used to highlight assignment operators."
  :group 'pnw-faces)

(defface font-lock-operator-inc-dec-face ;operator-inc-dec
  '((((class color)) (:inherit font-lock-operator-face :bold t)))
  "Font Lock mode face used to highlight inc-dec operators."
  :group 'pnw-faces)

;;;
===========================================================================
;;; Faces: Parenthesises and Braces

(defface font-lock-parens-face          ;braces
  '((((class color)) (:inherit font-lock-operator-face :bold nil)))
  "Font Lock mode face used to highlight braces."
  :group 'pnw-faces)

(defface font-lock-braces-face          ;braces
  '((((class color)) (:inherit font-lock-operator-face :bold t)))
  "Font Lock mode face used to highlight braces."
  :group 'pnw-faces)

;;;
===========================================================================
;;; Faces: Function Calls

(defface font-lock-function-call-face   ;function-call
  '((((class color)) (:inherit font-lock-function-name-face :bold
nil)))
  "Font Lock mode face used to highlight function calls."
  :group 'pnw-faces)

;;;
===========================================================================
;;; Faces: Variable Alteration

(defface font-lock-variable-alteration-face ;variable-alteration
  '((((class color)) (:inherit font-lock-variable-name-face :bold
nil)))
  "Font Lock mode face used to highlight the variable in an
  alteration."
  :group 'pnw-faces)

;;;
===========================================================================
;;; Faces: Number Literal

;; Note: Use to inherit font-lock-string-face
(defface font-lock-number-face
  '((((class color)) (:inherit font-lock-string-face :bold t)))
  "Font Lock mode face used to highlight number literals."
  :group 'pnw-faces)

(defface font-lock-number-alt-face      ;number-alt
  '((((class color) (min-colors 88) (background dark))
     (:foreground "tomato" :bold t)))
  "Font Lock mode face used to highlight number literals alternative."
  :group 'pnw-faces)

;; TODO: Perhaps a completely new color for this face.
(defface font-lock-number-passive-face  ;number-passive
  '((((class color)) (:inherit font-lock-string-face :bold nil)))
  "Font Lock mode face used to highlight passive parts of number
literals."
  :group 'pnw-faces)

;;;
===========================================================================
;;; Faces: Separator

(defface font-lock-separator-face
  '((((class color) (min-colors 88) (background dark))
     (:foreground "white" :bold nil)))
  "Font Lock mode face used to highlight separator literals."
  :group 'pnw-faces)

;;;
===========================================================================
;;; Faces: printf directives

;; TODO: Perhaps a completely new color for this face.
(defface font-lock-printf-directives-face ;printf-directives
  '((((class color)) (:inherit font-lock-string-face :bold t)))
  "Font Lock mode face used to highlight C printf directives."
  :group 'pnw-faces)

;; TODO: Perhaps a completely new color for this face.
(defface font-lock-printf-directive-conversion-face ;printf-directive-
conversion
  '((((class color)) (:inherit font-lock-type-face :bold t)))
  "Font Lock mode face used to highlight C printf conversion
directives."
  :group 'pnw-faces)

(provide 'pnw-faces)

;;; pnw-faces.el ends here




;;; pnw-cc-fancy-font-lock.el --- fancy font locking for CC Mode

;; Copyright (C) 2007 Per Nordlöw

;; Author: Per Nordlöw <per.nordlow@gmail.com>
;; Keywords: unix files

;; This file is NOT part of GNU Emacs.

(require 'pnw-regexps)

;; Adds fontification patterns for number literals.
(defun pnw-cc-fancy/number-font-locking ()
  (font-lock-add-keywords
   nil
   (list

    ;; number literal floating point
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-float-regexp
          '((1 'font-lock-number-face prepend)
            (2 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - 4 to 6 digits
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-4to6-regexp
          '((1 'font-lock-number-alt-face prepend)
            (2 'font-lock-number-face prepend)
            (3 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - 7 to 9 digits
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-7to9-regexp
          '((1 'font-lock-number-face prepend)
            (2 'font-lock-number-alt-face prepend)
            (3 'font-lock-number-face prepend)
            (4 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - 10 to 12 digits
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-10to12-regexp
          '((1 'font-lock-number-alt-face prepend)
            (2 'font-lock-number-face prepend)
            (3 'font-lock-number-alt-face prepend)
            (4 'font-lock-number-face prepend)
            (5 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - 13 to 15 digits
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-13to15-regexp
          '((1 'font-lock-number-face prepend)
            (2 'font-lock-number-alt-face prepend)
            (3 'font-lock-number-face prepend)
            (4 'font-lock-number-alt-face prepend)
            (5 'font-lock-number-face prepend)
            (6 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - 16 to 18 digits
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-16to18-regexp
          '((1 'font-lock-number-alt-face prepend)
            (2 'font-lock-number-face prepend)
            (3 'font-lock-number-alt-face prepend)
            (4 'font-lock-number-face prepend)
            (5 'font-lock-number-alt-face prepend)
            (6 'font-lock-number-face prepend)
            (7 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - 19 to 21 digits
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-19to21-regexp
          '((1 'font-lock-number-face prepend)
            (2 'font-lock-number-alt-face prepend)
            (3 'font-lock-number-face prepend)
            (4 'font-lock-number-alt-face prepend)
            (5 'font-lock-number-face prepend)
            (6 'font-lock-number-alt-face prepend)
            (7 'font-lock-number-face prepend)
            (8 'font-lock-number-passive-face prepend)
            ))

    ;; number literal decimal - ordinary
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-dec-regexp
          '((1 'font-lock-number-face append)
            (2 'font-lock-number-passive-face append)
            ))

    ;; number literal hexadecimal (byte-group-colored)
    ;; NOTE: needs to be before matching C operator '.' below
    (cons c-number-hex-fancy-regexp
          '((1 'font-lock-number-passive-face append)
            (2 'font-lock-number-face append)
            (3 'font-lock-number-alt-face append)
            (4 'font-lock-number-face append)
            (5 'font-lock-number-alt-face append)
            (6 'font-lock-number-face append)
            (7 'font-lock-number-alt-face append)
            (8 'font-lock-number-face append)
            (9 'font-lock-number-alt-face append)
            (10 'font-lock-number-passive-face append)
            ))

    ;; obselete number literal hexadecimal (replaced by fancy variant)
    ;; NOTE: needs to be before matching C operator '.' below
    ;;     (cons c-number-hex-regexp
    ;;    '((1 'font-lock-number-passive-face append)
    ;;      (2 'font-lock-number-face append)
    ;;      (3 'font-lock-number-passive-face append)
    ;;      ))
    )))

(defconst pnw-cc-fancy/switch-case-regexp
  (concat "\\_<" "case" "\\_>" "[[:blank:]]+"
          "\\<" "\\(" "\\w+" "\\)" "[[:blank:]]*"
          "\\(" ":"    "\\)")
  "C/C++ switch case constant."
  )

(defconst pnw-cc-fancy/character-literal-regexp
  (concat "'" "\\(" ".+?" "\\)" "'")
  "C/C++ character literal 'a', 'b', etc."
  )

;; TODO: Use only inside C string contexts
(defconst pnw-cc-fancy/printf
  (concat "\\("

          "%"                           ;initator

          "[\\+-]?"                     ;flag characters

          "[0-9\\*]*"                   ;field width
          "\\.?" "[0-9\\*]*"            ;precision

          ;;length modifier
          "\\(?:"
          "[hl]" "\\{" "0,2" "\\}" "\\|"
          "[Lqjzt]?"
          "\\)"

          "\\)"

          "\\("
          "[diouxXeEfFgGaAcsCSpnm]"     ;conversion specifier
          "\\)"
          )
  "C printf()), fprintf(), sprintf(), snprintf(), vprintf(),
vfprintf(), vsprintf(). See printf(3) manual page."
  )

(defconst pnw-cc-fancy/function-call-1
  (concat "^" "[[:blank:]]+"
          ".*?" "\\<" "\\(" "\\w+" "\\)" "[[:blank:]]*" "(")
  "C/C++ function call 1."
  )

(defconst pnw-cc-fancy/function-call-2
  (concat "[=({)]"
          ".*?" "\\<" "\\(" "\\w+" "\\)" "[[:blank:]]*" "(")
  "C/C++ function call 2."
  )

(defconst pnw-cc-fancy/variable-assignment
  (concat "\\(?:"
          "{" "\\|"                     ;opening curly brace
          "^" "\\|"                     ;beginning of line
          ":" "\\|"                     ;to work after case labels
          "," "\\|" ;to work after other statements (inside for loops
etc)
          ";" "\\|" ;to work after other statements
          "=" "\\|" ;for: x = y = z = 0;
          "\\." "\\|"                   ;C member operator
          "->" "\\|"                    ;C pointer member operator
          ;; "[^[[:alnum:]]_]" "[[:blank:]]*" "\\*+" "\\|" ;ptr-
ptr-... derefs
          "[^[[:alnum:]]_\\*]"   ;no identifier or pointer star before
          "\\)"
          "[[:blank:]\n]*"              ;blanks and newlines
          "\\<" "\\(" "\\w+" "\\)" "\\>"
          "[[:blank:]\n]*"              ;blanks and newlines
          "\\(" (regexp-quote-alt-list c-operators-assignment) "\\)"
          "[\['\"\\*([:blank:]\n]*" ;left-bracket,single/double-
quotes, stars, lparens, blanks or newlines
          "[\\+-]?"                 ;sign
          "[[:blank:]]*"            ;blanks
          "\\w+")
  "C/C++ variable name and operator in assignment."
  )

(defconst pnw-cc-fancy/member-operators
  (concat "\\(" (regexp-quote-alt-list c-operators-member) "\\)")
  "C/C++ Member Operators."
  )

(defconst pnw-cc-fancy/postfix-operators
  (concat "\\<" "\\(" "\\w+" "\\)" "\\>"
          "[[:blank:]\n]*"
          "\\(" (regexp-quote-alt-list c-operators-inc-dec) "\\)")
  "C/C++ Postfix Operators ++, --."
  )

(defconst pnw-cc-fancy/prefix-operators
  (concat "\\(" (regexp-quote-alt-list c-operators-inc-dec) "\\)"
          "[[:blank:]\n]*"
          "\\<" "\\(" "\\w+" "\\)" "\\>")
  "C/C++ Prefix Operators ++, --."
  )

(defconst pnw-cc-fancy/parenthesises
  (concat "\\(" (regexp-quote-alt-list c-parenthesises) "\\)")
  "C/C++ Parenthesises."
  )

(defconst pnw-cc-fancy/braces
  (concat "\\(" (regexp-quote-alt-list c-braces) "\\)")
  "C/C++ Hooks and Braces."
  )

(defconst pnw-cc-fancy/separators
  (concat "\\(" (regexp-quote-alt-list c-separators) "\\)")
  "C/C++ Separators."
  )

(defconst pnw-cc-fancy/operators-others
  (concat "\\(" (regexp-quote-alt-list c-operators-others) "\\)")
  "C/C++ Operators Others."
  )

;; Adds two fontification patterns for C mode and modes derived from C
mode
(defun pnw-cc-fancy/all-font-locking ()
  (pnw-cc-fancy/number-font-locking)

  (font-lock-add-keywords
   nil
   (list

    ;; other operators
    ;; NOTE: Deactivated this because this will be very inefficient.
    ;;     (cons (concat "#" "[[:blank:]]*" "if" "[ \t]+" "0"
    ;;            "\\(" "[.\n]*" "\\)"
    ;;            "#" "[[:blank:]]*"  "endif")
    ;;    '(1 'font-lock-warning-face t))

    (cons pnw-cc-fancy/switch-case-regexp
          '((1 'font-lock-constant-face append)
            (2 'font-lock-operator-face append)
            ))

    (cons pnw-cc-fancy/character-literal-regexp
          '(1 'font-lock-number-face append)
          )

    (cons pnw-cc-fancy/printf
          '((1 'font-lock-printf-directives-face append)
            ;;NOTE: intuitive to associate conversion directive with types
            (2 'font-lock-printf-directive-conversion-face prepend)
            ))

    (cons pnw-cc-fancy/function-call-1
          '(1 'font-lock-function-call-face keep))
    (cons pnw-cc-fancy/function-call-2
          '(1 'font-lock-function-call-face keep))

    (cons pnw-cc-fancy/variable-assignment
          ;;"[[:blank:]\n]*" ";")
          '((1 'font-lock-variable-alteration-face keep)
            (2 'font-lock-operator-assignment-face keep)
            ))

    (cons pnw-cc-fancy/member-operators
          '(1 'font-lock-operator-member-face
              keep))           ;keep: only dots in language statements

    (cons pnw-cc-fancy/postfix-operators
          '((1 'font-lock-variable-alteration-face keep)
            (2 'font-lock-operator-assignment-face keep)
            ))

    (cons pnw-cc-fancy/prefix-operators
          '((1 'font-lock-operator-assignment-face keep)
            (2 'font-lock-variable-alteration-face keep)
            ))

    ;; NOTE: Higher priority than c-operators-others
    (cons pnw-cc-fancy/parenthesises
          '(1 'font-lock-parens-face keep))

    ;; NOTE: Higher priority than c-operators-others
    (cons pnw-cc-fancy/braces
          '(1 'font-lock-braces-face keep))

    ;; other operators
    (cons pnw-cc-fancy/separators
          '(1 'font-lock-separator-face keep))

    ;; other operators
    (cons pnw-cc-fancy/operators-others
          '(1 'font-lock-operator-face keep))

    )
   nil))

(if t
    (progn
      (add-hook 'c-mode-hook 'pnw-cc-fancy/all-font-locking t)
      (add-hook 'c++-mode-hook 'pnw-cc-fancy/all-font-locking t)
      (add-hook 'objc-mode-hook 'pnw-cc-fancy/all-font-locking t)
      ;;FIXME: skip printf-patterns for java-mode
      (add-hook 'java-mode-hook 'pnw-cc-fancy/all-font-locking t)
      (add-hook 'csharp-mode-hook 'pnw-cc-fancy/all-font-locking t)
      (add-hook 'python-mode-hook 'pnw-cc-fancy/all-font-locking t)
      )
  (progn
    (remove-hook 'c-mode-hook 'pnw-cc-fancy/all-font-locking)
    (remove-hook 'c++-mode-hook 'pnw-cc-fancy/all-font-locking)
    (remove-hook 'objc-mode-hook 'pnw-cc-fancy/all-font-locking)
    ;;FIXME: skip printf-patterns for java-mode
    (remove-hook 'java-mode-hook 'pnw-cc-fancy/all-font-locking)
    (remove-hook 'csharp-mode-hook 'pnw-cc-fancy/all-font-locking)
    (remove-hook 'python-mode-hook 'pnw-cc-fancy/all-font-locking)
    ))

;;
============================================================================

(defun pnw-c++-fancy-font-locking ()
  (font-lock-add-keywords
   nil
   (list
    ;; other operators
    (cons (concat "\\(" (regexp-quote-alt-list c++-operators-members)
"\\)")
          '(1 'font-lock-operator-member-face append))
    )))

(add-hook 'c++-mode-hook 'pnw-c++-fancy-font-locking)

;;
============================================================================

(defun pnw-python-fancy-font-locking ()
  (font-lock-add-keywords
   nil
   (list
    ;; for statement operators
    (cons (concat "\_<" "for"
                  "[[:blank:]]*"
                  "\\(" "[[:word:]]*" "\\)"
                  "[[:blank:]]*"
                  "in"
                  "[[:blank:]]*"
                  )
          '(1 'font-lock-variable-name-face append))
    )))

(add-hook 'python-mode-hook 'pnw-python-fancy-font-locking)

;;
============================================================================

(provide 'pnw-cc-fancy-font-lock)

;;; pnw-cc-fancy-font-lock.el ends here


reply via email to

[Prev in Thread] Current Thread [Next in Thread]