From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Masatake YAMATO Newsgroups: gmane.emacs.devel Subject: Request for merging cc-guess.el Date: Thu, 30 Jun 2011 13:20:15 +0900 (JST) Organization: Red Hat Japan, Inc. Message-ID: <20110630.132015.825745574505660334.yamato@redhat.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1309407651 3947 80.91.229.12 (30 Jun 2011 04:20:51 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 30 Jun 2011 04:20:51 +0000 (UTC) Cc: Alan Mackenzie To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Jun 30 06:20:46 2011 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Qc8k8-0000KQ-3V for ged-emacs-devel@m.gmane.org; Thu, 30 Jun 2011 06:20:44 +0200 Original-Received: from localhost ([::1]:52439 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qc8k7-0005Jn-1v for ged-emacs-devel@m.gmane.org; Thu, 30 Jun 2011 00:20:43 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:52871) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qc8jo-0005Jf-03 for emacs-devel@gnu.org; Thu, 30 Jun 2011 00:20:26 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Qc8jl-0002K7-1T for emacs-devel@gnu.org; Thu, 30 Jun 2011 00:20:23 -0400 Original-Received: from mx1.redhat.com ([209.132.183.28]:17460) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Qc8jk-0002K1-DY for emacs-devel@gnu.org; Thu, 30 Jun 2011 00:20:20 -0400 Original-Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5U4KITh026172 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 30 Jun 2011 00:20:18 -0400 Original-Received: from localhost (beach.nrt.redhat.com [10.64.200.71]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5U4KGDO026238; Thu, 30 Jun 2011 00:20:16 -0400 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:141199 Archived-At: Hi, Chong Yidong wrote: > Just a reminder: the pretest is scheduled for late July, as discussed at > http://lists.gnu.org/archive/html/emacs-devel/2011-05/msg00953.html. > > In order to ensure a smooth transition to the pretest, I encourage > everyone who has a pending patch that implements a new feature to commit > it, or ask to have it committed, ASAP. If committing during July, > please discuss on emacs-devel first. I would like you to include cc-guess.el into Emacs 24. cc-guess.el is an extension of cc-mode. It guesses indentation values by scanning existing code. So in many cases the user don't need specifying indentation parameters. cc-guess.el is those who are working on multiple projects and each of them adopts different conding rule. e.g. emacs, linux, freetype, and fontforge. See the comments for more detail. cc-guess.el is in cc-mode source tree(at sourceforge) but not in cc-mode in emacs source tree. I started improving cc-guess.el(at sourceforge) five years ago. Alan and I have worked together in this Jun for brushing it up. Finally Alan (as the maintainer of cc-mode) approves merging it into Emacs. So I submit it here. Soon, Alan will submit the updated version of cc-mode.texi which explains the commands and options of cc-guess.el well. Regards, Masatake YAMATO === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-06-30 03:03:07 +0000 +++ lisp/ChangeLog 2011-06-30 03:51:59 +0000 @@ -1,3 +1,15 @@ +2011-06-30 Masatake YAMATO + + * progmodes/cc-guess.el: New file. + * progmodes/cc-langs.el (c-mode-menu): Added "Style..." + submenu. + + * progmodes/cc-styles.el (cc-choose-style-for-mode): + New function dereived from `c-basic-common-init'. + + * progmodes/cc-mode.el (top-level): Require cc-guess. + (c-basic-common-init): Use `cc-choose-style-for-mode'. + 2011-06-30 Glenn Morris * find-dired.el (find-grep-options): Simplify. === added file 'lisp/progmodes/cc-guess.el' --- lisp/progmodes/cc-guess.el 1970-01-01 00:00:00 +0000 +++ lisp/progmodes/cc-guess.el 2011-06-30 03:17:22 +0000 @@ -0,0 +1,576 @@ +;;; cc-guess.el --- guess indentation values by scanning existing code + +;; Copyright (C) 1985,1987,1992-2003, 2004, 2005, 2006 Free Software +;; Foundation, Inc. + +;; Author: 1994-1995 Barry A. Warsaw +;; 2011- Masatake YAMATO +;; Maintainer: bug-cc-mode@gnu.org +;; Created: August 1994, split from cc-mode.el +;; Version: See cc-mode.el +;; Keywords: c languages oop + +;; 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 2 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 this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; +;; This file contains routines that help guess the cc-mode style in a +;; particular region/buffer. Here style means `c-offsets-alist' and +;; `c-basic-offset'. +;; +;; The main entry point of this program is `c-guess' command but there +;; are some variants. +;; +;; Suppose the major mode for the current buffer is one of the modes +;; provided by cc-mode. `c-guess' guesses the indentation style by +;; examining the indentation in the region between beginning of buffer +;; and `c-guess-region-max'. + +;; and installs the guessed style. The name for installed style is given +;; by `c-guess-style-name'. +;; +;; `c-guess-buffer' does the same but in the whole buffer. +;; `c-guess-region' does the same but in the region between the point +;; and the mark. `c-guess-no-install', `c-guess-buffer-no-install' +;; and `c-guess-region-no-install' guess the indentation style but +;; don't install it. You can review a guessed style with `c-guess-view'. +;; After reviewing, use `c-guess-install' to install the style +;; if you prefer it. +;; +;; If you want to reuse the guessed style in another buffer, +;; run `c-set-style' command with the name of the guessed style: +;; "*c-guess*:". +;; Once the guessed style is installed explicitly with `c-guess-install' +;; or implicitly with `c-guess', `c-guess-buffer', or `c-guess-region', +;; a style name is given by `c-guess-style-name' with the above form. +;; +;; If you want to reuse the guessed style in future emacs sessions, +;; you may want to put it to your .emacs. `c-guess-view' is for +;; you. It emits emacs lisp code which defines the last guessed +;; style, in a temporary buffer. You can put the emitted code into +;; your .emacs. This command was suggested by Alan Mackenzie. + +;;; Code: + +(eval-when-compile + (let ((load-path + (if (and (boundp 'byte-compile-dest-file) + (stringp byte-compile-dest-file)) + (cons (file-name-directory byte-compile-dest-file) load-path) + load-path))) + (load "cc-bytecomp" nil t))) + +(cc-require 'cc-defs) +(cc-require 'cc-engine) +(cc-require 'cc-styles) + + + +(defcustom c-guess-offset-threshold 10 + "Threshold of acceptable offsets when examining indent information. +Discard an examined offset if its absolute value is greater than this. + +The offset of a line included in the indent information returned by +`c-guess-basic-syntax'." + :type 'integer + :group 'c) + +(defcustom c-guess-region-max 50000 + "The maximum region size for examining indent information with `c-guess'. +It takes a long time to examine indent information from a large region; +this option helps you limit that time. `nil' means no limit." + :type 'integer + :group 'c) + + +;;;###autoload +(defvar c-guess-guessed-offsets-alist nil + "Currently guessed offsets-alist.") +;;;###autoload +(defvar c-guess-guessed-basic-offset nil + "Currently guessed basic-offset.") + +(defvar c-guess-accumulator nil) +;; Accumulated examined indent information. Information is represented +;; in a list. Each element in it has following structure: +;; +;; (syntactic-symbol ((indentation-offset1 . number-of-times1) +;; (indentation-offset2 . number-of-times2) +;; ...)) +;; +;; This structure is built by `c-guess-accumulate-offset'. +;; +;; Here we call the pair (indentation-offset1 . number-of-times1) a +;; counter. `c-guess-sort-accumulator' sorts the order of +;; counters by number-of-times. +;; Use `c-guess-dump-accumulator' to see the value. + +(defconst c-guess-conversions + '((c . c-lineup-C-comments) + (inher-cont . c-lineup-multi-inher) + (string . -1000) + (comment-intro . c-lineup-comment) + (arglist-cont-nonempty . c-lineup-arglist) + (arglist-close . c-lineup-close-paren) + (cpp-macro . -1000))) + + +;;;###autoload +(defun c-guess (&optional accumulate) + "Guess the style in the region up to `c-guess-region-max', and install it. + +The style is given a name based on the file's absolute file name. + +If given a prefix argument (or if the optional argument ACCUMULATE is +non-nil) then the previous guess is extended, otherwise a new guess is +made from scratch." + (interactive "P") + (c-guess-region (point-min) + (min (point-max) (or c-guess-region-max + (point-max))) + accumulate)) + +;;;###autoload +(defun c-guess-no-install (&optional accumulate) + "Guess the style in the region up to `c-guess-region-max'; don't install it. + +If given a prefix argument (or if the optional argument ACCUMULATE is +non-nil) then the previous guess is extended, otherwise a new guess is +made from scratch." + (interactive "P") + (c-guess-region-no-install (point-min) + (min (point-max) (or c-guess-region-max + (point-max))) + accumulate)) + +;;;###autoload +(defun c-guess-buffer (&optional accumulate) + "Guess the style on the whole current buffer, and install it. + +The style is given a name based on the file's absolute file name. + +If given a prefix argument (or if the optional argument ACCUMULATE is +non-nil) then the previous guess is extended, otherwise a new guess is +made from scratch." + (interactive "P") + (c-guess-region (point-min) + (point-max) + accumulate)) + +;;;###autoload +(defun c-guess-buffer-no-install (&optional accumulate) + "Guess the style on the whole current buffer; don't install it. + +If given a prefix argument (or if the optional argument ACCUMULATE is +non-nil) then the previous guess is extended, otherwise a new guess is +made from scratch." + (interactive "P") + (c-guess-region-no-install (point-min) + (point-max) + accumulate)) + +;;;###autoload +(defun c-guess-region (start end &optional accumulate) + "Guess the style on the region and install it. + +The style is given a name based on the file's absolute file name. + +If given a prefix argument (or if the optional argument ACCUMULATE is +non-nil) then the previous guess is extended, otherwise a new guess is +made from scratch." + (interactive "r\nP") + (c-guess-region-no-install start end accumulate) + (c-guess-install)) + + +(defsubst c-guess-empty-line-p () + (eq (line-beginning-position) + (line-end-position))) + +;;;###autoload +(defun c-guess-region-no-install (start end &optional accumulate) + "Guess the style on the region; don't install it. + +Every line of code in the region is examined and values for the following two +variables are guessed: + +* `c-basic-offset', and +* the indentation values of the various syntactic symbols in + `c-offsets-alist'. + +The guessed values are put into `c-guess-guessed-basic-offset' and +`c-guess-guessed-offsets-alist'. + +Frequencies of use are taken into account when guessing, so minor +inconsistencies in the indentation style shouldn't produce wrong guesses. + +If given a prefix argument (or if the optional argument ACCUMULATE is +non-nil) then the previous examination is extended, otherwise a new +guess is made from scratch. + +Note that the larger the region to guess in, the slower the guessing. +So you can limit the region with `c-guess-region-max'." + (interactive "r\nP") + (let ((accumulator (when accumulate c-guess-accumulator))) + (setq c-guess-accumulator (c-guess-examine start end accumulator)) + (let ((pair (c-guess-guess c-guess-accumulator))) + (setq c-guess-guessed-basic-offset (car pair) + c-guess-guessed-offsets-alist (cdr pair))))) + + +(defun c-guess-examine (start end accumulator) + (let ((reporter (when (fboundp 'make-progress-reporter) + (make-progress-reporter "Examining Indentation " + start + end)))) + (save-excursion + (goto-char start) + (while (< (point) end) + (unless (c-guess-empty-line-p) + (mapc (lambda (s) + (setq accumulator (or (c-guess-accumulate accumulator s) + accumulator))) + (c-save-buffer-state () (c-guess-basic-syntax)))) + (when reporter (progress-reporter-update reporter (point))) + (forward-line 1))) + (when reporter (progress-reporter-done reporter))) + (c-guess-sort-accumulator accumulator)) + +(defun c-guess-guess (accumulator) + ;; Guess basic-offset and offsets-alist from ACCUMULATOR, + ;; then return them as a cons: (basic-offset . offsets-alist). + ;; See the comments at `c-guess-accumulator' about the format + ;; ACCUMULATOR. + (let* ((basic-offset (c-guess-make-basic-offset accumulator)) + (typical-offsets-alist (c-guess-make-offsets-alist + accumulator)) + (symbolic-offsets-alist (c-guess-symbolize-offsets-alist + typical-offsets-alist + basic-offset)) + (merged-offsets-alist (c-guess-merge-offsets-alists + (copy-tree c-guess-conversions) + symbolic-offsets-alist))) + (cons basic-offset merged-offsets-alist))) + +(defun c-guess-current-offset (relpos) + ;; Calculate relative indentation (point) to RELPOS. + (- (progn (back-to-indentation) + (current-column)) + (save-excursion + (goto-char relpos) + (current-column)))) + +(defun c-guess-accumulate (accumulator syntax-element) + ;; Add SYNTAX-ELEMENT to ACCUMULATOR. + (let ((symbol (car syntax-element)) + (relpos (cadr syntax-element))) + (when (numberp relpos) + (let ((offset (c-guess-current-offset relpos))) + (when (< (abs offset) c-guess-offset-threshold) + (c-guess-accumulate-offset accumulator + symbol + offset)))))) + +(defun c-guess-accumulate-offset (accumulator symbol offset) + ;; Added SYMBOL and OFFSET to ACCUMULATOR. See + ;; `c-guess-accumulator' about the structure of ACCUMULATOR. + (let* ((entry (assoc symbol accumulator)) + (counters (cdr entry)) + counter) + (if entry + (progn + (setq counter (assoc offset counters)) + (if counter + (setcdr counter (1+ (cdr counter))) + (setq counters (cons (cons offset 1) counters)) + (setcdr entry counters)) + accumulator) + (cons (cons symbol (cons (cons offset 1) nil)) accumulator)))) + +(defun c-guess-sort-accumulator (accumulator) + ;; Sort each element of ACCUMULATOR by the number-of-times. See + ;; `c-guess-accumulator' for more details. + (mapcar + (lambda (entry) + (let ((symbol (car entry)) + (counters (cdr entry))) + (cons symbol (sort counters + (lambda (a b) + (if (> (cdr a) (cdr b)) + t + (and + (eq (cdr a) (cdr b)) + (< (car a) (car b))))))))) + accumulator)) + +(defun c-guess-make-offsets-alist (accumulator) + ;; Throw away the rare cases in accumulator and make an offsets-alist structure. + (mapcar + (lambda (entry) + (cons (car entry) + (car (car (cdr entry))))) + accumulator)) + +(defun c-guess-merge-offsets-alists (strong weak) + ;; Merge two offsets-alists into one. + ;; When two offsets-alists have the same symbol + ;; entry, give STRONG priority over WEAK. + (mapc + (lambda (weak-elt) + (unless (assoc (car weak-elt) strong) + (setq strong (cons weak-elt strong)))) + weak) + strong) + +(defun c-guess-make-basic-offset (accumulator) + ;; As candidate for `c-basic-offset', find the most frequently appearing + ;; indentation-offset in ACCUMULATOR. + (let* (;; Drop the value related to `c' syntactic-symbol. + ;; (`c': Inside a multiline C style block comment.) + ;; The impact for values of `c' is too large for guessing + ;; `basic-offset' if the target source file is small and its license + ;; notice is at top of the file. + (accumulator (assq-delete-all 'c (copy-tree accumulator))) + ;; Drop syntactic-symbols from ACCUMULATOR. + (alist (apply #'append (mapcar (lambda (elts) + (mapcar (lambda (elt) + (cons (abs (car elt)) + (cdr elt))) + (cdr elts))) + accumulator))) + ;; Gather all indentation-offsets other than 0. + ;; 0 is meaningless as `basic-offset'. + (offset-list (delete 0 + (delete-dups (mapcar + (lambda (elt) (car elt)) + alist)))) + ;; Sum of number-of-times for offset: + ;; (offset . sum) + (summed (mapcar (lambda (offset) + (cons offset + (apply #'+ + (mapcar (lambda (a) + (if (eq (car a) offset) + (cdr a) + 0)) + alist)))) + offset-list))) + ;; + ;; Find the majority. + ;; + (let ((majority '(nil . 0))) + (while summed + (when (< (cdr majority) (cdr (car summed))) + (setq majority (car summed))) + (setq summed (cdr summed))) + (car majority)))) + +(defun c-guess-symbolize-offsets-alist (offsets-alist basic-offset) + ;; Convert the representation of OFFSETS-ALIST to an alist using + ;; `+', `-', `++', `--', `*', or `/'. These symbols represent + ;; a value relative to BASIC-OFFSET. Their meaning can be found + ;; in the CC Mode manual. + (mapcar + (lambda (elt) + (let ((s (car elt)) + (v (cdr elt))) + (cond + ((integerp v) + (cons s (c-guess-symbolize-integer v + basic-offset))) + (t elt)))) + offsets-alist)) + +(defun c-guess-symbolize-integer (int basic-offset) + (let ((aint (abs int))) + (cond + ((eq int basic-offset) '+) + ((eq aint basic-offset) '-) + ((eq int (* 2 basic-offset)) '++) + ((eq aint (* 2 basic-offset)) '--) + ((eq (* 2 int) basic-offset) '*) + ((eq (* 2 aint) basic-offset) '-) + (t int)))) + +(defun c-guess-style-name () + ;; Make a style name for the guessed style. + (format "*c-guess*:%s" (buffer-file-name))) + +(defun c-guess-make-style (basic-offset offsets-alist) + (when basic-offset + ;; Make a style from guessed values. + (let* ((offsets-alist (c-guess-merge-offsets-alists + offsets-alist + c-offsets-alist))) + `((c-basic-offset . ,basic-offset) + (c-offsets-alist . ,offsets-alist))))) + +;;;###autoload +(defun c-guess-install (&optional style-name) + "Install the latest guessed style into the current buffer. +\(This guessed style is a combination of `c-guess-guessed-basic-offset', +`c-guess-guessed-offsets-alist' and `c-offsets-alist'.) + +The style is entered into CC Mode's style system by +`c-add-style'. Its name is either STYLE-NAME, or a name based on +the absolute file name of the file if STYLE-NAME is nil." + (interactive "sNew style name (empty for default name): ") + (let* ((style (c-guess-make-style c-guess-guessed-basic-offset + c-guess-guessed-offsets-alist))) + (if style + (let ((style-name (or (if (equal style-name "") + nil + style-name) + (c-guess-style-name)))) + (c-add-style style-name style t) + (message "Style \"%s\" is installed" style-name)) + (error "Not yet guessed")))) + +(defun c-guess-dump-accumulator () + "Show `c-guess-accumulator'." + (interactive) + (with-output-to-temp-buffer "*Accumulated Examined Indent Information*" + (pp c-guess-accumulator))) + +(defun c-guess-reset-accumulator () + "Reset `c-guess-accumulator'." + (interactive) + (setq c-guess-accumulator nil)) + +(defun c-guess-dump-guessed-values () + "Show `c-guess-guessed-basic-offset' and `c-guess-guessed-offsets-alist'." + (interactive) + (with-output-to-temp-buffer "*Guessed Values*" + (princ "basic-offset: \n\t") + (pp c-guess-guessed-basic-offset) + (princ "\n\n") + (princ "offsets-alist: \n") + (pp c-guess-guessed-offsets-alist) + )) + +(defun c-guess-dump-guessed-style (&optional printer) + "Show the guessed style. +`pp' is used to print the style but if PRINTER is given, +PRINTER is used instead. If PRINTER is not `nil', it +is called with one argument, the guessed style." + (interactive) + (let ((style (c-guess-make-style c-guess-guessed-basic-offset + c-guess-guessed-offsets-alist))) + (if style + (with-output-to-temp-buffer "*Guessed Style*" + (funcall (if printer printer 'pp) style)) + (error "Not yet guessed")))) + +(defun c-guess-guessed-syntactic-symbols () + ;; Return syntactic symbols in c-guess-guessed-offsets-alist + ;; but not in c-guess-conversions. + (let ((alist c-guess-guessed-offsets-alist) + elt + (symbols nil)) + (while alist + (setq elt (car alist) + alist (cdr alist)) + (unless (assq (car elt) c-guess-conversions) + (setq symbols (cons (car elt) + symbols)))) + symbols)) + +(defun c-guess-view-reorder-offsets-alist-in-style (style guessed-syntactic-symbols) + ;; Reorder the `c-offsets-alist' field of STYLE. + ;; If an entry in `c-offsets-alist' holds a guessed value, move it to + ;; front in the field. In addition alphabetical sort by entry name is done. + (setq style (copy-tree style)) + (let ((offsets-alist-cell (assq 'c-offsets-alist style)) + (guessed-syntactic-symbols (c-guess-guessed-syntactic-symbols))) + (setcdr offsets-alist-cell + (sort (cdr offsets-alist-cell) + (lambda (a b) + (let ((a-guessed? (memq (car a) guessed-syntactic-symbols)) + (b-guessed? (memq (car b) guessed-syntactic-symbols))) + (cond + ((or (and a-guessed? b-guessed?) + (not (or a-guessed? b-guessed?))) + (string-lessp (symbol-name (car a)) + (symbol-name (car b)))) + (a-guessed? t) + (b-guessed? nil))))))) + style) + +(defun c-guess-view-mark-guessed-entries (guessed-syntactic-symbols) + ;; Put " ; Guess value" markers on all entries which hold + ;; guessed values. + ;; `c-basic-offset' is always considered as holding a guessed value. + (let ((needs-markers (cons 'c-basic-offset + guessed-syntactic-symbols))) + (while needs-markers + (goto-char (point-min)) + (when (search-forward (concat "(" + (symbol-name (car needs-markers)) + " ") nil t) + (move-end-of-line 1) + (comment-dwim nil) + (insert " Guessed value")) + (setq needs-markers + (cdr needs-markers))))) + +(defun c-guess-view (&optional with-name) + "Emit emacs lisp code which defines the last guessed style. +So you can put the code into .emacs if you prefer the +guessed code. +\"STYLE NAME HERE\" is used as the name for the style in the +emitted code. If WITH-NAME is given, it is used instead. +WITH-NAME is expected as a string but if this function +called interactively with prefix argument, the value for +WITH-NAME is asked to the user." + (interactive "P") + (let* ((temporary-style-name (cond + ((stringp with-name) with-name) + (with-name (read-from-minibuffer + "New style name: ")) + (t + "STYLE NAME HERE"))) + (guessed-style-name (c-guess-style-name)) + (current-style-name c-indentation-style) + (parent-style-name (if (string-equal guessed-style-name + current-style-name) + ;; The guessed style is already installed. + ;; It cannot be used as the parent style. + ;; Use the default style for the current + ;; major mode as the parent style. + (cc-choose-style-for-mode + major-mode + c-default-style) + ;; The guessed style is not installed yet. + current-style-name))) + (c-guess-dump-guessed-style + (lambda (style) + (let ((guessed-syntactic-symbols (c-guess-guessed-syntactic-symbols))) + (pp `(c-add-style ,temporary-style-name + ',(cons parent-style-name + (c-guess-view-reorder-offsets-alist-in-style + style + guessed-syntactic-symbols)))) + (with-current-buffer standard-output + (lisp-interaction-mode) + (c-guess-view-mark-guessed-entries + guessed-syntactic-symbols) + (buffer-enable-undo))))))) + + +(cc-provide 'cc-guess) +;;; cc-guess.el ends here === modified file 'lisp/progmodes/cc-langs.el' --- lisp/progmodes/cc-langs.el 2011-01-26 08:36:39 +0000 +++ lisp/progmodes/cc-langs.el 2011-06-30 03:33:51 +0000 @@ -295,6 +295,19 @@ ["Backslashify" c-backslash-region (c-fn-region-is-active-p)])) "----" + ("Style..." + ["Set Style..." c-set-style t] + ["Show Current Style Name" (message + "Style Name: %s" + c-indentation-style) t] + ["Guess Style from this Buffer" c-guess-buffer-no-install t] + ["Install the Last Guessed Style..." c-guess-install + (and c-guess-guessed-offsets-alist + c-guess-guessed-basic-offset) ] + ["View the Last Guessed Style" c-guess-view + (and c-guess-guessed-offsets-alist + c-guess-guessed-basic-offset) ]) + "----" ("Toggle..." ["Syntactic indentation" c-toggle-syntactic-indentation :style toggle :selected c-syntactic-indentation] === modified file 'lisp/progmodes/cc-mode.el' --- lisp/progmodes/cc-mode.el 2011-05-28 17:16:54 +0000 +++ lisp/progmodes/cc-mode.el 2011-06-30 03:09:44 +0000 @@ -93,6 +93,7 @@ (cc-require 'cc-cmds) (cc-require 'cc-align) (cc-require 'cc-menus) +(cc-require 'cc-guess) ;; Silence the compiler. (cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs @@ -553,11 +554,7 @@ (c-clear-found-types) ;; now set the mode style based on default-style - (let ((style (if (stringp default-style) - default-style - (or (cdr (assq mode default-style)) - (cdr (assq 'other default-style)) - "gnu")))) + (let ((style (cc-choose-style-for-mode mode default-style))) ;; Override style variables if `c-old-style-variable-behavior' is ;; set. Also override if we are using global style variables, ;; have already initialized a style once, and are switching to a === modified file 'lisp/progmodes/cc-styles.el' --- lisp/progmodes/cc-styles.el 2011-01-26 08:36:39 +0000 +++ lisp/progmodes/cc-styles.el 2011-06-30 03:09:44 +0000 @@ -650,6 +650,15 @@ (setq c-style-variables-are-local-p t)) )) +(defun cc-choose-style-for-mode (mode default-style) + "Return suitable style for MODE from DEFAULT-STYLE. +DEFAULT-STYLE has the same format as `c-default-style'." + (if (stringp default-style) + default-style + (or (cdr (assq mode default-style)) + (cdr (assq 'other default-style)) + "gnu"))) + (cc-provide 'cc-styles)