⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-mode.el

📁 早期freebsd实现
💻 EL
📖 第 1 页 / 共 2 页
字号:
      ;; 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))))    shift-amt))(defun calculate-c-indent (&optional parse-start)  "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."  (save-excursion    (beginning-of-line)    (let ((indent-point (point))	  (case-fold-search nil)	  state	  containing-sexp)      (if parse-start	  (goto-char parse-start)	(beginning-of-defun))      (while (< (point) indent-point)	(setq parse-start (point))	(setq state (parse-partial-sexp (point) indent-point 0))	(setq containing-sexp (car (cdr state))))      (cond ((or (nth 3 state) (nth 4 state))	     ;; return nil or t if should not change this line	     (nth 4 state))	    ((null containing-sexp)	     ;; Line is at top level.  May be data or function definition,	     ;; or may be function argument declaration.	     ;; Indent like the previous top level line	     ;; unless that ends in a closeparen without semicolon,	     ;; in which case this line is the first argument decl.	     (goto-char indent-point)	     (skip-chars-forward " \t")	     (if (= (following-char) ?{)		 0   ; Unless it starts a function body	       (c-backward-to-noncomment (or parse-start (point-min)))	       ;; Look at previous line that's at column 0	       ;; to determine whether we are in top-level decls	       ;; or function's arg decls.  Set basic-indent accordinglu.	       (let ((basic-indent		      (save-excursion			(re-search-backward "^[^ \^L\t\n#]" nil 'move)			(if (and (looking-at "\\sw\\|\\s_")				 (looking-at ".*(")				 (progn				   (goto-char (1- (match-end 0)))				   (forward-sexp 1)				   (and (< (point) indent-point)					(not (memq (following-char)						   '(?\, ?\;))))))			    c-argdecl-indent 0))))		 ;; Now add a little if this is a continuation line.		 (+ basic-indent (if (or (bobp)					 (memq (preceding-char) '(?\) ?\; ?\})))				     0 c-continued-statement-offset)))))	    ((/= (char-after containing-sexp) ?{)	     ;; line is expression, not statement:	     ;; indent to just after the surrounding open.	     (goto-char (1+ containing-sexp))	     (current-column))	    (t	     ;; Statement level.  Is it a continuation or a new statement?	     ;; Find previous non-comment character.	     (goto-char indent-point)	     (c-backward-to-noncomment containing-sexp)	     ;; Back up over label lines, since they don't	     ;; affect whether our line is a continuation.	     (while (or (eq (preceding-char) ?\,)			(and (eq (preceding-char) ?:)			     (or (eq (char-after (- (point) 2)) ?\')				 (memq (char-syntax (char-after (- (point) 2)))				       '(?w ?_)))))	       (if (eq (preceding-char) ?\,)		   (c-backward-to-start-of-continued-exp containing-sexp))	       (beginning-of-line)	       (c-backward-to-noncomment containing-sexp))	     ;; Now we get the answer.	     (if (not (memq (preceding-char) '(nil ?\, ?\; ?\} ?\{)))		 ;; This line is continuation of preceding line's statement;		 ;; indent  c-continued-statement-offset  more than the		 ;; previous line of the statement.		 (progn		   (c-backward-to-start-of-continued-exp containing-sexp)		   (+ c-continued-statement-offset (current-column)		      (if (save-excursion (goto-char indent-point)					  (skip-chars-forward " \t")					  (eq (following-char) ?{))			  c-continued-brace-offset 0)))	       ;; This line starts a new statement.	       ;; Position following last unclosed open.	       (goto-char containing-sexp)	       ;; Is line first statement after an open-brace?	       (or		 ;; If no, find that first statement and indent like it.		 (save-excursion		   (forward-char 1)		   (let ((colon-line-end 0))		     (while (progn (skip-chars-forward " \t\n")				   (looking-at "#\\|/\\*\\|case[ \t\n].*:\\|[a-zA-Z0-9_$]*:"))		       ;; Skip over comments and labels following openbrace.		       (cond ((= (following-char) ?\#)			      (forward-line 1))			     ((= (following-char) ?\/)			      (forward-char 2)			      (search-forward "*/" nil 'move))			     ;; case or label:			     (t			      (save-excursion (end-of-line)					      (setq colon-line-end (point)))			      (search-forward ":"))))		     ;; The first following code counts		     ;; if it is before the line we want to indent.		     (and (< (point) indent-point)			  (if (> colon-line-end (point))			      (- (current-indentation) c-label-offset)			    (current-column)))))		 ;; If no previous statement,		 ;; indent it relative to line brace is on.		 ;; For open brace in column zero, don't let statement		 ;; start there too.  If c-indent-level is zero,		 ;; use c-brace-offset + c-continued-statement-offset instead.		 ;; For open-braces not the first thing in a line,		 ;; add in c-brace-imaginary-offset.		 (+ (if (and (bolp) (zerop c-indent-level))			(+ c-brace-offset c-continued-statement-offset)		      c-indent-level)		    ;; Move back over whitespace before the openbrace.		    ;; If openbrace is not first nonwhite thing on the line,		    ;; add the c-brace-imaginary-offset.		    (progn (skip-chars-backward " \t")			   (if (bolp) 0 c-brace-imaginary-offset))		    ;; If the openbrace is preceded by a parenthesized exp,		    ;; move to the beginning of that;		    ;; possibly a different line		    (progn		      (if (eq (preceding-char) ?\))			  (forward-sexp -1))		      ;; Get initial indentation of the line we are on.		      (current-indentation))))))))))(defun calculate-c-indent-within-comment ()  "Return the indentation amount for line, assuming thatthe current line is to be regarded as part of a block comment."  (let (end star-start)    (save-excursion      (beginning-of-line)      (skip-chars-forward " \t")      (setq star-start (= (following-char) ?\*))      (skip-chars-backward " \t\n")      (setq end (point))      (beginning-of-line)      (skip-chars-forward " \t")      (and (re-search-forward "/\\*[ \t]*" end t)	   star-start	   (goto-char (1+ (match-beginning 0))))      (current-column))))(defun c-backward-to-noncomment (lim)  (let (opoint stop)    (while (not stop)      (skip-chars-backward " \t\n\f" lim)      (setq opoint (point))      (if (and (>= (point) (+ 2 lim))	       (save-excursion		 (forward-char -2)		 (looking-at "\\*/")))	  (search-backward "/*" lim 'move)	(setq stop (or (<= (point) lim)		       (save-excursion			 (beginning-of-line)			 (skip-chars-forward " \t")			 (not (looking-at "#")))))	(or stop (beginning-of-line))))))(defun c-backward-to-start-of-continued-exp (lim)  (if (= (preceding-char) ?\))      (forward-sexp -1))  (beginning-of-line)  (if (<= (point) lim)      (goto-char (1+ lim)))  (skip-chars-forward " \t"))(defun c-backward-to-start-of-if (&optional limit)  "Move to the start of the last ``unbalanced'' if."  (or limit (setq limit (save-excursion (beginning-of-defun) (point))))  (let ((if-level 1)	(case-fold-search nil))    (while (not (zerop if-level))      (backward-sexp 1)      (cond ((looking-at "else\\b")	     (setq if-level (1+ if-level)))	    ((looking-at "if\\b")	     (setq if-level (1- if-level)))	    ((< (point) limit)	     (setq if-level 0)	     (goto-char limit))))))(defun mark-c-function ()  "Put mark at end of C function, point at beginning."  (interactive)  (push-mark (point))  (end-of-defun)  (push-mark (point))  (beginning-of-defun)  (backward-paragraph))(defun indent-c-exp ()  "Indent each line of the C grouping following point."  (interactive)  (let ((indent-stack (list nil))	(contain-stack (list (point)))	(case-fold-search nil)	restart outer-loop-done inner-loop-done state ostate	this-indent last-sexp	at-else at-brace	(opoint (point))	(next-depth 0))    (save-excursion      (forward-sexp 1))    (save-excursion      (setq outer-loop-done nil)      (while (and (not (eobp)) (not outer-loop-done))	(setq last-depth next-depth)	;; Compute how depth changes over this line	;; plus enough other lines to get to one that	;; does not end inside a comment or string.	;; Meanwhile, do appropriate indentation on comment lines.	(setq inner-loop-done nil)	(while (and (not inner-loop-done)		    (not (and (eobp) (setq outer-loop-done t))))	  (setq ostate state)	  (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))					  nil nil state))	  (setq next-depth (car state))	  (if (and (car (cdr (cdr state)))		   (>= (car (cdr (cdr state))) 0))	      (setq last-sexp (car (cdr (cdr state)))))	  (if (or (nth 4 ostate))	      (c-indent-line))	  (if (or (nth 3 state))	      (forward-line 1)	    (setq inner-loop-done t)))	(if (<= next-depth 0)	    (setq outer-loop-done t))	(if outer-loop-done	    nil	  ;; If this line had ..))) (((.. in it, pop out of the levels	  ;; that ended anywhere in this line, even if the final depth	  ;; doesn't indicate that they ended.	  (while (> last-depth (nth 6 state))	    (setq indent-stack (cdr indent-stack)		  contain-stack (cdr contain-stack)		  last-depth (1- last-depth)))	  (if (/= last-depth next-depth)	      (setq last-sexp nil))	  ;; Add levels for any parens that were started in this line.	  (while (< last-depth next-depth)	    (setq indent-stack (cons nil indent-stack)		  contain-stack (cons nil contain-stack)		  last-depth (1+ last-depth)))	  (if (null (car contain-stack))	      (setcar contain-stack (or (car (cdr state))					(save-excursion (forward-sexp -1)							(point)))))	  (forward-line 1)	  (skip-chars-forward " \t")	  (if (eolp)	      nil	    (if (and (car indent-stack)		     (>= (car indent-stack) 0))		;; Line is on an existing nesting level.		;; Lines inside parens are handled specially.		(if (/= (char-after (car contain-stack)) ?{)		    (setq this-indent (car indent-stack))		  ;; Line is at statement level.		  ;; Is it a new statement?  Is it an else?		  ;; Find last non-comment character before this line		  (save-excursion		    (setq at-else (looking-at "else\\W"))		    (setq at-brace (= (following-char) ?{))		    (c-backward-to-noncomment opoint)		    (if (not (memq (preceding-char) '(nil ?\, ?\; ?} ?: ?{)))			;; Preceding line did not end in comma or semi;			;; indent this line  c-continued-statement-offset			;; more than previous.			(progn			  (c-backward-to-start-of-continued-exp (car contain-stack))			  (setq this-indent				(+ c-continued-statement-offset (current-column)				   (if at-brace c-continued-brace-offset 0))))		      ;; Preceding line ended in comma or semi;		      ;; use the standard indent for this level.		      (if at-else			  (progn (c-backward-to-start-of-if opoint)				 (setq this-indent (current-indentation)))			(setq this-indent (car indent-stack))))))	      ;; Just started a new nesting level.	      ;; Compute the standard indent for this level.	      (let ((val (calculate-c-indent			   (if (car indent-stack)			       (- (car indent-stack))))))		(setcar indent-stack			(setq this-indent val))))	    ;; Adjust line indentation according to its contents	    (if (or (looking-at "case[ \t]")		    (and (looking-at "[A-Za-z]")			 (save-excursion			   (forward-sexp 1)			   (looking-at ":"))))		(setq this-indent (max 1 (+ this-indent c-label-offset))))	    (if (= (following-char) ?})		(setq this-indent (- this-indent c-indent-level)))	    (if (= (following-char) ?{)		(setq this-indent (+ this-indent c-brace-offset)))	    ;; Put chosen indentation into effect.	    (or (= (current-column) this-indent)		(= (following-char) ?\#)		(progn		  (delete-region (point) (progn (beginning-of-line) (point)))		  (indent-to this-indent)))	    ;; Indent any comment following the text.	    (or (looking-at comment-start-skip)		(if (re-search-forward comment-start-skip (save-excursion (end-of-line) (point)) t)		    (progn (indent-for-comment) (beginning-of-line))))))))); (message "Indenting C expression...done")  )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -