guile-c.el 5.4 KB

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