guile-c.el 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. ;;; guile-c.el --- Guile C editing commands
  2. ;; Copyright (C) 2001, 2006 Free Software Foundation, Inc.
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free
  15. ;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  16. ;;;; 02111-1307 USA
  17. ;;; Commentary:
  18. ;; (add-hook 'c-mode-hook
  19. ;; (lambda ()
  20. ;; (require 'guile-c)
  21. ;; (define-key c-mode-map "\C-c\C-g\C-p" 'guile-c-insert-define)
  22. ;; (define-key c-mode-map "\C-c\C-g\C-e" 'guile-c-edit-docstring)
  23. ;; (define-key c-mode-map "\C-c\C-g\C-d" 'guile-c-deprecate-region)
  24. ;; ))
  25. ;;; Code:
  26. (require 'cc-mode)
  27. (defvar guile-c-prefix "scm_")
  28. ;;;
  29. ;;; Insert templates
  30. ;;;
  31. (defun guile-c-insert-define ()
  32. "Insert a template of a Scheme procedure.
  33. M-x guile-c-insert-define RET foo arg , opt . rest =>
  34. SCM_DEFINE (scm_foo, \"foo\", 1, 1, 1,
  35. (SCM arg, SCM opt, SCM rest),
  36. \"\")
  37. #define FUNC_NAME s_scm_foo
  38. {
  39. }
  40. #undef FUNC_NAME"
  41. (interactive)
  42. (let ((tokens (split-string (read-string "Procedure: ")))
  43. name args opts rest)
  44. ;; Get procedure name
  45. (if (not tokens) (error "No procedure name"))
  46. (setq name (car tokens) tokens (cdr tokens))
  47. ;; Get requisite arguments
  48. (while (and tokens (not (member (car tokens) '("," "."))))
  49. (setq args (cons (car tokens) args) tokens (cdr tokens)))
  50. (setq args (nreverse args))
  51. ;; Get optional arguments
  52. (when (string= (car tokens) ",")
  53. (setq tokens (cdr tokens))
  54. (while (and tokens (not (string= (car tokens) ".")))
  55. (setq opts (cons (car tokens) opts) tokens (cdr tokens)))
  56. (setq opts (nreverse opts)))
  57. ;; Get rest argument
  58. (when (string= (car tokens) ".")
  59. (setq rest (list (cadr tokens))))
  60. ;; Insert template
  61. (let ((c-name (guile-c-name-from-scheme-name name)))
  62. (insert (format "SCM_DEFINE (%s, \"%s\", %d, %d, %d,\n"
  63. c-name name (length args) (length opts) (length rest))
  64. "\t ("
  65. (mapconcat (lambda (a) (concat "SCM " a))
  66. (append args opts rest) ", ")
  67. "),\n"
  68. "\t \"\")\n"
  69. "#define FUNC_NAME s_" c-name "\n"
  70. "{\n\n}\n"
  71. "#undef FUNC_NAME\n\n")
  72. (previous-line 4)
  73. (indent-for-tab-command))))
  74. (defun guile-c-name-from-scheme-name (name)
  75. (while (string-match "\\?$" name) (setq name (replace-match "_p" t t name)))
  76. (while (string-match "!$" name) (setq name (replace-match "_x" t t name)))
  77. (while (string-match "^%" name) (setq name (replace-match "sys_" t t name)))
  78. (while (string-match "->" name) (setq name (replace-match "_to_" t t name)))
  79. (while (string-match "[-:]" name) (setq name (replace-match "_" t t name)))
  80. (concat guile-c-prefix name))
  81. ;;;
  82. ;;; Edit docstrings
  83. ;;;
  84. (defvar guile-c-window-configuration nil)
  85. (defun guile-c-edit-docstring ()
  86. (interactive)
  87. (let* ((region (guile-c-find-docstring))
  88. (doc (if region (buffer-substring (car region) (cdr region)))))
  89. (if (not doc)
  90. (error "No docstring!")
  91. (setq guile-c-window-configuration (current-window-configuration))
  92. (with-current-buffer (get-buffer-create "*Guile Docstring*")
  93. (erase-buffer)
  94. (insert doc)
  95. (goto-char (point-min))
  96. (while (not (eobp))
  97. (if (looking-at "[ \t]*\"")
  98. (delete-region (match-beginning 0) (match-end 0)))
  99. (end-of-line)
  100. (if (eq (char-before (point)) ?\")
  101. (delete-backward-char 1))
  102. (if (and (eq (char-before (point)) ?n)
  103. (eq (char-before (1- (point))) ?\\))
  104. (delete-backward-char 2))
  105. (forward-line))
  106. (goto-char (point-min))
  107. (texinfo-mode)
  108. (if global-font-lock-mode
  109. (font-lock-fontify-buffer))
  110. (local-set-key "\C-c\C-c" 'guile-c-edit-finish)
  111. (setq fill-column 63)
  112. (switch-to-buffer-other-window (current-buffer))
  113. (message "Type `C-c C-c' to finish")))))
  114. (defun guile-c-edit-finish ()
  115. (interactive)
  116. (goto-char (point-max))
  117. (while (eq (char-before) ?\n) (backward-delete-char 1))
  118. (goto-char (point-min))
  119. (if (eobp)
  120. (insert "\"\"")
  121. (while (not (eobp))
  122. (insert "\t \"")
  123. (end-of-line)
  124. (insert (if (eobp) "\"" "\\n\""))
  125. (forward-line 1)))
  126. (let ((doc (buffer-string)))
  127. (kill-buffer (current-buffer))
  128. (set-window-configuration guile-c-window-configuration)
  129. (let ((region (guile-c-find-docstring)))
  130. (goto-char (car region))
  131. (delete-region (car region) (cdr region)))
  132. (insert doc)))
  133. (defun guile-c-find-docstring ()
  134. (save-excursion
  135. (if (re-search-backward "^SCM_DEFINE" nil t)
  136. (let ((start (progn (forward-line 2) (point))))
  137. (while (looking-at "[ \t]*\"")
  138. (forward-line 1))
  139. (cons start (- (point) 2))))))
  140. ;;;
  141. ;;; Others
  142. ;;;
  143. (defun guile-c-deprecate-region (start end)
  144. (interactive "r")
  145. (save-excursion
  146. (let ((marker (make-marker)))
  147. (set-marker marker end)
  148. (goto-char start)
  149. (insert "#if (SCM_DEBUG_DEPRECATED == 0)\n\n")
  150. (goto-char marker)
  151. (insert "\n#endif /* (SCM_DEBUG_DEPRECATED == 0) */\n"))))
  152. (provide 'guile-c)
  153. ;; guile-c.el ends here