changes for MELPA compatibility

This commit is contained in:
nik gaffney 2022-07-30 19:15:38 +02:00
parent 36eae66a3c
commit 53d3959e1b
17 changed files with 1471 additions and 1225 deletions

View file

@ -7,8 +7,9 @@ SuperCollider/Emacs interface
There are 3 options for installation: There are 3 options for installation:
1. Using SuperCollider Quarks (recommended) 1. Using SuperCollider Quarks (recommended)
2. From debian package `supercollider-emacs` 2. Using an Emacs package manager
3. From source 3. From debian package `supercollider-emacs`
4. From source
Option #1 is the best cross-platform option, and is recommended. Whatever option Option #1 is the best cross-platform option, and is recommended. Whatever option
you choose, *make sure not to mix installation methods*. In particular, do not you choose, *make sure not to mix installation methods*. In particular, do not
@ -61,9 +62,11 @@ exec-path.
(setq exec-path (append exec-path '("/Applications/SuperCollider.app/Contents/MacOS/"))) (setq exec-path (append exec-path '("/Applications/SuperCollider.app/Contents/MacOS/")))
``` ```
#### Installing with an emacs package manager ### Install Option 2: Emacs package manager
It's completely possible to install with The `sclang` package can be installed from [MELPA](https://melpa.org/#/sclang) and configured with [use-package](https://github.com/jwiegley/use-package).
It's possible to install with
[straight.el](https://github.com/raxod502/straight.el), [straight.el](https://github.com/raxod502/straight.el),
[use-package](https://github.com/jwiegley/use-package), [use-package](https://github.com/jwiegley/use-package),
[doom](https://github.com/hlissner/doom-emacs), etc. Instructions for doing so [doom](https://github.com/hlissner/doom-emacs), etc. Instructions for doing so
@ -71,7 +74,7 @@ are beyond the scope of this README, but note that `autoloads` are implemented
for entry-point functions so if you like to have a speedy start-up time you can for entry-point functions so if you like to have a speedy start-up time you can
use the `:defer t` option. use the `:defer t` option.
### Install Option 2: Debian package ### Install Option 3: Debian package
There is a debian package which provides emacs integration called There is a debian package which provides emacs integration called
`supercollider-emacs`. Option #1 will likely be more recent, but `supercollider-emacs`. Option #1 will likely be more recent, but
@ -81,7 +84,7 @@ if you prefer you can install the package with:
sudo apt install supercollider-emacs sudo apt install supercollider-emacs
``` ```
### Install Option 3: Installing from source ### Install Option 4: Installing from source
If you are building SuperCollider from source, you can optionally compile and If you are building SuperCollider from source, you can optionally compile and
install this library along with it. The cmake `-DSC_EL` flag controls whether install this library along with it. The cmake `-DSC_EL` flag controls whether

View file

@ -4,3 +4,4 @@
;; We use it for package development and running tests ;; We use it for package development and running tests
(eldev-use-plugin 'autoloads) (eldev-use-plugin 'autoloads)
(eldev-use-package-archive 'melpa)

View file

@ -1,5 +1,9 @@
;; copyright 2003 stefan kersten <steve@k-hornz.de> ;;; sclang-browser.el --- SuperCollider documentation browser -*- coding: utf-8; lexical-binding: t -*-
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,31 +19,40 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
(require 'sclang-util) ;;; Commentary:
(require 'view nil t) ;; Browser for SuperCollider documentation.
;; TODO: better factoring ;; TODO: better factoring
;; derive from view mode, make mode-map pluggable ;; - derive from view mode, make mode-map pluggable
;; define derived mode for completion, definition, help ;; - define derived mode for completion, definition, help
;; - update 'display-buffer-reuse-frames'
;; - update view-return-to-alist
(defun sclang-browser-fill-keymap (map) (require 'sclang-util)
(require 'view)
;;; Code:
(defun sclang-browser-fill-keymap ()
"Create keymap and bindings."
(let ((map (make-sparse-keymap)))
(set-keymap-parent map view-mode-map)
(define-key map "\r" 'sclang-browser-follow-link) (define-key map "\r" 'sclang-browser-follow-link)
(define-key map [mouse-2] 'sclang-browser-mouse-follow-link) (define-key map [mouse-2] 'sclang-browser-mouse-follow-link)
(define-key map "\t" 'sclang-browser-next-link) (define-key map "\t" 'sclang-browser-next-link)
(define-key map [backtab] 'sclang-browser-previous-link) (define-key map [backtab] 'sclang-browser-previous-link)
(define-key map [(shift tab)] 'sclang-browser-previous-link) (define-key map [(shift tab)] 'sclang-browser-previous-link)
(define-key map [?q] 'sclang-browser-quit) (define-key map [?q] 'sclang-browser-quit)
map) map))
(defvar sclang-browser-mode-map (sclang-browser-fill-keymap (make-sparse-keymap))) (defvar sclang-browser-mode-map (sclang-browser-fill-keymap))
(defvar sclang-browser-mode-hook nil) (defvar sclang-browser-mode-hook nil)
(defvar sclang-browser-show-hook nil) (defvar sclang-browser-show-hook nil)
(defvar sclang-browser-link-function nil (defvar sclang-browser-link-function nil)
"buffer local") (defvar sclang-browser-return-method nil)
(defvar sclang-browser-return-method nil
"buffer local")
(defun sclang-browser-beginning-of-link () (defun sclang-browser-beginning-of-link ()
"Beginning of link."
(interactive) (interactive)
(when (get-text-property (point) 'sclang-browser-link) (when (get-text-property (point) 'sclang-browser-link)
(while (and (not (bobp)) (while (and (not (bobp))
@ -49,6 +62,7 @@
(point))) (point)))
(defun sclang-browser-next-link (&optional n) (defun sclang-browser-next-link (&optional n)
"Next link (or N further)."
(interactive) (interactive)
(let* ((n (or n 1)) (let* ((n (or n 1))
(prop 'sclang-browser-link) (prop 'sclang-browser-link)
@ -73,10 +87,12 @@
(setq pos (point))))))) (setq pos (point)))))))
(defun sclang-browser-previous-link () (defun sclang-browser-previous-link ()
"Previous link."
(interactive) (interactive)
(sclang-browser-next-link -1)) (sclang-browser-next-link -1))
(defun sclang-browser-follow-link (&optional pos) (defun sclang-browser-follow-link (&optional pos)
"Follow link (optionally POS)."
(interactive) (interactive)
(let* ((pos (or pos (point))) (let* ((pos (or pos (point)))
(data (get-text-property pos 'sclang-browser-link))) (data (get-text-property pos 'sclang-browser-link)))
@ -89,6 +105,7 @@
(error (sclang-message "Error in link function") nil))))))) (error (sclang-message "Error in link function") nil)))))))
(defun sclang-browser-mouse-follow-link (event) (defun sclang-browser-mouse-follow-link (event)
"Link. click. EVENT."
(interactive "e") (interactive "e")
(let* ((start (event-start event)) (let* ((start (event-start event))
(window (car start)) (window (car start))
@ -97,53 +114,54 @@
(sclang-browser-follow-link pos)))) (sclang-browser-follow-link pos))))
(defun sclang-browser-mode () (defun sclang-browser-mode ()
"Major mode for viewing hypertext and navigating references in it. "Major mode for viewing hypertext and navigating references.
Entry to this mode runs the normal hook `sclang-browser-mode-hook'. Entry to this mode runs the normal hook `sclang-browser-mode-hook'
Commands: Commands:
\\{sclang-browser-mode-map}" \\{sclang-browser-mode-map}"
(interactive) (interactive)
(view-mode)
(kill-all-local-variables) (kill-all-local-variables)
(use-local-map sclang-browser-mode-map) (use-local-map sclang-browser-mode-map)
(set-keymap-parent sclang-browser-mode-map view-mode-map)
(setq mode-name "Browser") (setq mode-name "Browser")
(setq major-mode 'sclang-browser-mode) (setq major-mode 'sclang-browser-mode)
(set (make-local-variable 'sclang-browser-link-function) nil) (set (make-local-variable 'sclang-browser-link-function) nil)
(set (make-local-variable 'sclang-browser-return-method) nil) (set (make-local-variable 'sclang-browser-return-method) nil)
(set (make-local-variable 'font-lock-defaults) nil) (set (make-local-variable 'font-lock-defaults) nil)
(view-mode)
(set (make-local-variable 'minor-mode-overriding-map-alist) (set (make-local-variable 'minor-mode-overriding-map-alist)
(list (cons 'view-mode sclang-browser-mode-map))) (list (cons 'view-mode sclang-browser-mode-map)))
(set (make-local-variable 'view-no-disable-on-exit) t) (set (make-local-variable 'view-no-disable-on-exit) t)
(run-hooks 'sclang-browser-mode-hook)) (run-hooks 'sclang-browser-mode-hook))
(defun sclang-browser-mode-setup () (defun sclang-browser-mode-setup ()
"Setup sclang-browser-mode."
(sclang-browser-mode) (sclang-browser-mode)
(setq buffer-read-only nil)) (setq buffer-read-only nil))
(defun sclang-browser-mode-finish () (defun sclang-browser-mode-finish ()
(toggle-read-only 1) "Finish sclang-browser-mode."
(setq view-return-to-alist (read-only-mode)
(list (cons (selected-window) sclang-browser-return-method))) ;; view-return-to-alist is an obsolete variable (as of 24.1)
;;(setq view-return-to-alist
;; (list (cons (selected-window) sclang-browser-return-method)))
(view-mode -1)
(run-hooks 'sclang-browser-show-hook)) (run-hooks 'sclang-browser-show-hook))
(defun sclang-browser-quit () (defun sclang-browser-quit ()
"Quit the sclang help browser."
(interactive) (interactive)
(when (eq major-mode 'sclang-browser-mode) (when (eq major-mode 'sclang-browser-mode)
(kill-buffer (current-buffer)))) (kill-buffer (current-buffer))))
(defun sclang-browser-make-link (link-text &optional link-data link-function) (defun sclang-browser-make-link (link-text &optional link-data link-function)
(let ((map (make-sparse-keymap))) "Make a link using LINK-TEXT (optional LINK-DATA and LINK-FUNCTION)."
(propertize link-text (propertize link-text
'mouse-face 'highlight 'mouse-face 'highlight
;;'help-echo "mouse-2: follow link" 'sclang-browser-link (cons link-function link-data)))
;;'keymap map
'sclang-browser-link (cons link-function link-data)
;;'sclang-browser-link-data link-data
;;'sclang-browser-link-function link-function)))
)))
(defun sclang-display-browser (buffer-name output-function) (defun sclang-display-browser (buffer-name output-function)
"header: what to insert in the buffer "Display browser using BUFFER-NAME and OUTPUT-FUNCTION.
header: what to insert in the buffer.
link-list: list of (link-text link-function link-data) link-list: list of (link-text link-function link-data)
link-function: function with args (link-text link-data)" link-function: function with args (link-text link-data)"
(let ((temp-buffer-setup-hook '(sclang-browser-mode-setup)) (let ((temp-buffer-setup-hook '(sclang-browser-mode-setup))
@ -160,18 +178,25 @@ Commands:
;; Secondly, the buffer has not been displayed yet, ;; Secondly, the buffer has not been displayed yet,
;; so we don't know whether its frame will be selected. ;; so we don't know whether its frame will be selected.
(cons (selected-window) t)) (cons (selected-window) t))
(display-buffer-reuse-frames ;; display-buffer-reuse-frames is obsolete since 24.3
(cons (selected-window) 'quit-window)) ;; replace with something like
;;+ (add-to-list 'display-buffer-alist
;;+ '("." nil (reusable-frames . t)))
;;- (display-buffer-reuse-frames
;;- (cons (selected-window) 'quit-window))
((not (one-window-p t)) ((not (one-window-p t))
(cons (selected-window) 'quit-window)) (cons (selected-window) 'quit-window))
(pop-up-windows ;; This variable is provided mainly for backward compatibility
(cons (selected-window) t)) ;; and should not be used in new code.
;; (pop-up-windows
;; (cons (selected-window) t))
(t (t
(list (selected-window) (window-buffer) (list (selected-window) (window-buffer)
(window-start) (window-point))))) (window-start) (window-point)))))
(funcall output-function))))) (funcall output-function)))))
(defmacro with-sclang-browser (buffer-name &rest body) (defmacro with-sclang-browser (buffer-name &rest body)
"Display browser in BUFFER-NAME and run BODY."
`(sclang-display-browser ,buffer-name (lambda () ,@body))) `(sclang-display-browser ,buffer-name (lambda () ,@body)))
;; ===================================================================== ;; =====================================================================
@ -180,4 +205,4 @@ Commands:
(provide 'sclang-browser) (provide 'sclang-browser)
;; EOF ;;; sclang-browser.el ends here

View file

@ -1,3 +1,9 @@
;;; sclang-dev.el --- IDE for working with SuperCollider -*- coding: utf-8;
;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -13,32 +19,25 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Edit SuperCollider help files.
(require 'sclang-util) (require 'sclang-util)
(require 'sclang-interp) (require 'sclang-interp)
;;; Code:
(sclang-set-command-handler (sclang-set-command-handler
'openDevSource 'openDevSource
(lambda (file) (lambda (file)))
)
)
(defun sclang-edit-dev-source () (defun sclang-edit-dev-source ()
"Edit the help file at the development location." "Edit the help file at the development location."
; (sclang-document-name . (prSetTitle (buffer-name)))
(interactive) (interactive)
(sclang-perform-command 'openDevSource (buffer-file-name)) ;; (sclang-document-name . (prSetTitle (buffer-name)))
) (sclang-perform-command 'openDevSource (buffer-file-name)))
(provide 'sclang-dev) (provide 'sclang-dev)
;(defun sclang-open-dev-source (file) ;;; sclang-dev.el ends here
; "Open the help file at the development location."
; (if (sclang-html-file-p file)
; (html-mode)
; ;; (find-file file)
; )
; (if ( sclang-sc-file-p file )
; (sclang-mode)
; )
; )

View file

@ -1,5 +1,9 @@
;; copyright 2003 stefan kersten <steve@k-hornz.de> ;;; sclang-document.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,6 +19,12 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; ???
;;; Code:
(provide 'sclang-document) (provide 'sclang-document)
;; EOF ;;; sclang-document.el ends here

View file

@ -1,5 +1,9 @@
;; copyright 2003 stefan kersten <steve@k-hornz.de> ;;; sclang-help.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,11 +19,17 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Access SuperCollider help files.
;;; Code:
(eval-when-compile (eval-when-compile
(require 'font-lock)) (require 'font-lock))
;; (require 'w3m) ;; not needed during compilation (require 'w3m)
(require 'cl-lib) (require 'cl-lib)
(require 'sclang-util) (require 'sclang-util)
(require 'sclang-interp) (require 'sclang-interp)
(require 'sclang-language) (require 'sclang-language)
@ -87,12 +97,15 @@
(defcustom sclang-help-filters (defcustom sclang-help-filters
'(("p\\.p\\([0-9]+\\)" . "#p\\1") '(("p\\.p\\([0-9]+\\)" . "#p\\1")
("<p class=\"\\(.*\\)\">\\(.*\\)</p>" . "<div id=\"\\1\">\\2</div>")) ("<p class=\"\\(.*\\)\">\\(.*\\)</p>" . "<div id=\"\\1\">\\2</div>"))
"list of pairs of (regexp . filter) defining html-tags to be replaced by the function sclang-help-substitute-for-filters" "Filters to replace html tags.
List of pairs of (regexp . filter) defining html-tags to be replaced
using the function `sclang-help-substitute-for-filters'."
:group 'sclang-interface :group 'sclang-interface
:type '(repeat (cons (string :tag "match") (string :tag "replacement")))) :type '(repeat (cons (string :tag "match") (string :tag "replacement"))))
(defun sclang-help-substitute-for-filters (&rest args) (defun sclang-help-substitute-for-filters (&rest args)
"substitute various tags in SCs html-docs" "Substitute various tags in SCs html-docs.
Optional argument ARGS unused?"
(mapcar #'(lambda (filter) (mapcar #'(lambda (filter)
(let ((regexp (car filter)) (let ((regexp (car filter))
(to-string (cdr filter))) (to-string (cdr filter)))
@ -104,12 +117,12 @@
;; w3m's content-filtering system ;; w3m's content-filtering system
(setq w3m-use-filter t) (setq w3m-use-filter t)
;; checks if w3m-filter is loaded. Is `eval-after-load' necessary here?
(eval-after-load "w3m-filter" (eval-after-load "w3m-filter"
'(add-to-list 'w3m-filter-rules '(add-to-list 'w3m-filter-rules
;; run on all files read by w3m... ;; run on all files read by w3m...
'(".*" sclang-help-substitute-for-filters))) '(".*" sclang-help-substitute-for-filters)))
(defvar sclang-help-topic-alist nil (defvar sclang-help-topic-alist nil
"Alist mapping help topics to file names.") "Alist mapping help topics to file names.")
@ -136,38 +149,49 @@
;; ===================================================================== ;; =====================================================================
(defun sclang-get-help-file (topic) (defun sclang-get-help-file (topic)
"Get the help file for TOPIC."
(let ((topic (or (cdr (assoc topic sclang-special-help-topics)) topic))) (let ((topic (or (cdr (assoc topic sclang-special-help-topics)) topic)))
(cdr (assoc topic sclang-help-topic-alist)))) (cdr (assoc topic sclang-help-topic-alist))))
(defun sclang-get-help-topic (file) (defun sclang-get-help-topic (file)
"Get the help topic for FILE."
(let ((topic (car (rassoc file sclang-help-topic-alist)))) (let ((topic (car (rassoc file sclang-help-topic-alist))))
(or (car (rassoc topic sclang-special-help-topics)) topic))) (or (car (rassoc topic sclang-special-help-topics)) topic)))
(defun sclang-help-buffer-name (topic) (defun sclang-help-buffer-name (topic)
"Set the help buffer name to TOPIC."
(sclang-make-buffer-name (concat "Help:" topic))) (sclang-make-buffer-name (concat "Help:" topic)))
;; file predicate functions
(defun sclang-rtf-file-p (file) (defun sclang-rtf-file-p (file)
"Does an rtf FILE exist?"
(let ((case-fold-search t)) (let ((case-fold-search t))
(string-match ".*\\.rtf$" file))) (string-match ".*\\.rtf$" file)))
;; ========= ADDITION for HTML help files
(defun sclang-html-file-p (file) (defun sclang-html-file-p (file)
"Does an html FILE exist?"
(let ((case-fold-search t)) (let ((case-fold-search t))
(string-match ".*\\.html?$" file))) (string-match ".*\\.html?$" file)))
(defun sclang-sc-file-p (file) (defun sclang-sc-file-p (file)
"Does an sc FILE exist?"
(let ((case-fold-search t)) (let ((case-fold-search t))
(string-match ".*\\.sc$" file))) (string-match ".*\\.sc$" file)))
(defun sclang-scd-file-p (file) (defun sclang-scd-file-p (file)
"Does an scd FILE exist?"
(let ((case-fold-search t)) (let ((case-fold-search t))
(string-match ".*\\.scd$" file))) (string-match ".*\\.scd$" file)))
(defun sclang-help-file-p (file) (defun sclang-help-file-p (file)
"Is FILE a help file?"
(string-match sclang-help-file-regexp file)) (string-match sclang-help-file-regexp file))
(defun sclang-help-topic-name (file) (defun sclang-help-topic-name (file)
(if (string-match sclang-help-file-regexp file) "Get the help topic from FILE."
(when (string-match sclang-help-file-regexp file)
(cons (file-name-nondirectory (replace-match "" nil nil file 1)) (cons (file-name-nondirectory (replace-match "" nil nil file 1))
file))) file)))
@ -178,7 +202,7 @@
(defconst sclang-rtf-face-change-token "\0") (defconst sclang-rtf-face-change-token "\0")
(defun sclang-fill-rtf-syntax-table (table) (defun sclang-fill-rtf-syntax-table (table)
;; character quote "Fill RTF syntax TABLE."
(modify-syntax-entry ?\\ "/" table) (modify-syntax-entry ?\\ "/" table)
(modify-syntax-entry ?\" "." table) (modify-syntax-entry ?\" "." table)
(modify-syntax-entry ?\{ "(" table) (modify-syntax-entry ?\{ "(" table)
@ -204,13 +228,16 @@
(defun sclang-code-p (pos) (not (rtf-p pos)))) (defun sclang-code-p (pos) (not (rtf-p pos))))
(defmacro with-sclang-rtf-state-output (state &rest body) (defmacro with-sclang-rtf-state-output (state &rest body)
"Wrap rtf STATE output around BODY."
`(with-current-buffer (sclang-rtf-state-output ,state) `(with-current-buffer (sclang-rtf-state-output ,state)
,@body)) ,@body))
(defmacro sclang-rtf-state-add-font (state font-id font-name) (defmacro sclang-rtf-state-add-font (state font-id font-name)
"Add font to STATE font table using FONT-ID and FONT-NAME."
`(push (cons ,font-id (intern ,font-name)) (sclang-rtf-state-font-table ,state))) `(push (cons ,font-id (intern ,font-name)) (sclang-rtf-state-font-table ,state)))
(defmacro sclang-rtf-state-apply (state) (defmacro sclang-rtf-state-apply (state)
"Apply STATE to rtf output."
(let ((pos (cl-gensym)) (let ((pos (cl-gensym))
(font (cl-gensym)) (font (cl-gensym))
(face (cl-gensym))) (face (cl-gensym)))
@ -230,11 +257,13 @@
(setf (sclang-rtf-state-pos ,state) (point))))))) (setf (sclang-rtf-state-pos ,state) (point)))))))
(defmacro sclang-rtf-state-set-font (state font) (defmacro sclang-rtf-state-set-font (state font)
"Set FONT in STATE."
`(progn `(progn
(sclang-rtf-state-apply ,state) (sclang-rtf-state-apply ,state)
(setf (sclang-rtf-state-font ,state) ,font))) (setf (sclang-rtf-state-font ,state) ,font)))
(defmacro sclang-rtf-state-push-face (state face) (defmacro sclang-rtf-state-push-face (state face)
"Push FACE to STATE."
(let ((list (cl-gensym))) (let ((list (cl-gensym)))
`(let ((,list (sclang-rtf-state-face state))) `(let ((,list (sclang-rtf-state-face state)))
(sclang-rtf-state-apply ,state) (sclang-rtf-state-apply ,state)
@ -243,12 +272,14 @@
(append ,list (list ,face))))))) (append ,list (list ,face)))))))
(defmacro sclang-rtf-state-pop-face (state face) (defmacro sclang-rtf-state-pop-face (state face)
"Pop FACE from STATE."
(let ((list (cl-gensym))) (let ((list (cl-gensym)))
`(let* ((,list (sclang-rtf-state-face ,state))) `(let* ((,list (sclang-rtf-state-face ,state)))
(sclang-rtf-state-apply ,state) (sclang-rtf-state-apply ,state)
(setf (sclang-rtf-state-face ,state) (delq ,face ,list))))) (setf (sclang-rtf-state-face ,state) (delq ,face ,list)))))
(defun sclang-parse-rtf (state) (defun sclang-parse-rtf (state)
"Parse rtf STATE."
(while (not (eobp)) (while (not (eobp))
(cond ((looking-at "{") (cond ((looking-at "{")
;; container ;; container
@ -278,6 +309,7 @@
(forward-char 1))))) (forward-char 1)))))
(defun sclang-parse-rtf-container (state) (defun sclang-parse-rtf-container (state)
"Parse RTF container. STATE."
(cond ((looking-at "\\\\rtf1") ; document (cond ((looking-at "\\\\rtf1") ; document
(goto-char (match-end 0)) (goto-char (match-end 0))
(sclang-parse-rtf state)) (sclang-parse-rtf state))
@ -295,10 +327,10 @@
(insert-image image) (insert-image image)
(sclang-rtf-state-push-face state 'italic) (sclang-rtf-state-push-face state 'italic)
(insert file) (insert file)
(sclang-rtf-state-pop-face state 'italic))))) (sclang-rtf-state-pop-face state 'italic)))))))
))
(defun sclang-parse-rtf-control (state ctrl) (defun sclang-parse-rtf-control (state ctrl)
"Parse RTF control chars. STATE CTRL."
(let ((char (aref ctrl 0))) (let ((char (aref ctrl 0)))
(cond ((memq char '(?{ ?} ?\\)) (cond ((memq char '(?{ ?} ?\\))
(with-sclang-rtf-state-output state (insert char))) (with-sclang-rtf-state-output state (insert char)))
@ -318,10 +350,10 @@
((string= ctrl "b0") ((string= ctrl "b0")
(sclang-rtf-state-pop-face state 'bold)) (sclang-rtf-state-pop-face state 'bold))
((string-match "^f[0-9]+$" ctrl) ((string-match "^f[0-9]+$" ctrl)
(sclang-rtf-state-set-font state ctrl)) (sclang-rtf-state-set-font state ctrl)))))
)))
(defun sclang-convert-rtf-buffer (output) (defun sclang-convert-rtf-buffer (output)
"Convert rtf buffer. OUTPUT."
(let ((case-fold-search nil) (let ((case-fold-search nil)
(fill-column sclang-help-fill-column)) (fill-column sclang-help-fill-column))
(save-excursion (save-excursion
@ -337,14 +369,17 @@
;; ===================================================================== ;; =====================================================================
(defun sclang-fill-help-syntax-table (table) (defun sclang-fill-help-syntax-table (table)
"Fill help syntax TABLE."
;; make ?- be part of symbols for selection and sclang-symbol-at-point ;; make ?- be part of symbols for selection and sclang-symbol-at-point
(modify-syntax-entry ?- "_" table)) (modify-syntax-entry ?- "_" table))
(defun sclang-fill-help-mode-map (map) (defun sclang-fill-help-mode-map (map)
"Fill sclang help mode keymap MAP."
(define-key map "\C-c}" 'bury-buffer) (define-key map "\C-c}" 'bury-buffer)
(define-key map "\C-c\C-v" 'sclang-edit-help-file)) (define-key map "\C-c\C-v" 'sclang-edit-help-file))
(defmacro sclang-help-mode-limit-point-to-code (&rest body) (defmacro sclang-help-mode-limit-point-to-code (&rest body)
"Limit point to code BODY."
(let ((min (cl-gensym)) (let ((min (cl-gensym))
(max (cl-gensym)) (max (cl-gensym))
(res (cl-gensym))) (res (cl-gensym)))
@ -360,14 +395,17 @@
(t ,res))))))) (t ,res)))))))
(defun sclang-help-mode-beginning-of-defun (&optional arg) (defun sclang-help-mode-beginning-of-defun (&optional arg)
"Move to beginning of function (or back ARG)."
(interactive "p") (interactive "p")
(sclang-help-mode-limit-point-to-code (sclang-beginning-of-defun arg))) (sclang-help-mode-limit-point-to-code (sclang-beginning-of-defun arg)))
(defun sclang-help-mode-end-of-defun (&optional arg) (defun sclang-help-mode-end-of-defun (&optional arg)
"Move to end of function (or forward ARG)."
(interactive "p") (interactive "p")
(sclang-help-mode-limit-point-to-code (sclang-end-of-defun arg))) (sclang-help-mode-limit-point-to-code (sclang-end-of-defun arg)))
(defun sclang-help-mode-fontify-region (start end loudly) (defun sclang-help-mode-fontify-region (start end loudly)
"Fontify region from START to END and LOUDLY."
(cl-flet ((fontify-code (cl-flet ((fontify-code
(start end loudly) (start end loudly)
(funcall 'font-lock-default-fontify-region start end loudly)) (funcall 'font-lock-default-fontify-region start end loudly))
@ -395,6 +433,7 @@
(defun sclang-help-mode-indent-line () (defun sclang-help-mode-indent-line ()
"Indent sclang code in documentation."
(if (sclang-code-p (point)) (if (sclang-code-p (point))
(sclang-indent-line) (sclang-indent-line)
(insert "\t"))) (insert "\t")))
@ -415,7 +454,7 @@
(unwind-protect (unwind-protect
(progn (progn
(sclang-convert-rtf-buffer tmp-buffer) (sclang-convert-rtf-buffer tmp-buffer)
(toggle-read-only 0) (read-only-mode)
(erase-buffer) (erase-buffer)
(insert-buffer-substring tmp-buffer)) (insert-buffer-substring tmp-buffer))
(and (buffer-modified-p) (not modified-p) (set-buffer-modified-p nil)) (and (buffer-modified-p) (not modified-p) (set-buffer-modified-p nil))
@ -425,8 +464,7 @@
(append font-lock-defaults (append font-lock-defaults
'((font-lock-fontify-region-function . sclang-help-mode-fontify-region)))) '((font-lock-fontify-region-function . sclang-help-mode-fontify-region))))
(set (make-local-variable 'beginning-of-defun-function) 'sclang-help-mode-beginning-of-defun) (set (make-local-variable 'beginning-of-defun-function) 'sclang-help-mode-beginning-of-defun)
(set (make-local-variable 'indent-line-function) 'sclang-help-mode-indent-line) (set (make-local-variable 'indent-line-function) 'sclang-help-mode-indent-line)))
))
;; ===================================================================== ;; =====================================================================
;; help file access ;; help file access
@ -436,7 +474,8 @@
"Answer t if PATH should be skipped during help file indexing." "Answer t if PATH should be skipped during help file indexing."
(let ((directory (file-name-nondirectory path))) (let ((directory (file-name-nondirectory path)))
(cl-some (lambda (regexp) (string-match regexp directory)) (cl-some (lambda (regexp) (string-match regexp directory))
'("^\.$" "^\.\.$" "^CVS$" "^\.svn$" "^_darcs$")))) ;; skip "." ".." "CVS" ".svn" and "_darcs" directories
'("\\.\\'" "\\.\\.\\'" "^CVS\\'" "^\\.svn$" "^_darcs\\'"))))
(defun sclang-filter-help-directories (list) (defun sclang-filter-help-directories (list)
"Remove paths to be skipped from LIST of directories." "Remove paths to be skipped from LIST of directories."
@ -446,7 +485,7 @@
list)) list))
(defun sclang-directory-files-save (directory &optional full match nosort) (defun sclang-directory-files-save (directory &optional full match nosort)
"Return a list of names of files in DIRECTORY, or nil on error." "List files in DIRECTORY (optionally FULL MATCH NOSORT) or nil."
(condition-case nil (condition-case nil
(directory-files directory full match nosort) (directory-files directory full match nosort)
(error nil))) (error nil)))
@ -505,20 +544,17 @@
"Edit the help file associated with the current buffer. "Edit the help file associated with the current buffer.
Switches w3m to edit mode (actually HTML mode)." Switches w3m to edit mode (actually HTML mode)."
(interactive) (interactive)
(w3m-edit-current-url) (w3m-edit-current-url))
)
(defun sclang-edit-help-code () (defun sclang-edit-help-code ()
"Edit the help file to make code variations. "Edit the help file to make code variations.
Switches to text mode with sclang-minor-mode." Switches to text mode with `sclang-minor-mode'."
(interactive) (interactive)
(w3m-copy-buffer) (w3m-copy-buffer)
;; (text-mode) ;; (text-mode)
(sclang-mode) (sclang-mode)
(toggle-read-only) (read-only-mode)
(rename-buffer "*SC_Help:CodeEdit*") (rename-buffer "*SC_Help:CodeEdit*"))
)
(defun sclang-edit-help-file () (defun sclang-edit-help-file ()
"Edit the help file associated with the current buffer. "Edit the help file associated with the current buffer.
@ -552,7 +588,7 @@ Either visit file internally (.sc) or start external editor (.rtf)."
sclang-help-topic-alist)))))) sclang-help-topic-alist))))))
(defun sclang-goto-help-browser () (defun sclang-goto-help-browser ()
"Switch to the *w3m* buffer to browse help files" "Switch to the *w3m* buffer to browse help files."
(interactive) (interactive)
(let* ((buffer-name "*w3m*") (let* ((buffer-name "*w3m*")
(buffer (get-buffer buffer-name))) (buffer (get-buffer buffer-name)))
@ -564,24 +600,15 @@ Either visit file internally (.sc) or start external editor (.rtf)."
(if buffer2 (if buffer2
(switch-to-buffer buffer2) (switch-to-buffer buffer2)
;; else ;; else
(sclang-find-help "Help") (sclang-find-help "Help"))))
)
)
)
(if buffer (if buffer
(with-current-buffer buffer (with-current-buffer buffer
(rename-buffer "*SC_Help:w3m*") (rename-buffer "*SC_Help:w3m*")
(sclang-help-minor-mode)
;;(setq buffer-read-only false) ;;(setq buffer-read-only false)
) (sclang-help-minor-mode)))))
)
; (if buffer
;
; )
)
)
(defun sclang-find-help (topic) (defun sclang-find-help (topic)
"Find help for TOPIC."
(interactive (interactive
(list (list
(let ((topic (or (and mark-active (buffer-substring-no-properties (region-beginning) (region-end))) (let ((topic (or (and mark-active (buffer-substring-no-properties (region-beginning) (region-end)))
@ -609,17 +636,15 @@ Either visit file internally (.sc) or start external editor (.rtf)."
(set-buffer-modified-p nil))) (set-buffer-modified-p nil)))
(switch-to-buffer buffer)) (switch-to-buffer buffer))
(if (sclang-html-file-p file) (if (sclang-html-file-p file)
(sclang-goto-help-browser)) (sclang-goto-help-browser)))
)
(sclang-message "Help file not found") nil) (sclang-message "Help file not found") nil)
(sclang-message "No help for \"%s\"" topic) nil))) (sclang-message "No help for \"%s\"" topic) nil)))
(defun sclang-open-help-gui () (defun sclang-open-help-gui ()
"Open SCDoc Help Browser" "Open SCDoc Help Browser."
(interactive) (interactive)
(sclang-eval-string (sclang-format "Help.gui")) (sclang-eval-string (sclang-format "Help.gui")))
)
(defvar sclang-scdoc-topics (make-hash-table :size 16385) (defvar sclang-scdoc-topics (make-hash-table :size 16385)
"List of all scdoc topics.") "List of all scdoc topics.")
@ -629,24 +654,23 @@ Either visit file internally (.sc) or start external editor (.rtf)."
(lambda (list-of-symbols) (lambda (list-of-symbols)
(mapcar (lambda (arg) (mapcar (lambda (arg)
(puthash arg nil sclang-scdoc-topics)) (puthash arg nil sclang-scdoc-topics))
list-of-symbols) list-of-symbols)))
))
(defun sclang-find-help-in-gui (topic) (defun sclang-find-help-in-gui (topic)
"Search for topic in SCDoc Help Browser" "Search for TOPIC in Help Browser."
(interactive (interactive
(list (list
(let ((topic (sclang-symbol-at-point))) (let ((topic (sclang-symbol-at-point)))
(completing-read (format "Help topic%s: " (if topic (completing-read
(format "Help topic%s: " (if topic
(format " (default %s)" topic) (format " (default %s)" topic)
"")) ""))
sclang-scdoc-topics nil nil nil 'sclang-help-topic-history topic))) sclang-scdoc-topics nil nil nil 'sclang-help-topic-history topic))))
)
(if topic (if topic
(sclang-eval-string (sclang-format "HelpBrowser.openHelpFor(%o)" topic)) (sclang-eval-string
(sclang-eval-string (sclang-format "Help.gui")) (sclang-format "HelpBrowser.openHelpFor(%o)" topic))
) (sclang-eval-string
) (sclang-format "Help.gui"))))
;; ===================================================================== ;; =====================================================================
@ -664,16 +688,18 @@ Either visit file internally (.sc) or start external editor (.rtf)."
(lambda () (lambda ()
(clrhash sclang-scdoc-topics))) (clrhash sclang-scdoc-topics)))
(add-to-list 'auto-mode-alist '("\\.rtf$" . sclang-help-mode)) (add-to-list 'auto-mode-alist '("\\.rtf\\'" . sclang-help-mode))
;; ========= ADDITION for HTML help files?? ============ ;; ========= ADDITION for HTML help files?? ============
;; (add-to-list 'auto-mode-alist '("\\.html$" . sclang-help-mode)) ;; (add-to-list 'auto-mode-alist '("\\.html$" . sclang-help-mode))
;; (setq mm-text-html-renderer 'w3m) ;; (setq mm-text-html-renderer 'w3m)
;; (setq mm-inline-text-html-with-images t) ;; (setq mm-inline-text-html-with-images t)
;; (setq mm-inline-text-html-with-w3m-keymap nil) ;; (setq mm-inline-text-html-with-w3m-keymap nil)
;; ===================================================== ;; =====================================================
(sclang-fill-help-syntax-table sclang-help-mode-syntax-table) (sclang-fill-help-syntax-table sclang-help-mode-syntax-table)
(sclang-fill-help-mode-map sclang-help-mode-map) (sclang-fill-help-mode-map sclang-help-mode-map)
(provide 'sclang-help) (provide 'sclang-help)
;; EOF ;;; sclang-help.el ends here

View file

@ -1,5 +1,9 @@
;; copyright 2003-2005 stefan kersten <steve@k-hornz.de> ;;; sclang-interp.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,6 +19,10 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; SuperCollider interpreter interface
(require 'sclang-util) (require 'sclang-util)
(require 'compile) (require 'compile)
@ -24,6 +32,8 @@
;; FIXME: everything will fail when renaming the post buffer! ;; FIXME: everything will fail when renaming the post buffer!
;;; Code:
(defconst sclang-post-buffer (sclang-make-buffer-name "PostBuffer") (defconst sclang-post-buffer (sclang-make-buffer-name "PostBuffer")
"Name of the SuperCollider process output buffer.") "Name of the SuperCollider process output buffer.")
@ -34,7 +44,7 @@
"Character for highlighting errors (utf-8).") "Character for highlighting errors (utf-8).")
(defconst sclang-parse-error-regexp (defconst sclang-parse-error-regexp
"^\\(WARNING\\|ERROR\\): .*\n[\t ]*in file '\\([^']\+\\)'\n[\t ]*line \\([0-9]\+\\) char \\([0-9]\+\\)" "^\\(WARNING\\|ERROR\\): .*\n[\t ]*in file '\\([^']+\\)'\n[\t ]*line \\([0-9]+\\) char \\([0-9]+\\)"
"Regular expression matching parse errors during library compilation.") "Regular expression matching parse errors during library compilation.")
(defcustom sclang-max-post-buffer-size 0 (defcustom sclang-max-post-buffer-size 0
@ -52,9 +62,11 @@ Default behavior is to only scroll when point is not at end of buffer."
:type 'boolean) :type 'boolean)
(defun sclang-get-post-buffer () (defun sclang-get-post-buffer ()
"Get or create the sclang post buffer."
(get-buffer-create sclang-post-buffer)) (get-buffer-create sclang-post-buffer))
(defmacro with-sclang-post-buffer (&rest body) (defmacro with-sclang-post-buffer (&rest body)
"BODY in the sclang post buffer."
`(with-current-buffer (sclang-get-post-buffer) `(with-current-buffer (sclang-get-post-buffer)
,@body)) ,@body))
@ -115,13 +127,14 @@ If EOB-P is non-nil, positions cursor at end of buffer."
(lambda (&rest args))) (lambda (&rest args)))
;; setup compilation mode ;; setup compilation mode
(compilation-minor-mode) (compilation-minor-mode)
(set (make-variable-buffer-local 'compilation-error-screen-columns) nil) ;; see elisp docs for `make-variable-buffer-local' and `make-local-variable' use cases
(set (make-variable-buffer-local 'compilation-error-regexp-alist) (set (make-local-variable 'compilation-error-screen-columns) nil)
(set (make-local-variable 'compilation-error-regexp-alist)
(cons (list sclang-parse-error-regexp 2 3 4) compilation-error-regexp-alist)) (cons (list sclang-parse-error-regexp 2 3 4) compilation-error-regexp-alist))
(set (make-variable-buffer-local 'compilation-parse-errors-function) (set (make-local-variable 'compilation-parse-errors-function)
(lambda (limit-search find-at-least) (lambda (limit-search find-at-least)
(compilation-parse-errors limit-search find-at-least))) (compilation-parse-errors limit-search find-at-least)))
(set (make-variable-buffer-local 'compilation-parse-errors-filename-function) (set (make-local-variable 'compilation-parse-errors-filename-function)
(lambda (file-name) (lambda (file-name)
file-name))) file-name)))
(sclang-clear-post-buffer) (sclang-clear-post-buffer)
@ -189,6 +202,7 @@ If EOB-P is non-nil, positions cursor at end of buffer."
;; ===================================================================== ;; =====================================================================
(defun sclang-get-process () (defun sclang-get-process ()
"Return the current sclang process."
(get-process sclang-process)) (get-process sclang-process))
;; ===================================================================== ;; =====================================================================
@ -217,16 +231,19 @@ If EOB-P is non-nil, positions cursor at end of buffer."
;; initialization ;; initialization
(defun sclang-library-initialized-p () (defun sclang-library-initialized-p ()
"Is sclang library initialized?"
(and (sclang-get-process) (and (sclang-get-process)
sclang-library-initialized-p)) sclang-library-initialized-p))
(defun sclang-on-library-startup () (defun sclang-on-library-startup ()
"Initialize sclang library."
(sclang-message "Initializing library...") (sclang-message "Initializing library...")
(setq sclang-library-initialized-p t) (setq sclang-library-initialized-p t)
(run-hooks 'sclang-library-startup-hook) (run-hooks 'sclang-library-startup-hook)
(sclang-message "Initializing library...done")) (sclang-message "Initializing library...done"))
(defun sclang-on-library-shutdown () (defun sclang-on-library-shutdown ()
"Library shutdown."
(when sclang-library-initialized-p (when sclang-library-initialized-p
(run-hooks 'sclang-library-shutdown-hook) (run-hooks 'sclang-library-shutdown-hook)
(setq sclang-library-initialized-p nil) (setq sclang-library-initialized-p nil)
@ -237,6 +254,7 @@ If EOB-P is non-nil, positions cursor at end of buffer."
;; ===================================================================== ;; =====================================================================
(defun sclang-process-sentinel (proc msg) (defun sclang-process-sentinel (proc msg)
"Process sentinel PROC MSG."
(with-sclang-post-buffer (with-sclang-post-buffer
(goto-char (point-max)) (goto-char (point-max))
(insert (insert
@ -248,6 +266,7 @@ If EOB-P is non-nil, positions cursor at end of buffer."
(sclang-stop-command-process))) (sclang-stop-command-process)))
(defun sclang-process-filter (process string) (defun sclang-process-filter (process string)
"Process filter PROCESS STRING."
(let ((buffer (process-buffer process))) (let ((buffer (process-buffer process)))
(with-current-buffer buffer (with-current-buffer buffer
(when (and (> sclang-max-post-buffer-size 0) (when (and (> sclang-max-post-buffer-size 0)
@ -275,13 +294,16 @@ If EOB-P is non-nil, positions cursor at end of buffer."
;; ===================================================================== ;; =====================================================================
(defun sclang-memory-option-p (string) (defun sclang-memory-option-p (string)
"Is STRING an sclang memory option?"
(let ((case-fold-search nil)) (let ((case-fold-search nil))
(string-match "^[1-9][0-9]*[km]?$" string))) (string-match "^[1-9][0-9]*[km]?$" string)))
(defun sclang-port-option-p (number) (defun sclang-port-option-p (number)
"Is NUMBER a valid sclang port?"
(and (integerp number) (>= number 0) (<= number #XFFFF))) (and (integerp number) (>= number 0) (<= number #XFFFF)))
(defun sclang-make-options () (defun sclang-make-options ()
"Make options."
(let ((default-directory "")) (let ((default-directory ""))
(nconc (nconc
(when (and sclang-runtime-directory (when (and sclang-runtime-directory
@ -346,8 +368,7 @@ If EOB-P is non-nil, positions cursor at end of buffer."
"Recompile class library." "Recompile class library."
(interactive) (interactive)
(when (sclang-get-process) (when (sclang-get-process)
(process-send-string sclang-process "\x18") (process-send-string sclang-process "\x18")))
))
;; ===================================================================== ;; =====================================================================
;; command process ;; command process
@ -371,23 +392,26 @@ Change this if \"cat\" has a non-standard name or location."
"Subprocess for receiving command results from sclang.") "Subprocess for receiving command results from sclang.")
(defconst sclang-cmd-helper-proc "SCLang Command Helper" (defconst sclang-cmd-helper-proc "SCLang Command Helper"
"Dummy subprocess that will keep the command fifo open for writing "Dummy subprocess that will keep the command fifo open for writing.
so reading does not fail automatically when sclang closes its own This is needed so reading does not automatically fail when sclang
writing end of the fifo") closes its own writing end of the fifo.")
(defvar sclang-command-fifo nil (defvar sclang-command-fifo nil
"FIFO for communicating with the subprocess.") "FIFO for communicating with the subprocess.")
(defun sclang-delete-command-fifo () (defun sclang-delete-command-fifo ()
"Delete the command fifo."
(and sclang-command-fifo (and sclang-command-fifo
(file-exists-p sclang-command-fifo) (file-exists-p sclang-command-fifo)
(delete-file sclang-command-fifo))) (delete-file sclang-command-fifo)))
(defun sclang-release-command-fifo () (defun sclang-release-command-fifo ()
"Release the command fifo."
(sclang-delete-command-fifo) (sclang-delete-command-fifo)
(setq sclang-command-fifo nil)) (setq sclang-command-fifo nil))
(defun sclang-create-command-fifo () (defun sclang-create-command-fifo ()
"Create the command fifo."
(setq sclang-command-fifo (make-temp-name (setq sclang-command-fifo (make-temp-name
(expand-file-name (expand-file-name
"sclang-command-fifo." temporary-file-directory))) "sclang-command-fifo." temporary-file-directory)))
@ -400,6 +424,7 @@ Change this if \"cat\" has a non-standard name or location."
(setq sclang-command-fifo nil)))) (setq sclang-command-fifo nil))))
(defun sclang-start-command-process () (defun sclang-start-command-process ()
"Start the command process."
(sclang-create-command-fifo) (sclang-create-command-fifo)
(when sclang-command-fifo (when sclang-command-fifo
;; start the dummy process to keep the fifo open ;; start the dummy process to keep the fifo open
@ -423,6 +448,7 @@ Change this if \"cat\" has a non-standard name or location."
(message "SCLang: Couldn't start command process")))) (message "SCLang: Couldn't start command process"))))
(defun sclang-stop-command-process () (defun sclang-stop-command-process ()
"Stop the command process."
(when (get-process sclang-cmd-helper-proc) (when (get-process sclang-cmd-helper-proc)
(kill-process sclang-cmd-helper-proc) (kill-process sclang-cmd-helper-proc)
(delete-process sclang-cmd-helper-proc)) (delete-process sclang-cmd-helper-proc))
@ -434,6 +460,7 @@ Change this if \"cat\" has a non-standard name or location."
"Unprocessed command process output.") "Unprocessed command process output.")
(defun sclang-command-process-filter (proc string) (defun sclang-command-process-filter (proc string)
"Command process filter PROC STRING."
(when sclang-command-process-previous (when sclang-command-process-previous
(setq string (concat sclang-command-process-previous string))) (setq string (concat sclang-command-process-previous string)))
(let (end) (let (end)
@ -452,27 +479,31 @@ Change this if \"cat\" has a non-standard name or location."
;; symbol property: sclang-command-handler ;; symbol property: sclang-command-handler
(defun sclang-set-command-handler (symbol function) (defun sclang-set-command-handler (symbol function)
"Set command handler SYMBOL to FUNCTION."
(put symbol 'sclang-command-handler function)) (put symbol 'sclang-command-handler function))
(defun sclang-perform-command (symbol &rest args) (defun sclang-perform-command (symbol &rest args)
"Eval command SYMBOL with ARGS."
(sclang-eval-string (sclang-format (sclang-eval-string (sclang-format
"Emacs.lispPerformCommand(%o, %o, true)" "Emacs.lispPerformCommand(%o, %o, true)"
symbol args))) symbol args)))
(defun sclang-perform-command-no-result (symbol &rest args) (defun sclang-perform-command-no-result (symbol &rest args)
"Eval command SYMBOL with ARGS. No result."
(sclang-eval-string (sclang-format (sclang-eval-string (sclang-format
"Emacs.lispPerformCommand(%o, %o, false)" "Emacs.lispPerformCommand(%o, %o, false)"
symbol args))) symbol args)))
(defun sclang-default-command-handler (fun arg) (defun sclang-default-command-handler (fun arg)
"Default command handler. "Default command handler for FUN with ARG.
Displays short message on error." Displays short message on error."
(condition-case nil (condition-case err
(funcall fun arg) (funcall fun arg)
(error (sclang-message "Error in command handler") nil))) (error (sclang-message
(format "Error in command handler: %s" err)) nil)))
(defun sclang-debug-command-handler (fun arg) (defun sclang-debug-command-handler (fun arg)
"Debugging command handler. "Debugging command handler for FUN with ARG.
Enters debugger on error." Enters debugger on error."
(let ((debug-on-error t) (let ((debug-on-error t)
(debug-on-signal t)) (debug-on-signal t))
@ -482,20 +513,21 @@ Enters debugger on error."
"Function called when handling command result.") "Function called when handling command result.")
(defun sclang-toggle-debug-command-handler (&optional arg) (defun sclang-toggle-debug-command-handler (&optional arg)
"Toggle debugging of command handler. "Toggle debugging of command handler (or set with ARG).
With arg, activate debugging iff arg is positive." Activate debugging iff ARG is positive."
(interactive "P") (interactive "P")
(setq sclang-command-handler (setq sclang-command-handler
(if (or (and arg (> arg 0)) (if (or (and arg (> arg 0))
(eq sclang-command-handler 'sclang-debug-command-handler)) (eq sclang-command-handler 'sclang-debug-command-handler))
'sclang-default-command-handler 'sclang-default-command-handler
'sclang-default-command-handler)) 'sclang-debug-command-handler))
(sclang-message "Command handler debugging %s." (sclang-message "Command handler debugging %s."
(if (eq sclang-command-handler 'sclang-debug-command-handler) (if (eq sclang-command-handler 'sclang-debug-command-handler)
"enabled" "enabled"
"disabled"))) "disabled")))
(defun sclang-handle-command-result (list) (defun sclang-handle-command-result (list)
"Handle command result LIST."
(condition-case nil (condition-case nil
(let ((fun (get (nth 0 list) 'sclang-command-handler)) (let ((fun (get (nth 0 list) 'sclang-command-handler))
(arg (nth 1 list)) (arg (nth 1 list))
@ -520,25 +552,26 @@ With arg, activate debugging iff arg is positive."
:type 'boolean) :type 'boolean)
(defun sclang-send-string (token string &optional force) (defun sclang-send-string (token string &optional force)
"Send TOKEN STRING to sclang (optionally FORCE)."
(let ((proc (sclang-get-process))) (let ((proc (sclang-get-process)))
(when (and proc (or (sclang-library-initialized-p) force)) (when (and proc (or (sclang-library-initialized-p) force))
(process-send-string proc (concat string token)) (process-send-string proc (concat string token))
string))) string)))
(defun sclang-eval-string (string &optional print-p) (defun sclang-eval-string (string &optional print-p)
"Send STRING to the sclang process for evaluation and print the result "Evaluate STRING with sclang and print the result if PRINT-P is non-nil.
if PRINT-P is non-nil. Return STRING if successful, otherwise nil." Return STRING if successful, otherwise nil."
(sclang-send-string (sclang-send-string
(if print-p sclang-token-interpret-print-cmd-line sclang-token-interpret-cmd-line) (if print-p sclang-token-interpret-print-cmd-line sclang-token-interpret-cmd-line)
string)) string))
(defun sclang-eval-expression (string &optional silent-p) (defun sclang-eval-expression (string &optional silent-p)
"Execute STRING as SuperCollider code." "Evaluate STRING as SuperCollider code (suppress output if SILENT-P is non-nil)."
(interactive "sEval: \nP") (interactive "sEval: \nP")
(sclang-eval-string string (not silent-p))) (sclang-eval-string string (not silent-p)))
(defun sclang-eval-line (&optional silent-p) (defun sclang-eval-line (&optional silent-p)
"Execute the current line as SuperCollider code." "Evaluate current line with sclang (suppress output if SILENT-P is non-nil)."
(interactive "P") (interactive "P")
(let ((string (sclang-line-at-point))) (let ((string (sclang-line-at-point)))
(when string (when string
@ -549,32 +582,39 @@ if PRINT-P is non-nil. Return STRING if successful, otherwise nil."
string)) string))
(defun sclang-eval-region (&optional silent-p) (defun sclang-eval-region (&optional silent-p)
"Execute the region as SuperCollider code." "Evaluate current region with sclang (suppress output if SILENT-P is non-nil)."
(interactive "P") (interactive "P")
(sclang-eval-string (sclang-eval-string
(buffer-substring-no-properties (region-beginning) (region-end)) (buffer-substring-no-properties (region-beginning) (region-end))
(not silent-p))) (not silent-p)))
(defun sclang-eval-region-or-line (&optional silent-p) (defun sclang-eval-region-or-line (&optional silent-p)
"Evaluate current line or region (suppress output if SILENT-P is non-nil)."
(interactive "P") (interactive "P")
(if (and transient-mark-mode mark-active) (if (and transient-mark-mode mark-active)
(sclang-eval-region silent-p) (sclang-eval-region silent-p)
(sclang-eval-line silent-p))) (sclang-eval-line silent-p)))
(defun sclang-eval-defun (&optional silent-p) (defun sclang-eval-defun (&optional silent-p)
"Evaluate current function definition (suppress output if SILENT-P is non-nil)."
(interactive "P") (interactive "P")
(let ((string (sclang-defun-at-point))) (let ((string (sclang-defun-at-point)))
(when (and string (string-match "^(" string)) (when (and string (string-match "^(" string))
(sclang-eval-string string (not silent-p)) (sclang-eval-string string (not silent-p))
string))) string)))
(defun sclang-eval-dwim ()
"Evaluate line, region, function or buffer."
(interactive "P")
(or (sclang-eval-defun)
(sclang-eval-region-or-line)))
(defun sclang-eval-document (&optional silent-p) (defun sclang-eval-document (&optional silent-p)
"Execute the whole document as SuperCollider code." "Evaluate current buffer with sclang (suppress output if SILENT-P is non-nil)."
(interactive "P") (interactive "P")
(save-excursion (save-excursion
(mark-whole-buffer)
(sclang-eval-string (sclang-eval-string
(buffer-substring-no-properties (region-beginning) (region-end)) (buffer-substring-no-properties (point-min) (point-max))
(not silent-p)))) (not silent-p))))
(defvar sclang-eval-results nil (defvar sclang-eval-results nil
@ -585,7 +625,7 @@ if PRINT-P is non-nil. Return STRING if successful, otherwise nil."
(lambda (arg) (push arg sclang-eval-results))) (lambda (arg) (push arg sclang-eval-results)))
(defun sclang-eval-sync (string) (defun sclang-eval-sync (string)
"Eval STRING in sclang and return result as a lisp value." "Eval STRING in sclang and return result as a Lisp value."
(let ((proc (get-process sclang-command-process))) (let ((proc (get-process sclang-command-process)))
(if (and (processp proc) (eq (process-status proc) 'run)) (if (and (processp proc) (eq (process-status proc) 'run))
(let ((time (current-time)) (tick 10000) elt) (let ((time (current-time)) (tick 10000) elt)
@ -653,15 +693,18 @@ if PRINT-P is non-nil. Return STRING if successful, otherwise nil."
(defconst sclang-workspace-buffer (sclang-make-buffer-name "Workspace")) (defconst sclang-workspace-buffer (sclang-make-buffer-name "Workspace"))
(defun sclang-fill-workspace-mode-map (map) (defun sclang-fill-workspace-mode-map (map)
"Fill the workspace keymap MAP."
(define-key map "\C-c}" 'bury-buffer)) (define-key map "\C-c}" 'bury-buffer))
(defun sclang-switch-to-workspace () (defun sclang-switch-to-workspace ()
"Switch to SuperCollider workspace buffer."
(interactive) (interactive)
(let ((buffer (get-buffer sclang-workspace-buffer))) (let ((buffer (get-buffer sclang-workspace-buffer)))
(unless buffer (unless buffer
(setq buffer (get-buffer-create sclang-workspace-buffer)) (setq buffer (get-buffer-create sclang-workspace-buffer))
(with-current-buffer buffer (with-current-buffer buffer
(sclang-mode) (sclang-mode)
;; why a buffer local keymap?
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(set-keymap-parent map sclang-mode-map) (set-keymap-parent map sclang-mode-map)
(sclang-fill-workspace-mode-map map) (sclang-fill-workspace-mode-map map)
@ -690,10 +733,12 @@ if PRINT-P is non-nil. Return STRING if successful, otherwise nil."
;; ===================================================================== ;; =====================================================================
(defun sclang-main-run () (defun sclang-main-run ()
"Run sclang process."
(interactive) (interactive)
(sclang-eval-string "thisProcess.run")) (sclang-eval-string "thisProcess.run"))
(defun sclang-main-stop () (defun sclang-main-stop ()
"Stop sclang process."
(interactive) (interactive)
(sclang-eval-string "thisProcess.stop")) (sclang-eval-string "thisProcess.stop"))
@ -739,6 +784,7 @@ if PRINT-P is non-nil. Return STRING if successful, otherwise nil."
(sclang-mode) (sclang-mode)
(switch-to-buffer (current-buffer)))))))) (switch-to-buffer (current-buffer))))))))
(provide 'sclang-interp) (provide 'sclang-interp)
;; EOF ;;; sclang-interp.el ends here

View file

@ -1,5 +1,9 @@
;; copyright 2003 stefan kersten <steve@k-hornz.de> ;;; sclang-keys.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,6 +19,15 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Read & send keys between Emacs and SuperCollider
;;; Code:
(eval-and-compile (require 'sclang-util)
(require 'sclang-interp))
;; (defvar sclang-key-table (make-char-table 'foo)) ;; (defvar sclang-key-table (make-char-table 'foo))
;; (defun sclang-define-key (char beg end) ;; (defun sclang-define-key (char beg end)
@ -25,10 +38,9 @@
;; (defun sclang-execute-key (char) ;; (defun sclang-execute-key (char)
;; (sclang-eval-string (sclang-format "Emacs.executeKey(%o)" char))) ;; (sclang-eval-string (sclang-format "Emacs.executeKey(%o)" char)))
(eval-and-compile (require 'sclang-util)
(require 'sclang-interp))
(defun sclang-read-keys () (defun sclang-read-keys ()
"Read and send keys between Emacs and SuperCollider."
(interactive) (interactive)
(let (char) (let (char)
(clear-this-command-keys) (clear-this-command-keys)
@ -39,5 +51,7 @@
(message "%s (%d)" (char-to-string char) char) (message "%s (%d)" (char-to-string char) char)
(sclang-eval-string (format "Emacs.keys.at(%d).value(%d)" char char)))))) (sclang-eval-string (format "Emacs.keys.at(%d).value(%d)" char char))))))
;; EOF
(provide 'sclang-keys)
;;; sclang-keys.el ends here

View file

@ -1,5 +1,9 @@
;; copyright 2003-2005 stefan kersten <steve@k-hornz.de> ;;; sclang-language.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,14 +19,20 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Utilities for SuperCollider syntax
(require 'cl-lib) (require 'cl-lib)
(require 'sclang-browser) (require 'sclang-browser)
(require 'sclang-interp) (require 'sclang-interp)
(require 'sclang-util) (require 'sclang-util)
;; ===================================================================== ;; ===================================================================
;; regexp utilities ;; regexp utilities
;; ===================================================================== ;; ===================================================================
;;; Code:
(defun sclang-regexp-group (regexp &optional addressable) (defun sclang-regexp-group (regexp &optional addressable)
"Enclose REGEXP in grouping parentheses. "Enclose REGEXP in grouping parentheses.
@ -37,9 +47,9 @@ separately after matching."
The expressions are joined as alternatives with the \\| operator." The expressions are joined as alternatives with the \\| operator."
(mapconcat 'sclang-regexp-group regexps "\\|")) (mapconcat 'sclang-regexp-group regexps "\\|"))
;; ===================================================================== ;; ===================================================================
;; some useful regular expressions ;; some useful regular expressions
;; ===================================================================== ;; ===================================================================
(defconst sclang-symbol-regexp (defconst sclang-symbol-regexp
"\\(?:\\sw\\|\\s_\\)*" "\\(?:\\sw\\|\\s_\\)*"
@ -119,9 +129,9 @@ enclosed by parenthesis (`sclang-block-regexp').")
A specification is of the form <class-name>-<method-name>.") A specification is of the form <class-name>-<method-name>.")
;; ===================================================================== ;; ===================================================================
;; regexp building ;; regexp building
;; ===================================================================== ;; ===================================================================
(defun sclang-make-class-definition-regexp (name) (defun sclang-make-class-definition-regexp (name)
"Return a regular expression matching the class definition NAME." "Return a regular expression matching the class definition NAME."
@ -138,9 +148,9 @@ A specification is of the form <class-name>-<method-name>.")
"Return a regular expression matching the method definition NAME." "Return a regular expression matching the method definition NAME."
(concat "\\(" (regexp-quote name) "\\)\\s *{")) (concat "\\(" (regexp-quote name) "\\)\\s *{"))
;; ===================================================================== ;; ===================================================================
;; string matching ;; string matching
;; ===================================================================== ;; ===================================================================
(defun sclang-string-match (regexp string) (defun sclang-string-match (regexp string)
"Match REGEXP with STRING while preserving case." "Match REGEXP with STRING while preserving case."
@ -148,48 +158,57 @@ A specification is of the form <class-name>-<method-name>.")
(string-match regexp string))) (string-match regexp string)))
(defun sclang-symbol-match (symbol-regexp string) (defun sclang-symbol-match (symbol-regexp string)
"Match SYMBOL-REGEXP in STRING."
(sclang-string-match (concat "^" symbol-regexp "$") string)) (sclang-string-match (concat "^" symbol-regexp "$") string))
;; ===================================================================== ;; ===================================================================
;; symbol name predicates ;; symbol name predicates
;; ===================================================================== ;; ===================================================================
(defun sclang-class-name-p (string) (defun sclang-class-name-p (string)
"Is STRING an sclang class name?"
(sclang-symbol-match sclang-class-name-regexp string)) (sclang-symbol-match sclang-class-name-regexp string))
(defun sclang-meta-class-name-p (string) (defun sclang-meta-class-name-p (string)
"Is STRING an sclang meta class name?"
(and (sclang-class-name-p string) (and (sclang-class-name-p string)
(sclang-string-match "^Meta_" string))) (sclang-string-match "^Meta_" string)))
(defun sclang-method-name-p (string) (defun sclang-method-name-p (string)
"Is STRING an sclang method name?"
(sclang-symbol-match sclang-method-name-regexp string)) (sclang-symbol-match sclang-method-name-regexp string))
(defun sclang-symbol-name-p (string) (defun sclang-symbol-name-p (string)
"Is STRING an sclang symbol name?"
(sclang-symbol-match sclang-symbol-name-regexp string)) (sclang-symbol-match sclang-symbol-name-regexp string))
(defun sclang-method-name-setter-p (method-name) (defun sclang-method-name-setter-p (method-name)
"Is METHOD-NAME an sclang method name setter?"
(string-match "_$" method-name)) (string-match "_$" method-name))
(defun sclang-method-name-getter-p (method-name) (defun sclang-method-name-getter-p (method-name)
"Is METHOD-NAME an sclang method name getter?"
(not (sclang-method-name-setter-p method-name))) (not (sclang-method-name-setter-p method-name)))
;; ===================================================================== ;; ===================================================================
;; symbol name manipulation ;; symbol name manipulation
;; ===================================================================== ;; ===================================================================
(defun sclang-method-name-setter (method-name) (defun sclang-method-name-setter (method-name)
"Return a method name setter for METHOD-NAME."
(if (sclang-method-name-setter-p method-name) (if (sclang-method-name-setter-p method-name)
method-name method-name
(concat method-name "_"))) (concat method-name "_")))
(defun sclang-method-name-getter (method-name) (defun sclang-method-name-getter (method-name)
"Return a method name getter for METHOD-NAME."
(if (sclang-method-name-setter-p method-name) (if (sclang-method-name-setter-p method-name)
(substring method-name 0 (1- (length method-name))) (substring method-name 0 (1- (length method-name)))
method-name)) method-name))
;; ===================================================================== ;; ===================================================================
;; symbol table access ;; symbol table access
;; ===================================================================== ;; ===================================================================
(defcustom sclang-use-symbol-table t (defcustom sclang-use-symbol-table t
"*Retrieve symbol table upon library initialization. "*Retrieve symbol table upon library initialization.
@ -238,17 +257,21 @@ low-resource systems."
(sclang-update-font-lock))) (sclang-update-font-lock)))
(defun sclang-get-symbol-completion-table () (defun sclang-get-symbol-completion-table ()
"Get symbol completion table."
(mapcar (lambda (s) (cons s nil)) sclang-symbol-table)) (mapcar (lambda (s) (cons s nil)) sclang-symbol-table))
(defun sclang-make-symbol-completion-predicate (predicate) (defun sclang-make-symbol-completion-predicate (predicate)
"Make symbol completion PREDICATE."
(and predicate (lambda (assoc) (funcall predicate (car assoc))))) (and predicate (lambda (assoc) (funcall predicate (car assoc)))))
(defun sclang-get-symbol (string) (defun sclang-get-symbol (string)
"Get symbol named STRING."
(if (and sclang-use-symbol-table sclang-symbol-table) (if (and sclang-use-symbol-table sclang-symbol-table)
(car (member string sclang-symbol-table)) (car (member string sclang-symbol-table))
string)) string))
(defun sclang-read-symbol (prompt &optional default predicate require-match inherit-input-method) (defun sclang-read-symbol (prompt &optional default predicate require-match inherit-input-method)
"Read symbol PROMPT (options DEFAULT PREDICATE REQUIRE-MATCH and INHERIT-INPUT-METHOD)."
(if sclang-use-symbol-table (if sclang-use-symbol-table
(cl-flet ((make-minibuffer-local-map (cl-flet ((make-minibuffer-local-map
(parent-keymap) (parent-keymap)
@ -271,14 +294,12 @@ low-resource systems."
(read-string (sclang-make-prompt-string prompt default) nil (read-string (sclang-make-prompt-string prompt default) nil
'sclang-symbol-history default inherit-input-method))) 'sclang-symbol-history default inherit-input-method)))
;; ===================================================================== ;; ===================================================================
;; buffer movement ;; buffer movement
;; ===================================================================== ;; ===================================================================
(defun sclang-point-in-comment-p () (defun sclang-point-in-comment-p ()
"Return non-nil if point is inside a comment. "Return non-nil if point is inside a comment."
Use font-lock information if font-lock-mode is enabled."
(if (and (boundp 'font-lock-mode) (eval 'font-lock-mode)) (if (and (boundp 'font-lock-mode) (eval 'font-lock-mode))
;; use available information in font-lock-mode ;; use available information in font-lock-mode
(eq (get-text-property (point) 'face) 'font-lock-comment-face) (eq (get-text-property (point) 'face) 'font-lock-comment-face)
@ -289,6 +310,7 @@ Use font-lock information if font-lock-mode is enabled."
(not (null (nth 4 (parse-partial-sexp (point) beg)))))))) (not (null (nth 4 (parse-partial-sexp (point) beg))))))))
(defun sclang-beginning-of-defun (&optional arg) (defun sclang-beginning-of-defun (&optional arg)
"Move to beginning of function (optionally ARG)."
(interactive "p") (interactive "p")
(let ((case-fold-search nil) (let ((case-fold-search nil)
(arg (or arg (prefix-numeric-value current-prefix-arg))) (arg (or arg (prefix-numeric-value current-prefix-arg)))
@ -324,6 +346,7 @@ Return value is nil or (beg end) of defun."
(list beg end))))) (list beg end)))))
(defun sclang-end-of-defun (&optional arg) (defun sclang-end-of-defun (&optional arg)
"Move to end of function (optionally ARG)."
(interactive "p") (interactive "p")
(let ((case-fold-search nil) (let ((case-fold-search nil)
(arg (or arg (prefix-numeric-value current-prefix-arg))) (arg (or arg (prefix-numeric-value current-prefix-arg)))
@ -351,9 +374,9 @@ Return value is nil or (beg end) of defun."
(when success (when success
(forward-line 1) t))) (forward-line 1) t)))
;; ===================================================================== ;; ===================================================================
;; buffer object access ;; buffer object access
;; ===================================================================== ;; ===================================================================
(defun sclang-symbol-at-point (&optional symbol-name-regexp) (defun sclang-symbol-at-point (&optional symbol-name-regexp)
"Return the symbol at point, or nil if not a valid symbol. "Return the symbol at point, or nil if not a valid symbol.
@ -394,9 +417,9 @@ A defun may either be a class definition or a code block, see
(cl-multiple-value-bind (beg end) (sclang-point-in-defun-p) (cl-multiple-value-bind (beg end) (sclang-point-in-defun-p)
(and beg end (buffer-substring-no-properties beg end)))))) (and beg end (buffer-substring-no-properties beg end))))))
;; ===================================================================== ;; ===================================================================
;; symbol completion ;; symbol completion
;; ===================================================================== ;; ===================================================================
(defun sclang-complete-symbol (&optional predicate) (defun sclang-complete-symbol (&optional predicate)
"Perform completion on symbol preceding point. "Perform completion on symbol preceding point.
@ -471,9 +494,9 @@ are considered."
:exclusive 'no :exclusive 'no
:company-docsig #'identity))) :company-docsig #'identity)))
;; ===================================================================== ;; ===================================================================
;; introspection ;; introspection
;; ===================================================================== ;; ===================================================================
(defcustom sclang-definition-marker-ring-length 32 (defcustom sclang-definition-marker-ring-length 32
"*Length of marker ring `sclang-definition-marker-ring'." "*Length of marker ring `sclang-definition-marker-ring'."
@ -492,6 +515,7 @@ are considered."
(make-ring sclang-definition-marker-ring-length)))) (make-ring sclang-definition-marker-ring-length))))
(defun sclang-open-definition (name file pos &optional pos-func) (defun sclang-open-definition (name file pos &optional pos-func)
"Open definition NAME in FILE at POS (optionally POS-FUNC)."
(let ((buffer (find-file file))) (let ((buffer (find-file file)))
(when (bufferp buffer) (when (bufferp buffer)
(with-current-buffer buffer (with-current-buffer buffer
@ -512,6 +536,7 @@ are considered."
(set-marker marker nil nil)))) (set-marker marker nil nil))))
(defun sclang-browse-definitions (name definitions buffer-name header &optional pos-func) (defun sclang-browse-definitions (name definitions buffer-name header &optional pos-func)
"Browse definitions. NAME DEFINITIONS BUFFER-NAME HEADER (optionally POS-FUNC)."
(if (cdr definitions) (if (cdr definitions)
(let ((same-window-buffer-names (list buffer-name))) (let ((same-window-buffer-names (list buffer-name)))
(with-sclang-browser (with-sclang-browser
@ -630,7 +655,7 @@ are considered."
(sclang-message "No references to '%s'" name))))) (sclang-message "No references to '%s'" name)))))
(defun sclang-show-method-args () (defun sclang-show-method-args ()
"whooha. in full effect." "Show method args."
(interactive) (interactive)
(let ((regexp (concat (let ((regexp (concat
sclang-class-name-regexp sclang-class-name-regexp
@ -683,9 +708,9 @@ are considered."
class 'sclang-class-name-p t)))) class 'sclang-class-name-p t))))
(sclang-eval-string (format "%s.dumpInterface" class))) (sclang-eval-string (format "%s.dumpInterface" class)))
;; ===================================================================== ;; ===================================================================
;; cscope interface ;; cscope interface
;; ===================================================================== ;; ===================================================================
(defcustom sclang-source-directory nil (defcustom sclang-source-directory nil
"Toplevel SuperCollider source directory. "Toplevel SuperCollider source directory.
@ -698,7 +723,7 @@ database."
:options '(must-match)) :options '(must-match))
(defun sclang-find-primitive (name) (defun sclang-find-primitive (name)
"Find primitive name a cscope database. "Find primitive NAME in a cscope database.
The database is searched in `sclang-source-directory', or the The database is searched in `sclang-source-directory', or the
current-directory, iff `sclang-source-directoy' is nil." current-directory, iff `sclang-source-directoy' is nil."
@ -708,23 +733,26 @@ current-directory, iff `sclang-source-directoy' is nil."
nil nil default)))) nil nil default))))
(if (require 'xcscope nil t) (if (require 'xcscope nil t)
(let ((cscope-initial-directory sclang-source-directory)) (let ((cscope-initial-directory sclang-source-directory))
;; only fboundp when xcscope is loaded
(cscope-find-this-text-string (cscope-find-this-text-string
(if (string-match "^_" name) name (concat "_" name)))) (if (string-match "^_" name) name (concat "_" name))))
(sclang-message "cscope not available"))) (sclang-message "cscope not available")))
;; ===================================================================== ;; ===================================================================
;; sc-code formatting ;; sc-code formatting
;; ===================================================================== ;; ===================================================================
(defun sclang-list-to-string (list) (defun sclang-list-to-string (list)
"Convert sclang LIST to string."
(mapconcat 'sclang-object-to-string list ", ")) (mapconcat 'sclang-object-to-string list ", "))
(defconst false 'false) (defconst sclang-false 'false)
(defun sclang-object-to-string (obj) (defun sclang-object-to-string (obj)
"Convert sclang object OBJ to string."
(cond ((null obj) (cond ((null obj)
"nil") "nil")
((eq false obj) ((eq sclang-false obj)
"false") "false")
((eq t obj) ((eq t obj)
"true") "true")
@ -735,7 +763,7 @@ current-directory, iff `sclang-source-directoy' is nil."
(t (format "%S" obj)))) (t (format "%S" obj))))
(defun sclang-format (string &rest args) (defun sclang-format (string &rest args)
"format chars: "Format STRING using ARGS.
%s - print string %s - print string
%o - print object %o - print object
%l - print argument list" %l - print argument list"
@ -798,7 +826,8 @@ want smart pattern guessing, use `sclang-format' directly to format your Pseq."
(cl-decf i)))) (cl-decf i))))
(cl-decf rep))) (cl-decf rep)))
(accept-process-output nil 0 100) (accept-process-output nil 0 100)
(message "Processed...%S" ret) ;; invent better progress info ;; invent better progress info
(message "Processed...%S" ret)
(setq r (append r (list ret)) (setq r (append r (list ret))
items (nthcdr skip items)))) items (nthcdr skip items))))
r)) r))
@ -816,10 +845,10 @@ want smart pattern guessing, use `sclang-format' directly to format your Pseq."
(mapconcat #'elem-to-string compressed ", ") (mapconcat #'elem-to-string compressed ", ")
" ], 1)"))))) " ], 1)")))))
;; ===================================================================== ;; ===================================================================
;; module setup ;; module setup
;; ===================================================================== ;; ===================================================================
(provide 'sclang-language) (provide 'sclang-language)
;; EOF ;;; sclang-language.el ends here

View file

@ -1,5 +1,9 @@
;; copyright 2003 stefan kersten <steve@k-hornz.de> ;;; sclang-menu.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,9 +19,16 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Menus
;;; Code:
;; (sclang-set-command-handler ;; (sclang-set-command-handler
;; '_updateMenu ;; '_updateMenu
;; (lambda (arg) ;; (lambda (arg)
;; (message "menu: %s" arg))) ;; (message "menu: %s" arg)))
(provide 'sclang-menu) (provide 'sclang-menu)
;;; sclang-menu.el ends here

View file

@ -1,7 +1,9 @@
;;; sclang-minor-mode for use in help files ;;; sclang-minor-mode.el --- IDE for working with SuperCollider -*- coding: utf-8;
;;; SuperCollider ;;
;;; (c) 2007, Marije Baalman - nescivi <nescivi@gmail.com> ;; Copyright (c) 2007, Marije Baalman - nescivi <nescivi@gmail.com>
;;;
;;; License:
;;; This program is free software; you can redistribute it and/or modify ;;; This program is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by ;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 2 of the License, or ;;; the Free Software Foundation; either version 2 of the License, or
@ -16,6 +18,12 @@
;;; along with this program; if not, write to the Free Software ;;; along with this program; if not, write to the Free Software
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;;; Commentary:
;;
;; sclang-minor-mode for use in help files
;;; Code:
(require 'sclang-util) (require 'sclang-util)
(require 'sclang-mode) (require 'sclang-mode)
@ -25,53 +33,55 @@ With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode. Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode. Null prefix argument turns off the mode.
When sclang-minor-mode is enabled, you can execute When sclang-minor-mode is enabled, you can use the key sequences
sclang code with the normal command C-c C-c and C-c C-d." \\<sclang-minor-mode-map>\\[sclang-eval-region-or-line] or \\<sclang-minor-mode-map>\\[sclang-eval-region] to eval sclang code."
;; The initial value. ;; The initial value.
nil :init-value nil
;; The indicator for the mode line. ;; The indicator for the mode line.
" sclang" :lighter " sclang"
;; The minor mode bindings. ;; The minor mode bindings.
'(("\C-c\C-c" . sclang-eval-region-or-line) :keymap '(("\C-c\C-c" . sclang-eval-region-or-line)
("\C-c\C-d" . sclang-eval-region) ("\C-c\C-d" . sclang-eval-region)
("\C-\M-x" . sclang-eval-defun) ("\C-\M-x" . sclang-eval-defun)
("\C-c\C-h" . sclang-find-help) ("\C-c\C-h" . sclang-find-help)
("\C-\M-h" . sclang-goto-help-browser) ("\C-\M-h" . sclang-goto-help-browser)
("\C-c\C-s" . sclang-main-stop) ("\C-c\C-s" . sclang-main-stop)
("\C-c\C-k" . sclang-edit-dev-source) ("\C-c\C-k" . sclang-edit-dev-source)))
))
(provide 'sclang-minor-mode) (provide 'sclang-minor-mode)
(easy-mmode-define-minor-mode sclang-help-minor-mode (easy-mmode-define-minor-mode sclang-help-minor-mode
"Toggle sclang-minor-mode. "Toggle sclang-minor-mode.
With no argument, this command toggles the mode. With no argument, this command toggles the mode.
Non-null prefix argument turns on the mode. Non-null prefix argument turns on the mode.
Null prefix argument turns off the mode. Null prefix argument turns off the mode.
When sclang-help-minor-mode is enabled, you can execute When sclang-help-minor-mode is enabled, you can use the key sequences
sclang code with the normal command C-c C-c and C-c C-d." \\<sclang-minor-mode-map>\\[sclang-eval-region-or-line] or \\<sclang-minor-mode-map>\\[sclang-eval-region] to eval sclang code."
;; The initial value. ;; The initial value.
nil :init-value nil
;; The indicator for the mode line. ;; The indicator for the mode line.
" sclang-help" :lighter " sclang-help"
;; The minor mode bindings. ;; The minor mode bindings.
'(("\C-c\C-c" . sclang-eval-region-or-line) :keymap '(("\C-c\C-c" . sclang-eval-region-or-line)
("\C-c\C-d" . sclang-eval-region) ("\C-c\C-d" . sclang-eval-region)
("\C-\M-x" . sclang-eval-defun) ("\C-\M-x" . sclang-eval-defun)
("\C-c\C-h" . sclang-find-help) ("\C-c\C-h" . sclang-find-help)
("\C-c\C-s" . sclang-main-stop) ("\C-c\C-s" . sclang-main-stop)
("\C-c\C-v" . sclang-edit-html-help-file) ("\C-c\C-v" . sclang-edit-html-help-file)
("E" . sclang-edit-help-code) ("E" . sclang-edit-help-code)
("\C-c\C-k" . sclang-edit-dev-source) ("\C-c\C-k" . sclang-edit-dev-source)))
))
(provide 'sclang-help-minor-mode) (provide 'sclang-help-minor-mode)
;; mode hooks
(defun sclang-minor-hooks ()
"Sclang minor mode hooks."
(sclang-init-document)
(sclang-make-document))
(add-hook 'sclang-help-minor-mode-hook 'sclang-minor-hooks) (add-hook 'sclang-help-minor-mode-hook 'sclang-minor-hooks)
(add-hook 'sclang-minor-mode-hook 'sclang-minor-hooks) (add-hook 'sclang-minor-mode-hook 'sclang-minor-hooks)
(defun sclang-minor-hooks () ;;; sclang-minor-mode.el ends here
(sclang-init-document)
(sclang-make-document)
)

View file

@ -1,5 +1,9 @@
;; copyright 2003-2005 stefan kersten <steve@k-hornz.de> ;;; sclang-mode.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,12 +19,14 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Code:
;;; Commentary:
;; sclang mode
;;; Code:
(require 'cl-lib) (require 'cl-lib)
;; Make byte-compiler happy by declaring external functions and ;; Keep byte-compiler happy by declaring external functions and variables.
;; variables.
(declare-function company-mode "ext:company") (declare-function company-mode "ext:company")
(defvar company-backends) (defvar company-backends)
@ -31,7 +37,7 @@
(require 'sclang-dev) (require 'sclang-dev)
(defun sclang-fill-syntax-table (table) (defun sclang-fill-syntax-table (table)
;; string "Fill the sclang syntax TABLE."
(modify-syntax-entry ?\" "\"" table) (modify-syntax-entry ?\" "\"" table)
(modify-syntax-entry ?\' "\"" table) ; no string syntax class for single quotes (modify-syntax-entry ?\' "\"" table) ; no string syntax class for single quotes
;; expression prefix ;; expression prefix
@ -75,10 +81,10 @@
table) table)
(defun sclang-mode-make-menu (title) (defun sclang-mode-make-menu (title)
"Make mode menu with TITLE."
(easy-menu-create-menu (easy-menu-create-menu
title title
'( '(["Start Interpreter" sclang-start :included (not (sclang-library-initialized-p))]
["Start Interpreter" sclang-start :included (not (sclang-library-initialized-p))]
["Restart Interpreter" sclang-start :included (sclang-library-initialized-p)] ["Restart Interpreter" sclang-start :included (sclang-library-initialized-p)]
["Recompile Class Library" sclang-recompile :included (sclang-library-initialized-p)] ["Recompile Class Library" sclang-recompile :included (sclang-library-initialized-p)]
["Stop Interpreter" sclang-stop :included (sclang-get-process)] ["Stop Interpreter" sclang-stop :included (sclang-get-process)]
@ -110,10 +116,12 @@
"-" "-"
["Run Main" sclang-main-run] ["Run Main" sclang-main-run]
["Stop Main" sclang-main-stop] ["Stop Main" sclang-main-stop]
["Show Server Panels" sclang-show-server-panel] ["Show Server Panels" sclang-show-server-panel])))
)))
(defun sclang-fill-mode-map (map) (defun sclang-fill-mode-map (map)
"Fill keymap MAP for sclang mode."
;; NOTE: keybindings should follow the conventions in https://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Conventions.html
;; process control ;; process control
(define-key map "\C-c\C-l" 'sclang-recompile) (define-key map "\C-c\C-l" 'sclang-recompile)
(define-key map "\C-c\C-o" 'sclang-start) (define-key map "\C-c\C-o" 'sclang-start)
@ -137,10 +145,10 @@
(define-key map "\C-c{" 'sclang-dump-full-interface) (define-key map "\C-c{" 'sclang-dump-full-interface)
(define-key map "\C-c[" 'sclang-dump-interface) (define-key map "\C-c[" 'sclang-dump-interface)
;; documentation access ;; documentation access
(define-key map "\C-c\C-h" 'sclang-find-help) (define-key map "\C-c\C-?f" 'sclang-find-help)
(define-key map "\C-\M-h" 'sclang-goto-help-browser) (define-key map "\C-c\C-?g" 'sclang-goto-help-browser)
(define-key map "\C-c\C-y" 'sclang-open-help-gui) (define-key map "" 'sclang-open-help-gui)
(define-key map "\C-ch" 'sclang-find-help-in-gui) (define-key map "" 'sclang-find-help-in-gui)
;; language control ;; language control
(define-key map "\C-c\C-r" 'sclang-main-run) (define-key map "\C-c\C-r" 'sclang-main-run)
(define-key map "\C-c\C-s" 'sclang-main-stop) (define-key map "\C-c\C-s" 'sclang-main-stop)
@ -163,8 +171,7 @@
;; ===================================================================== ;; =====================================================================
(defconst sclang-font-lock-keyword-list (defconst sclang-font-lock-keyword-list
'( '("arg"
"arg"
"classvar" "classvar"
"const" "const"
"super" "super"
@ -174,22 +181,18 @@
"thisMethod" "thisMethod"
"thisProcess" "thisProcess"
"thisThread" "thisThread"
"var" "var")
)
"*List of keywords to highlight in SCLang mode.") "*List of keywords to highlight in SCLang mode.")
(defconst sclang-font-lock-builtin-list (defconst sclang-font-lock-builtin-list
'( '("false"
"false"
"inf" "inf"
"nil" "nil"
"true" "true")
)
"*List of builtins to highlight in SCLang mode.") "*List of builtins to highlight in SCLang mode.")
(defconst sclang-font-lock-method-list (defconst sclang-font-lock-method-list
'( '("ar"
"ar"
"for" "for"
"forBy" "forBy"
"if" "if"
@ -197,19 +200,16 @@
"kr" "kr"
"tr" "tr"
"loop" "loop"
"while" "while")
)
"*List of methods to highlight in SCLang mode.") "*List of methods to highlight in SCLang mode.")
(defconst sclang-font-lock-error-list (defconst sclang-font-lock-error-list
'( '("die"
"die"
"error" "error"
"exit" "exit"
"halt" "halt"
"verboseHalt" "verboseHalt"
"warn" "warn")
)
"*List of methods signalling errors or warnings.") "*List of methods signalling errors or warnings.")
(defvar sclang-font-lock-class-keywords nil) (defvar sclang-font-lock-class-keywords nil)
@ -229,14 +229,13 @@
(defconst sclang-font-lock-defaults '((sclang-font-lock-keywords (defconst sclang-font-lock-defaults '((sclang-font-lock-keywords
sclang-font-lock-keywords-1 sclang-font-lock-keywords-1
sclang-font-lock-keywords-2 sclang-font-lock-keywords-2
sclang-font-lock-keywords-3 sclang-font-lock-keywords-3)
)
nil nil nil nil
nil nil
beginning-of-defun beginning-of-defun))
))
(defun sclang-font-lock-syntactic-face (state) (defun sclang-font-lock-syntactic-face (state)
"Return font lock face for STATE."
(cond ((eq (nth 3 state) ?') (cond ((eq (nth 3 state) ?')
;; symbol ;; symbol
'font-lock-constant-face) 'font-lock-constant-face)
@ -248,6 +247,7 @@
'font-lock-comment-face))) 'font-lock-comment-face)))
(defun sclang-font-lock-class-keyword-matcher (limit) (defun sclang-font-lock-class-keyword-matcher (limit)
"Font lock class keywords up to LIMIT."
(let ((regexp (concat "\\<" sclang-class-name-regexp "\\>")) (let ((regexp (concat "\\<" sclang-class-name-regexp "\\>"))
(case-fold-search nil) (case-fold-search nil)
(continue t) (continue t)
@ -264,6 +264,7 @@
res)) res))
(defun sclang-set-font-lock-keywords () (defun sclang-set-font-lock-keywords ()
"Set font lock keywords."
(setq (setq
;; level 1 ;; level 1
sclang-font-lock-keywords-1 sclang-font-lock-keywords-1
@ -279,8 +280,7 @@
;; constants ;; constants
(cons "\\s/\\s\\?." 'font-lock-constant-face) ; characters (cons "\\s/\\s\\?." 'font-lock-constant-face) ; characters
(cons (concat "\\\\\\(" sclang-symbol-regexp "\\)") (cons (concat "\\\\\\(" sclang-symbol-regexp "\\)")
'font-lock-constant-face) ; symbols 'font-lock-constant-face)) ; symbols
)
;; level 2 ;; level 2
sclang-font-lock-keywords-2 sclang-font-lock-keywords-2
(append (append
@ -299,23 +299,19 @@
'font-lock-function-name-face) 'font-lock-function-name-face)
;; errors ;; errors
(cons (regexp-opt sclang-font-lock-error-list 'words) (cons (regexp-opt sclang-font-lock-error-list 'words)
'font-lock-warning-face) 'font-lock-warning-face)))
))
;; level 3 ;; level 3
sclang-font-lock-keywords-3 sclang-font-lock-keywords-3
(append (append
sclang-font-lock-keywords-2 sclang-font-lock-keywords-2
(list (list
;; classes ;; classes
(cons 'sclang-font-lock-class-keyword-matcher 'font-lock-type-face) (cons 'sclang-font-lock-class-keyword-matcher 'font-lock-type-face)))
;; (cons (concat "\\<" sclang-class-name-regexp "\\>") 'font-lock-type-face)
))
;; default level ;; default level
sclang-font-lock-keywords sclang-font-lock-keywords-1 sclang-font-lock-keywords sclang-font-lock-keywords-1))
))
(defun sclang-update-font-lock () (defun sclang-update-font-lock ()
"Update font-lock information in all sclang-mode buffers." "Update font-lock information in all `sclang-mode' buffers."
;; too expensive ;; too expensive
;; (dolist (buffer (buffer-list)) ;; (dolist (buffer (buffer-list))
;; (with-current-buffer buffer ;; (with-current-buffer buffer
@ -323,7 +319,7 @@
;; (eq t (car font-lock-keywords)) ;; (eq t (car font-lock-keywords))
;; (setq font-lock-keywords (cdr font-lock-keywords))))) ;; (setq font-lock-keywords (cdr font-lock-keywords)))))
(if (eq major-mode 'sclang-mode) (if (eq major-mode 'sclang-mode)
(font-lock-fontify-buffer))) (font-lock-ensure (point-min) (point-max))))
;; ===================================================================== ;; =====================================================================
;; indentation ;; indentation
@ -337,7 +333,7 @@
(defun sclang-indent-line () (defun sclang-indent-line ()
"Indent current line as sclang code. "Indent current line as sclang code.
Return the amount the indentation changed by." Return the amount the indentation changed by."
(let ((indent (calculate-sclang-indent)) (let ((indent (sclang-calculate-indent))
beg shift-amt beg shift-amt
(case-fold-search nil) (case-fold-search nil)
(pos (- (point-max) (point)))) (pos (- (point-max) (point))))
@ -356,8 +352,8 @@ Return the amount the indentation changed by."
(goto-char (- (point-max) pos)))) (goto-char (- (point-max) pos))))
shift-amt)) shift-amt))
(defun calculate-sclang-indent (&optional parse-start) (defun sclang-calculate-indent (&optional parse-start)
"Return appropriate indentation for current line as sclang code. "Return indentation for current line (optionally from PARSE-START).
Returns the column to indent to." Returns the column to indent to."
(save-excursion (save-excursion
(beginning-of-line) (beginning-of-line)
@ -410,6 +406,7 @@ Returns the column to indent to."
;; ===================================================================== ;; =====================================================================
(defun sclang-electric-brace (arg) (defun sclang-electric-brace (arg)
"Electrify brace ARG."
(interactive "*P") (interactive "*P")
(self-insert-command (prefix-numeric-value arg)) (self-insert-command (prefix-numeric-value arg))
(and (save-excursion (and (save-excursion
@ -418,6 +415,7 @@ Returns the column to indent to."
(indent-according-to-mode))) (indent-according-to-mode)))
(defun sclang-electric-slash (arg) (defun sclang-electric-slash (arg)
"Electrify slash ARG."
(interactive "*P") (interactive "*P")
(let* ((char (char-before)) (let* ((char (char-before))
(indent-p (or (eq char ?/) (indent-p (or (eq char ?/)
@ -426,6 +424,7 @@ Returns the column to indent to."
(if indent-p (indent-according-to-mode)))) (if indent-p (indent-according-to-mode))))
(defun sclang-electric-star (arg) (defun sclang-electric-star (arg)
"Electrify star ARG."
(interactive "*P") (interactive "*P")
(let ((indent-p (eq (char-before) ?/))) (let ((indent-p (eq (char-before) ?/)))
(self-insert-command (prefix-numeric-value arg)) (self-insert-command (prefix-numeric-value arg))
@ -454,24 +453,30 @@ Returns the column to indent to."
(sclang-document-edited-p . (prSetEdited (buffer-modified-p))))) (sclang-document-edited-p . (prSetEdited (buffer-modified-p)))))
(defmacro sclang-next-document-id () (defmacro sclang-next-document-id ()
"Return next document id."
`(cl-incf sclang-document-counter)) `(cl-incf sclang-document-counter))
(defun sclang-document-id (buffer) (defun sclang-document-id (buffer)
"Document id of BUFFER."
(cdr (assq 'sclang-document-id (buffer-local-variables buffer)))) (cdr (assq 'sclang-document-id (buffer-local-variables buffer))))
(defun sclang-document-p (buffer) (defun sclang-document-p (buffer)
"Is BUFFER an sclang document?"
(integerp (sclang-document-id buffer))) (integerp (sclang-document-id buffer)))
(defmacro with-sclang-document (buffer &rest body) (defmacro with-sclang-document (buffer &rest body)
"With sclang BUFFER BODY."
`(when (sclang-document-p buffer) `(when (sclang-document-p buffer)
(with-current-buffer buffer (with-current-buffer buffer
,@body))) ,@body)))
(defun sclang-get-document (id) (defun sclang-get-document (id)
"Return buffer with document ID or nil."
(cl-find-if (lambda (buffer) (eq id (sclang-document-id buffer))) (cl-find-if (lambda (buffer) (eq id (sclang-document-id buffer)))
sclang-document-list)) sclang-document-list))
(defun sclang-init-document () (defun sclang-init-document ()
"Initialize document."
(set (make-local-variable 'sclang-document-id) (sclang-next-document-id)) (set (make-local-variable 'sclang-document-id) (sclang-next-document-id))
(set (make-local-variable 'sclang-document-envir) nil) (set (make-local-variable 'sclang-document-envir) nil)
(dolist (assoc sclang-document-property-map) (dolist (assoc sclang-document-property-map)
@ -479,6 +484,7 @@ Returns the column to indent to."
(cl-pushnew (current-buffer) sclang-document-list)) (cl-pushnew (current-buffer) sclang-document-list))
(defun sclang-document-update-property-1 (assoc &optional force) (defun sclang-document-update-property-1 (assoc &optional force)
"Update document property ASSOC (optionally FORCE)."
(when (consp assoc) (when (consp assoc)
(let* ((key (car assoc)) (let* ((key (car assoc))
(prop (cdr assoc)) (prop (cdr assoc))
@ -491,17 +497,21 @@ Returns the column to indent to."
(car prop) cur-value))))) (car prop) cur-value)))))
(defun sclang-document-update-property (key &optional force) (defun sclang-document-update-property (key &optional force)
"Update document property KEY (optionally FORCE)."
(sclang-document-update-property-1 (assq key sclang-document-property-map) force)) (sclang-document-update-property-1 (assq key sclang-document-property-map) force))
(defun sclang-document-update-properties (&optional force) (defun sclang-document-update-properties (&optional force)
"Update all document properties (optionally FORCE)."
(dolist (assoc sclang-document-property-map) (dolist (assoc sclang-document-property-map)
(sclang-document-update-property-1 assoc force))) (sclang-document-update-property-1 assoc force)))
(defun sclang-make-document () (defun sclang-make-document ()
"Make a new document."
(sclang-perform-command-no-result 'documentNew sclang-document-id) (sclang-perform-command-no-result 'documentNew sclang-document-id)
(sclang-document-update-properties t)) (sclang-document-update-properties t))
(defun sclang-close-document (buffer) (defun sclang-close-document (buffer)
"Close document in BUFFER."
(with-sclang-document (with-sclang-document
buffer buffer
(setq sclang-document-list (delq buffer sclang-document-list)) (setq sclang-document-list (delq buffer sclang-document-list))
@ -509,27 +519,32 @@ Returns the column to indent to."
'documentClosed sclang-document-id))) 'documentClosed sclang-document-id)))
(defun sclang-set-current-document (buffer &optional force) (defun sclang-set-current-document (buffer &optional force)
"Set current document to BUFFER (optionally FORCE)."
(when (or force (not (eq buffer sclang-current-document))) (when (or force (not (eq buffer sclang-current-document)))
(setq sclang-current-document buffer) (setq sclang-current-document buffer)
(sclang-perform-command-no-result 'documentSetCurrent (sclang-document-id buffer)) (sclang-perform-command-no-result 'documentSetCurrent (sclang-document-id buffer))
t)) t))
(defun sclang-document-library-startup-hook-function () (defun sclang-document-library-startup-hook-function ()
"Document library startup hook."
(dolist (buffer sclang-document-list) (dolist (buffer sclang-document-list)
(with-current-buffer buffer (with-current-buffer buffer
(sclang-make-document))) (sclang-make-document)))
(sclang-set-current-document (current-buffer) t)) (sclang-set-current-document (current-buffer) t))
(defun sclang-document-kill-buffer-hook-function () (defun sclang-document-kill-buffer-hook-function ()
"Document kill buffer hook."
(sclang-close-document (current-buffer))) (sclang-close-document (current-buffer)))
(defun sclang-document-post-command-hook-function () (defun sclang-document-post-command-hook-function ()
"Document post command hook."
(when (and (sclang-library-initialized-p) (when (and (sclang-library-initialized-p)
(sclang-document-p (current-buffer))) (sclang-document-p (current-buffer)))
(sclang-document-update-properties)) (sclang-document-update-properties))
(sclang-set-current-document (current-buffer))) (sclang-set-current-document (current-buffer)))
(defun sclang-document-change-major-mode-hook-function () (defun sclang-document-change-major-mode-hook-function ()
"Document change major mode hook."
(sclang-close-document (current-buffer))) (sclang-close-document (current-buffer)))
;; ===================================================================== ;; =====================================================================
@ -605,8 +620,7 @@ Returns the column to indent to."
(let ((doc (and (integerp id) (sclang-get-document id)))) (let ((doc (and (integerp id) (sclang-get-document id))))
(when doc (when doc
(with-current-buffer doc (with-current-buffer doc
(insert str) (insert str))
)
nil))))) nil)))))
(sclang-set-command-handler (sclang-set-command-handler
@ -621,6 +635,7 @@ Returns the column to indent to."
;; ===================================================================== ;; =====================================================================
(defun sclang-mode-set-local-variables () (defun sclang-mode-set-local-variables ()
"Local variables."
(set (make-local-variable 'require-final-newline) nil) (set (make-local-variable 'require-final-newline) nil)
;; indentation ;; indentation
(set (make-local-variable 'indent-line-function) (set (make-local-variable 'indent-line-function)
@ -700,4 +715,5 @@ Returns the column to indent to."
(add-hook 'change-major-mode-hook 'sclang-document-change-major-mode-hook-function) (add-hook 'change-major-mode-hook 'sclang-document-change-major-mode-hook-function)
(provide 'sclang-mode) (provide 'sclang-mode)
;;; sclang-mode ends here
;;; sclang-mode.el ends here

View file

@ -1,5 +1,9 @@
;; copyright 2003-2005 stefan kersten <steve@k-hornz.de> ;;; sclang-server.el --- IDE for working with SuperCollider -*- coding: utf-8;
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -15,12 +19,18 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Interface to the sclang server
(require 'cl-lib) (require 'cl-lib)
(require 'sclang-util) (require 'sclang-util)
(require 'sclang-interp) (require 'sclang-interp)
(require 'sclang-language) (require 'sclang-language)
(require 'sclang-mode) (require 'sclang-mode)
;;; Code:
(defcustom sclang-server-panel "Server.default.makeWindow" (defcustom sclang-server-panel "Server.default.makeWindow"
"Expression to execute when `sclang-show-server-panel' is invoked." "Expression to execute when `sclang-show-server-panel' is invoked."
:group 'sclang-interface :group 'sclang-interface
@ -47,10 +57,12 @@
"Face for highlighting a server's running state in the mode-line.") "Face for highlighting a server's running state in the mode-line.")
(defun sclang-get-server (&optional name) (defun sclang-get-server (&optional name)
"Get sclang server (optionally by NAME)."
(unless name (setq name sclang-current-server)) (unless name (setq name sclang-current-server))
(cdr (assq name sclang-server-alist))) (cdr (assq name sclang-server-alist)))
(defun sclang-set-server (&optional name) (defun sclang-set-server (&optional name)
"Set current sclang server (optionally by NAME)."
(unless name (setq name sclang-current-server)) (unless name (setq name sclang-current-server))
(setq sclang-current-server (setq sclang-current-server
(car (or (assq name sclang-server-alist) (car (or (assq name sclang-server-alist)
@ -79,18 +91,21 @@
(setq sclang-current-server (car (car list)))) (setq sclang-current-server (car (car list))))
(sclang-update-server-info)) (sclang-update-server-info))
(defun sclang-mouse-next-server (event) (defun sclang-mouse-next-server (_event)
"Select next server for display." "Select next server for display."
(interactive "e") (interactive "e")
(sclang-next-server)) (sclang-next-server))
(defun sclang-server-running-p (&optional name) (defun sclang-server-running-p (&optional name)
"Is the sclang server NAME running?"
(plist-get (sclang-get-server name) 'running)) (plist-get (sclang-get-server name) 'running))
(defun sclang-server-booting-p (&optional name) (defun sclang-server-booting-p (&optional name)
"Is the sclang server NAME running?"
(plist-get (sclang-get-server name) 'booting)) (plist-get (sclang-get-server name) 'booting))
(defun sclang-create-server-menu (title) (defun sclang-create-server-menu (title)
"Create the server menu with TITLE."
(easy-menu-create-menu (easy-menu-create-menu
title title
'( '(
@ -101,6 +116,7 @@
["Make Default" sclang-server-make-default]))) ["Make Default" sclang-server-make-default])))
(defun sclang-server-fill-mouse-map (map prefix) (defun sclang-server-fill-mouse-map (map prefix)
"Fill mouse MAP using PREFIX."
(define-key map (vector prefix 'mouse-1) 'sclang-mouse-next-server) (define-key map (vector prefix 'mouse-1) 'sclang-mouse-next-server)
(define-key map (vector prefix 'down-mouse-3) (sclang-create-server-menu "Commands")) (define-key map (vector prefix 'down-mouse-3) (sclang-create-server-menu "Commands"))
map) map)
@ -109,7 +125,7 @@
"Keymap used for controlling servers in the mode line.") "Keymap used for controlling servers in the mode line.")
(defun sclang-server-fill-key-map (map) (defun sclang-server-fill-key-map (map)
"Fill server prefix map." "Fill server keymap MAP."
(define-key map [?b] 'sclang-server-boot) (define-key map [?b] 'sclang-server-boot)
(define-key map [?d] 'sclang-server-display-default) (define-key map [?d] 'sclang-server-display-default)
(define-key map [?f] 'sclang-server-free-all) (define-key map [?f] 'sclang-server-free-all)
@ -154,6 +170,7 @@
"Info string used in the post buffer mode line.") "Info string used in the post buffer mode line.")
(defun sclang-update-server-info () (defun sclang-update-server-info ()
"Update server info in the modeline."
(interactive) (interactive)
(sclang-set-server) (sclang-set-server)
(setq sclang-server-info-string (sclang-get-server-info-string)) (setq sclang-server-info-string (sclang-get-server-info-string))
@ -164,8 +181,10 @@
;; ===================================================================== ;; =====================================================================
(defun sclang-perform-server-command (command &rest args) (defun sclang-perform-server-command (command &rest args)
"Perform server COMMAND with ARGS."
(sclang-eval-string (sclang-eval-string
(sclang-format "Server.named.at(%o.asSymbol).performList(\\tryPerform, %o.asSymbol.asArray ++ %o)" (sclang-format
"Server.named.at(%o.asSymbol).performList(\\tryPerform, %o.asSymbol.asArray ++ %o)"
sclang-current-server command args) sclang-current-server command args)
nil)) nil))
@ -213,7 +232,7 @@ if (server.notNil) {
nil)) nil))
(defun sclang-server-dump-osc (&optional code) (defun sclang-server-dump-osc (&optional code)
"Set the current server's dump OSC mode." "Set the current server's dump OSC mode (with optional CODE)."
(interactive "P") (interactive "P")
(sclang-perform-server-command "dumpOSC" (sclang-perform-server-command "dumpOSC"
(cond ((consp code) 0) (cond ((consp code) 0)
@ -221,7 +240,7 @@ if (server.notNil) {
(t code)))) (t code))))
(defun sclang-server-prepare-for-record (&optional path) (defun sclang-server-prepare-for-record (&optional path)
"Prepare current server for recording a sound file." "Prepare current server for recording a sound file (with optional PATH)."
(interactive (interactive
(list (list
(and current-prefix-arg (read-file-name "Record to file: ")))) (and current-prefix-arg (read-file-name "Record to file: "))))
@ -242,10 +261,10 @@ if (server.notNil) {
(interactive) (interactive)
(sclang-perform-server-command "stopRecording")) (sclang-perform-server-command "stopRecording"))
(defun sclang-set-server-latency (lat) (defun sclang-set-server-latency (latency)
"Set the current server's `latency' instance variable." "Set the current server's LATENCY instance variable."
(interactive "nSet latency: ") (interactive "nSet latency: ")
(sclang-perform-server-command "latency_" lat)) (sclang-perform-server-command "latency_" latency))
(defun sclang-show-server-latency () (defun sclang-show-server-latency ()
"Show the current server's latency." "Show the current server's latency."
@ -274,6 +293,7 @@ if (server.notNil) {
(lambda () (lambda ()
(setq sclang-current-server-initialized nil))) (setq sclang-current-server-initialized nil)))
(provide 'sclang-server) (provide 'sclang-server)
;; EOF ;;; sclang-server.el ends here

View file

@ -1,7 +1,9 @@
;;; package: sclang-util --- Utility helpers for sclang ;;; sclang-util.el --- Utility helpers for sclang -*- coding: utf-8;
;;
;; copyright 2003-2005 stefan kersten <steve@k-hornz.de>
;; ;;
;; Copyright 2003-2005 stefan kersten <steve@k-hornz.de>
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -17,13 +19,20 @@
;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
;; USA ;; USA
;;; Commentary:
;; Utility helpers for sclang
;;; Code:
(defun sclang-message (string &rest args) (defun sclang-message (string &rest args)
"Create a message from STRING with optional ARGS."
(message "SCLang: %s" (apply 'format string args))) (message "SCLang: %s" (apply 'format string args)))
(defun sclang-make-buffer-name (string &optional private-p) (defun sclang-make-buffer-name (name &optional private-p)
(concat (and private-p " ") "*SCLang:" string "*")) "Set the buffer name to NAME (optimally PRIVATE-P)."
(concat (and private-p " ") "*SCLang:" name "*"))
(defun sclang-make-prompt-string (prompt default) (defun sclang-make-prompt-string (prompt default)
"Return a prompt string using PROMPT and DEFAULT."
(if (and default (string-match "\\(:\\)\\s *" prompt)) (if (and default (string-match "\\(:\\)\\s *" prompt))
(replace-match (replace-match
(format " (default %s):" default) (format " (default %s):" default)
@ -31,22 +40,23 @@
prompt)) prompt))
(defun sclang-string-to-int32 (str) (defun sclang-string-to-int32 (str)
"Convert first 4 bytes of str (network byteorder) to 32 bit integer." "Convert first 4 bytes of STR (network byteorder) to 32 bit integer."
(logior (lsh (logand (aref str 0) #XFF) 24) (logior (ash (logand (aref str 0) #XFF) 24)
(lsh (logand (aref str 1) #XFF) 16) (ash (logand (aref str 1) #XFF) 16)
(lsh (logand (aref str 2) #XFF) 8) (ash (logand (aref str 2) #XFF) 8)
(logand (aref str 3) #XFF))) (logand (aref str 3) #XFF)))
(defun sclang-int32-to-string (n) (defun sclang-int32-to-string (n)
"Convert 32 bit integer n to 4 byte string (network byte order)." "Convert 32 bit integer N to 4 byte string (network byte order)."
(let ((str (make-string 4 0))) (let ((str (make-string 4 0)))
(aset str 0 (logand (lsh n -24) #XFF)) (aset str 0 (logand (ash n -24) #XFF))
(aset str 1 (logand (lsh n -16) #XFF)) (aset str 1 (logand (ash n -16) #XFF))
(aset str 2 (logand (lsh n -8) #XFF)) (aset str 2 (logand (ash n -8) #XFF))
(aset str 3 (logand n #XFF)) (aset str 3 (logand n #XFF))
str)) str))
(defun sclang-compress-newlines (&optional buffer) (defun sclang-compress-newlines (&optional buffer)
"Compress newlines (optionally in BUFFER)."
(with-current-buffer (or buffer (current-buffer)) (with-current-buffer (or buffer (current-buffer))
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))

View file

@ -35,4 +35,5 @@
Bound only when library is installed with SuperCollider.") Bound only when library is installed with SuperCollider.")
(provide 'sclang-vars) (provide 'sclang-vars)
;;; sclang-vars.el ends here ;;; sclang-vars.el ends here

View file

@ -1,9 +1,8 @@
;;; sclang-widgets.el --- Widget definitions for SCLang ;;; sclang-widgets.el --- Widget definitions for SCLang -*- coding: utf-8; lexical-binding: t -*-
;; Copyright (C) 2005 Free Software Foundation, Inc. ;; Copyright (C) 2005 Free Software Foundation, Inc.
;; Author: Mario Lang <mlang@blind.guru> ;; Author: Mario Lang <mlang@blind.guru>
;; Keywords: comm
;; This file is free software; you can redistribute it and/or modify ;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by ;; it under the terms of the GNU General Public License as published by
@ -21,8 +20,8 @@
;; Boston, MA 02110-1301, USA. ;; Boston, MA 02110-1301, USA.
;;; Commentary: ;;; Commentary:
;; ;;
;; Widget definitions for SCLang
;;; Code: ;;; Code:
@ -31,6 +30,9 @@
(require 'sclang-language) (require 'sclang-language)
(require 'sclang-interp) (require 'sclang-interp)
(require 'widget)
(require 'wid-edit)
(defvar sclang-widgets nil) (defvar sclang-widgets nil)
(make-variable-buffer-local 'sclang-widgets) (make-variable-buffer-local 'sclang-widgets)
@ -46,13 +48,13 @@
(widget-specify-insert (widget-specify-insert
(let ((from (point)) (let ((from (point))
button-begin button-end) button-begin button-end)
(setq button-begin (point)) (setq button-begin from)
(insert (widget-get-indirect widget :button-prefix)) (insert (widget-get-indirect widget :button-prefix))
(princ (nth (widget-get widget :value) (widget-get widget :states)) (current-buffer)) (princ (nth (widget-get widget :value) (widget-get widget :states)) (current-buffer))
(insert (widget-get-indirect widget :button-suffix)) (insert (widget-get-indirect widget :button-suffix))
(setq button-end (point)) (setq button-end from)
;; Specify button, and insert value. ;; Specify button, and insert value.
(and button-begin button-end (and button-begin button-end
@ -65,7 +67,8 @@
(widget-put widget :to to))) (widget-put widget :to to)))
(widget-clear-undo)) (widget-clear-undo))
(defun sclang-widget-button-action (widget event) (defun sclang-widget-button-action (widget _event)
"Set button action for WIDGET."
(widget-value-set widget (widget-value-set widget
(if (>= (widget-get widget :value) (1- (length (widget-get widget :states)))) (if (>= (widget-get widget :value) (1- (length (widget-get widget :states))))
0 0
@ -103,7 +106,7 @@
(let ((from (point)) (let ((from (point))
(inhibit-redisplay t) (inhibit-redisplay t)
button-begin button-end) button-begin button-end)
(setq button-begin (point)) (setq button-begin from)
(insert (widget-get-indirect widget :button-prefix)) (insert (widget-get-indirect widget :button-prefix))
(insert-char ?- (widget-get widget :size)) (insert-char ?- (widget-get widget :size))
@ -125,6 +128,7 @@
(widget-clear-undo)) (widget-clear-undo))
(defun sclang-widget-slider-value-set (widget value) (defun sclang-widget-slider-value-set (widget value)
"Set slider WIDGET to VALUE."
(save-excursion (save-excursion
(let ((inhibit-read-only t)) (let ((inhibit-read-only t))
(goto-char (widget-get widget :from)) (goto-char (widget-get widget :from))
@ -145,6 +149,7 @@
:dynargs #'sclang-widget-class-tree-dynargs) :dynargs #'sclang-widget-class-tree-dynargs)
(defun sclang-widget-class-tree-dynargs (widget) (defun sclang-widget-class-tree-dynargs (widget)
"Class tree WIDGET."
(sclang-eval-sync (sclang-format "EmacsClassTree.dynargs(%o)" (sclang-eval-sync (sclang-format "EmacsClassTree.dynargs(%o)"
(widget-get widget :tag)))) (widget-get widget :tag))))
@ -161,5 +166,7 @@
(list (sclang-read-symbol "Class: " "Object" #'sclang-class-name-p))) (list (sclang-read-symbol "Class: " "Object" #'sclang-class-name-p)))
(sclang-eval-string (format "EmacsClassBrowser(%s)" class-name))) (sclang-eval-string (format "EmacsClassBrowser(%s)" class-name)))
(provide 'sclang-widgets) (provide 'sclang-widgets)
;;; sclang-widgets.el ends here ;;; sclang-widgets.el ends here

View file

@ -1,8 +1,15 @@
;;; sclang.el --- IDE for working with the SuperCollider language ;;; sclang.el --- IDE for working with SuperCollider -*- coding: utf-8; lexical-binding: t -*-
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;; Version: 1.0.0
;; URL: https://github.com/supercollider/scel
;; ;;
;; Copyright 2003 stefan kersten <steve@k-hornz.de>
;;
;; Author: stefan kersten
;; Keywords: supercollider, multimedia, languages, tools
;; Version: 1.1.0
;; Package-Requires: ((emacs "27.1") (w3m "0.0"))
;; URL: https://github.com/supercollider/scel
;;; License:
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as ;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2 of the ;; published by the Free Software Foundation; either version 2 of the
@ -24,8 +31,19 @@
;; In order to be useful you need to install SuperCollider and the ;; In order to be useful you need to install SuperCollider and the
;; sc-el Quark. See the README or https://github.com/supercollider/scel ;; sc-el Quark. See the README or https://github.com/supercollider/scel
;; for more information. ;; for more information.
;;
;; Recent versions of w3m use tab-line which is only available after 27.1
;; However sclang should work on Emacs 26.3 to 27.1 without the help browser.
;;; Credits:
;;
;; stefan kersten <steve@k-hornz.de>
;; and everyone in...
;; git shortlog -s | sort -r | cut -c8-
;;; Code: ;;; Code:
(defgroup sclang nil (defgroup sclang nil
"IDE for working with the SuperCollider language." "IDE for working with the SuperCollider language."
:group 'languages) :group 'languages)
@ -43,7 +61,7 @@
:group 'sclang) :group 'sclang)
(defgroup sclang-programs nil (defgroup sclang-programs nil
"Paths to programs used by sclang-mode." "Paths to programs used by `sclang-mode'."
:group 'sclang-interface) :group 'sclang-interface)
(defgroup sclang-options nil (defgroup sclang-options nil