115 lines
4.2 KiB
EmacsLisp
115 lines
4.2 KiB
EmacsLisp
;;; sclang-helper.el --- Enhance the functionality of scel -*- lexical-binding: t; -*-
|
|
|
|
;;; Commentary:
|
|
;; This program contains serveral custom additional functions to scel.
|
|
;; https://github.com/yilin-zhang/sclang-helper
|
|
|
|
;;; Code:
|
|
(require 'sclang)
|
|
(require 'cl-lib)
|
|
(require 'pulse)
|
|
|
|
(defun sclang-helper-eval-line (&optional silent-p)
|
|
"Execute the current line as SuperCollider code with highlight."
|
|
(interactive "P")
|
|
(let ((string (sclang-line-at-point)))
|
|
(when string
|
|
(sclang-eval-string string (not silent-p)))
|
|
(pulse-momentary-highlight-one-line (point)) ;; highlighting
|
|
string))
|
|
|
|
(defun sclang-helper-eval-region (&optional silent-p)
|
|
"Execute the region as SuperCollider code with highlight"
|
|
(interactive "P")
|
|
(sclang-eval-string
|
|
(buffer-substring-no-properties (region-beginning) (region-end))
|
|
(not silent-p))
|
|
(pulse-momentary-highlight-region (region-beginning) (region-end))) ;; highlighting
|
|
|
|
(defun sclang-helper-eval-region-or-line (&optional silent-p)
|
|
"Execute the line or region as SuperCollider code with highlight"
|
|
(interactive "P")
|
|
(if (and transient-mark-mode mark-active)
|
|
(sclang-helper-eval-region silent-p)
|
|
(sclang-helper-eval-line silent-p)))
|
|
|
|
;; TODO: It's not functional when the prentheses don't match.
|
|
(defun sclang-helper-eval-paren-region (&optional silent-p)
|
|
"Execute the region inside the outermost parentheses.
|
|
Return t if the evaluation happens, nil if it doens't happen."
|
|
(interactive "P")
|
|
(cl-flet
|
|
((check-char-text (char)
|
|
"Check if the char is normal text"
|
|
(if (and (characterp char)
|
|
(not (member (get-char-code-property char 'general-category) '(Zs Cc))))
|
|
t
|
|
nil)))
|
|
|
|
(save-excursion
|
|
;; iteratively check if there's an upper level left parenthesis
|
|
(let ((paren-matched nil))
|
|
(while
|
|
(condition-case nil
|
|
(progn
|
|
(if (equal (char-to-string (char-after)) "(")
|
|
(setq paren-matched t)
|
|
(setq paren-matched nil))
|
|
(backward-up-list)
|
|
t)
|
|
(error nil)))
|
|
(if paren-matched
|
|
(progn
|
|
(let ((point-paren-1 (point))
|
|
(point-paren-2 (progn (forward-list) (point))))
|
|
;; check if there's nothing around the paired parentheses
|
|
(if (or (check-char-text (char-before point-paren-1))
|
|
;; after calling forward-list, point-paren-2 is actually the char after
|
|
;; the right parenthesis
|
|
(check-char-text (char-after point-paren-2)))
|
|
nil
|
|
(progn
|
|
(set-mark point-paren-1)
|
|
(setq mark-active t)
|
|
(sclang-helper-eval-region-or-line silent-p)
|
|
(setq mark-active nil)
|
|
t))))
|
|
nil)))))
|
|
|
|
(defun sclang-helper-auto-eval (&optional silent-p)
|
|
(interactive "P")
|
|
(if (and transient-mark-mode mark-active)
|
|
(sclang-eval-region silent-p)
|
|
(if (not (sclang-helper-eval-paren-region silent-p))
|
|
(sclang-helper-eval-line silent-p))))
|
|
|
|
(defun sclang-helper-show-meter ()
|
|
(interactive)
|
|
(sclang-eval-string "Server.local.meter"))
|
|
|
|
(defun sclang-helper-show-freqscope()
|
|
(interactive)
|
|
(sclang-eval-string "Server.local.freqscope"))
|
|
|
|
(defun sclang-helper-show-tree()
|
|
(interactive)
|
|
(sclang-eval-string "Server.local.plotTree"))
|
|
|
|
;;;###autoload
|
|
(define-minor-mode sclang-helper-mode
|
|
"Toggle sclang mode."
|
|
:lighter " sclang-helper"
|
|
:keymap (let ((map (make-sparse-keymap)))
|
|
(define-key map (kbd "<s-return>") 'sclang-helper-auto-eval)
|
|
(define-key map (kbd "<C-return>") 'sclang-helper-auto-eval)
|
|
(define-key map (kbd "s-m") 'sclang-helper-show-meter)
|
|
(define-key map (kbd "s-f") 'sclang-helper-show-freqscope)
|
|
(define-key map (kbd "s-n") 'sclang-helper-show-tree)
|
|
(define-key map (kbd "s-.") 'sclang-main-stop)
|
|
(define-key map (kbd "s-d") 'sclang-find-help-in-gui)
|
|
map))
|
|
|
|
(provide 'sclang-helper)
|
|
|
|
;;; sclang-helper.el ends here
|