📄 c++-mode.el
字号:
(defun c++-toggle-auto-hungry-state (arg) "Toggle auto-newline and hungry-delete-key state.Actual toggling of these states is controlled byc++-auto-hungry-toggle variable.Optional argument has the following meanings when supplied: Universal argument \\[universal-argument] resets state to c++-auto-hungry-initial-state. negative number turn off both auto-newline and hungry-delete-key. positive number turn on both auto-newline and hungry-delete-key. zero toggle both states regardless of c++-auto-hungry-toggle-p." (interactive "P") (let* ((numarg (prefix-numeric-value arg)) (apl (list 'auto-only 'auto-hungry t)) (hpl (list 'hungry-only 'auto-hungry t)) (auto (cond ((not arg) (if (memq c++-auto-hungry-toggle apl) (not c++-auto-newline) c++-auto-newline)) ((listp arg) (memq c++-auto-hungry-initial-state apl)) ((zerop numarg) (not c++-auto-newline)) ((< arg 0) nil) (t t))) (hungry (cond ((not arg) (if (memq c++-auto-hungry-toggle hpl) (not c++-hungry-delete-key) c++-hungry-delete-key)) ((listp arg) (memq c++-auto-hungry-initial-state hpl)) ((zerop numarg) (not c++-hungry-delete-key)) ((< arg 0) nil) (t t)))) (c++-set-auto-hungry-state auto hungry)))(defun c++-tame-insert (arg) "Safely inserts certain troublesome characters in comment regions.Because of a syntax bug in emacs' scan-lists function, characters withstring or parenthesis syntax must be escaped with a backslash or lotsof things get messed up. Unfortunately, settingparse-sexp-ignore-comments to non-nil does not fix the problem.See also the variable c++-untame-characters." (interactive "p") (if (and (memq last-command-char c++-untame-characters) (memq (c++-in-literal) '(c c++))) (insert "\\")) (self-insert-command arg))(defun c++-electric-delete (arg) "If c++-hungry-delete-key is non-nil, consumes all precedingwhitespace unless ARG is supplied, or point is inside a C or C++ stylecomment or string. If ARG is supplied, this just callsbackward-delete-char-untabify passing along ARG.If c++-hungry-delete-key is nil, just callbackward-delete-char-untabify." (interactive "P") (cond ((or (not c++-hungry-delete-key) arg) (funcall c++-delete-function (prefix-numeric-value arg))) ((let ((bod (c++-point 'bod))) (not (or (memq (c++-in-literal bod) '(c c++ string)) (save-excursion (skip-chars-backward " \t") (= (preceding-char) ?#))))) (let ((here (point))) (skip-chars-backward " \t\n") (if (/= (point) here) (delete-region (point) here) (funcall c++-delete-function 1)))) (t (funcall c++-delete-function 1))))(defun c++-electric-pound (arg) (interactive "p") (if (memq (c++-in-literal) '(c c++ string)) (self-insert-command arg) (let ((here (point-marker)) (bobp (bobp)) (bolp (bolp))) (if (memq 'alignleft c++-electric-pound-behavior) (progn (beginning-of-line) (delete-horizontal-space))) (if bobp (insert (make-string arg last-command-char)) (insert-before-markers (make-string arg last-command-char))) (if (not bolp) (goto-char here)) (set-marker here nil))))(defun c++-electric-brace (arg) "Insert character and correct line's indentation." (interactive "P") (let (insertpos (last-command-char last-command-char) (bod (c++-point 'bod))) (if (and (not arg) (eolp) (or (save-excursion (skip-chars-backward " \t") (bolp)) (let ((c++-auto-newline c++-auto-newline) (open-brace-p (= last-command-char ?{))) (if (and open-brace-p (or (eq c++-hanging-braces t) (and c++-hanging-braces (not (c++-at-top-level-p t bod))))) (setq c++-auto-newline nil)) (if (c++-auto-newline) ;; this may have auto-filled so we need to ;; indent the previous line. we also need to ;; indent the currently line, or ;; c++-beginning-of-defun will not be able to ;; correctly find the bod when ;; c++-match-headers-strongly is nil. (progn (c++-indent-line) (save-excursion (forward-line -1) (c++-indent-line)))) t))) (progn (if (and (memq last-command-char c++-untame-characters) (memq (c++-in-literal bod) '(c c++))) (insert "\\")) (insert last-command-char) ;; try to clean up empty defun braces if conditions apply (let ((here (point-marker))) (and (memq 'empty-defun-braces c++-cleanup-list) (c++-at-top-level-p t bod) c++-auto-newline (= last-command-char ?\}) (progn (forward-char -1) (skip-chars-backward " \t\n") (= (preceding-char) ?\{)) (not (memq (c++-in-literal) '(c c++ string))) (delete-region (point) (1- here))) (goto-char here) (set-marker here nil)) (let ((here (point-marker)) mbeg mend) (if (and (memq 'brace-else-brace c++-cleanup-list) (= last-command-char ?\{) (let ((status (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t))) (setq mbeg (match-beginning 0) mend (match-end 0)) status) (= mend here) (not (memq (c++-in-literal bod) '(c c++ string)))) (progn ;; we should clean up brace-else-brace syntax (delete-region mbeg mend) (insert-before-markers "} else {") (goto-char here) (set-marker here nil)) (goto-char here) (set-marker here nil))) (c++-indent-line) (if (c++-auto-newline) (progn ;; c++-auto-newline may have done an auto-fill (save-excursion (let ((here (point-marker))) (goto-char (- (point) 2)) (c++-indent-line) (setq insertpos (- (goto-char here) 2)) (set-marker here nil))) (c++-indent-line))) (save-excursion (if insertpos (goto-char (1+ insertpos))) (delete-char -1)))) (if insertpos (save-excursion (goto-char insertpos) (self-insert-command (prefix-numeric-value arg))) (self-insert-command (prefix-numeric-value arg)))))(defun c++-electric-slash (arg) "Slash as first non-whitespace character on line indents as commentunless we're inside a C style comment, or a string, does not doindentation. if first non-whitespace character on line is not a slash,then we just insert the slash. in this case use indent-for-comment ifyou want to add a comment to the end of a line." (interactive "P") (let ((c++-auto-newline c++-auto-newline)) (if (= (preceding-char) ?/) (setq c++-auto-newline nil)) (if (memq (preceding-char) '(?/ ?*)) (c++-electric-terminator arg) (self-insert-command (prefix-numeric-value arg)))))(defun c++-electric-star (arg) "Works with c++-electric-slash to auto indent C style comment lines." (interactive "P") (if (= (preceding-char) ?/) (let ((c++-auto-newline nil)) (c++-electric-terminator arg)) (self-insert-command (prefix-numeric-value arg)) (if (and (memq (c++-in-literal) '(c)) (or (= (point) (c++-point 'boi)) (= (preceding-char) ?*))) (c++-indent-line))))(defun c++-electric-semi (arg) "Insert character and correct line's indentation." (interactive "P") (if (c++-in-literal) (self-insert-command (prefix-numeric-value arg)) (let ((here (point-marker))) (if (and (memq 'defun-close-semi c++-cleanup-list) c++-auto-newline (progn (skip-chars-backward " \t\n") (= (preceding-char) ?}))) (delete-region here (point))) (goto-char here) (set-marker here nil)) (c++-electric-terminator arg)))(defun c++-electric-colon (arg) "Electrify colon. De-auto-newline double colons. No auto-new-linesfor member initialization list." (interactive "P") (if (c++-in-literal) (self-insert-command (prefix-numeric-value arg)) (let ((c++-auto-newline c++-auto-newline) (insertion-point (point)) (bod (c++-point 'bod))) (save-excursion (cond ;; check for double-colon where the first colon is not in a ;; comment or literal region ((progn (skip-chars-backward " \t\n") (and (= (preceding-char) ?:) (not (memq (c++-in-literal bod) '(c c++ string))))) (progn (delete-region insertion-point (point)) (setq c++-auto-newline nil insertion-point (point)))) ;; check for ?: construct which may be at any level ((progn (goto-char insertion-point) (condition-case premature-end (backward-sexp 1) (error nil)) (c++-backward-over-syntactic-ws bod) (= (preceding-char) ?\?)) (setq c++-auto-newline nil)) ;; check for being at top level or top with respect to the ;; class. if not, process as normal ((progn (goto-char insertion-point) (not (c++-at-top-level-p t bod)))) ;; if at top level, check to see if we are introducing a member ;; init list. if not, continue ((progn (c++-backward-over-syntactic-ws bod) (= (preceding-char) ?\))) (goto-char insertion-point) ;; at a member init list, figure out about auto newlining. if ;; nil or before then put a newline before the colon and ;; adjust the insertion point, but *only* if there is no ;; newline already before the insertion point (if (memq c++-hanging-member-init-colon '(nil before)) (if (not (save-excursion (skip-chars-backward " \t") (bolp))) (let ((c++-auto-newline t)) (c++-auto-newline) (setq insertion-point (point))))) ;; if hanging colon is after or nil, then newline is inserted ;; after colon. set up variable so c++-electric-terminator ;; places the newline correctly (setq c++-auto-newline (memq c++-hanging-member-init-colon '(nil after)))) ;; last condition is always put newline after colon (t (setq c++-auto-newline nil)) )) ; end-cond, end-save-excursion (goto-char insertion-point) (c++-electric-terminator arg))))(defun c++-electric-terminator (arg) "Insert character and correct line's indentation." (interactive "P") (let (insertpos (end (point))) (if (and (not arg) (eolp) (not (save-excursion (beginning-of-line) (skip-chars-forward " \t") (or (= (following-char) ?#) ;; Colon is special only after a label, or ;; case, or another colon. ;; So quickly rule out most other uses of colon ;; and do no indentation for them. (and (eq last-command-char ?:) (not (looking-at "case[ \t]")) (save-excursion (forward-word 1) (skip-chars-forward " \t") (< (point) end)) ;; Do re-indent double colons (save-excursion (end-of-line 1) (looking-at ":"))) (progn (c++-beginning-of-defun) (let ((pps (parse-partial-sexp (point) end))) (or (nth 3 pps) (nth 4 pps) (nth 5 pps)))))))) (progn (insert last-command-char) (c++-indent-line) (and c++-auto-newline (not (c++-in-parens-p)) (progn ;; the new marker object, used to be just an integer (setq insertpos (make-marker)) ;; changed setq to set-marker (set-marker insertpos (1- (point))) ;; do this before the newline, since in auto fill can break (newline) (c++-indent-line))) (save-excursion (if insertpos (goto-char (1+ insertpos))) (delete-char -1)))) (if insertpos (save-excursion (goto-char insertpos)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -