C customizations

I’ve ben doing a decent amount of C and C++ coding recently - both for courses and for hacking on emacs. I ended up doing a bit of work on my C configuration, though probably not as much as I should.

Part of these efforts included improving h-file-create, the function that is automatically run whenever I create a new header file. Previously, it only created the #ifndef guards; While these are the only things I’ll always need, the vast majority of time I also wanted to define a class, and so I programmed the class to be inserted automatically.

(defun h-file-create ()
  "Create a new h file.  Insert a infdef/define/endif block"
  (interactive)
  (if (or (equal (substring (buffer-name (current-buffer)) -2 ) ".h")
          (equal (substring (buffer-name (current-buffer)) -4 ) ".hpp"))
      (let* ((buffer-name (buffer-name (current-buffer)))
             (class-name (substring buffer-name 0 (string-match "\\." buffer-name))))
      (when (equal "" (buffer-string))
          (insert "#ifndef "
                  (upcase class-name)
                  "_H\n#define "
                  (upcase class-name) 
                  "_H\n\nclass "
                  (capitalize class-name)
                  " {\npublic:\n\n\nprivate:\n\n\n};"
                  "\n\n#endif")
        (search-backward "public:\n")
        (next-line)))))

Another function I ended up needing was to insert includes to header files or forward declarations of classes. Previously, I’d have to go to the top of my file, interrupting whatever I was doing, and maneuver back. This was just an annoyance, so I wrote the following functions that would either include or forward declare something, defaulting to the current word at point. Since whether I #included or forward declared often depended on whether I was in a header or implementation file, so I wrote another function that delegates to one of the other two depending on which file you were in. String-match-any is a utility function I wrote to help do this.

(defun string-match-any (regexp-list string &optional start)
  "Returns whether the given string, starting at position start,
matches any regexp in the list"
  (if regexp-list
      (let ((result (string-match (car regexp-list) string start)))
            (if result
                result
              (string-match-any (cdr regexp-list) string start)))))
 
(defun-my c-include
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (if (search-forward "#include" nil t)
        (progn (beginning-of-line)
               (insert (concat "#include \"" (downcase arg) ".hpp\"\n")))
      (search-forward "\n\n")
      (insert "#include \"" (downcase arg) ".hpp\"\n\n"))))
 
(defun-my c-forward-declare
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (if (re-search-forward "class [a-zA-Z]*;" nil t)
        (insert (concat "\nclass " (capitalize arg) ";"))
      (search-forward "\n\n")
      (insert "class " (capitalize arg) ";\n\n"))))
 
(defun-my c-fwdinclude
  (interactive)
  (let ((buffer-name (buffer-name (current-buffer))))
    (if (string-match-any (list "\.h" "\.hpp") buffer-name )
        (c-forward-declare arg)
      (c-include arg))))
(define-key c-mode-base-map (kbd "C-c c f") 'my-c-fwdinclude)

I’ve also been using c-eldoc-mode more. It’s pretty awesome, but there is one problem with it: its speed. On a large project like emacs, it will frequently lock the input for some time. It’s useful enough that I’d for it to be faster. If there’s a later version that fixes this that you know of, please tell me; the latest I’ve found is v0.4. Otherwise, I’m going to look into it further to see if I can figure out how to speed it up some more.

Leave a Reply