Skip to content

Commit f5db105

Browse files
committed
Add idris-start-idris2-project which uses idris2 --init to
generate new ipkg file. Why: Idris2 does better job to create the ipkg file than us.
1 parent 09de86a commit f5db105

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

idris-commands.el

+56
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,62 @@ of the term to replace."
12441244
(find-file (car files)))
12451245
(t (find-file (completing-read "Package file: " files nil t))))))
12461246

1247+
(defun idris-start-idris2-project (&optional no-visit)
1248+
"Interactively create a new Idris2 project with ipkg file and source directory.
1249+
1250+
When NO-VISIT is t does not open the generated ipkg file in other window."
1251+
(interactive)
1252+
(cl-flet ((project-name ()
1253+
(let ((project-name (string-trim (read-string "Project name: "))))
1254+
(when (string-match-p "[^a-zA-Z0-9_ ]" project-name)
1255+
(user-error "Project name should consist only of letters, numbers, spaces and underscores"))
1256+
(when (string= "" project-name)
1257+
(user-error "Project name can not be empty"))
1258+
project-name))
1259+
(project-directory (default-filename)
1260+
(let ((dir (read-directory-name "Create in: " nil default-filename nil default-filename)))
1261+
(when (string= "" dir)
1262+
(user-error "Project directory can not be empty"))
1263+
(when (file-exists-p dir)
1264+
(user-error "%s already exists" dir))
1265+
dir)))
1266+
(let* ((project-name (project-name))
1267+
(default-filename (downcase (replace-regexp-in-string "[^a-zA-Z0-9_]" "_" project-name)))
1268+
(package-name (replace-regexp-in-string "[^a-zA-Z0-9_]" "" project-name))
1269+
(create-in (project-directory default-filename))
1270+
(src-dir (string-trim (read-string "Source directory (src): " nil nil "src")))
1271+
(authors (string-trim (read-string (format "Authors (%s): " (user-full-name)) nil nil (user-full-name))))
1272+
(options (string-trim (read-string "Options: ")))
1273+
(ipkg-file (file-truename (concat (file-name-as-directory create-in)
1274+
(concat default-filename ".ipkg"))))
1275+
(output-buffer (generate-new-buffer "*Idris Script Output*"))
1276+
(input-buffer (generate-new-buffer "*Idris Script Input*")))
1277+
(make-directory (concat (file-name-as-directory create-in) src-dir) t)
1278+
(with-current-buffer input-buffer
1279+
(insert package-name "\n")
1280+
(insert authors "\n")
1281+
(insert options "\n")
1282+
(insert src-dir "\n")
1283+
(call-process-region (point-min) (point-max)
1284+
idris-interpreter-path
1285+
nil
1286+
output-buffer
1287+
nil
1288+
"--init"
1289+
ipkg-file))
1290+
(let ((output (with-current-buffer output-buffer
1291+
(buffer-string))))
1292+
(when (string-match-p "error" output)
1293+
(message "Idris: %s" output)))
1294+
1295+
(kill-buffer output-buffer)
1296+
(kill-buffer input-buffer)
1297+
(when (file-exists-p ipkg-file)
1298+
(with-current-buffer (find-file-noselect ipkg-file)
1299+
(insert "-- " project-name "\n"))
1300+
1301+
(when (null no-visit) (find-file-other-window ipkg-file))))))
1302+
12471303
(defun idris-start-project ()
12481304
"Interactively create a new Idris project, complete with ipkg file."
12491305
(interactive)

test/idris-commands-test.el

+53
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,59 @@ myReverse xs = revAcc [] xs where
313313
(delete-directory mock-directory-name t)
314314
(idris-quit))))
315315

316+
(defmacro idris-generate-mock-read (clauses &optional default)
317+
"Generate a function with cond expression from CLAUSES and optional DEFAULT."
318+
`(lambda (prompt &optional &rest _)
319+
(cond
320+
,@(mapcar (lambda (clause)
321+
`((string-match-p ,(if (symbolp (car clause))
322+
;; Convert symbol to string and
323+
;; remove leading colon and
324+
;; replace dashes with a space
325+
(replace-regexp-in-string
326+
"^\\:" ""
327+
(replace-regexp-in-string "-" " " (symbol-name (car clause))))
328+
(car clause))
329+
prompt)
330+
,(cdr clause)))
331+
clauses)
332+
(t (or ,default "")))))
333+
334+
(when (string-match-p "idris2$" idris-interpreter-path)
335+
(ert-deftest idris-start-idris2-project ()
336+
"Test `idris-start-idris2-project' creating a project."
337+
(cl-flet ((read-string-stub (idris-generate-mock-read ((:project-name . "Idris2 Test Project")
338+
(:author . "Joe Doe")
339+
(:source-dir . "mysrc")
340+
(:options . "--some-option"))))
341+
(read-dir-stub
342+
(idris-generate-mock-read
343+
((:create-in . (idris-file-name-concat "test-data" "Idris2TestProject"))))))
344+
(advice-add 'read-string :override #'read-string-stub)
345+
(advice-add 'read-directory-name :override #'read-dir-stub)
346+
(unwind-protect
347+
(progn
348+
(idris-start-idris2-project t)
349+
(let* ((ipkg-file-path (idris-file-name-concat "test-data"
350+
"Idris2TestProject"
351+
"idris2_test_project.ipkg"))
352+
(ipkg-buffer (find-file-noselect ipkg-file-path))
353+
(ipkg-content (with-current-buffer ipkg-buffer
354+
(buffer-substring-no-properties (point-min) (point-max)))))
355+
356+
(should (string-match-p "-- Idris2 Test Project" ipkg-content))
357+
(should (string-match-p "package Idris2TestProject" ipkg-content))
358+
(should (string-match-p "authors = \"Joe Doe\"" ipkg-content))
359+
(should (string-match-p "opts = \"--some-option\"" ipkg-content))
360+
(should (string-match-p "sourcedir = \"mysrc\"" ipkg-content)))
361+
362+
(should (file-exists-p (idris-file-name-concat "test-data"
363+
"Idris2TestProject"
364+
"mysrc"))))
365+
(advice-remove 'read-string #'read-string-stub)
366+
(advice-remove 'read-directory-name #'read-dir-stub)
367+
(delete-directory (idris-file-name-concat "test-data" "Idris2TestProject") t)))))
368+
316369
;; Tests by Yasuhiko Watanabe
317370
;; https://github.com/idris-hackers/idris-mode/pull/537/files
318371
(idris-ert-command-action "test-data/CaseSplit.idr" idris-case-split idris-test-eq-buffer)

0 commit comments

Comments
 (0)