2013-06-12 23:40:20 +02:00
|
|
|
;;==============================================================================
|
2013-07-03 13:55:42 +02:00
|
|
|
;; C/C++
|
2013-06-12 23:40:20 +02:00
|
|
|
;;==============================================================================
|
|
|
|
(require 'compile)
|
|
|
|
|
2013-07-09 13:22:19 +02:00
|
|
|
(defun get-closest-pathname (&optional file)
|
|
|
|
"Determine the pathname of the first instance of FILE starting
|
|
|
|
from the current directory towards root. This may not do the
|
|
|
|
correct thing in presence of links. If it does not find FILE,
|
|
|
|
then it shall return the name of FILE in the current directory,
|
|
|
|
suitable for creation"
|
|
|
|
(let ((current-dir default-directory) (looping t) (makefile (or file "Makefile")))
|
|
|
|
(while (progn
|
|
|
|
(if (file-exists-p (expand-file-name makefile current-dir))
|
|
|
|
(setq looping nil)
|
|
|
|
(setq current-dir (expand-file-name ".." current-dir)))
|
|
|
|
(and looping (not (equal current-dir "/")))))
|
|
|
|
(if (equal current-dir "/") nil (expand-file-name makefile current-dir))))
|
|
|
|
|
|
|
|
|
2013-07-03 13:55:42 +02:00
|
|
|
(defcustom mode-cc-ldlibs "-lm -pthread"
|
|
|
|
"[Local variable] Custom linker flags for C/C++ linkage."
|
|
|
|
:safe 'stringp)
|
2013-06-12 23:40:20 +02:00
|
|
|
|
2013-07-09 13:22:19 +02:00
|
|
|
(defcustom mode-cc-ldflags ""
|
2013-07-03 13:55:42 +02:00
|
|
|
"[Local variable] Custom linker libs for C/C++ linkage."
|
2013-06-12 23:40:20 +02:00
|
|
|
:safe 'stringp)
|
|
|
|
|
2013-07-04 10:37:18 +02:00
|
|
|
(defun cc-set-compiler ()
|
|
|
|
"Set C/C++ compile command to be nearest Makefile found in
|
|
|
|
parent folders. If no Makefile is found, then a configurable
|
|
|
|
command line is provided."
|
2013-06-12 23:40:20 +02:00
|
|
|
(interactive)
|
2013-07-03 13:55:42 +02:00
|
|
|
(if (get-closest-pathname)
|
|
|
|
(set (make-local-variable 'compile-command) (format "make -k -f %s" (get-closest-pathname)))
|
|
|
|
(set (make-local-variable 'compile-command)
|
|
|
|
(let
|
2013-07-09 13:22:19 +02:00
|
|
|
((is-cpp (equal major-mode "c++-mode"))
|
2013-07-03 13:55:42 +02:00
|
|
|
(file (file-name-nondirectory buffer-file-name)))
|
2013-07-09 13:22:19 +02:00
|
|
|
(format "%s %s -o %s %s %s %s"
|
2013-07-03 13:55:42 +02:00
|
|
|
(if is-cpp
|
|
|
|
(or (getenv "CPP") "g++")
|
|
|
|
(or (getenv "CC") "gcc"))
|
2013-07-09 13:22:19 +02:00
|
|
|
file
|
2013-07-03 13:55:42 +02:00
|
|
|
(file-name-sans-extension file)
|
|
|
|
(if is-cpp
|
|
|
|
(or (getenv "CPPFLAGS") "-Wall -Wextra -Wshadow -DDEBUG=9 -g3 -O0")
|
|
|
|
(or (getenv "CFLAGS") "-ansi -pedantic -std=c99 -Wall -Wextra -Wshadow -DDEBUG=9 -g3 -O0"))
|
|
|
|
(or (getenv "LDFLAGS") mode-cc-ldflags)
|
2013-07-09 13:22:19 +02:00
|
|
|
(or (getenv "LDLIBS") mode-cc-ldlibs))))))
|
2013-07-03 13:55:42 +02:00
|
|
|
|
2013-07-06 20:02:05 +02:00
|
|
|
(defun cc-clean ()
|
|
|
|
"Find Makefile and call the `clean' rule. If no Makefile is
|
|
|
|
found, no action is taken. The previous `compile' command is then
|
|
|
|
restored."
|
|
|
|
(interactive)
|
|
|
|
(when (get-closest-pathname)
|
|
|
|
(let ((compile-command-backup compile-command))
|
|
|
|
(compile (format "make -k -f %s clean" (get-closest-pathname)))
|
|
|
|
(setq compile-command compile-command-backup))))
|
|
|
|
|
2013-07-03 13:55:42 +02:00
|
|
|
;;==============================================================================
|
|
|
|
;; C-mode
|
|
|
|
;;==============================================================================
|
|
|
|
|
|
|
|
;; Identation style
|
|
|
|
(setq c-default-style "linux" c-basic-offset 4)
|
2013-06-12 23:40:20 +02:00
|
|
|
|
|
|
|
(add-hook
|
|
|
|
'c-mode-hook
|
|
|
|
(lambda ()
|
2013-07-04 10:37:18 +02:00
|
|
|
(cc-set-compiler)
|
2013-07-06 20:02:05 +02:00
|
|
|
(local-set-key (kbd "<f9>") 'cc-clean)
|
2013-06-12 23:40:20 +02:00
|
|
|
(local-set-key (kbd "M-TAB") 'semantic-complete-analyze-inline)
|
2013-06-17 17:29:23 +02:00
|
|
|
(local-set-key (kbd "C-M-e") (lambda () (interactive) (c-beginning-of-defun -1)))
|
2013-06-12 23:40:20 +02:00
|
|
|
;; (local-set-key "." 'semantic-complete-self-insert) ; This is a bit slow.
|
|
|
|
;; (local-set-key ">" 'semantic-complete-self-insert)
|
|
|
|
))
|
|
|
|
|
|
|
|
;;==============================================================================
|
|
|
|
;; C++-mode
|
|
|
|
;;==============================================================================
|
|
|
|
(require 'compile)
|
|
|
|
|
|
|
|
;; TODO: test this!
|
|
|
|
;; (defun vlad-cc-style()
|
|
|
|
;; (c-set-style "linux")
|
|
|
|
;; (c-set-offset 'innamespace '0)
|
|
|
|
;; (c-set-offset 'inextern-lang '0)
|
|
|
|
;; (c-set-offset 'inline-open '0)
|
|
|
|
;; (c-set-offset 'label '*)
|
|
|
|
;; (c-set-offset 'case-label '*)
|
|
|
|
;; (c-set-offset 'access-label '/)
|
|
|
|
;; (setq c-basic-offset 4)
|
|
|
|
;; (setq tab-width 4)
|
|
|
|
;; (setq indent-tabs-mode nil)
|
|
|
|
;; )
|
|
|
|
;; (add-hook 'c++-mode-hook 'vlad-cc-style)
|
|
|
|
|
|
|
|
(add-hook
|
|
|
|
'c++-mode-hook
|
|
|
|
(lambda ()
|
2013-07-04 10:37:18 +02:00
|
|
|
(cc-set-compiler)
|
2013-07-06 20:02:05 +02:00
|
|
|
(local-set-key (kbd "<f9>") 'cc-clean)
|
2013-07-03 13:55:42 +02:00
|
|
|
(local-set-key (kbd "C-M-e") (lambda () (interactive) (c-beginning-of-defun -1)))
|
2013-06-12 23:40:20 +02:00
|
|
|
(local-set-key (kbd "M-TAB") 'semantic-complete-analyze-inline)))
|
|
|
|
|
|
|
|
;; autoinsert C/C++ header
|
|
|
|
(define-auto-insert
|
|
|
|
(cons "\\.\\([Hh]\\|hh\\|hpp\\)\\'" "My C / C++ header")
|
|
|
|
'(nil
|
|
|
|
"/" (make-string 79 ?*) "\n"
|
|
|
|
" * @file " (file-name-nondirectory buffer-file-name) "\n"
|
|
|
|
" * @date \n"
|
|
|
|
" * @brief \n"
|
|
|
|
" *\n"
|
|
|
|
" " (make-string 78 ?*) "/\n\n"
|
|
|
|
(let* ((noext (substring buffer-file-name 0 (match-beginning 0)))
|
|
|
|
(nopath (file-name-nondirectory noext))
|
|
|
|
(ident (concat (upcase nopath) "_H")))
|
|
|
|
(concat "#ifndef " ident "\n"
|
|
|
|
"#define " ident " 1\n\n\n"
|
2013-07-09 10:57:02 +02:00
|
|
|
"\n\n#endif // " ident "\n"))))
|
2013-06-12 23:40:20 +02:00
|
|
|
|
|
|
|
;; auto insert C/C++
|
|
|
|
(define-auto-insert
|
|
|
|
(cons "\\.\\([Cc]\\|cc\\|cpp\\)\\'" "My C++ implementation")
|
|
|
|
'(nil
|
|
|
|
"/" (make-string 79 ?*) "\n"
|
|
|
|
" * @file " (file-name-nondirectory buffer-file-name) "\n"
|
|
|
|
" * @date \n"
|
|
|
|
" * @brief \n"
|
|
|
|
" *\n"
|
|
|
|
" " (make-string 78 ?*) "/\n\n"
|
|
|
|
(let* ((noext (substring buffer-file-name 0 (match-beginning 0)))
|
|
|
|
(nopath (file-name-nondirectory noext))
|
|
|
|
(ident (concat nopath ".h")))
|
|
|
|
(if (file-exists-p ident)
|
2013-07-09 10:57:02 +02:00
|
|
|
(concat "#include \"" ident "\"\n")))))
|
2013-06-12 23:40:20 +02:00
|
|
|
|
|
|
|
;;==============================================================================
|
|
|
|
;; Qt semantic support
|
|
|
|
;;==============================================================================
|
|
|
|
|
|
|
|
;; Qt base directory, meaning the directory where the 'Qt' directory can be found.
|
|
|
|
;; Adapt accordingly.
|
2013-07-09 11:25:15 +02:00
|
|
|
(when (fboundp 'semantic-add-system-include)
|
|
|
|
(setq qt4-base-dir "/usr/include/qt4")
|
|
|
|
(setq qt4-gui-dir (concat qt4-base-dir "/QtGui"))
|
|
|
|
(semantic-add-system-include qt4-base-dir 'c++-mode)
|
|
|
|
(semantic-add-system-include qt4-gui-dir 'c++-mode)
|
|
|
|
(add-to-list 'auto-mode-alist (cons qt4-base-dir 'c++-mode))
|
|
|
|
(add-hook
|
|
|
|
'c++-mode-hook
|
|
|
|
(lambda ()
|
|
|
|
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig.h"))
|
|
|
|
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig-large.h"))
|
|
|
|
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qglobal.h")))))
|