* bug#23719: [PATCH] Automatically detect whether .h file is C or C++
@ 2016-06-07 13:16 Michal Nazarewicz
2016-06-15 16:26 ` Michal Nazarewicz
0 siblings, 1 reply; 2+ messages in thread
From: Michal Nazarewicz @ 2016-06-07 13:16 UTC (permalink / raw)
To: 23719
* lisp/progmodes/cc-mode.el (c-or-c++-mode): A new function which
analyses contents of the buffer to determine whether it looks like C++
source code and based on that enables c-mode or c++-mode.
(c-or-c++-mode--regexp): Regular expression which, when matches
a buffer, signals file is C++.
---
etc/NEWS | 7 +++++
lisp/progmodes/cc-mode.el | 39 +++++++++++++++++++++++--
test/lisp/progmodes/cc-mode.el | 65 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 109 insertions(+), 2 deletions(-)
create mode 100644 test/lisp/progmodes/cc-mode.el
diff --git a/etc/NEWS b/etc/NEWS
index 23f6efc..8f4be56 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -373,6 +373,13 @@ string is computed dynamically based on 'url-privacy-level'.
colorful faces to make it more obvious to the user what the state is.
See the 'vc-faces' customization group.
+** CC mode
+
+*** Opening a .h file will turn C or C++ mode depending on language used.
+This is done with the help of 'c-or-c++-mode' function which analyses
+contents of the buffer to determine whether it's a C or C++ source
+file.
+
\f
* New Modes and Packages in Emacs 25.2
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9ab0480..f544dcb 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1444,7 +1444,8 @@ c-mode-map
;;;###autoload (add-to-list 'auto-mode-alist '("\\.[ch]\\(pp\\|xx\\|\\+\\+\\)\\'" . c++-mode))
;;;###autoload (add-to-list 'auto-mode-alist '("\\.\\(CC?\\|HH?\\)\\'" . c++-mode))
-;;;###autoload (add-to-list 'auto-mode-alist '("\\.[ch]\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.c\\'" . c-mode))
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.h\\'" . c-or-c++-mode))
;; NB: The following two associate yacc and lex files to C Mode, which
;; is not really suitable for those formats. Anyway, afaik there's
@@ -1485,6 +1486,40 @@ c-mode
(cc-imenu-init cc-imenu-c-generic-expression)
(c-run-mode-hooks 'c-mode-common-hook))
+(defconst c-or-c++-mode--regexp
+ (eval-when-compile
+ (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\\)>"
+ "\\)")))
+ "A regexp applied to C header files to check if they are really C++.")
+
+;;;###autoload
+(defun c-or-c++-mode ()
+ "Analyse buffer and enable either C or C++ mode.
+
+Some people and projects use .h extension for C++ header files
+which is also the one used for C header files. This makes
+matching on file name insufficient for detecting major mode that
+should be used.
+
+This function attempts to use file contents to determine whether
+the code is C or C++ and based on that chooses whether to enable
+`c-mode' or `c++-mode'."
+ (if (save-excursion
+ (save-restriction
+ (save-match-data
+ (widen)
+ (goto-char (point-min))
+ (re-search-forward c-or-c++-mode--regexp
+ (+ (point) c-guess-region-max) t))))
+ (c++-mode)
+ (c-mode)))
+
\f
;; Support for C++
diff --git a/test/lisp/progmodes/cc-mode.el b/test/lisp/progmodes/cc-mode.el
new file mode 100644
index 0000000..6cd9fa4
--- /dev/null
+++ b/test/lisp/progmodes/cc-mode.el
@@ -0,0 +1,65 @@
+;;; cc-mode-tests.el --- Test suite for cc-mode. -*- lexical-binning: t -*-
+
+;; Copyright (C) 2016 Free Software Foundation, Inc.
+
+;; Author: Michal Nazarewicz <mina86@mina86.com>
+;; Keywords: internal
+;; Human-Keywords: internal
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'cc-mode)
+
+(ert-deftest c-or-c++-mode ()
+ "Test c-or-c++-mode language detection."
+ (cl-letf* ((mode nil)
+ (do-test (lambda (content expected)
+ (delete-region (point-min) (point-max))
+ (insert content)
+ (setq mode nil)
+ (c-or-c++-mode)
+ (unless(eq expected mode)
+ (ert-fail
+ (format "expected %s but got %s when testing '%s'"
+ expected mode content)))))
+ ((symbol-function 'c-mode) (lambda () (setq mode 'c-mode)))
+ ((symbol-function 'c++-mode) (lambda () (setq mode 'c++-mode))))
+ (with-temp-buffer
+ (mapc (lambda (content)
+ (funcall do-test content 'c++-mode)
+ (funcall do-test (concat "// " content) 'c-mode)
+ (funcall do-test (concat " * " content) 'c-mode))
+ '("using \t namespace \t std;"
+ "using \t std::string;"
+ "namespace \t {"
+ "namespace \t foo \t {"
+ "class \t Blah_42 \t {"
+ "class \t Blah_42 \t \n"
+ "class \t _42_Blah:public Foo {"
+ "template \t < class T >"
+ "template< class T >"
+ "#include <string>"
+ "#include<iostream>"
+ "#include \t <map>"))
+
+ (mapc (lambda (content) (funcall do-test content 'c-mode))
+ '("struct \t Blah_42 \t {"
+ "struct template {"
+ "#include <string.h>")))))
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related [flat|nested] 2+ messages in thread
* bug#23719: [PATCH] Automatically detect whether .h file is C or C++
2016-06-07 13:16 bug#23719: [PATCH] Automatically detect whether .h file is C or C++ Michal Nazarewicz
@ 2016-06-15 16:26 ` Michal Nazarewicz
0 siblings, 0 replies; 2+ messages in thread
From: Michal Nazarewicz @ 2016-06-15 16:26 UTC (permalink / raw)
To: 23719-done
On Tue, Jun 07 2016, Michal Nazarewicz wrote:
> * lisp/progmodes/cc-mode.el (c-or-c++-mode): A new function which
> analyses contents of the buffer to determine whether it looks like C++
> source code and based on that enables c-mode or c++-mode.
> (c-or-c++-mode--regexp): Regular expression which, when matches
> a buffer, signals file is C++.
Since there seem to be no objections to this patch, I’ve committed it.
--
Best regards
ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴイツ
«If at first you don’t succeed, give up skydiving»
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-06-15 16:26 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-07 13:16 bug#23719: [PATCH] Automatically detect whether .h file is C or C++ Michal Nazarewicz
2016-06-15 16:26 ` Michal Nazarewicz
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.