[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master 5d79ce4: * sm-c-mode: Improve indentation of struct; plus
From: |
Stefan Monnier |
Subject: |
[elpa] master 5d79ce4: * sm-c-mode: Improve indentation of struct; plus bug fixes |
Date: |
Tue, 24 Nov 2015 21:06:14 +0000 |
branch: master
commit 5d79ce42f323cd10aed073aac50104a2d7920ec3
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>
* sm-c-mode: Improve indentation of struct; plus bug fixes
* packages/sm-c-mode/GNUmakefile: New file.
* packages/sm-c-mode/sm-c-mode-test.c: Add some "struct" tests.
Plus a #include.
* packages/sm-c-mode/sm-c-mode.el (sm-c-syntax-propertize): Mark the <...>
of #include as a string.
(sm-c-smie--*-token): Try not to look too far back.
(sm-c-smie-rules): Indent the {...} of struct and enum definitions.
(sm-c--bs-realign-1): Fix behavior at EOB.
(sm-c--cpp-is-not-really-a-comment): New function.
(comment-only-p): Use it.
---
packages/sm-c-mode/GNUmakefile | 21 +++++++++++
packages/sm-c-mode/sm-c-mode-test.c | 16 ++++++++-
packages/sm-c-mode/sm-c-mode.el | 63 ++++++++++++++++++++++++++++------
3 files changed, 88 insertions(+), 12 deletions(-)
diff --git a/packages/sm-c-mode/GNUmakefile b/packages/sm-c-mode/GNUmakefile
new file mode 100644
index 0000000..2c6da32
--- /dev/null
+++ b/packages/sm-c-mode/GNUmakefile
@@ -0,0 +1,21 @@
+
+EMACS=emacs
+DIFF=diff
+
+test: sm-c-mode-test.c.test
+
+.PHONY: refresh
+refresh:
+
+%.elc : %.el
+ $(EMACS) --batch -L . --no-init-file -f batch-byte-compile $<
+
+%.test: % sm-c-mode.elc refresh
+ $(EMACS) --batch -l sm-c-mode-autoloads.el \
+ sm-c-mode-test.c \
+ --eval '(setq indent-tabs-mode nil)' \
+ --eval '(setq create-lockfiles nil)' \
+ --eval '(indent-region (point-min) (point-max) nil)' \
+ --eval '(indent-region (point-min) (point-max) nil)' \
+ --eval '(write-region (point-min) (point-max) "$@")'
+ $(DIFF) $< $@ || true; $(RM) $@
diff --git a/packages/sm-c-mode/sm-c-mode-test.c
b/packages/sm-c-mode/sm-c-mode-test.c
index 94cf476..4690105 100644
--- a/packages/sm-c-mode/sm-c-mode-test.c
+++ b/packages/sm-c-mode/sm-c-mode-test.c
@@ -1,5 +1,7 @@
/* -*- sm-c -*- */
+#include <toto>
+
#define toto(arg) /* bla
bla */ \
if (a) { /* toto
@@ -11,7 +13,19 @@
#define test(arg) \
(hello + arg)
-struct foo;
+struct foo
+ {
+ int field;
+ };
+
+struct foo {
+ int field;
+};
+
+struct foo *getfoo (void)
+{
+ return NULL;
+}
#define titi(arg) { \
if (a) { \
diff --git a/packages/sm-c-mode/sm-c-mode.el b/packages/sm-c-mode/sm-c-mode.el
index 7616616..1ac263e 100644
--- a/packages/sm-c-mode/sm-c-mode.el
+++ b/packages/sm-c-mode/sm-c-mode.el
@@ -35,9 +35,8 @@
;; it'd be nice to hook the sm-c--while-to-do, sm-c--else-to-if, and sm-c--boi
;; functions into SMIE at some level.
-;; FIXME:
-;; - M-; mistakes # for a comment in CPP directives!
-;; Ha! As if this was the only/main problem!
+;; Note that this mode makes no attempt to try and handle sanely K&R style
+;; function definitions.
;;; Code:
@@ -233,7 +232,15 @@ Typically 2 for GNU style and `tab-width' for Linux style."
(sm-c--cpp-syntax-propertize end)
(funcall
(syntax-propertize-rules
- (sm-c--cpp-regexp (2 (prog1 "< c" (sm-c--cpp-syntax-propertize end)))))
+ (sm-c--cpp-regexp
+ (2 (prog1 "< c"
+ (when (and (equal (match-string 3) "include")
+ (looking-at "[ \t]*\\(<\\)[^>\n]*\\(>\\)"))
+ (put-text-property (match-beginning 1) (match-end 1)
+ 'syntax-table (string-to-syntax "|"))
+ (put-text-property (match-beginning 2) (match-end 2)
+ 'syntax-table (string-to-syntax "|")))
+ (sm-c--cpp-syntax-propertize end)))))
(point) end))
(defun sm-c-syntactic-face-function (ppss)
@@ -495,9 +502,19 @@ if INNER is non-nil, it stops at the innermost one."
((or "(" "[" "{" "}") "* deref")
(`nil
(goto-char pos)
- (pcase (smie-backward-sexp "* mult")
- (`(,_ ,_ ,(or ";" "{")) "* deref")
- (_ "* mult")))
+ (let ((res nil))
+ (while (not res)
+ (pcase (smie-backward-sexp)
+ (`(,_ ,_ ,(or ";" "{")) (setq res "* deref"))
+ ((and `nil (guard (looking-at "{"))) (setq res "* deref"))
+ (`(,left ,_ ,op)
+ (if (and (numberp left)
+ (numberp (nth 2 (assoc op smie-grammar)))
+ (< (nth 2 (assoc op smie-grammar))
+ (nth 1 (assoc "* mult" smie-grammar))))
+ (smie-backward-sexp 'halfsexp)
+ (setq res "* mult")))))
+ res))
(_ "* mult")))))
(defun sm-c-smie-hanging-eolp ()
@@ -565,8 +582,20 @@ if INNER is non-nil, it stops at the innermost one."
(sm-c--boi 'inner) (sm-c--skip-labels (point-max))
(let ((tok (save-excursion (sm-c-smie-forward-token))))
(cond
- ((member tok '("typedef")) ; "enum" "struct"
- `(column . ,(+ (funcall smie-rules-function :elem 'basic)
+ ((or (equal tok "typedef")
+ (and (member tok '("enum" "struct"))
+ ;; Make sure that the {...} is about this struct/enum,
+ ;; as opposed to "struct foo *get_foo () {...}"!
+ (save-excursion
+ (smie-indent-forward-token)
+ (smie-indent-forward-token)
+ (forward-comment (point-max))
+ (>= (point) pos))))
+ `(column . ,(+ (if (save-excursion
+ (goto-char pos)
+ (smie-rule-hanging-p))
+ 0
+ (funcall smie-rules-function :elem 'basic))
(smie-indent-virtual))))
((or (member tok sm-c-paren-block-keywords)
(equal tok "do"))
@@ -689,6 +718,7 @@ if INNER is non-nil, it stops at the innermost one."
(end-of-line)
(unless (zerop (mod (skip-chars-backward "\\\\") 2))
(skip-chars-backward " \t")
+ (setq from (point))
(let ((col (current-column))
start end)
(while
@@ -702,14 +732,14 @@ if INNER is non-nil, it stops at the innermost one."
(while
(progn (setq end (point))
(end-of-line 2)
- (and (> (point) start)
+ (and (> (line-beginning-position) end)
(not (zerop (mod (skip-chars-backward "\\\\") 2)))))
(skip-chars-backward " \t")
(setq col (max (current-column) col)))
(goto-char to)
(beginning-of-line)
(unless (or (> (point) end) ;Don't realign if we changed outside!
- (< end start)) ;A lone \
+ (<= end start)) ;A lone \
(setq col (1+ col)) ;Add a space before the backslashes.
(goto-char end)
@@ -801,5 +831,16 @@ if INNER is non-nil, it stops at the innermost one."
(add-hook 'after-change-functions #'sm-c--bs-after-change nil t)
(add-hook 'post-command-hook #'sm-c--bs-realign nil t))
+(defun sm-c--cpp-is-not-really-a-comment (&rest args)
+ ;; Without this, placing the region around a CPP directive and hitting
+ ;; M-; would just strip the leading "#" instead of commenting things out.
+ (if (not (derived-mode-p 'sm-c-mode))
+ (apply args)
+ (let ((parse-sexp-lookup-properties nil))
+ (apply args))))
+
+;; FIXME: Clearly, we should change newcomment.el instead.
+(advice-add 'comment-only-p :around #'sm-c--cpp-is-not-really-a-comment)
+
(provide 'sm-c-mode)
;;; sm-c-mode.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] master 5d79ce4: * sm-c-mode: Improve indentation of struct; plus bug fixes,
Stefan Monnier <=