diff --git a/misc/fuel/factor-mode.el b/misc/fuel/factor-mode.el index b302fb6b8f..cc8ebe35fb 100644 --- a/misc/fuel/factor-mode.el +++ b/misc/fuel/factor-mode.el @@ -125,7 +125,8 @@ code in the buffer." (defun factor-mode--indent-setter-line () (when (fuel-syntax--at-setter-line) (save-excursion - (let ((indent (and (fuel-syntax--at-constructor-line) (current-indentation)))) + (let ((indent (and (fuel-syntax--at-constructor-line) + (current-indentation)))) (while (not (or indent (bobp) (fuel-syntax--at-begin-of-def) @@ -225,6 +226,19 @@ code in the buffer." (defsubst factor-mode--cycling-setup () (setq factor-mode--cycling-no-ask nil)) +(defun factor-mode--code-file (kind &optional file) + (let* ((file (or file (buffer-file-name))) + (bn (file-name-nondirectory file))) + (and (string-match (format "\\(.+\\)-%s\\.factor$" kind) bn) + (expand-file-name (concat (match-string 1 bn) ".factor") + (file-name-directory file))))) + +(defsubst factor-mode--in-docs (&optional file) + (factor-mode--code-file "docs")) + +(defsubst factor-mode--in-tests (&optional file) + (factor-mode--code-file "tests")) + (defun factor-mode-visit-other-file (&optional skip) "Cycle between code, tests and docs factor files. With prefix, non-existing files will be skipped." diff --git a/misc/fuel/fuel-markup.el b/misc/fuel/fuel-markup.el index 80fe8e830b..cc788fe5dc 100644 --- a/misc/fuel/fuel-markup.el +++ b/misc/fuel/fuel-markup.el @@ -382,7 +382,7 @@ (when (looking-at "Word *\\(Stack effect\\|Syntax\\)$") (push (list "Word" (match-string-no-properties 1)) rows) (forward-line)) - (while (looking-at "\\(.+?\\)\\( +\\(.+\\)\\)?$") + (while (looking-at " ?\\(.+?\\)\\( +\\(.+\\)\\)?$") (let ((word `($link ,(match-string-no-properties 1) ,(match-string-no-properties 1) word)) diff --git a/misc/fuel/fuel-mode.el b/misc/fuel/fuel-mode.el index 0186392f34..282ef3240f 100644 --- a/misc/fuel/fuel-mode.el +++ b/misc/fuel/fuel-mode.el @@ -172,7 +172,10 @@ interacting with a factor listener is at your disposal. (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode)) (setq fuel-stack-mode-string "/S") - (when fuel-mode-stack-p (fuel-stack-mode fuel-mode))) + (when fuel-mode-stack-p (fuel-stack-mode fuel-mode)) + + (when (and fuel-mode (not (file-exists-p (buffer-file-name)))) + (fuel-scaffold--maybe-insert))) ;;; Keys: diff --git a/misc/fuel/fuel-scaffold.el b/misc/fuel/fuel-scaffold.el index b1c4462503..9b7d9861c7 100644 --- a/misc/fuel/fuel-scaffold.el +++ b/misc/fuel/fuel-scaffold.el @@ -39,6 +39,64 @@ (let ((cmd '(:fuel* (vocab-roots get :get) "fuel"))) (fuel-eval--retort-result (fuel-eval--send/wait cmd)))) +(defun fuel-scaffold--dev-name () + (or fuel-scaffold-developer-name + (let ((cmd '(:fuel* (developer-name get :get) "fuel"))) + (fuel-eval--retort-result (fuel-eval--send/wait cmd))) + "Your name")) + +(defun fuel-scaffold--first-vocab () + (goto-char (point-min)) + (re-search-forward fuel-syntax--current-vocab-regex nil t)) + +(defsubst fuel-scaffold--vocab (file) + (save-excursion + (set-buffer (find-file-noselect file)) + (fuel-scaffold--first-vocab) + (fuel-syntax--current-vocab))) + +(defconst fuel-scaffold--tests-header-format + "! Copyright (C) %s %s +! See http://factorcode.org/license.txt for BSD license. +USING: %s tools.test ; +IN: %s +") + +(defsubst fuel-scaffold--check-auto (var) + (and var (or (eq var 'always) (y-or-n-p "Insert template? ")))) + +(defun fuel-scaffold--tests (parent) + (when (and parent (fuel-scaffold--check-auto fuel-scaffold-test-autoinsert-p)) + (let ((year (format-time-string "%Y")) + (name (fuel-scaffold--dev-name)) + (vocab (fuel-scaffold--vocab parent))) + (insert (format fuel-scaffold--tests-header-format + year name vocab vocab)) + t))) + +(defsubst fuel-scaffold--create-docs (vocab) + (let ((cmd `(:fuel* (,vocab ,fuel-scaffold-developer-name fuel-scaffold-help) + "fuel"))) + (fuel-eval--send/wait cmd))) + +(defun fuel-scaffold--help (parent) + (when (and parent (fuel-scaffold--check-auto fuel-scaffold-help-autoinsert-p)) + (let* ((ret (fuel-scaffold--create-docs (fuel-scaffold--vocab parent))) + (file (fuel-eval--retort-result ret))) + (when file + (revert-buffer t t t) + (when (and fuel-scaffold-help-header-only-p + (fuel-scaffold--first-vocab)) + (delete-region (1+ (point)) (point-max)) + (save-buffer)) + (message "Inserting template ... done.")) + (goto-char (point-min))))) + +(defun fuel-scaffold--maybe-insert () + (ignore-errors + (or (fuel-scaffold--tests (factor-mode--in-tests)) + (fuel-scaffold--help (factor-mode--in-docs))))) + ;;; User interface: @@ -73,9 +131,7 @@ You can configure `fuel-scaffold-developer-name' (set by default to (interactive "P") (let* ((vocab (or (and (not arg) (fuel-syntax--current-vocab)) (fuel-completion--read-vocab nil))) - (cmd `(:fuel* (,vocab ,fuel-scaffold-developer-name fuel-scaffold-help) - "fuel")) - (ret (fuel-eval--send/wait cmd)) + (ret (fuel-scaffold--create-docs vocab)) (file (fuel-eval--retort-result ret))) (unless file (error "Error creating help file" (car (fuel-eval--retort-error ret)))) diff --git a/misc/fuel/fuel-table.el b/misc/fuel/fuel-table.el index a00b21bf2f..1af2e25712 100644 --- a/misc/fuel/fuel-table.el +++ b/misc/fuel/fuel-table.el @@ -72,21 +72,67 @@ (push (fuel-table--pad-row (reverse frow)) frows))) (reverse frows))) +(defvar fuel-table-corner-lt "┌") +(defvar fuel-table-corner-lb "└") +(defvar fuel-table-corner-rt "┐") +(defvar fuel-table-corner-rb "┘") +(defvar fuel-table-line "─") +(defvar fuel-table-tee-t "┬") +(defvar fuel-table-tee-b "┴") +(defvar fuel-table-tee-l "├") +(defvar fuel-table-tee-r "┤") +(defvar fuel-table-crux "┼") +(defvar fuel-table-sep "│") + +(defun fuel-table--insert-line (widths first last sep) + (insert first fuel-table-line) + (dolist (w widths) + (while (> w 0) + (insert fuel-table-line) + (setq w (1- w))) + (insert fuel-table-line sep fuel-table-line)) + (delete-char -2) + (insert fuel-table-line last) + (newline)) + +(defun fuel-table--insert-first-line (widths) + (fuel-table--insert-line widths + fuel-table-corner-lt + fuel-table-corner-rt + fuel-table-tee-t)) + +(defun fuel-table--insert-middle-line (widths) + (fuel-table--insert-line widths + fuel-table-tee-l + fuel-table-tee-r + fuel-table-crux)) + +(defun fuel-table--insert-last-line (widths) + (fuel-table--insert-line widths + fuel-table-corner-lb + fuel-table-corner-rb + fuel-table-tee-b)) + +(defun fuel-table--insert-row (r) + (let ((ln (length (car r))) + (l 0)) + (while (< l ln) + (insert (concat fuel-table-sep " " + (mapconcat 'identity + (mapcar `(lambda (x) (nth ,l x)) r) + (concat " " fuel-table-sep " ")) + " " fuel-table-sep "\n")) + (setq l (1+ l))))) + (defun fuel-table--insert (rows) (let* ((widths (fuel-table--col-widths rows)) - (rows (fuel-table--format-rows rows widths)) - (ls (concat "+" (mapconcat (lambda (n) (make-string n ?-)) widths "-+") "-+"))) - (insert ls "\n") + (rows (fuel-table--format-rows rows widths))) + (fuel-table--insert-first-line widths) (dolist (r rows) - (let ((ln (length (car r))) - (l 0)) - (while (< l ln) - (insert (concat "|" (mapconcat 'identity - (mapcar `(lambda (x) (nth ,l x)) r) - " |") - " |\n")) - (setq l (1+ l)))) - (insert ls "\n")))) + (fuel-table--insert-row r) + (fuel-table--insert-middle-line widths)) + (kill-line -1) + (fuel-table--insert-last-line widths))) (provide 'fuel-table)