lang/cc: rewrite C/C++/OBJC header file detection
This commit is contained in:
parent
80eb1dc449
commit
31c8c0c033
2 changed files with 47 additions and 26 deletions
|
@ -66,6 +66,45 @@ preceded by the opening brace or a comma (disregarding whitespace in between)."
|
|||
(memq (char-before) (list ?, ?\( ?\;))))
|
||||
(c-lineup-arglist langlem)))
|
||||
|
||||
(defun +cc--re-search-for (regexp)
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(save-match-data
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward regexp magic-mode-regexp-match-limit t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +cc-c-c++-objc-mode (&optional file)
|
||||
"Sets either `c-mode', `objc-mode' or `c++-mode', whichever is appropriate."
|
||||
(let ((base (file-name-sans-extension buffer-file-name))
|
||||
file)
|
||||
(cond ((file-exists-p! (or (concat base ".cpp")
|
||||
(concat base ".cc")))
|
||||
(c++-mode))
|
||||
((or (file-exists-p! (or (concat base ".m")
|
||||
(concat base ".mm")))
|
||||
(+cc--re-search-for
|
||||
(concat "^[ \t\r]*\\(?:"
|
||||
"@\\(?:class\\|interface\\|property\\|end\\)\\_>"
|
||||
"\\|#import +<Foundation/Foundation.h>"
|
||||
"\\|[-+] ([a-zA-Z0-9_]+)"
|
||||
"\\)")))
|
||||
(objc-mode))
|
||||
((fboundp 'c-or-c++-mode) ; introduced in Emacs 26.1
|
||||
(c-or-c++-mode))
|
||||
((+cc--re-search-for ; TODO Remove this along with Emacs 25 support
|
||||
(let ((id "[a-zA-Z0-9_]+") (ws "[ \t\r]+") (ws-maybe "[ \t\r]*"))
|
||||
(concat "^" ws-maybe "\\(?:"
|
||||
"using" ws "\\(?:namespace" ws "std;\\|std::\\)"
|
||||
"\\|" "namespace" "\\(:?" ws id "\\)?" ws-maybe "{"
|
||||
"\\|" "class" ws id ws-maybe "[:{\n]"
|
||||
"\\|" "template" ws-maybe "<.*>"
|
||||
"\\|" "#include" ws-maybe "<\\(?:string\\|iostream\\|map\\)>"
|
||||
"\\)")))
|
||||
(c++-mode))
|
||||
((c-mode)))))
|
||||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
|
|
@ -26,37 +26,19 @@ compilation database is present in the project.")
|
|||
(def-package! cc-mode
|
||||
:commands (c-mode c++-mode objc-mode java-mode)
|
||||
:mode ("\\.mm\\'" . objc-mode)
|
||||
:preface
|
||||
;; The plusses in c++-mode can be annoying to search for ivy/helm (which reads
|
||||
;; queries as regexps), so wee add these for convenience.
|
||||
(defalias 'cpp-mode 'c++-mode)
|
||||
(defvaralias 'cpp-mode-map 'c++-mode-map)
|
||||
|
||||
(defun +cc-c++-header-file-p ()
|
||||
(and buffer-file-name
|
||||
(equal (file-name-extension buffer-file-name) "h")
|
||||
(or (file-exists-p (expand-file-name
|
||||
(concat (file-name-sans-extension buffer-file-name)
|
||||
".cpp")))
|
||||
(when-let* ((file (car-safe (projectile-get-other-files
|
||||
buffer-file-name
|
||||
(projectile-current-project-files)))))
|
||||
(equal (file-name-extension file) "cpp")))))
|
||||
|
||||
(defun +cc-objc-header-file-p ()
|
||||
(and buffer-file-name
|
||||
(equal (file-name-extension buffer-file-name) "h")
|
||||
(re-search-forward "@\\<interface\\>" magic-mode-regexp-match-limit t)))
|
||||
|
||||
(unless (assq '+cc-c++-header-file-p magic-mode-alist)
|
||||
(push '(+cc-c++-header-file-p . c++-mode) magic-mode-alist)
|
||||
(push '(+cc-objc-header-file-p . objc-mode) magic-mode-alist))
|
||||
|
||||
:init
|
||||
(setq-default c-basic-offset tab-width
|
||||
c-backspace-function #'delete-backward-char
|
||||
c-default-style "doom")
|
||||
|
||||
;; The plusses in c++-mode can be annoying to search for ivy/helm (which reads
|
||||
;; queries as regexps), so we add these for convenience.
|
||||
(defalias 'cpp-mode 'c++-mode)
|
||||
(defvaralias 'cpp-mode-map 'c++-mode-map)
|
||||
|
||||
;; Activate `c-mode', `c++-mode' or `objc-mode' depending on heuristics
|
||||
(add-to-list 'auto-mode-alist '("\\.h\\'" . +cc-c-c++-objc-mode))
|
||||
|
||||
:config
|
||||
(set-electric! '(c-mode c++-mode objc-mode java-mode) :chars '(?\n ?\}))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue