📄 c++-mode.el
字号:
)))))(defun c++-in-literal (&optional lim) "Determine if point is in a C++ `literal'.Return 'c if in a C-style comment, 'c++ if in a C++ style comment,'string if in a string literal, 'pound if on a preprocessor line, ornil if not in a comment at all. Optional LIM is used as the backwardlimit of the search. If omitted, or nil, c++-beginning-of-defun isused." (save-excursion (let* ((here (point)) (state nil) (match nil) (backlim (or lim (c++-point 'bod)))) (goto-char backlim) (while (< (point) here) (setq match (and (re-search-forward "\\(/[/*]\\)\\|[\"']\\|\\(^[ \t]*#\\)" here 'move) (buffer-substring (match-beginning 0) (match-end 0)))) (setq state (cond ;; no match ((null match) nil) ;; looking at the opening of a C++ style comment ((string= "//" match) (if (<= here (progn (end-of-line) (point))) 'c++)) ;; looking at the opening of a C block comment ((string= "/*" match) (if (not (re-search-forward "*/" here 'move)) 'c)) ;; looking at the opening of a double quote string ((string= "\"" match) (if (not (save-restriction ;; this seems to be necessary since the ;; re-search-forward will not work without it (narrow-to-region (point) here) (re-search-forward ;; this regexp matches a double quote ;; which is preceeded by an even number ;; of backslashes, including zero "\\([^\\]\\|^\\)\\(\\\\\\\\\\)*\"" here 'move))) 'string)) ;; looking at the opening of a single quote string ((string= "'" match) (if (not (save-restriction ;; see comments from above (narrow-to-region (point) here) (re-search-forward ;; this matches a single quote which is ;; preceeded by zero or two backslashes. "\\([^\\]\\|^\\)\\(\\\\\\\\\\)?'" here 'move))) 'string)) ((string-match "[ \t]*#" match) (if (<= here (progn (end-of-line) (point))) 'pound)) (t nil))) ) ; end-while state)))(defun c++-in-parens-p (&optional lim) "Return t if inside a paren expression.Optional LIM is used as the backward limit of the search." (let ((lim (or lim (c++-point 'bod)))) (condition-case () (save-excursion (save-restriction (narrow-to-region (point) lim) (goto-char (point-max)) (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\())) (error nil))));; ======================================================================;; defuns for calculating indentation;; ======================================================================(defun c++-indent-line (&optional bod) "Indent current line as C++ code.Return the amount the indentation changed by. Optional BOD is thepoint of the beginning of the C++ definition." (let* ((bod (or bod (c++-point 'bod))) (indent (c++-calculate-indent nil bod)) beg shift-amt (comcol nil) (case-fold-search nil) (pos (- (point-max) (point)))) (beginning-of-line) (setq beg (point)) (cond ((eq indent nil) (setq indent (current-indentation))) ((eq indent t) (setq indent (c++-calculate-c-indent-within-comment))) ((looking-at "[ \t]*#") (setq indent 0)) ((save-excursion (and (not (back-to-indentation)) (looking-at "//\\|/\\*") (/= (setq comcol (current-column)) 0))) ;; we've found a comment-only line. we now must try to ;; determine if the line is a continuation from a comment ;; on the previous line. we check to see if the comment ;; starts in comment-column and if so, we don't change its ;; indentation. (if (= comcol comment-column) (setq indent comment-column) (setq indent (+ indent c++-comment-only-line-offset)))) (t (skip-chars-forward " \t") (if (listp indent) (setq indent (car indent))) (cond ((looking-at c++-access-key) (setq indent (+ indent c++-access-specifier-offset))) ((looking-at "default:") (setq indent (+ indent c-label-offset))) ((or (looking-at "case\\b") (and (looking-at "[A-Za-z]") (save-excursion (forward-sexp 1) (looking-at ":[^:]")))) (setq indent (max 1 (+ indent c-label-offset)))) ((and (looking-at "else\\b") (not (looking-at "else\\s_"))) (setq indent (save-excursion (c-backward-to-start-of-if) (back-to-indentation) (skip-chars-forward "{ \t") (current-column)))) ((looking-at "\\<friend\\>") (setq indent (+ indent c++-friend-offset))) ((and (= (following-char) ?\)) c++-paren-as-block-close-p) (setq indent (+ (- indent c-indent-level) (save-excursion (forward-char 1) (cond ((c++-at-top-level-p nil bod) (- c++-block-close-brace-offset)) ((c++-at-top-level-p t bod) c-indent-level) (t c++-block-close-brace-offset)))))) ((= (following-char) ?}) (setq indent (+ (- indent c-indent-level) (if (save-excursion (forward-char 1) (c++-at-top-level-p nil bod)) (- c++-block-close-brace-offset) c++-block-close-brace-offset)))) ((= (following-char) ?{) (setq indent (+ indent c-brace-offset)))))) (skip-chars-forward " \t") (setq shift-amt (- indent (current-column))) (if (zerop shift-amt) (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos))) (delete-region beg (point)) (indent-to indent) ;; If initial point was within line's indentation, ;; position after the indentation. Else stay at same point in text. (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos)))) ;; save-excursion is necessary because things break if the hook ;; changes point or mark (save-excursion (run-hooks 'c++-special-indent-hook)) shift-amt))(defun c++-calculate-indent (&optional parse-start bod) "Return appropriate indentation for current line as C++ code.In usual case returns an integer: the column to indent to.Returns nil if line starts inside a string, t if in a comment.Optional PARSE-START is the location to start parsing, and optionalBOD is the beginning of the C++ definition." (save-excursion (beginning-of-line) (let ((indent-point (point)) (case-fold-search nil) state do-indentation literal containing-sexp streamop-pos (inclass-shift 0) inclass-depth (bod (or bod (c++-point 'bod)))) (if parse-start (goto-char parse-start) (goto-char bod)) (setq parse-start (point) state (c++-parse-state indent-point) containing-sexp (nth 1 state)) ;; it is possible that c++-defun-header-weak could not find the ;; beginning of the C++ definition. The following code attempts ;; to work around this. It is probably better to just use ;; c++-match-header-strongly, but there are performance questions (if (null state) (let* ((c++-match-header-strongly t) (bod (c++-point 'bod))) (goto-char bod) (setq state (c++-parse-state indent-point) containing-sexp (nth 1 state) parse-start (point)))) (setq literal (c++-in-literal bod)) (cond ((memq literal '(string)) ;; in a string. nil) ((memq literal '(c c++)) ;; in a C or C++ style comment. t) ;; is this a comment-only line in the first column or ;; comment-column? if so we don't change the indentation, ;; otherwise, we indent relative to surrounding code ;; (later on). ((progn (goto-char indent-point) (beginning-of-line) (skip-chars-forward " \t") (and (looking-at comment-start-skip) (or (zerop (current-column)) (= (current-column) comment-column)))) (current-column)) ((setq inclass-depth (c++-at-top-level-p t bod)) ;; Line is at top level. May be comment-only line, data ;; or function definition, or may be function argument ;; declaration or member initialization. Indent like the ;; previous top level line unless: ;; ;; 1. the previous line ends in a closeparen without ;; semicolon, in which case this line is the first ;; argument declaration or member initialization, or ;; ;; 2. the previous line ends with a closeparen ;; (closebrace), optional spaces, and a semicolon, in ;; which case this line follows a multiline function ;; declaration (class definition), or ;; ;; 3. the previous line begins with a colon, in which ;; case this is the second line of member inits. It is ;; assumed that arg decls and member inits are not mixed. ;; (+ ;; add an offset if we are inside a class defun body, ;; i.e. we are at the top level, but only wrt a ;; containing class (setq inclass-shift (* c++-class-member-indent inclass-depth)) (progn (goto-char indent-point) (skip-chars-forward " \t") (if (looking-at "/[/*]") ;; comment only line, but must not be in the first ;; column since cond case above would have caught it 0 (if (= (following-char) ?{) 0 (c++-backward-over-syntactic-ws parse-start) (if (or (= (preceding-char) ?\)) (and (= (preceding-char) ?t) (save-excursion (forward-word -1) (looking-at "\\<const\\>")))) (progn ; first arg decl or member init (goto-char indent-point) (skip-chars-forward " \t") (if (= (following-char) ?:) c++-member-init-indent c-argdecl-indent)) (if (= (preceding-char) ?\;) (progn (backward-char 1) (skip-chars-backward " \t"))) ;; may be first line after a hanging member init colon (if (or (= (preceding-char) ?:) (save-excursion (forward-line 1) (skip-chars-forward " \t") (= (following-char) ?:))) ;; check to see if we're looking at a member ;; init, or access specifier (if (progn (beginning-of-line) (skip-chars-forward " \t") (looking-at c++-access-key)) ;; access specifier so add zero to inclass-shift 0 ;; member init, so add offset, but ;; subtract inclass-shift (- c++-member-init-indent c++-class-member-indent)) (if (or (= (preceding-char) ?}) (= (preceding-char) ?\)) (save-excursion (beginning-of-line) (looking-at "[ \t]*\\<friend\\>"))) 0 (beginning-of-line) ; cont arg decls or member inits (skip-chars-forward " \t") (if (or (memq (c++-in-literal bod) '(c c++)) (looking-at "/[/*]")) 0 (if (= (following-char) ?:) (if c++-continued-member-init-offset (+ (current-indentation) c++-continued-member-init-offset) (progn (forward-char 1) (skip-chars-forward " \t") (- (current-column) inclass-shift))) ;; else first check to see if its a ;; multiple inheritance continuation line (if (looking-at (concat c++-class-key "[ \t]+" "\\(\\w+[ \t]*:[ \t]*\\)?")) (if (progn (goto-char indent-point) (c++-backward-over-syntactic-ws) (= (preceding-char) ?,)) (progn (goto-char (match-end 0)) (current-column)) 0) ;; we might be looking at the opening ;; brace of a class defun (if (= (following-char) ?\{) (- c-indent-level c++-class-member-indent) (if (eolp) ;; looking at a blank line, indent ;; next line to zero 0 (if (save-excursion (goto-char indent-point) (beginning-of-line) (bobp)) ;; at beginning of buffer, if ;; nothing else, indent to zero
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -