Skip to content

Commit 01da4eb

Browse files
committed
Init with first working draft.
Just copypasted and partly adapted from go-playground.
1 parent 210518c commit 01da4eb

File tree

2 files changed

+184
-2
lines changed

2 files changed

+184
-2
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1-
# rust-playground
2-
GNU/Emacs mode that setup local playground for code snippets in Rust language.
1+
# rust-playground [WIP]
2+
3+
GNU/Emacs mode that setup local playground for code snippets in Rust
4+
language. This is a fast and dirty port of
5+
[go-playground](https://github.com/grafov/go-playground) adapted for
6+
Rust environment.
7+
8+
*Work in progress.*

rs-playground.el

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
;;; rs-playground.el --- Local Rust playground for short code snippets.
2+
3+
;; Copyright (C) 2016 Alexander I.Grafov (axel)
4+
5+
;; Author: Alexander I.Grafov <[email protected]>
6+
;; URL: https://github.com/grafov/rs-playground
7+
;; Keywords: tools, rust
8+
;; Package-Requires: ((emacs "24") (rust-mode "1.0.0"))
9+
10+
;; This program is free software; you can redistribute it and/or modify
11+
;; it under the terms of the GNU General Public License as published by
12+
;; the Free Software Foundation, either version 3 of the License, or
13+
;; (at your option) any later version.
14+
15+
;; This program is distributed in the hope that it will be useful,
16+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
;; GNU General Public License for more details.
19+
20+
;; You should have received a copy of the GNU General Public License
21+
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
23+
;;; Commentary:
24+
25+
;; Local playground for the Rust programs similar to play.rust-lang.org.
26+
;; `M-x rs-playground` and type you rust code then make&run it with `C-Return`.
27+
28+
;; Playground works in conjunction with `rust-mode` and requires
29+
;; preconfigured environment for Rust language.
30+
31+
;; It is port of github.com/grafov/go-playground for Go language.
32+
33+
;; You may push code to play.rust-lang.org with rust-mode' function `rust-playpen-buffer`.
34+
35+
;;
36+
37+
;;; Code:
38+
39+
(require 'rust-mode)
40+
(require 'compile)
41+
(require 'time-stamp)
42+
43+
; I think it should be defined in rust-mode.
44+
(defcustom rust-bin "rustc"
45+
"The ’rust’ command."
46+
:type 'string
47+
:group 'rust-mode)
48+
49+
(defgroup rs-playground nil
50+
"Options specific to Rust Playground."
51+
:group 'rust-mode)
52+
53+
(defcustom rs-playground-ask-file-name nil
54+
"Non-nil means we ask for a name for the snippet.
55+
56+
By default it will be created as snippet.go"
57+
:type 'boolean
58+
:group 'rs-playground)
59+
60+
(defcustom rs-playground-confirm-deletion t
61+
"Non-nil means you will be asked for confirmation on the snippet deletion with `rs-playground-rm'.
62+
63+
By default confirmation required."
64+
:type 'boolean
65+
:group 'rs-playground)
66+
67+
(defcustom rs-playground-basedir "~/rs-playground"
68+
"Base directory for playground snippets."
69+
:group 'rs-playground)
70+
71+
(defvar-local rs-playground-current-snippet-file "snippet.rs"
72+
"The current snippet file.")
73+
74+
(define-minor-mode rs-playground-mode
75+
"A place for playing with golang code and export it in short snippets."
76+
:init-value nil
77+
:lighter ""
78+
:keymap '(([C-return] . rs-playground-exec))
79+
(setq mode-name "Play(Rust)"))
80+
81+
(defun rs-playground-snippet-file-name(&optional snippet-name)
82+
(setq-local rs-playground-current-snippet-file (let ((file-name (cond (snippet-name)
83+
(rs-playground-ask-file-name
84+
(read-string "Rust Playground filename: "))
85+
("snippet"))))
86+
(concat (rs-playground-snippet-unique-dir file-name) "/" file-name ".rs"))))
87+
88+
(defun rs-playground-exec ()
89+
"Save the buffer then runs Rust compiler for executing the code."
90+
(interactive)
91+
(make-local-variable 'compile-command)
92+
(let ((snippet-file buffer-file-name))
93+
(save-buffer t)
94+
(compile (concat rust-bin " " snippet-file " -o snippet && " (file-name-directory snippet-file) "snippet"))))
95+
96+
;;;###autoload
97+
(defun rs-playground ()
98+
"Run playground for Rust language in a new buffer."
99+
(interactive)
100+
(let ((snippet-file-name (rs-playground-snippet-file-name)))
101+
(switch-to-buffer (create-file-buffer snippet-file-name))
102+
(rs-playground-insert-template-head "snippet of code")
103+
(insert "fn main() {
104+
105+
println!(\"Results:\")
106+
107+
}
108+
")
109+
(backward-char 3)
110+
(rust-mode)
111+
(rs-playground-mode)
112+
(set-visited-file-name snippet-file-name t)))
113+
114+
(defun rs-playground-insert-template-head (description)
115+
(insert "// -*- mode:rust;mode:rs-playground -*-
116+
// " description " @ " (time-stamp-string "%:y-%02m-%02d %02H:%02M:%02S") "
117+
118+
// === Rust Playground ===
119+
// Execute the snippet with Ctl-Return
120+
// Remove the snippet completely with its dir and all files M-x `rs-playground-rm`
121+
122+
"))
123+
124+
;;;###autoload
125+
(defun rs-playground-rm ()
126+
"Remove files of the current snippet together with directory of this snippet."
127+
(interactive)
128+
(if (string-match-p (file-truename rs-playground-basedir) (file-truename (buffer-file-name)))
129+
(if (or (not rs-playground-confirm-deletion)
130+
(y-or-n-p (format "Do you want delete whole snippet dir %s? "
131+
(file-name-directory (buffer-file-name)))))
132+
(progn
133+
(save-buffer)
134+
(delete-directory (file-name-directory (buffer-file-name)) t t)
135+
(kill-buffer)))
136+
(message "Won't delete this! Because %s is not under the path %s. Remove the snippet manually!"
137+
(buffer-file-name) rs-playground-basedir)))
138+
139+
;; ;;;###autoload
140+
;; (defun rs-playground-download (url)
141+
;; "Download a paste from the play.golang.org and insert it in a new local playground buffer.
142+
;; Tries to look for a URL at point."
143+
;; (interactive (list (read-from-minibuffer "Playground URL: " (ffap-url-p (ffap-string-at-point 'url)))))
144+
;; (with-current-buffer
145+
;; (let ((url-request-method "GET") url-request-data url-request-extra-headers)
146+
;; (url-retrieve-synchronously (concat url ".go")))
147+
;; (let* ((snippet-file-name (rs-playground-snippet-file-name)) (buffer (create-file-buffer snippet-file-name)))
148+
;; (goto-char (point-min))
149+
;; (re-search-forward "\n\n")
150+
;; (copy-to-buffer buffer (point) (point-max))
151+
;; (kill-buffer)
152+
;; (with-current-buffer buffer
153+
;; (goto-char (point-min))
154+
;; (rs-playground-insert-template-head (concat url " imported"))
155+
;; (rust-mode)
156+
;; (rs-playground-mode)
157+
;; (set-visited-file-name snippet-file-name t)
158+
;; (switch-to-buffer buffer)))))
159+
160+
;; (defun rs-playground-upload ()
161+
;; "Upload the current buffer to play.golang.org and return the short URL of the playground."
162+
;; (interactive)
163+
;; (goto-char (point-min))
164+
;; (forward-line)
165+
;; (insert (rust-playpen-buffer)))
166+
167+
(defun rs-playground-snippet-unique-dir (prefix)
168+
"Get unique directory under `rs-playground-basedir`."
169+
(let ((dir-name (concat rs-playground-basedir "/"
170+
(if (and prefix rs-playground-ask-file-name) (concat prefix "-"))
171+
(time-stamp-string "at-%:y-%02m-%02d-%02H%02M%02S"))))
172+
(make-directory dir-name t)
173+
dir-name))
174+
175+
(provide 'rs-playground)
176+
;;; rs-playground.el ends here

0 commit comments

Comments
 (0)