home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / modes / objective-C-mode.el < prev    next >
Encoding:
Text File  |  1992-06-23  |  43.8 KB  |  1,358 lines

  1. ;; objective-C-mode.el
  2. ;; -------------------
  3. ;;
  4. ;; LCD Archive Entry:
  5. ;; objective-C-mode|Kenneth Persson|benneth@eb.se|
  6. ;; Major mode for editing Objective-C programs.|
  7. ;; 91-11-28|3.02|~/modes/objective-C-mode.el.Z|
  8. ;;
  9. ;; Major mode for editing Objective-C programs.
  10. ;; The Objective-C-mode is an extension of the
  11. ;; default C-mode. Unfortunately there are many
  12. ;; hardcoded parts for EB SIGNAL use only. However
  13. ;; it can be changed.  (And has: changed for RDR
  14. ;; by Chris Walters.
  15. ;;
  16. ;; Author: Kenneth Persson (kenneth@eb.se)
  17. ;;         EB Signal AB, Stockholm, Sweden
  18. ;;
  19. ;; Modified by:
  20. ;;         Douglas Worthington,
  21. ;;         dougw@grebyn.com
  22. ;;
  23. ;; This is version 3.02.
  24. ;;
  25. ;; Put this in your .emacs file if its not in site-init.el:
  26. ;;
  27. ;; (autoload 'objective-C-mode "yourLispCodeDirectory/objective-C-mode"
  28. ;;           "Objective-C mode" t nil)
  29. ;; (setq auto-mode-alist
  30. ;;       (append '(("\\.h$" . objective-C-mode)
  31. ;;            ("\\.m$" . objective-C-mode))
  32. ;;           auto-mode-alist))
  33.  
  34. (provide 'objective-C-mode)
  35.  
  36. (defun objective-C-mode-version ()
  37.   "3.03a")
  38.  
  39. (defun echo-objective-C-mode-version ()
  40.   (interactive)
  41.   (message (concat "Version "
  42.            (objective-C-mode-version)
  43.            " of "
  44.            mode-name
  45.            " mode.")))
  46.  
  47. (defvar objective-C-interface-file-dir nil
  48.   "The directory where to put generated interface files")
  49.  
  50. (defvar objective-C-document-file-dir nil
  51.   "The directory where to put generated document files")
  52.  
  53. (defvar objective-C-mode-map nil
  54.   "*Keymap used in objective-C mode.")
  55. (if objective-C-mode-map
  56.     nil
  57.   (let ((map (make-sparse-keymap))) 
  58.     (define-key map "\C-cc"     'objective-C-mfile-header)
  59.     (define-key map "\C-ch"     'objective-C-hfile-header)   
  60.     (define-key map "\C-cp"     'objective-C-protocol)
  61.     (define-key map "\C-cf"     'objective-C-factory-method)
  62.     (define-key map "\C-cm"     'objective-C-instance-method)
  63.     (define-key map "\C-cl"     'objective-C-codelimit)
  64.     (define-key map "\C-c\C-m"  'objective-C-method-comment)
  65.     (define-key map "\C-c\C-cd" 'generate-Objective-C-documentation)
  66.     (define-key map "\C-c\C-ch" 'generate-Objective-C-hfile)   
  67.     (define-key map "\C-c?"     'describe-objective-C-mode)   
  68.     (define-key map "\C-ci"     'indent-region)
  69.     (define-key map "\C-ca"     'add-user-sign)
  70.     (define-key map "\C-cv"     'echo-objective-C-mode-version)
  71.     (define-key map "{"         'electric-objective-C-brace)
  72.     (define-key map "}"         'electric-objective-C-brace)
  73.     (define-key map ":"         'electric-objective-C-keyword-match)
  74.     (define-key map "\177"      'backward-delete-char-untabify)
  75.     (define-key map "\t"        'objective-C-indent-command)
  76.     (setq objective-C-mode-map map)))
  77.  
  78. (define-abbrev-table 'objective-C-mode-abbrev-table ())
  79. (defvar objective-C-mode-abbrev-table nil
  80.   "abbrevations to use in objective-c")
  81.  
  82. ;;      (append objective-C-mode-abbrev-table
  83. ;;          (list '("ryes" "return YES"      nil)
  84. ;;            '("ry"   "return YES"      nil)
  85. ;;            '("rno"  "return NO"       nil)
  86. ;;            '("rn"   "return NO"       nil)
  87. ;;            '("rs"   "return self"     nil)
  88. ;;            '("rnil" "return nil"      nil)
  89. ;;            '("imp"  "@implementation" nil)
  90. ;;            '("intf" "@interface"      nil)
  91. ;;            '("slef" "self"            nil)
  92. ;;            '("st"   "STR"             nil)
  93. ;;            '("bo"   "BOOL"            nil))))
  94.  
  95. (defvar objective-C-mode-syntax-table nil
  96.   "Syntax table in use in Objective-C-Mode buffers.")
  97. (if objective-C-mode-syntax-table
  98.     nil
  99.   (setq objective-C-mode-syntax-table (make-syntax-table))
  100.   (modify-syntax-entry ?\\ "\\" objective-C-mode-syntax-table)
  101.   (modify-syntax-entry ?/ ". 14" objective-C-mode-syntax-table)
  102.   (modify-syntax-entry ?* ". 23" objective-C-mode-syntax-table)
  103.   (modify-syntax-entry ?+ "." objective-C-mode-syntax-table)
  104.   (modify-syntax-entry ?- "." objective-C-mode-syntax-table)
  105.   (modify-syntax-entry ?= "." objective-C-mode-syntax-table)
  106.   (modify-syntax-entry ?% "." objective-C-mode-syntax-table)
  107.   (modify-syntax-entry ?< "." objective-C-mode-syntax-table)
  108.   (modify-syntax-entry ?> "." objective-C-mode-syntax-table)
  109.   (modify-syntax-entry ?& "." objective-C-mode-syntax-table)
  110.   (modify-syntax-entry ?| "." objective-C-mode-syntax-table)
  111.   (modify-syntax-entry ?\' "\"" objective-C-mode-syntax-table))
  112.  
  113. (defconst objective-C-indent-level 4
  114.   "*Indentation of C statements with respect to containing block.")
  115. (defconst objective-C-brace-imaginary-offset 0
  116.   "*Imagined indentation of a C open brace that actually follows a statement.")
  117. (defconst objective-C-brace-offset -4
  118.   "*Extra indentation for braces, compared with other text in same context.")
  119. (defconst objective-C-argdecl-indent 5
  120.   "*Indentation level of declarations of C function arguments.")
  121. (defconst objective-C-label-offset -4
  122.   "*Offset of C label lines and case statements relative to usual indentation.")
  123. (defconst objective-C-continued-statement-offset 4
  124.   "*Extra indent for lines not starting new statements.")
  125. (defconst objective-C-auto-newline nil
  126.   "*Non-nil means automatically newline before and after braces,
  127. and after colons and semicolons, inserted in C code.")
  128. (defconst objective-C-tab-always-indent t
  129.   "*Non-nil means TAB in C mode should always reindent the current line,
  130. regardless of where in the line point is when the TAB command is used.")
  131.  
  132. (defun objective-C-mode ()
  133.   "  A major mode for the Objective-C language.
  134. Commands:
  135.   Expression and list commands understand all Objective-C brackets.
  136.   Tab anywhere on a line indents it according to Objective-C
  137.   conventions. LF does a CR and then an indentation like above.
  138.   Comments are delimited with /* ... */ or // to cr.
  139.   Paragraphs are separated by blank lines only.
  140.   Delete converts tabs to spaces as it moves back.
  141. \\{objective-C-mode-map}
  142.  
  143. Variables controlling indentation style:
  144.   objective-C-indent-level
  145.     Indentation of C statements within surrounding block.
  146.     The surrounding block's indentation is the indentation
  147.     of the line on which the open-brace appears.
  148.  
  149. Variables controlling directories of generated files:
  150.     objective-C-interface-file-dir
  151.       If non nil generated interface files will be put into
  152.       this directory. The default is current directory.
  153.     objective-C-document-file-dir
  154.       If non nil generated dokument files will be put into
  155.       this directory. The default is current directory.
  156.  
  157. Skeletons of the major Objective-C constructs are inserted with:
  158.   C-c c class header    C-c m instanceMethod     C-c f factoryMethod
  159.   C-c p protocol        C-c l limiter            C-c h header in h file
  160.   C-c <RET> method comment
  161.  
  162. Other useful stuff
  163.   C-c ? Describe objective-C mode
  164.   C-c a Add signature to use in comments
  165.   C-c v Return the version of this mode
  166.   C-c C-c h Generate an interface file from the implementation file
  167.   C-c C-c d Generate an documentation file from the implementation file
  168.  
  169. Abbreviations:
  170.   ry   & ryes  = return YES
  171.   rn   & rno   = return NO
  172.   rs   & rself = return self
  173.   rnil         = return nil
  174.   imp          = @implementation
  175.   intf         = @interface
  176.   st           = STR
  177.   bo           = BOOL
  178.  
  179. Turning on Objective-C mode calls the value of the variable
  180. objective-C-mode-hook with abbrevs, if that value is non-nil."
  181.   (interactive)
  182.   (kill-all-local-variables)
  183.   (use-local-map objective-C-mode-map)
  184.   (setq major-mode 'objective-C-mode)
  185.   (setq mode-name "Objective-C")
  186.   (setq local-abbrev-table objective-C-mode-abbrev-table)
  187.   (set-syntax-table objective-C-mode-syntax-table)
  188.   (make-local-variable 'paragraph-start)
  189.   (setq paragraph-start (concat "^$\\|" page-delimiter))
  190.   (make-local-variable 'paragraph-separate)
  191.   (setq paragraph-separate paragraph-start)
  192.   (make-local-variable 'indent-line-function)
  193.   (setq indent-line-function 'objective-C-indent-line)
  194.   (make-local-variable 'require-final-newline)
  195.   (setq require-final-newline t)
  196.   (make-local-variable 'comment-start)
  197.   (setq comment-start "/* ")
  198.   (make-local-variable 'signatures)
  199.   (setq signatures nil)
  200.   (make-local-variable 'comment-end)
  201.   (setq comment-end " */")
  202.   (make-local-variable 'comment-column)
  203.   (setq comment-column 32)
  204.   (make-local-variable 'comment-start-skip)
  205.   (setq comment-start-skip "/\\*+ *")
  206.   (make-local-variable 'comment-indent-hook)
  207.   (setq comment-indent-hook 'objective-C-comment-indent)
  208.   (make-local-variable 'parse-sexp-ignore-comments)
  209.   (setq parse-sexp-ignore-comments t)
  210.   (setq objective-C-line-length 70)
  211.   (make-local-variable 'super-filename)
  212.   (setq super-filename nil)
  213.   (run-hooks 'objective-C-mode-hook))
  214.  
  215. ;; ------------------------ EB Stuff ---------------------------
  216.  
  217. ;;--------------- site-init.el --------------- START
  218. (defun eb-day (aString)
  219.   (let ((a
  220.      (car (cdr (assoc aString '((" 1"  "01")
  221.                     (" 2"  "02")
  222.                     (" 3"  "03")
  223.                     (" 4"  "04")
  224.                     (" 5"  "05")
  225.                     (" 6"  "06")
  226.                     (" 7"  "07")
  227.                     (" 8"  "08")
  228.                     (" 9"  "09")))))))
  229.     (if (null a) aString a)))
  230.  
  231. (defun eb-month (aString)
  232.   (let ((a
  233.      (car (cdr (assoc aString '(("JAN"  "01")
  234.                     ("FEB"  "02")
  235.                     ("MAR"  "03")
  236.                     ("APR"  "04")
  237.                     ("MAY"  "05")
  238.                     ("JUN"  "06")
  239.                     ("JUL"  "07")
  240.                     ("AUG"  "08")
  241.                     ("SEP"  "09")
  242.                     ("OCT"  "10")
  243.                     ("NOV"  "11")
  244.                     ("DEC"  "12")
  245.                     ))))))
  246.     (if (null a) aString a)))
  247.  
  248. (defun eb-date ()
  249.   "Return the current date in an EB Signal standard form"
  250.   (concat (substring (current-time-string) -4 nil)
  251.       "-"
  252.       (eb-month (substring (current-time-string) 4 7))
  253.       "-"
  254.       (eb-day (substring (current-time-string) 8 10))))
  255. ;;--------------- site-init.el --------------- END
  256.  
  257. ;; ------------------ File and Class name ------------------------
  258.  
  259. ;; return the type ".m" or ".h" kan be improved
  260. (defun file-type (&optional name)
  261.   (substring (if (null name) (m-filename) name) -2 nil))
  262.  
  263. (defun m-filename ()
  264.   (file-name-nondirectory (file-name-sans-versions buffer-file-name)))
  265.  
  266. (defun is-m-file (&optional name)
  267.   (string-equal ".m" (file-type name)))
  268.  
  269. (defun h-filename ()
  270.   (concat (substring (m-filename) 0 -2) ".h"))
  271.  
  272. (defun h-file-dir ()
  273.   (if (null objective-C-interface-file-dir)
  274.       ""
  275.     objective-C-interface-file-dir))
  276.  
  277. (defun is-h-file (&optional name)
  278.   (string-equal ".h" (file-type name)))
  279.  
  280. (defun doc-filename ()
  281.   (concat (substring (m-filename) 0 -2) ".txt"))
  282.  
  283. (defun doc-dir ()
  284.   (if (null objective-C-document-file-dir)
  285.       ""
  286.     objective-C-document-file-dir))
  287.  
  288. (defun class-from-filename (&optional name)
  289.   (substring (if (null name) (m-filename) name)
  290.          0 (string-match "\\.\\([0-9]*\\.\\)?\\(m\\|h\\|txt\\)"
  291.                  (if (null name) (m-filename) name))))
  292.  
  293. (defun number-from-filename (&optional name)
  294.   (let ((m-file (if (null name) (m-filename) name)))
  295.     (substring m-file
  296.            (string-match "\\([0-9]*\\)?\\.\\(m\\|h\\)" m-file)
  297.            (- (length m-file) 2))))
  298.  
  299. ;; Tested and used. Not a very goodlooking
  300. (defun super-class ()
  301.   (let* ((row (concat "@implementation "
  302.               (class-from-filename)
  303.               "\\( \\|\t\\|\n\\)*"
  304.               ":"
  305.               "\\( \\|\t\\|\n\\)*"))
  306.      (row2 (concat row "[a-zA-Z][a-zA-Z0-9$_]*"))
  307.      (a-list (list (string-match row (buffer-string))
  308.                (match-end 0)))
  309.      (b-list (list (string-match row2 (buffer-string))
  310.                (match-end 0))))
  311.     (cond ((null (car a-list)) nil)
  312.       ((null (car b-list)) nil)
  313.       (t (buffer-substring (1+ (cadr a-list))
  314.                    (1+ (cadr b-list)))))))
  315.  
  316. (defun super-class-number ()
  317.   (let ((sc (super-class))
  318.     (no nil))
  319.     (if (null sc) "NO_SUPER_CLASS_FOUND"
  320.       (setq no (read-string (concat "Class number for superclass "
  321.                     (super-class)
  322.                     ": ")))
  323.       (if (string-equal "" no) no
  324.     (concat "." no)))))
  325.  
  326. (defun super-hfilename (&optional number)
  327.   (let ((sc (super-class))
  328.     (no (if (null number) (super-class-number) number)))
  329.     (if (null sc) "NO_SUPER_CLASS_FOUND" (concat sc no ".h"))))
  330.  
  331. ;; ---------------------- AUX ------------------------
  332.  
  333. (defun user-sign ()
  334.   (car (cdr (assoc (user-login-name) signatures))))
  335.  
  336. (defun cadr (l)
  337.   (car (cdr l)))
  338.  
  339. (defun odd (e)
  340.   "True if it's argument is odd."
  341.   (eq (% e 2) 1))
  342.  
  343. (defun e-empty-line-p ()
  344.   "True if current line is empty."
  345.   (save-excursion
  346.     (beginning-of-line)
  347.     (looking-at "^[ \\t]*$")))
  348.  
  349. (defun insert-right (name diff &optional c)
  350.   (let* ((u  (- objective-C-line-length (length name) diff))
  351.      (fillChar (if (char-or-string-p c) c (string-to-char " "))))
  352.     (insert-char fillChar u)
  353.     (insert name)))
  354.  
  355. (defun insert-centered (name diff &optional c)
  356.   "Inserts the name centered in the Objective-C environment
  357. diff is a number that tells how many positions that already
  358. are used on the line (/*     */ = 4) and the optional c
  359. character is used to fill white space with."
  360.   (let* ((toshare  (- objective-C-line-length (length name) diff))
  361.      (u        (/ toshare 2))
  362.      (fillChar (if (char-or-string-p c) c (string-to-char " "))))
  363.     (insert-char fillChar u)
  364.     (insert name)
  365.     (insert-char fillChar (if (odd toshare) (1+ u) u))))
  366.  
  367. (defun add-user-sign ()
  368.   (interactive)
  369.   (let* ((name (user-login-name))
  370.      (sign (read-string (concat "Signature for " name ": "))))
  371.     (setq signatures (cons (list name sign) signatures))))
  372.  
  373. (defun classes-used ()
  374.   "Extract the used classes from the file"
  375.   (save-excursion
  376.     (let ((aString ""))
  377.       (beginning-of-buffer)
  378.       (re-search-forward "Classes used")
  379.       (forward-line 1)
  380.       (while (e-empty-line-p)
  381.     (forward-line 1))
  382.       (beginning-of-line)
  383.       (while (and
  384.           (not (eobp))
  385.           (not (e-empty-line-p))
  386.           (looking-at "#import"))
  387.     (setq aString (concat aString (grep-class-from-line) " "))
  388.     (forward-line 1)
  389.     (beginning-of-line))
  390.       aString)))
  391.  
  392. (defun beginning-of-line-point (&optional aBool)
  393.   (save-excursion
  394.     (beginning-of-line)
  395.     (cond (aBool (skip-chars-forward " \t*/")))
  396.     (point)))
  397.  
  398. (defun end-of-line-point (&optional aBool)
  399.   (save-excursion
  400.     (end-of-line)
  401.     (cond (aBool (skip-chars-backward " \t*/")))
  402.     (point)))
  403.  
  404. (defun grep-class-from-line ()
  405.   (let ((bp (beginning-of-line-point))
  406.     (ep (end-of-line-point)))
  407.     (buffer-substring (+ bp 9) (- ep 3))))
  408.  
  409. (defun start-of-instance-point ()
  410.   (save-excursion
  411.     (beginning-of-buffer)
  412.     (search-forward "@implementation")
  413.     (forward-line 1)
  414.     (while (or (e-empty-line-p)
  415.            (looking-at "{"))
  416.       (forward-line 1)
  417.       (beginning-of-line))
  418.     (point)))
  419.  
  420. (defun end-of-instance-point ()
  421.   (save-excursion
  422.     (beginning-of-buffer)
  423.     (search-forward "@implementation")
  424.     (search-forward "}")
  425.     (forward-line -1)
  426.     (while (e-empty-line-p)
  427.       (forward-line -1))
  428.     (end-of-line)
  429.     (point)))
  430.  
  431. (defun have-instance-variables ()
  432.   (save-excursion
  433.     (beginning-of-buffer)
  434.     (search-forward "@implementation")
  435.     (forward-line 1)
  436.     (while (e-empty-line-p)      
  437.       (forward-line 1))
  438.     (skip-chars-forward " \t")
  439.     (looking-at "{")))
  440.  
  441. (defun instance-variables ()
  442.   (cond ((have-instance-variables)
  443.      (buffer-substring (start-of-instance-point)
  444.                (end-of-instance-point)))
  445.     (t "\t // none")))
  446.  
  447. (defun start-of-intro-point ()
  448.   (save-excursion
  449.     (beginning-of-buffer)
  450.     (cond ((null (search-forward "Introduction"
  451.                  (start-of-instance-point)
  452.                  t))
  453.        1)
  454.       (t (forward-line 1)
  455.          (while (e-empty-line-p)
  456.            (forward-line 1))
  457.          (beginning-of-line)
  458.          (point)))))
  459.  
  460. (defun end-of-intro-point ()
  461.   (save-excursion
  462.     (beginning-of-buffer)
  463.     (cond ((null (search-forward "Revision History"
  464.                  (start-of-instance-point)
  465.                  t))
  466.        1)
  467.       (t (forward-line -1)
  468.          (while (e-empty-line-p)
  469.            (forward-line -1))
  470.          (end-of-line)
  471.          (point)))))
  472.  
  473. (defun class-intro ()
  474.   (let ((si (start-of-intro-point))
  475.     (ei (end-of-intro-point)))
  476.     (if (or (= si ei) (= si 1) (= ei 1))
  477.     "\tCan't extract the class description since the strings\n\tIntroduction and/or Revision History are missing in the source code."
  478.       (buffer-substring si ei))))
  479.  
  480. (defun find-next-protocol-or-method ()
  481.   (beginning-of-line)
  482.   (while (and (not (eobp))
  483.           (not (looking-at "/\\*====="))
  484.           (not (looking-at "+[a-zA-Z( ]"))
  485.           (not (looking-at "-[a-zA-Z( ]")))
  486.     (forward-line 1)
  487.     (beginning-of-line))
  488.   (cond ((looking-at "/\\*=====")
  489.      (forward-line 1)
  490.      (beginning-of-line)))
  491.   (not (eobp)))
  492.  
  493. (defun line-is-method ()
  494.   (save-excursion
  495.     (beginning-of-line)
  496.     (or (looking-at "+[a-zA-Z( ]")
  497.     (looking-at "-[a-zA-Z( ]"))))
  498.  
  499. (defun line-is-protocol ()
  500.   (save-excursion
  501.     (forward-line -1)
  502.     (beginning-of-line)
  503.     (looking-at "/\\*=====")))
  504.  
  505. (defun is-gps-comment ()
  506.   (save-excursion
  507.     (let ((ordinary (is-ordinary-comment)))
  508.       (beginning-of-line)
  509.       (and (looking-at "---------") ordinary))))
  510.  
  511. (defun is-ordinary-comment ()
  512.   (save-excursion
  513.     (and (char-equal ?* (char-after (- (point) 2)))
  514.      (char-equal ?/ (char-after (- (point) 1)))
  515.      (not (char-equal ?= (char-after (beginning-of-line-point)))))))
  516.  
  517. (defun is-date-entry ()
  518.   (< 50 (- (beginning-of-line-point t) (beginning-of-line-point))))
  519.  
  520. (defun is-method-name-entry ()
  521.   (and (char-equal ?| (char-after (beginning-of-line-point t)))
  522.        (char-equal ?| (char-after (- (end-of-line-point t) 1)))))
  523.  
  524. (defun is-empty-line-info ()
  525.   (string-equal "" (buffer-substring (beginning-of-line-point t)
  526.                      (end-of-line-point))))
  527.  
  528. (defun is-not-crap-line ()
  529.     (and (not (is-date-entry))
  530.      (not (is-method-name-entry))
  531.      (not (is-empty-line-info))))
  532.  
  533. (defun look-for-comment-at-previous-line ()
  534.   (save-excursion
  535.     (forward-line -1)
  536.     (beginning-of-line)
  537.     (skip-chars-forward "\t ")
  538.     (and (char-equal ?/ (char-after (point)))
  539.      (char-equal ?* (char-after (+ (point) 1))))))
  540.  
  541. (defun is-still-comment ()
  542.   (save-excursion
  543.     (beginning-of-line)
  544.     (skip-chars-forward "\t ")
  545.     (if (and (char-equal ?/ (char-after (point)))
  546.          (char-equal ?* (char-after (+ (point) 1))))
  547.     (look-for-comment-at-previous-line)
  548.       t)))
  549.  
  550. (defun is-objc-comment ()
  551.   (save-excursion
  552.     (beginning-of-line)
  553.     (looking-at "//")))
  554.  
  555. (defun gps-comment ()
  556.   (ordinary-comment))
  557.  
  558. (defun ordinary-comment ()
  559.   (let ((aStr ""))
  560.     (forward-line -1)
  561.     (while (is-still-comment)
  562.       (beginning-of-line)
  563.       (skip-chars-forward " \t*/")
  564.       (cond ((is-not-crap-line)
  565.          (setq aStr
  566.            (concat (buffer-substring (point) (end-of-line-point t))
  567.                "\n"
  568.                aStr))))
  569.       (forward-line -1))
  570.     aStr))
  571.  
  572. (defun objc-comment ()
  573.   (let ((aStr ""))
  574.     (while (is-objc-comment)
  575.       (beginning-of-line)
  576.       (skip-chars-forward "/ ")
  577.       (cond ((is-not-crap-line)
  578.          (setq aStr
  579.            (concat (buffer-substring (point) (end-of-line-point t))
  580.                "\n"
  581.                aStr))))
  582.       (forward-line -1))
  583.     aStr))
  584.  
  585. (defun no-comment ()
  586.   "This method has not been documented in the source code.")
  587.  
  588. (defun line-as-doc-file-delimiter ()
  589.   (save-excursion
  590.     (beginning-of-line)
  591.     (skip-chars-forward " \t")
  592.     (setq start (point))
  593.     (end-of-line)
  594.     (skip-chars-backward " \t")
  595.     (concat "\n" (buffer-substring start (point)) "\n")))
  596.  
  597. (defun line-as-inteface-file-delimiter ()
  598.   (save-excursion
  599.     (beginning-of-line)
  600.     (skip-chars-forward " \t")
  601.     (setq start (point))
  602.     (end-of-line)
  603.     (skip-chars-backward " \t")
  604.     (setq name     (buffer-substring start (point)))
  605.     (setq toshare  (- objective-C-line-length (length name) 8))
  606.     (concat "\n/* "
  607.         (make-string (/ toshare 2) ?-)
  608.         " "
  609.         (buffer-substring start (point))
  610.         " "
  611.         (make-string (if (odd toshare)
  612.                  (+ (/ toshare 2) 1)
  613.                (/ toshare 2))
  614.              ?-)
  615.         " */")))
  616.  
  617. (defun skip-comment (str)
  618.   (let ((p (string-match "//" str)))
  619.     (cond ((null p) str)
  620.       (t (substring str 0 p)))))
  621.  
  622. (defun line-as-inteface-file-method ()
  623.   (save-excursion
  624.     (beginning-of-line)
  625.     (skip-chars-forward " \t")
  626.     (setq start (point))
  627.     (re-search-forward "{")
  628.     (backward-char 1)
  629.     (skip-chars-backward " \t\n")
  630.     (concat (skip-comment (buffer-substring start (point))) ";")))
  631.  
  632. (defun extract-method-comment ()
  633.   (forward-line -1)
  634.   (while (e-empty-line-p)
  635.     (forward-line -1))
  636.   (end-of-line)
  637.   (skip-chars-backward " \t")
  638.   (cond ((is-gps-comment)      (gps-comment))
  639.     ((is-ordinary-comment) (ordinary-comment))
  640.     ((is-objc-comment)     (objc-comment))
  641.     (t                     (no-comment))))
  642.  
  643. (defun method-description (method-name start-point)
  644.   (save-excursion
  645.     (goto-char start-point)
  646.     (concat method-name "\n" (extract-method-comment))))
  647.  
  648. (defun line-as-doc-file-method ()
  649.   (save-excursion
  650.     (beginning-of-line)
  651.     (skip-chars-forward " \t")
  652.     (setq start (point))
  653.     (re-search-forward "{")
  654.     (backward-char 1)
  655.     (skip-chars-backward " \t\n")
  656.     (method-description
  657.      (concat "|" (buffer-substring start (point)) "|") start)))
  658.  
  659. (defun class-as-short ()
  660.   (save-excursion
  661.     (let ((aString ""))
  662.       (beginning-of-buffer)
  663.       (re-search-forward "@implementation")
  664.       (while (and (not (eobp)) (find-next-protocol-or-method))
  665.     (setq aString
  666.           (concat
  667.            aString
  668.            (cond ((line-is-protocol) (line-as-doc-file-delimiter))
  669.              ((line-is-method)   (line-as-doc-file-method))
  670.              (t ""))
  671.            "\n"))
  672.     (forward-line))
  673.       aString)))
  674.  
  675. (defun class-as-short-no-comments ()
  676.   (save-excursion
  677.     (let ((aString ""))
  678.       (beginning-of-buffer)
  679.       (re-search-forward "@implementation")
  680.       (while (and (not (eobp)) (find-next-protocol-or-method))
  681.     (setq aString
  682.           (concat
  683.            aString
  684.            (cond ((line-is-protocol) (line-as-inteface-file-delimiter))
  685.              ((line-is-method)   (line-as-inteface-file-method))
  686.              (t ""))
  687.            "\n"))
  688.     (forward-line))
  689.       aString)))
  690.  
  691. ;; ------------------ Objective-C mode -------------------
  692.  
  693. (defun describe-objective-C-mode ()
  694.   (interactive)
  695.   (describe-mode))
  696.  
  697. (defun objective-C-mfile-header ()
  698.   "Build a class skeleton prompting for class name."
  699.   (interactive)
  700.   (if (not (is-m-file))
  701.       (message "This is not an implementation file (.m)!")
  702.     (let* ((file  (m-filename))
  703.        (class (class-from-filename))
  704.        (nr    (number-from-filename))
  705.        (cname (read-string "Class: " class))
  706.        (super (read-string "Super: ")))
  707.       (if (not (e-empty-line-p))
  708.       (progn (end-of-line)(newline)))
  709.       (indent-to 0)                
  710.       (insert "/* ")
  711.       (insert-char ?- (- objective-C-line-length 3))
  712.       (insert "\n\n")
  713.       (insert "\tRDR, Inc. \n\n")
  714.       (insert "\tObjective-C source file for the class " cname "\n\n")
  715.       (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  716.           ", RDR, Inc.\n")
  717.       (insert "\tALL RIGHTS RESERVED.\n\n")
  718.       (insert "\tResponsible:\t\t\tApproved:\n")
  719.       (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  720.       (insert "\tDate:\t\t\t\tRev:\n")
  721.       (insert "\t" (eb-date)    "\t\t\t___\n\n")
  722. ;      (insert "\tReference:\t\t\tDocument no:\n")
  723. ;      (insert "\tLXA 108 104\t\t\t1/190 55 - CAL 124 1"
  724. ;          (if (string-equal "" nr) "***" nr) "\n\n\n\n\n")
  725.       (insert-centered cname 0)
  726.       (insert "\n\n")
  727.       (insert "\t1. Introduction")
  728.       (insert "\n\n\n")
  729.       (insert "\t2. Revision History")
  730.       (insert "\n\n")
  731.       (insert "\t___\tThe starting point.\t\t\t"
  732.           (user-full-name) "/" (eb-date) "\n\n\n")
  733.       (insert "\t3. Source Code")
  734.       (insert "\n\n")
  735.       (insert-char ?- (- objective-C-line-length 3))
  736.       (insert " */\n\n")
  737.       (comment-line "Import files")
  738.       (insert "#import <appkit/appkit.h>\n\n")
  739.       (comment-line " Classes used ")
  740.       (insert "#import \"foo.h\"\n\n")
  741.       (comment-line " Externals ")
  742.       (insert "\n\n")
  743.       (comment-line " Defines ")
  744.       (insert "\n\n")
  745.       (comment-line " Class variables ")
  746.       (insert "\n\n")
  747.       (comment-box (concat "Implementation of class " cname))
  748.       (insert "#import \"" (concat (substring file 0 -1) "h") "\"\n\n")
  749.       (insert "@implementation " cname " : " super"\n{\n\n}\n\n")
  750.       (comment-box "Instance Creation")
  751.       (insert "\n\n")
  752.       (comment-box "Initialize")
  753.       (insert "\n\n")
  754.       (comment-box "Free")
  755.       (insert "\n\n")
  756.       (insert "@end\n"))
  757.     (re-search-backward "@implementation")
  758.     (next-line 2)
  759.     (objective-C-indent-line)))
  760.  
  761. (defun objective-C-hfile-header (&optional classname super-filename)
  762.   "Gives an interface file sceleton."
  763.   (interactive)
  764.   (if (not (is-h-file))
  765.       (message "This is not an interface file (.h)!")
  766.     (let* ((class (if (null classname) (class-from-filename) classname))
  767.        (cname (read-string "Class: " class))
  768.        (nr    (number-from-filename))
  769.        (super (if (null super-filename)
  770.               (concat (read-string "Super: ") ".h")
  771.             super-filename)))
  772.       (insert "/* ")
  773.       (insert-char ?- (- objective-C-line-length 3))
  774.       (insert "\n\n")
  775.       (insert "\tRDR, Inc. \n\n")
  776.       (insert "\tObjective-C interface file for the class " cname "\n\n")
  777.       (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  778.           ", RDR, Inc.\n")
  779.       (insert "\tALL RIGHTS RESERVED.\n\n")
  780.       (insert "\tResponsible:\t\t\tApproved:\n")
  781.       (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  782.       (insert "\tDate:\t\t\t\tRev:\n")
  783.       (insert "\t" (eb-date)    "\t\t\t___\n\n")
  784.       (insert "\tReference:\t\t\tDocument no:\n")
  785. ;      (insert "\tLXA 108 104\t\t\t2/190 55 - CAL 124 1"
  786. ;          (if (string-equal "" nr) "***" nr) "\n\n")
  787. ;      (insert-char ?- (- objective-C-line-length 3))
  788.       (insert " */\n\n")
  789.       (comment-box (concat "Interface of class " cname))
  790.       (insert "#import \"" super "\"\n\n")
  791.       (insert "@interface " cname " : " (class-from-filename super)
  792.           "\n{\n\n}\n\n")
  793.       (insert "@end\n"))
  794.     (re-search-backward "@interface")
  795.     (next-line 2)
  796.     (objective-C-indent-line)))
  797.  
  798. (defun generate-Objective-C-hfile ()
  799.   "Generate the interface file for the current implementation file."
  800.   (interactive)
  801.   (let* ((file-name (read-string "Interface file name: "
  802.                  (concat (h-file-dir) (h-filename))))
  803.      (buf       (create-file-buffer file-name))
  804.      (class     (class-from-filename))
  805.      (no        (number-from-filename))
  806.      (instance  (instance-variables))
  807.      (short     (class-as-short-no-comments))
  808.      (super     (super-hfilename)))
  809.     (set-buffer buf)
  810.     (set-visited-file-name file-name)
  811.     (insert "/* ")
  812.     (insert-char ?- (- objective-C-line-length 3))
  813.     (insert "\n\n")
  814.     (insert "\tRDR, Inc. \n\n")
  815.     (insert "\tObjective-C interface file for the class " class "\n\n")
  816.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  817.         ", RDR, Inc.\n")
  818.     (insert "\tALL RIGHTS RESERVED.\n\n")
  819.     (insert "\tResponsible:\t\t\tApproved:\n")
  820.     (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  821.     (insert "\tDate:\t\t\t\tRev:\n")
  822.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  823.     (insert "\tReference:\t\t\tDocument no:\n")
  824. ;    (insert "\tLXA 108 104\t\t\t2/190 55 - CAL 124 1"
  825. ;        (if (string-equal "" no) "***" no) "\n\n")
  826. ;    (insert-char ?- (- objective-C-line-length 3))
  827.     (insert " */\n\n")
  828.     (comment-box (concat "Interface of class " class))
  829.     (insert "#import \"" super "\"\n\n")
  830.     (insert "@interface " class " : " (class-from-filename super) "\n{\n")
  831.     (insert instance)
  832.     (insert "\n}\n")
  833.     (insert short)
  834.     (insert "\n@end\n")
  835.     (beginning-of-buffer)
  836.     (display-buffer buf)))
  837.  
  838. (defun generate-Objective-C-documentation ()
  839.   "Open a new buffer and write the documentation there."
  840.   (interactive)
  841.   (let* ((file-name (read-string "Documentation file name: "
  842.                  (concat (doc-dir) (doc-filename))))
  843.      (buf       (create-file-buffer file-name))
  844.      (used      (classes-used))
  845.      (class     (class-from-filename))
  846.      (super     (super-class))
  847.      (no        (number-from-filename))
  848.      (instance  (instance-variables))
  849.      (short     (class-as-short))
  850.      (intro     (class-intro)))
  851.     (set-buffer buf)
  852.     (set-visited-file-name file-name)
  853.     (indent-to 0)                
  854.     (insert-char ?- objective-C-line-length)
  855.     (insert "\n\n")
  856.     (insert "\tRDR, Inc. \n\n")
  857.     (insert "\tObjective-C documentation file for the class "
  858.         class "\n")
  859.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  860.         ", RDR, Inc.\n\n")
  861.     (insert "\tResponsible:\t\t\tApproved:\n")
  862.     (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  863.     (insert "\tDate:\t\t\t\tRev:\n")
  864.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  865.     (insert "\tReference:\t\t\tDocument no:\n")
  866. ;    (insert "\tLXA 108 104\t\t\t1551 - CAL 124 1"
  867. ;            (if (string-equal "" no)
  868. ;        "***"
  869. ;          no) "\n\n")
  870. ;    (insert-char ?- objective-C-line-length)
  871.     (insert "\n\n\n")
  872.     (insert-centered class 0)
  873.     (insert "\n\n\n\tInherits from:\t\t" super "\n\n")
  874.     (insert "\tClasses used:\t\t" used "\n\n")
  875.     (insert "\tInterface file:\t\t" class "." no ".h" "\n\n")
  876.     (insert "\tImplementation file:\t" class "." no ".m" "\n\n\n")
  877.     (insert-centered "Introduction" 0)
  878.     (insert "\n\n")
  879.     (insert intro)
  880.     (insert "\n\n")
  881.     (insert-centered "Instance Variables" 0)
  882.     (insert "\n\n")
  883.     (insert instance)
  884.     (insert "\n\n")
  885.     (insert-centered "Methods" 0)
  886.     (insert "\n")
  887.     (insert short)   
  888.     (insert "\nEnd\n")
  889.     (beginning-of-buffer)
  890.     (display-buffer buf)))
  891.  
  892. (defun comment-box (name)
  893.   "Print name in an comment-box"
  894.   (if (not (e-empty-line-p))
  895.       (progn (end-of-line)(newline)))
  896.   (insert "/*")
  897.   (insert-centered "" 2 ?=)
  898.   (insert "\n")
  899.   (insert-centered name 0 (string-to-char " "))
  900.   (insert "\n")
  901.   (insert-centered "" 2 ?=)
  902.   (insert "*/\n"))
  903.  
  904. (defun comment-line (name)
  905.   "Print name in an comment-line"
  906.   (if (not (e-empty-line-p))
  907.       (progn (end-of-line)(newline)))
  908.   (insert "/* ")
  909.   (insert-centered (concat " " name " ") 6 ?-)
  910.   (insert " */\n"))
  911.  
  912. (defun objective-C-protocol ()
  913.   "Build a protocol skeleton prompting for protocol name."
  914.   (interactive)
  915.   (comment-box (read-string "Protocol name: ")))
  916.  
  917. (defun objective-C-codelimit ()
  918.   "Print name on a centered line."
  919.   (interactive)
  920.   (comment-line (read-string "Centered text: ")))
  921.  
  922. (defun objective-C-method (prefix name)
  923.   (indent-to 0)                
  924.   (insert "/*")
  925.   (insert-centered "" 2 ?-)
  926.   (insert "\n")
  927.   (insert "|" prefix name "| \n" (if (string-equal "-" prefix)
  928.                      "Return self.\n"
  929.                    "\n"))
  930.   (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  931.   (insert "\n")
  932.   (insert-centered "" 2 ?-)
  933.   (insert "*/\n")
  934.   (insert prefix name "\n")
  935.   (insert "{\n")
  936.   (indent-to objective-C-indent-level)
  937.   (if (string-equal "+" prefix)
  938.       (insert "self = [super new];\n")
  939.     (insert "\n"))
  940.   (indent-to objective-C-indent-level)
  941.   (insert "return self;\n")
  942.   (insert "}\n\n")
  943.   (next-line -4))
  944.  
  945. (defun objective-C-method-comment ()
  946.   "Insert a comment according to the style used with methods in GPS"
  947.   (interactive)
  948.   (indent-to 0)                
  949.   (insert "/*")
  950.   (insert-centered "" 2 ?-)
  951.   (insert "\n\n\n")
  952.   (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  953.   (insert "\n")
  954.   (insert-centered "" 2 ?-)
  955.   (insert "*/\n"))
  956.  
  957. (defun objective-C-instance-method ()
  958.   "Build a routine skeleton prompting for method name."
  959.   (interactive)
  960.   (if (not (e-empty-line-p))
  961.       (progn (end-of-line)(newline)))
  962.   (objective-C-method "-" (read-string "Instance method name: ")))
  963.  
  964. (defun objective-C-factory-method ()
  965.   "Build a routine skeleton prompting for method name."
  966.   (interactive)
  967.   (if (not (e-empty-line-p))
  968.       (progn (end-of-line)(newline)))
  969.   (objective-C-method "+" (read-string "Factory method name: ")))
  970.  
  971. ;; ------------------ C- mode fix ---------------------
  972.  
  973. ;; This is used by indent-for-comment
  974. ;; to decide how much to indent a comment in C code
  975. ;; based on its context.
  976. (defun objective-C-comment-indent ()
  977.   (if (looking-at "^/\\*")
  978.       0                ;Existing comment at bol stays there.
  979.     (save-excursion
  980.       (skip-chars-backward " \t")
  981.       (max (1+ (current-column))    ;Else indent at comment column
  982.        comment-column))))    ; except leave at least one space.
  983.  
  984. ;; implement this function later
  985. (defun electric-objective-C-keyword-match ()
  986.   "Match two following lines with keyword arguments"
  987.   (interactive)
  988.   (insert ":"))
  989.  
  990. (defun electric-objective-C-brace (arg)
  991.   "Insert character and correct line's indentation."
  992.   (interactive "P")
  993.   (let (insertpos)
  994.     (if (and (not arg)
  995.          (eolp)
  996.          (or (save-excursion
  997.            (skip-chars-backward " \t")
  998.            (bolp))
  999.          (if objective-C-auto-newline
  1000.              (progn (objective-C-indent-line) (newline) t) nil)))
  1001.     (progn
  1002.       (insert last-command-char)
  1003.       (objective-C-indent-line)
  1004.       (if objective-C-auto-newline
  1005.           (progn
  1006.         (setq insertpos (1- (point)))
  1007.         (newline)
  1008.         (objective-C-indent-line)))
  1009.       (save-excursion
  1010.         (if insertpos (goto-char (1+ insertpos)))
  1011.         (delete-char -1))))
  1012.     (if insertpos
  1013.     (save-excursion
  1014.       (goto-char insertpos)
  1015.       (self-insert-command (prefix-numeric-value arg)))
  1016.       (self-insert-command (prefix-numeric-value arg)))))
  1017.  
  1018. (defun electric-objective-C-semi (arg)
  1019.   "Insert character and correct line's indentation."
  1020.   (interactive "P")
  1021.   (if objective-C-auto-newline
  1022.       (electric-objective-C-terminator arg)
  1023.     (self-insert-command (prefix-numeric-value arg))))
  1024.  
  1025. (defun electric-objective-C-terminator (arg)
  1026.   "Insert character and correct line's indentation."
  1027.   (interactive "P")
  1028.   (let (insertpos (end (point)))
  1029.     (if (and (not arg) (eolp)
  1030.          (not (save-excursion
  1031.             (beginning-of-line)
  1032.             (skip-chars-forward " \t")
  1033.             (or (= (following-char) ?#)
  1034.             ;; Colon is special only after a label, or case ....
  1035.             ;; So quickly rule out most other uses of colon
  1036.             ;; and do no indentation for them.
  1037.             (and (eq last-command-char ?:)
  1038.                  (not (looking-at "case"))
  1039.                  (save-excursion
  1040.                    (forward-word 2)
  1041.                    (<= (point) end)))
  1042.             (progn
  1043.               (beginning-of-defun)
  1044.               (let ((pps (parse-partial-sexp (point) end)))
  1045.                 (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
  1046.     (progn
  1047.       (insert last-command-char)
  1048.       (objective-C-indent-line)
  1049.       (and objective-C-auto-newline
  1050.            (not (objective-C-inside-parens-p))
  1051.            (progn
  1052.          (setq insertpos (1- (point)))
  1053.          (newline)
  1054.          (objective-C-indent-line)))
  1055.       (save-excursion
  1056.         (if insertpos (goto-char (1+ insertpos)))
  1057.         (delete-char -1))))
  1058.     (if insertpos
  1059.     (save-excursion
  1060.       (goto-char insertpos)
  1061.       (self-insert-command (prefix-numeric-value arg)))
  1062.       (self-insert-command (prefix-numeric-value arg)))))
  1063.  
  1064. (defun objective-C-inside-parens-p ()
  1065.   (condition-case ()
  1066.       (save-excursion
  1067.     (save-restriction
  1068.       (narrow-to-region (point)
  1069.                 (progn (beginning-of-defun) (point)))
  1070.       (goto-char (point-max))
  1071.       (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
  1072.     (error nil)))
  1073.  
  1074. (defun objective-C-indent-command (&optional whole-exp)
  1075.   (interactive "P")
  1076.   "Indent current line as C code, or in some cases insert a tab character.
  1077. If objective-C-tab-always-indent is non-nil (the default), always indent current line.
  1078. Otherwise, indent the current line only if point is at the left margin
  1079. or in the line's indentation; otherwise insert a tab.
  1080.  
  1081. A numeric argument, regardless of its value,
  1082. means indent rigidly all the lines of the expression starting after point
  1083. so that this line becomes properly indented.
  1084. The relative indentation among the lines of the expression are preserved."
  1085.   (if whole-exp
  1086.       ;; If arg, always indent this line as C
  1087.       ;; and shift remaining lines of expression the same amount.
  1088.       (let ((shift-amt (objective-C-indent-line))
  1089.         beg end)
  1090.     (save-excursion
  1091.       (if objective-C-tab-always-indent
  1092.           (beginning-of-line))
  1093.       (setq beg (point))
  1094.       (forward-sexp 1)
  1095.       (setq end (point))
  1096.       (goto-char beg)
  1097.       (forward-line 1)
  1098.       (setq beg (point)))
  1099.     (if (> end beg)
  1100.         (indent-code-rigidly beg end shift-amt "#")))
  1101.     (if (and (not objective-C-tab-always-indent)
  1102.          (save-excursion
  1103.            (skip-chars-backward " \t")
  1104.            (not (bolp))))
  1105.     (insert-tab)
  1106.       (objective-C-indent-line))))
  1107.  
  1108. (defun objective-C-indent-line ()
  1109.   "Indent current line as C code.
  1110. Return the amount the indentation changed by."
  1111.   (let ((indent (calculate-objective-C-indent nil))
  1112.     beg shift-amt
  1113.     (case-fold-search nil)
  1114.     (pos (- (point-max) (point))))
  1115.     (beginning-of-line)
  1116.     (setq beg (point))
  1117.     (cond ((eq indent nil)
  1118.        (setq indent (current-indentation)))
  1119.       ((eq indent t)
  1120.        (setq indent (calculate-objective-C-indent-within-comment)))
  1121.       ((looking-at "[ \t]*#")
  1122.        (setq indent 0))
  1123.       (t
  1124.        (skip-chars-forward " \t")
  1125.        (if (listp indent) (setq indent (car indent)))
  1126.        (cond ((or (looking-at "case\\b")
  1127.               (and (looking-at "[A-Za-z]")
  1128.                (save-excursion
  1129.                  (forward-sexp 1)
  1130.                  (looking-at ":"))))
  1131.           (setq indent (max 1 (+ indent objective-C-label-offset))))
  1132.          ((and (looking-at "else\\b")
  1133.                (not (looking-at "else\\s_")))
  1134.           (setq indent (save-excursion
  1135.                  (objective-C-backward-to-start-of-if)
  1136.                  (current-indentation))))
  1137.          ((= (following-char) ?})
  1138.           (setq indent (- indent objective-C-indent-level)))
  1139.          ((= (following-char) ?{)
  1140.           (setq indent (+ indent objective-C-brace-offset))))))
  1141.     (skip-chars-forward " \t")
  1142.     (setq shift-amt (- indent (current-column)))
  1143.     (if (zerop shift-amt)
  1144.     (if (> (- (point-max) pos) (point))
  1145.         (goto-char (- (point-max) pos)))
  1146.       (delete-region beg (point))
  1147.       (indent-to indent)
  1148.       ;; If initial point was within line's indentation,
  1149.       ;; position after the indentation.  Else stay at same point in text.
  1150.       (if (> (- (point-max) pos) (point))
  1151.       (goto-char (- (point-max) pos))))
  1152.     shift-amt))
  1153.  
  1154. (defun calculate-objective-C-indent (&optional parse-start)
  1155.   "Return appropriate indentation for current line as C code.
  1156. In usual case returns an integer: the column to indent to.
  1157. Returns nil if line starts inside a string, t if in a comment."
  1158.   (save-excursion
  1159.     (beginning-of-line)
  1160.     (let ((indent-point (point))
  1161.       (case-fold-search nil)
  1162.       state
  1163.       containing-sexp)
  1164.       (if parse-start
  1165.       (goto-char parse-start)
  1166.     (beginning-of-defun))
  1167.       (while (< (point) indent-point)
  1168.     (setq parse-start (point))
  1169.     (setq state (parse-partial-sexp (point) indent-point 0))
  1170.     (setq containing-sexp (car (cdr state))))
  1171.       (cond ((or (nth 3 state) (nth 4 state))
  1172.          ;; return nil or t if should not change this line
  1173.          (nth 4 state))
  1174.         ((null containing-sexp)
  1175.          ;; Line is at top level.  May be data or function definition,
  1176.          ;; or may be function argument declaration.
  1177.          ;; Indent like the previous top level line
  1178.          ;; unless that ends in a closeparen without semicolon,
  1179.          ;; in which case this line is the first argument decl.
  1180.          (goto-char indent-point)
  1181.          (skip-chars-forward " \t")
  1182.          (if (= (following-char) ?{)
  1183.          0   ; Unless it starts a function body
  1184.            (objective-C-backward-to-noncomment (or parse-start (point-min)))
  1185.            ;; Look at previous line that's at column 0
  1186.            ;; to determine whether we are in top-level decls
  1187.            ;; or function's arg decls.  Set basic-indent accordinglu.
  1188.            (let ((basic-indent
  1189.               (save-excursion
  1190.             (re-search-backward "^[^ \^L\t\n#]" nil 'move)
  1191.             (if (and (looking-at "\\sw\\|\\s_")
  1192.                  (looking-at ".*(")
  1193.                  (progn
  1194.                    (goto-char (1- (match-end 0)))
  1195.                    (forward-sexp 1)
  1196.                    (and (< (point) indent-point)
  1197.                     (not (memq (following-char)
  1198.                            '(?\, ?\;))))))
  1199.                 objective-C-argdecl-indent 0))))
  1200.         
  1201.            ;; Now add a little if this is a continuation line.
  1202.            (+ basic-indent
  1203.             (if    (or (bobp)
  1204.                 (memq (preceding-char) '(?\) ?\; ?\})))
  1205.             0 0)))))
  1206.           ((/= (char-after containing-sexp) ?{)
  1207.            ;; line is expression, not statement:
  1208.            ;; indent to just after the surrounding open.
  1209.         
  1210.          (goto-char (1+ containing-sexp))
  1211.          (current-column))
  1212.         (t
  1213.          ;; Statement level.  Is it a continuation or a new statement?
  1214.          ;; Find previous non-comment character.
  1215.          (goto-char indent-point)
  1216.          (objective-C-backward-to-noncomment containing-sexp)
  1217.          ;; Back up over label lines, since they don't
  1218.          ;; affect whether our line is a continuation.
  1219.          (while (or (eq (preceding-char) ?\,)
  1220.             (and (eq (preceding-char) ?:)
  1221.                  (or (eq (char-after (- (point) 2)) ?\')
  1222.                  (memq (char-syntax (char-after (- (point) 2)))
  1223.                        '(?w ?_)))))
  1224.            (if (eq (preceding-char) ?\,)
  1225.            (objective-C-backward-to-start-of-continued-exp containing-sexp))
  1226.            (beginning-of-line)
  1227.            (objective-C-backward-to-noncomment containing-sexp))
  1228.          ;; Now we get the answer.
  1229.          (if (not (memq (preceding-char) '(nil ?\, ?\; ?\} ?\{)))
  1230.          ;; This line is continuation of preceding line's statement;
  1231.          ;; indent  objective-C-continued-statement-offset  more than the
  1232.          ;; previous line of the statement.
  1233.          (progn
  1234.            (objective-C-backward-to-start-of-continued-exp containing-sexp)
  1235.            (+ objective-C-continued-statement-offset (current-column)))
  1236.            ;; This line starts a new statement.
  1237.            ;; Position following last unclosed open.
  1238.            (goto-char containing-sexp)
  1239.            ;; Is line first statement after an open-brace?
  1240.            (or
  1241.         ;; If no, find that first statement and indent like it.
  1242.         (save-excursion
  1243.           (forward-char 1)
  1244.           (let ((colon-line-end 0))
  1245.             (while (progn (skip-chars-forward " \t\n")
  1246.                   (looking-at "#\\|/\\*\\|case[ \t\n].*:\\|[a-zA-Z0-9_$]*:"))
  1247.               ;; Skip over comments and labels following openbrace.
  1248.               (cond ((= (following-char) ?\#)
  1249.                  (forward-line 1))
  1250.                 ((= (following-char) ?\/)
  1251.                  (forward-char 2)
  1252.                  (search-forward "*/" nil 'move))
  1253.                 ;; case or label:
  1254.                 (t
  1255.                  (save-excursion (end-of-line)
  1256.                          (setq colon-line-end (point)))
  1257.                  (search-forward ":"))))
  1258.             ;; The first following code counts
  1259.             ;; if it is before the line we want to indent.
  1260.             (and (< (point) indent-point)
  1261.              (if (> colon-line-end (point))
  1262.                  (- (current-indentation) objective-C-label-offset)
  1263.                (current-column)))))
  1264.         ;; If no previous statement,
  1265.         ;; indent it relative to line brace is on.
  1266.         ;; For open brace in column zero, don't let statement
  1267.         ;; start there too.  If objective-C-indent-offset is zero,
  1268.         ;; use objective-C-brace-offset + objective-C-continued-statement-offset instead.
  1269.         ;; For open-braces not the first thing in a line,
  1270.         ;; add in objective-C-brace-imaginary-offset.
  1271.         (+ (if (and (bolp) (zerop objective-C-indent-level))
  1272.                (+ objective-C-brace-offset objective-C-continued-statement-offset)
  1273.              objective-C-indent-level)
  1274.            ;; Move back over whitespace before the openbrace.
  1275.            ;; If openbrace is not first nonwhite thing on the line,
  1276.            ;; add the objective-C-brace-imaginary-offset.
  1277.            (progn (skip-chars-backward " \t")
  1278.               (if (bolp) 0 objective-C-brace-imaginary-offset))
  1279.            ;; If the openbrace is preceded by a parenthesized exp,
  1280.            ;; move to the beginning of that;
  1281.            ;; possibly a different line
  1282.            (progn
  1283.              (if (eq (preceding-char) ?\))
  1284.              (forward-sexp -1))
  1285.              ;; Get initial indentation of the line we are on.
  1286.              (current-indentation))))))))))
  1287.  
  1288. (defun calculate-objective-C-indent-within-comment ()
  1289.   "Return the indentation amount for line, assuming that
  1290. the current line is to be regarded as part of a block comment."
  1291.   (let (end star-start)
  1292.     (save-excursion
  1293.       (beginning-of-line)
  1294.       (skip-chars-forward " \t")
  1295.       (setq star-start (= (following-char) ?\*))
  1296.       (skip-chars-backward " \t\n")
  1297.       (setq end (point))
  1298.       (beginning-of-line)
  1299.       (skip-chars-forward " \t")
  1300.       (and (re-search-forward "/\\*[ \t]*" end t)
  1301.        star-start
  1302.        (goto-char (1+ (match-beginning 0))))
  1303.       (current-column))))
  1304.  
  1305.  
  1306. (defun objective-C-backward-to-noncomment (lim)
  1307.   (let (opoint stop)
  1308.     (while (not stop)
  1309.       (skip-chars-backward " \t\n\f" lim)
  1310.       (setq opoint (point))
  1311.       (if (and (>= (point) (+ 2 lim))
  1312.            (save-excursion
  1313.          (forward-char -2)
  1314.          (looking-at "\\*/")))
  1315.       (search-backward "/*" lim 'move)
  1316.     (beginning-of-line)
  1317.     (skip-chars-forward " \t")
  1318.     (if (looking-at "#")
  1319.         (setq stop (<= (point) lim))
  1320.       (setq stop t)
  1321.       (goto-char opoint))))))  
  1322.  
  1323. (defun objective-C-backward-to-start-of-continued-exp (lim)
  1324.   (if (= (preceding-char) ?\))
  1325.       (forward-sexp -1))
  1326.   (beginning-of-line)
  1327.   (if (<= (point) lim)
  1328.       (goto-char (1+ lim)))
  1329.   (skip-chars-forward " \t"))
  1330.  
  1331. (defun objective-C-backward-to-start-of-if (&optional limit)
  1332.   "Move to the start of the last ``unbalanced'' if."
  1333.   (or limit (setq limit (save-excursion (beginning-of-defun) (point))))
  1334.   (let ((if-level 1)
  1335.     (case-fold-search nil))
  1336.     (while (not (zerop if-level))
  1337.       (backward-sexp 1)
  1338.       (cond ((looking-at "else\\b")
  1339.          (setq if-level (1+ if-level)))
  1340.         ((looking-at "if\\b")
  1341.          (setq if-level (1- if-level)))
  1342.         ((< (point) limit)
  1343.          (setq if-level 0)
  1344.          (goto-char limit))))))
  1345.  
  1346. (defun mark-objective-C-function ()
  1347.   "Put mark at end of C function, point at beginning."
  1348.   (interactive)
  1349.   (push-mark (point))
  1350.   (end-of-defun)
  1351.   (push-mark (point))
  1352.   (beginning-of-defun)
  1353.   (backward-paragraph))
  1354.  
  1355.  
  1356.  
  1357. /* End of text from cm-next-9:next */
  1358.