icon.el

来自「早期freebsd实现」· EL 代码 · 共 532 行 · 第 1/2 页

EL
532
字号
    (beginning-of-line)    (let ((indent-point (point))	  (case-fold-search nil)	  state	  containing-sexp	  toplevel)      (if parse-start	  (goto-char parse-start)	(setq toplevel (beginning-of-icon-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))	    ((and containing-sexp		  (/= (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.	      (if toplevel		  (progn (icon-backward-to-noncomment (point-min))			 (if (icon-is-continuation-line)			     icon-continued-statement-offset 0))		(if (null containing-sexp)		    (progn (beginning-of-icon-defun)			   (setq containing-sexp (point))))		(goto-char indent-point)		(icon-backward-to-noncomment containing-sexp)		;; Now we get the answer.		(if (icon-is-continuation-line)		    ;; This line is continuation of preceding line's statement;		    ;; indent  icon-continued-statement-offset  more than the		    ;; first line of the statement.		    (progn		      (icon-backward-to-start-of-continued-exp containing-sexp)		      (+ icon-continued-statement-offset (current-column)			 (if (save-excursion (goto-char indent-point)					     (skip-chars-forward " \t")					     (eq (following-char) ?{))			     icon-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		      (if (looking-at "procedure\\s ")			  (forward-sexp 3)			(forward-char 1))		      (while (progn (skip-chars-forward " \t\n")				    (looking-at "#"))			;; Skip over comments following openbrace.			(forward-line 1))		      ;; The first following code counts		      ;; if it is before the line we want to indent.		      (and (< (point) indent-point)			   (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 icon-indent-level is zero,		    ;; use icon-brace-offset + icon-continued-statement-offset instead.		    ;; For open-braces not the first thing in a line,		    ;; add in icon-brace-imaginary-offset.		    (+ (if (and (bolp) (zerop icon-indent-level))			   (+ icon-brace-offset icon-continued-statement-offset)			 icon-indent-level)		       ;; Move back over whitespace before the openbrace.		       ;; If openbrace is not first nonwhite thing on the line,		       ;; add the icon-brace-imaginary-offset.		       (progn (skip-chars-backward " \t")			      (if (bolp) 0 icon-brace-imaginary-offset))		       ;; here we are		       (current-indentation))))))))))(defun icon-is-continuation-line ()  (let* ((ch (preceding-char))	 (ch-syntax (char-syntax ch)))    (if (eq ch-syntax ?w)	(assoc (buffer-substring		 (progn (forward-word -1) (point))		 (progn (forward-word 1) (point)))	       '(("do") ("dynamic") ("else") ("initial") ("link")		 ("local") ("of") ("static") ("then")))      (not (memq ch '(0 ?\; ?\} ?\{ ?\) ?\] ?\" ?\' ?\n))))))(defun icon-backward-to-noncomment (lim)  (let (opoint stop)    (while (not stop)      (skip-chars-backward " \t\n\f" lim)      (setq opoint (point))      (beginning-of-line)      (if (and (search-forward "#" opoint 'move)	       (< lim (point)))	  (forward-char -1)	(setq stop t)))))(defun icon-backward-to-start-of-continued-exp (lim)  (if (memq (preceding-char) '(?\) ?\]))      (forward-sexp -1))  (while (icon-is-continued-line)    (end-of-line 0))  (beginning-of-line)  (if (<= (point) lim)      (goto-char (1+ lim)))  (skip-chars-forward " \t"))(defun icon-is-continued-line ()  (save-excursion    (end-of-line 0)    (icon-is-continuation-line)))(defun icon-backward-to-start-of-if (&optional limit)  "Move to the start of the last ``unbalanced'' if."  (or limit (setq limit (save-excursion (beginning-of-icon-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-icon-function ()  "Put mark at end of Icon function, point at beginning."  (interactive)  (push-mark (point))  (end-of-icon-defun)  (push-mark (point))  (beginning-of-line 0)  (beginning-of-icon-defun))(defun beginning-of-icon-defun ()  "Go to the start of the enclosing procedure; return t if at top level."  (interactive)  (if (re-search-backward "^procedure\\s \\|^end[ \t\n]" (point-min) 'move)      (looking-at "e")    t))(defun end-of-icon-defun ()  (interactive)  (if (not (bobp)) (forward-char -1))  (re-search-forward "\\(\\s \\|^\\)end\\(\\s \\|$\\)" (point-max) 'move)  (forward-word -1)  (forward-line 1))(defun indent-icon-exp ()  "Indent each line of the Icon 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 at-do	(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 innerloop-done nil)	(while (and (not innerloop-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))	      (icon-indent-line))	  (if (or (nth 3 state))	      (forward-line 1)	    (setq innerloop-done t)))	(if (<= next-depth 0)	    (setq outer-loop-done t))	(if outer-loop-done	    nil	  (if (/= last-depth next-depth)	      (setq last-sexp nil))	  (while (> last-depth next-depth)	    (setq indent-stack (cdr indent-stack)		  contain-stack (cdr contain-stack)		  last-depth (1- last-depth)))	  (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) ?{))		    (icon-backward-to-noncomment opoint)		    (if (icon-is-continuation-line)			;; Preceding line did not end in comma or semi;			;; indent this line  icon-continued-statement-offset			;; more than previous.			(progn			  (icon-backward-to-start-of-continued-exp (car contain-stack))			  (setq this-indent				(+ icon-continued-statement-offset (current-column)				   (if at-brace icon-continued-brace-offset 0))))		      ;; Preceding line ended in comma or semi;		      ;; use the standard indent for this level.		      (if at-else			  (progn (icon-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-icon-indent			   (if (car indent-stack)			       (- (car indent-stack))))))		(setcar indent-stack			(setq this-indent val))))	    ;; Adjust line indentation according to its contents	    (if (or (= (following-char) ?})		    (looking-at "end\\b"))		(setq this-indent (- this-indent icon-indent-level)))	    (if (= (following-char) ?{)		(setq this-indent (+ this-indent icon-brace-offset)))	    ;; Put chosen indentation into effect.	    (or (= (current-column) this-indent)		(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))))))))))

⌨️ 快捷键说明

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