;; -*- lexical-binding: t; -*- (require 'transient) (defun snowball-reformat-chanced-file () "Run the current buffer through Pint." (interactive) (let ((format-file-name (concat "fmt-" (file-name-nondirectory (buffer-file-name))))) (unwind-protect (progn (write-region (point-min) (point-max) format-file-name) (shell-command (format "%s %s" (expand-file-name "../chanced-scripts/format" (project-root (project-current))) (file-relative-name format-file-name (project-root (project-current)))) nil nil) (let ((temp-buffer (find-file-noselect format-file-name))) (unwind-protect (replace-buffer-contents temp-buffer) (kill-buffer temp-buffer)))) (delete-file format-file-name)))) (defun tomwpunt:enable-directory-local-modes () "Enable hooks and modes that are bound to specific directory." (cond ((string-suffix-p "code/diamond-interactive/social-api/" (or (and-let* ((project (project-current))) (project-root project)) "")) (local-set-key (kbd "C-c c") #'artisan-transient) (local-set-key (kbd "C-c t t") '("Run tests" . artisan-run-test)) (local-set-key (kbd "C-c t T") '("Run tests (stop on failure)" . artisan-run-test-and-stop)) (local-set-key (kbd "C-c t f") '("Run tests in current file" . artisan-run-current-file-test)) (local-set-key (kbd "C-c t F") '("Run tests in current file (stop on failure)" . artisan-run-current-file-test-and-stop)) (local-set-key (kbd "C-c t p") '("Run Test at point" . artisan-run-test-at-point)) (local-set-key (kbd "C-c t P") '("Run Test at point (stop on failure)" . artisan-run-test-at-point-and-stop)) (when (equal major-mode 'php-mode) (add-hook 'before-save-hook 'snowball-reformat-chanced-file nil t))))) (add-hook 'find-file-hook 'tomwpunt:enable-directory-local-modes) (transient-define-prefix artisan-transient () "A transient to run artisan commands." ["Punt" ["Composer" ("pci" "Install" artisan-punt-composer-install)] ["Artisan" ("pac" "Run Command" artisan-punt-run-command) ("pam" "Migrate" artisan-punt-migrate)]] ["Chanced" ["Composer" ("cci" "Install" artisan-chanced-composer-install)] ["Artisan" ("cac" "Run Command" artisan-chanced-run-command) ("cam" "Migrate" artisan-chanced-migrate)]] ["Commands" ;; ("t" "Test" artisan-test-transient) ("mm" "Make Migration" artisan-make-migration-transient) ("mM" "Make Model" artisan-make-model-transient) ("mf" "Make Factory" artisan-make-factory-transient)]) (defun artisan-punt-composer-install () (interactive) (let ((default-directory (expand-file-name "punt" (project-root (project-current))))) (async-shell-command "docker exec -it punt-backend composer install"))) (defun artisan-chanced-composer-install (brand) (interactive (list (oni-read-brand))) (mapcar (lambda (b) (let ((default-directory (expand-file-name b (project-root (project-current)))) (containers '(("chanced" . "chanced-backend") ("punt" . "punt-backend") ("filament" . "chanced-admin-panel")))) (async-shell-command (format "docker exec -it %s composer install" (map-elt containers b)) (get-buffer-create (format "*%s-composer*" (upcase b)))))) (if (string= brand "all") '("chanced" "punt" "filament") (list brand)))) (defun artisan-punt-run-command (command) (interactive (list (read-string "Command: "))) (let ((default-directory (expand-file-name "punt" (project-root (project-current))))) (async-shell-command (format "docker exec -it punt-backend php artisan %s" command)))) (defun artisan-chanced-run-command (command) (interactive (list (read-string "Command: "))) (let ((default-directory (expand-file-name "chanced" (project-root (project-current))))) (async-shell-command (format "docker exec -it chanced-backend php artisan %s" command)))) (defun artisan-punt-migrate () (interactive) (let ((default-directory (expand-file-name "punt" (project-root (project-current))))) (async-shell-command "docker exec -it punt-backend php artisan migrate"))) (defun artisan-chanced-migrate () (interactive) (let ((default-directory (expand-file-name "chanced" (project-root (project-current))))) (async-shell-command "docker exec -it chanced-backend php artisan migrate"))) ;; (transient-define-prefix artisan-test-transient () ;; "Artisan Test." ;; ["Arguments & Switches" ;; ("-b" "Brand" "--brand=" :choices ("chanced" "punt")) ;; ("-f" "Stop on failure" "--stop-on-failure") ;; ("-p" "Pick test" "--pick") ;; ("-P" "Test at point" "--at-point")] ;; ;; ["Commands" ;; ;; ("t" "Test" artisan-chanced-test)] ;; ) ;; (defun artisan-chanced-test (&optional args) ;; (interactive (list (transient-args transient-current-command))) ;; (let ((pick (transient-arg-value "--pick" args)) ;; (fail (transient-arg-value "--stop-on-failure" args)) ;; (brand (transient-arg-value "--brand=" args)) ;; (at-point (transient-arg-value "--at-point" args))) ;; (artisan--test-internal pick (or brand "chanced") ;; (if (string= brand "punt") ;; "chanced" ;; "punt") ;; fail ;; at-point))) (defvar artisan--test-last-state nil "The last testing commnand that was run in the test buffer. This variable should always be buffer local and only set in test buffers.") (make-variable-buffer-local 'artisan--test-last-state) (defun oni-read-brand () "Ask for Chanced or Punt." (nth 1 (read-multiple-choice "Which application? " '((?a "all" "All") (?c "chanced" "Chanced") (?p "punt" "Punt") (?f "filament" "Filament"))))) (cl-defun artisan-run-test (name &key file filter stop-on-failure-p) (interactive (let* ((refresh current-prefix-arg) (project (oni-read-brand)) (buffer-name (format "*%s Tests*" (capitalize project))) (buffer (get-buffer-create buffer-name))) (append (list project) (unless refresh (with-current-buffer buffer artisan--test-last-state))))) (let* ((default-directory (expand-file-name name (project-root (project-current)))) (buffer-name (format "*%s Tests*" (capitalize name))) (buffer (get-buffer-create buffer-name)) (command (with-current-buffer buffer (format "../../chanced-scripts/test %s %s %s %s" name (if filter (format "--filter='::%s( |$)'" filter) "") (if stop-on-failure-p "--stop-on-defect" "") (or file ""))))) (cl-letf (((symbol-function 'compilation-buffer-name) (lambda (&rest _) buffer-name))) (compile command)) (with-current-buffer buffer (setq artisan--test-last-state (list :file file :filter filter :stop-on-failure-p stop-on-failure-p)) (local-set-key (kbd "g") (lambda () (interactive) (artisan-run-test name :file file :filter filter :stop-on-failure-p stop-on-failure-p))) (local-set-key (kbd "q") #'bury-buffer) (local-set-key (kbd "s") (lambda () (interactive) (interrupt-process))) (local-set-key (kbd "M-p") (lambda () (interactive) (forward-line -1) (search-backward " •"))) (local-set-key (kbd "M-n") (lambda () (interactive) (forward-line) (search-forward " •")))))) (defun artisan-run-test-and-stop (name) (interactive (list (oni-read-brand))) (artisan-run-test name :stop-on-failure-p t)) (defun artisan-run-current-file-test (name &optional stopp) "Run PHP artisan test on the current file NAME. Optional argument STOPP means stop on any defect." (interactive (list (oni-read-brand))) (let* ((project-root (project-root (project-current))) (file (concat "../" (file-relative-name (buffer-file-name) project-root)))) (artisan-run-test name :file file :stop-on-failure-p stopp))) (autoload 'which-function "which-func") (defun artisan-run-test-at-point (name &optional stopp) "Run PHP artisan test on the function NAME. Optional argument STOPP means stop on any defect." (interactive (list (oni-read-brand))) (let* ((project-root (project-root (project-current))) (file (concat "../" (file-relative-name (buffer-file-name) project-root))) (test (which-function))) (artisan-run-test name :file file :filter test :stop-on-failure-p stopp))) (defun artisan-run-current-file-test-and-stop (name) (interactive (list (oni-read-brand))) (artisan-run-current-file-test name t)) (defun artisan-run-test-at-point-and-stop (name) (interactive (list (oni-read-brand))) (artisan-run-test-at-point name t)) ;; (defun artisan--test-internal (pick name ignore fail test-at-point-p) ;; (let* ((default-directory (expand-file-name name (project-root (project-current)))) ;; (buffer-name (format "*%s Tests*" (capitalize name))) ;; (buffer (get-buffer-create buffer-name)) ;; (state ((with-current-buffer buffer ;; artisan--test-last-state))) ;; (filter (or (map-elt state 'filter) ;; (when test-at-point-p (which-function)))) ;; (files (unless (map-elt state 'file) ;; (cons '("all" . "") ;; (mapcar (lambda (dir) (cons (file-name-nondirectory dir) dir)) ;; (directory-files-recursively "../" (rx "Test.php") nil (lambda (subdir) (not (or (string-suffix-p "vendor" subdir) ;; (string-suffix-p "data" subdir) ;; (string-suffix-p "cdk.out" subdir) ;; (string-suffix-p ignore subdir))))))))) ;; (file (or (and (not pick) ;; (map-elt state 'file)) ;; (and test-at-point-p ;; (concat "../" (file-relative-name (buffer-file-name) (project-root (project-current))))) ;; (map-elt files (completing-read "File: " files nil t)))) ;; (command (with-current-buffer buffer ;; (format "../../chanced-scripts/test %s %s %s %s" ;; name ;; (if fail "--stop-on-failure" "") ;; (if filter (format "--filter=%s" filter) "") ;; file))) ;; (compilation-scroll-output t)) ;; (cl-letf (((symbol-function 'compilation-buffer-name) ;; (lambda (&rest _) buffer-name))) ;; (compile command)) ;; (with-current-buffer buffer ;; (setq artisan--test-last-state ;; `((file . ,file) ;; (filter . ,filter))) ;; (local-set-key (kbd "g") ;; (lambda () ;; (interactive) ;; (artisan--test-internal nil name ignore fail))) ;; (local-set-key (kbd "q") #'bury-buffer) ;; (local-set-key (kbd "s") (lambda () (interactive) (interrupt-process))) ;; (local-set-key (kbd "M-p") (lambda () ;; (interactive) ;; (forward-line -1) ;; (search-backward " •"))) ;; (local-set-key (kbd "M-n") (lambda () ;; (interactive) ;; (forward-line) ;; (search-forward " •")))))) (transient-define-prefix artisan-make-migration-transient () "Make migration." ["Arguments & Switches"] ["Commands" ("m" "Make" artisan-make-migration)]) (defun artisan-make-migration (&optional name) (interactive "MName: ") (let ((default-directory (expand-file-name "chanced" (project-root (project-current))))) (shell-command (format "docker exec chanced-backend php artisan make:migration --path=../common/database/migrations %S" name)) (find-file (car (directory-files (expand-file-name "common/database/migrations" (project-root (project-current))) t (rx "_" (literal name) ".php")))) (vc-register))) (transient-define-prefix artisan-make-model-transient () "Make model." ["Arguments & Switches" ("-f" "Factory" "--factory") ("-m" "Migration" "--migration")] ["Commands" ("m" "Make" artisan-make-model)]) (defun artisan-make-model (&optional name args) (interactive (list (read-string "Name: ") (transient-args transient-current-command))) (let* ((root (project-root (project-current))) (default-directory (expand-file-name "chanced" root)) (bad-file-name (expand-file-name (format "chanced/app/%s.php" name) root)) (good-file-name (expand-file-name (format "common/app/Models/%s.php" name) root)) (factoryp (transient-arg-value "--factory" args)) (migrationp (transient-arg-value "--migration" args))) (shell-command (format "docker exec chanced-backend php artisan make:model %s %s -- %S" (if factoryp "--factory" "") (if migrationp "--migration" "") name)) (when factoryp (rename-file (expand-file-name (format "chanced/database/factories/%sFactory.php" name) root) (expand-file-name "common/database/factories/" root)) (vc-register (cons 'Git (list (list (expand-file-name (format "common/database/factories/%sFactory.php" name) root)))))) (when migrationp (rename-file (car (file-expand-wildcards (expand-file-name (format "chanced/database/migrations/*_create%s*_table.php" (let ((case-fold-search nil)) (replace-regexp-in-string (rx (group (any (?A . ?Z)))) (lambda (match) (concat "_" (downcase match))) name t))) root))) (expand-file-name "common/database/migrations/" root)) (vc-register (cons 'Git (list (list (car (file-expand-wildcards (expand-file-name (format "common/database/migrations/*_create%s*_table.php" (let ((case-fold-search nil)) (replace-regexp-in-string (rx (group (any (?A . ?Z)))) (lambda (match) (concat "_" (downcase match))) name t))) root)))))))) (rename-file bad-file-name good-file-name) (find-file good-file-name) (save-excursion (goto-char (point-min)) (search-forward "namespace App;") (kill-whole-line) (insert "namespace App\\Models;\n") (save-buffer)) (vc-register))) (transient-define-prefix artisan-make-factory-transient () "Make model." ["Arguments & Switches"] ["Commands" ("m" "Make" artisan-make-factory)]) (defun artisan-make-factory (&optional name) (interactive "MName: ") (let* ((root (project-root (project-current))) (default-directory (expand-file-name "chanced" root)) (bad-file-name (expand-file-name (format "chanced/database/factories/%sFactory.php" name) root)) (good-file-name (expand-file-name (format "common/database/factories/%sFactory.php" name) root))) (shell-command (format "docker exec chanced-backend php artisan make:factory -m %S %S" name name)) (rename-file bad-file-name good-file-name) (find-file good-file-name) (vc-register))) (require 'dashboard) (dashboard-setup-startup-hook) (run-with-idle-timer 300 t (lambda () (switch-to-buffer dashboard-buffer-name))) (run-at-time "02:00" 86400 #'dashboard-open) ;;; (setq dashboard-navigator-buttons `(((,(propertize " " 'display `(image :type svg :file ,(expand-file-name "search.svg" oni-gui-icons-dir) :ascent center :margin (5 . 0))) "Conversations" "Open pull requests" (lambda (&rest _) (browse-url "https://github.com/pulls?q=commenter%3Atomw-punt+review%3Achanges_requested+is%3Aopen")) default "[" "]") (,(propertize " " 'display `(image :type svg :file ,(expand-file-name "search.svg" oni-gui-icons-dir) :ascent center :margin (5 . 0))) "PRs" "Open pull requests" (lambda (&rest _) (browse-url "https://github.com/pulls?q=is%3Aopen+is%3Apr+org%3Ajuked-social+draft%3Afalse+review%3Anone+-author%3Aapp%2Fdependabot+-base%3Adev+-base%3Amain+-base%3Achanced_dev")) default "[" "]")) ((,(propertize " " 'display `(image :type svg :file ,(expand-file-name "search.svg" oni-gui-icons-dir) :ascent center :margin (5 . 0))) "back-end" "Unmerged into back-end" (lambda (&rest _) (browse-url "https://github.com/juked-social/social-api/compare/main...staging")) default "[" "]") (,(propertize " " 'display `(image :type svg :file ,(expand-file-name "search.svg" oni-gui-icons-dir) :ascent center :margin (5 . 0))) "chanced" "Unmerged into chanced front-end" (lambda (&rest _) (browse-url "https://github.com/juked-social/chanced-frontend/compare/main...staging")) default "[" "]") (,(propertize " " 'display `(image :type svg :file ,(expand-file-name "search.svg" oni-gui-icons-dir) :ascent center :margin (5 . 0))) "punt" "Unmerged into punt front-end" (lambda (&rest _) (browse-url "https://github.com/juked-social/punt-frontend/compare/main...staging")) default "[" "]")))) (setq dashboard-startup-banner "~/code/personal/dotfiles/oni/home/services/emacs/pop-os-logo.svg") (setq dashboard-set-navigator t) (setq dashboard-set-footer nil) (setq dashboard-projects-show-base t) (setq dashboard-recentf-show-base t) (add-hook 'server-after-make-frame-hook #'dashboard-open) (add-hook 'dashboard-mode-hook 'olivetti-mode) (add-hook 'dashboard-after-initialize-hook (lambda () (setq truncate-lines t))) (setq browse-url-browser-function #'browse-url-generic) (setq browse-url-generic-args nil) (setq browse-url-generic-program "~/Downloads/glide/glide") (defun oni-fixup-phpstan-filenames (errors) "Change the file name from each error in ERRORS to one on local disk." (mapcar (lambda (e) (setf (flycheck-error-filename e) (expand-file-name (replace-regexp-in-string (rx string-start "/app/") (if (string-match (rx "filament") default-directory) "filament/" "") (flycheck-error-filename e)) (project-root (project-current)))) e) errors)) (with-eval-after-load 'flycheck-phpstan (advice-add 'flycheck-phpstan-parse-output :filter-return #'oni-fixup-phpstan-filenames)) (with-eval-after-load 'grep (add-to-list 'grep-files-aliases '("js" . "*.js *.jsx *.json *.vue"))) (with-eval-after-load 'php-mode (require 'flycheck-phpstan nil t)) (with-eval-after-load 'flycheck (flycheck-add-mode 'javascript-eslint 'web-mode)) (with-eval-after-load 'sql (setf (map-elt sql-connection-alist "localhost") '((sql-product 'postgres) (sql-user "chanced") (sql-password "secret") (sql-database "chanced") (sql-server "localhost") (sql-port 5433)) (map-elt sql-connection-alist "chanced-remote") '((sql-product 'postgres) (sql-user "tom") (sql-database "chanced") (sql-server "localhost") (sql-port 5432)) (map-elt sql-connection-alist "chanced-stg") '((sql-product 'postgres) (sql-user "tom") (sql-database "chanced") (sql-server "localhost") (sql-port 5432)) (map-elt sql-connection-alist "punt-remote") '((sql-product 'postgres) (sql-user "tom") (sql-database "punt") (sql-server "localhost") (sql-port 5432)))) (with-eval-after-load 'web-mode (defun web-mode-scan-blocks (reg-beg reg-end) "Identifies blocks (with block-side, block-beg, block-end text properties)." (save-excursion (let ((i 0) open close closing-string sub1 sub2 pos tagopen tmp delim-open delim-close part-beg part-end tagclose) (goto-char reg-beg) ;;(message "%S: %Sx%S" (point) reg-beg reg-end) ;;(message "regexp=%S" web-mode-block-regexp) (while (and (< i 2000) (> reg-end (point)) web-mode-block-regexp (re-search-forward web-mode-block-regexp reg-end t) (not (eobp))) (setq i (1+ i) closing-string nil close nil tagopen (match-string 0) open (match-beginning 0) delim-open nil delim-close nil pos nil) (let ((l (length tagopen))) (when (member (string-to-char tagopen) '(?\s ?\t)) (setq tagopen (replace-regexp-in-string "\\`[ \t]*" "" tagopen)) (setq open (+ open (- l (length tagopen)))) (setq l (length tagopen)) ) (setq sub1 (substring tagopen 0 1) sub2 (substring tagopen 0 (if (>= l 2) 2 1))) ) ;;(message " found block #(%S) at pos=(%S), part-type=(%S)" i open (get-text-property open 'part-side)) (cond ((string= web-mode-engine "php") (unless (member (char-after) '(?x ?X)) (setq closing-string '("<\\?". "\\?>"))) (cond ((looking-at-p "")) ((eq (char-after) ?\=) (setq delim-open "")) (t (setq delim-open "")) ) ;cond ) ;php ((string= web-mode-engine "erb") (cond ((string= sub2 "<%") (setq closing-string '("<%". "%>") delim-open "<%\\(==\\|[=-]\\)?" delim-close "[-]?%>")) (t (setq closing-string "EOL" delim-open "%")) ) ) ;erb ((string= web-mode-engine "django") (cond ((string= sub2 "{{") (setq closing-string "EODQ" ;;(setq closing-string '("{{" . "}}") delim-open "{{" delim-close "}}")) ((string= sub2 "{%") (setq closing-string "%}" delim-open "{%[+-]?" delim-close "[-]?%}")) ((string= sub2 "{#") (setq closing-string "#}")) (t (setq closing-string "EOL" delim-open "#[#]?")) ) ) ;django ((string= web-mode-engine "anki") (setq closing-string "}}" delim-open "{{[#/^]?" delim-close "}}") ) ;anki ((string= web-mode-engine "ejs") (setq closing-string "%>" delim-open "<%[=-]?" delim-close "[-]?%>") ) ;ejs ((string= web-mode-engine "lsp") (setq closing-string "%>" delim-open "<%[%#]?" delim-close "%>") ) ;lsp ((string= web-mode-engine "mako") (cond ((and (string= tagopen "<%") (member (char-after) '(?\s ?\n ?\!))) (setq closing-string "%>" delim-open "<%[!]?" delim-close "%>")) ((member sub2 '("<%" "" delim-open "")) ((string= sub2 "${") (setq closing-string "}" delim-open "${" delim-close "}")) (t (setq closing-string "EOL" delim-open "%")) ) ) ;mako ((string= web-mode-engine "cl-emb") (cond ((string= tagopen "<%#") (setq closing-string "#%>")) ((string= sub2 "<%") (setq closing-string "%>" delim-open "<%[=%]?" delim-close "%>")) ) ) ;cl-emb ((string= web-mode-engine "artanis") (cond ((string= tagopen "<%;") (setq closing-string "%>")) ((string= tagopen "<%#|") (setq closing-string "|#%>")) ((string= sub2 "<@") (setq closing-string "%>" delim-open "<@\\(css\\|icon\\|include\\|js\\)" delim-close "%>")) ((string= sub2 "<%") (setq closing-string "%>" delim-open "<%[=]?" delim-close "%>")) ) ) ;artanis ((string= web-mode-engine "elixir") (cond ((member (char-after) '(?\#)) (setq closing-string "%>")) (t (setq closing-string "%>" delim-open "<%[=%]?" delim-close "%>")) ) ) ;elixir ((string= web-mode-engine "mojolicious") (cond ((string= tagopen "<%#") (setq closing-string "%>")) ((string= sub2 "<%") (setq closing-string "%>" delim-open "<%\\(==\\|[=%]\\)?" delim-close "%>")) ((string= sub2 "%#") (setq closing-string "EOL")) (t (setq closing-string "EOL" delim-open "%\\(==\\|[=%]\\)?")) ) ) ;mojolicious ((string= web-mode-engine "ctemplate") (cond ((member tagopen '("{{{" "{{~")) (setq closing-string "}~?}}" delim-open "{{~?{" delim-close "}~?}}") ) ((string= tagopen "{~{") (setq closing-string "}~?}" delim-open "{~{" delim-close "}~?}") ) ((string= tagopen "{{!") (setq closing-string (if (looking-at-p "--") "--}}" "}}")) ) ((string= sub2 "{{") (setq closing-string "}~?}" delim-open "{{[>#/%^&]?" delim-close "}~?}")) (t (setq closing-string "}}" delim-open "${{" delim-close "}}")) ) ) ;ctemplate ((string= web-mode-engine "antlers") (cond ((string= tagopen "{{$") (setq closing-string "$}}" delim-open "{{$" delim-close "$}}") ) ((string= tagopen "{{?") (setq closing-string "?}}" delim-open "{{?" delim-close "?}}") ) ((string= tagopen "{{$") (setq closing-string "$}}" delim-open "{{$" delim-close "$}}") ) ((string= sub2 "{{") (setq closing-string "}}" delim-open "{{" delim-close "}}")) ) ) ;antlers ((string= web-mode-engine "astro") (cond ((string= tagopen "---") (setq closing-string "---" delim-open "---" delim-close "---") ) ) ) ;astro ((string= web-mode-engine "aspx") (setq closing-string "%>" delim-open "<%[:=#@$]?" delim-close "%>") ) ;aspx ((string= web-mode-engine "asp") (cond ((string= sub2 "<%") (setq closing-string "%>" delim-open "<%[:=#@$]?" delim-close "%>")) (t (setq closing-string ">" delim-open "")) ) ) ;asp ((string= web-mode-engine "jsp") (cond ((looking-at-p "--") (setq closing-string "--%>")) ((string= sub2 "<%") (setq closing-string "%>" delim-open "<%\\([!=@]\\|#=\\)?" delim-close "[-]?%>")) ((string= sub2 "${") (setq closing-string "}" delim-open "${" delim-close "}")) ) ) ;jsp ((string= web-mode-engine "clip") (setq closing-string ">" delim-open "") ) ;clip ((string= web-mode-engine "perl") (setq closing-string ">" delim-open "") ) ;perl ((string= web-mode-engine "blade") (cond ((string= tagopen "{{-") (setq closing-string "--}}")) ((string= tagopen "{!!") (setq closing-string "!!}" delim-open "{!!" delim-close "!!}")) ((string= tagopen "@{{") (setq closing-string nil)) ((string= tagopen "{{{") (setq closing-string "}}}" delim-open "{{{" delim-close "}}}")) ((string= sub2 "{{") (setq closing-string "}}" delim-open "{{" delim-close "}}")) ((looking-at-p "[[:alnum:]]+\\.[[:alpha:]]+") ) ((string= sub1 "@") (setq closing-string "EOB" delim-open "@")) ((looking-at-p "[[:alnum:]]+(") (setq closing-string ")" delim-open "@")) ) ;;(message "closing-string=%S delim-open=%S delim-close=%S" closing-string delim-open delim-close) ) ;blade ((string= web-mode-engine "smarty") (cond ((string= tagopen "{*") (setq closing-string "*}") ) ((string= tagopen "{#") (setq closing-string "#}" delim-open "{#" delim-close "#}") ) (t (setq closing-string (cons "{" "}") delim-open "{/?" delim-close "}") ) ;t ) ;cond ) ;smarty ((string= web-mode-engine "hero") (setq closing-string "%>" delim-open "<%==?\\([biufsv]\\|bs\\)?\\|<%[:~@+!]?" delim-close "%>") ) ;hero ((string= web-mode-engine "xoops") (cond ((string= tagopen "<{*") (setq closing-string "*}>") ) ((string= tagopen "<{#") (setq closing-string "#}>" delim-open "<{#" delim-close "#}>") ) (t (setq closing-string (cons "<{" "}>") delim-open "<{/?" delim-close "}>") ) ;t ) ;cond ) ;xoops ((string= web-mode-engine "web2py") (setq closing-string "}}" delim-open "{{[=]?" delim-close "}}") ) ;web2py ((string= web-mode-engine "expressionengine") (cond ((string= sub2 "{!--") (setq closing-string "--}")) (t (setq closing-string '("{". "}") delim-open "{/?" delim-close "}") ) ) ) ;expressionengine ((string= web-mode-engine "dust") (cond ((string= sub2 "{!") (setq closing-string "!}")) (t (setq closing-string '("{". "}") delim-open "{[#/:?@><+^]?" delim-close "/?}") ) ) ) ;dust ((string= web-mode-engine "svelte") (cond ((string= sub2 "{!") (setq closing-string "!}")) ((string= sub2 "{}") (setq closing-string nil delim-open nil delim-close nil)) (t (setq closing-string '("{". "}") delim-open "{[#/:?@><+^]?" delim-close "/?}") ) ) ) ;svelte ((string= web-mode-engine "closure") (cond ((string= sub2 "//") (setq closing-string "EOL") ) ((string= sub2 "/*") (setq closing-string "*/") ) (t (setq closing-string "}" delim-open "{/?" delim-close "/?}") ) ) ) ;closure ((string= web-mode-engine "go") (setq closing-string "}}" delim-open "{{-?" delim-close "-?}}") ) ;go ((string= web-mode-engine "angular") (setq closing-string "}}" delim-open "{{" delim-close "}}") ) ;angular ((string= web-mode-engine "vue") (cond ((string-match-p "[:@][-[:alpha:].]+=\"" tagopen) (setq closing-string "\"" delim-open tagopen delim-close "\"")) ((string= tagopen "{{") (setq closing-string "}}" delim-open "{{" delim-close "}}"))) ) ;vue ((string= web-mode-engine "mason") (cond ((and (member sub2 '("<%" "" delim-open "<[/]?%" delim-close ">") (setq closing-string (concat "") delim-open "<[^>]+>" delim-close "<[^>]+>") ) ;if ) ((and (string= sub2 "<%") (eq (char-after) ?\s)) (setq closing-string "%>" delim-open "<%" delim-close "%>")) ((string= tagopen "" delim-open "") ) ((string= sub2 "<&") (setq closing-string "&>" delim-open "<&[|]?" delim-close "&>")) (t (setq closing-string "EOL" delim-open "%")) ) ) ;mason ((string= web-mode-engine "underscore") (setq closing-string "%>" delim-open "<%" delim-close "%>") ) ;underscore ((string= web-mode-engine "template-toolkit") (cond ((string= tagopen "%%#") (setq closing-string "EOL")) ((string= tagopen "[%#") (setq closing-string "%]")) (t (setq closing-string "%]" delim-open "\\[%[-+]?" delim-close "[-=+]?%\\]")) ) ) ;template-toolkit ((string= web-mode-engine "freemarker") (cond ((and (string= sub2 "<#") (eq (char-after) ?\-)) (setq closing-string "-->")) ((string= sub1 "<") (setq closing-string ">" delim-open "")) ((string= sub1 "[") (setq closing-string "]" delim-open "\\[/?[#@]" delim-close "/?\\]")) (t (setq closing-string "}" delim-open "${" delim-close "}")) ) ) ;freemarker ((string= web-mode-engine "velocity") (cond ((string= sub2 "##") (setq closing-string "EOL")) ((string= sub2 "#*") (setq closing-string "*#")) (t (setq closing-string "EOV" delim-open "#")) ) ) ;velocity ((string= web-mode-engine "razor") (cond ((string= sub2 "@@") (forward-char 2) (setq closing-string nil)) ((string= sub2 "@*") (setq closing-string "*@")) ((string= sub1 "@") (setq closing-string "EOR" delim-open "@")) ((and (string= sub1 "}") (looking-at-p "[ ]*\n")) ;;(setq closing-string "EOC") (save-excursion (let (paren-pos) (setq paren-pos (web-mode-part-opening-paren-position (1- (point)))) (if (and paren-pos (get-text-property paren-pos 'block-side)) (setq closing-string "EOC") (setq closing-string nil) ) ;if ) ;let ) ;save-excursion ;;(message "%s %S %S" sub2 (point) (get-text-property (point) 'part-side)) ) ((string= sub1 "}") ;;(message "%s: %s" (point) sub1) (save-excursion (let (paren-pos) (setq paren-pos (web-mode-part-opening-paren-position (1- (point)))) (if (and paren-pos (get-text-property paren-pos 'block-side)) (setq closing-string "EOR") (setq closing-string nil) ) ;if ) ;let ) ;save-excursion ) ;case } ) ;cond ) ;razor ((and (string= web-mode-engine "riot") (not (get-text-property open 'part-side))) (setq closing-string (if (string= tagopen "{") "}" "/// end script") delim-open "{" delim-close "}") ) ;riot ((string= web-mode-engine "spip") (cond ((and (string= sub1 "#") (looking-at "[A-Z0-9_]+")) (setq closing-string (match-string-no-properties 0))) ((string= sub1 "(") (setq closing-string '("(" . ")"))) ((string= sub1 "{") (setq closing-string '("{" . "}"))) ((string= sub2 "<:") (setq closing-string ":>")) (t (setq closing-string "]")) )) ((string= web-mode-engine "marko") (setq closing-string "}" delim-open "${" delim-close "}") ) ;marko ) ;cond (when closing-string (cond ((listp closing-string) (cond ((web-mode-rsf-balanced (car closing-string) (cdr closing-string) reg-end t) (setq close (match-end 0) pos (point)) ) ((and (string= web-mode-engine "php") (string= " (point) reg-end) reg-end (point)) pos (if (> (point) reg-end) reg-end (point))) (goto-char pos)) ((string= closing-string "EOV") (web-mode-velocity-skip open) (setq close (point) pos (point))) ((and (member web-mode-engine '("ctemplate")) (re-search-forward closing-string reg-end t)) (setq close (match-end 0) pos (point))) ((and (member web-mode-engine '("antlers")) (re-search-forward closing-string reg-end t)) (setq close (match-end 0) pos (point))) ((and (member web-mode-engine '("astro")) (re-search-forward closing-string reg-end t)) (setq close (match-end 0) pos (point))) ((search-forward closing-string reg-end t) (setq close (match-end 0) pos (point))) ) ;cond (when (and close (>= reg-end pos)) ;;(message "pos(%S) : open(%S) close(%S)" pos open close) (put-text-property open (1+ open) 'block-beg 0) (put-text-property open (1+ open) 'block-controls 0) (put-text-property open close 'block-side t) (put-text-property (1- close) close 'block-end t) (when delim-open (web-mode-block-delimiters-set open close delim-open delim-close)) (web-mode-block-scan open close) (cond ((and (string= web-mode-engine "erb") (looking-at-p "<%= javascript_tag do %>")) (setq tagopen "<%= javascript_tag do %>")) ((and (string= web-mode-engine "mojolicious") (looking-at-p "%= javascript begin")) (setq tagopen "%= javascript begin")) ((and (string= web-mode-engine "mako") (looking-at-p "<%block filter=\"collect_js\">")) (setq tagopen "<%block filter=\"collect_js\">")) ((and (string= web-mode-engine "mako") (looking-at-p "<%block filter=\"collect_css\">")) (setq tagopen "<%block filter=\"collect_css\">")) ((and (string= web-mode-engine "django") (looking-at-p "{% javascript %}")) (setq tagopen "{% javascript %}")) ((and (string= web-mode-engine "django") (looking-at-p "{% schema %}")) (setq tagopen "{% schema %}")) ((and (string= web-mode-engine "django") (looking-at-p "{% stylesheet %}")) (setq tagopen "{% stylesheet %}")) ) ;;(message "%S %s" (point) tagopen) (when (and (member tagopen '("" "<%block filter=\"collect_js\">" "<%block filter=\"collect_css\">" "{% javascript %}" "{% schema %}" "{% stylesheet %}" "%= javascript begin" "---")) (setq part-beg close) (setq tagclose (cond ((string= tagopen "") "<% end %>") ((member tagopen '("<%block filter=\"collect_js\">" "<%block filter=\"collect_css\">")) " part-end part-beg)) ;;(message "tagopen=%S tagclose=%S end=%S" tagopen tagclose (point)) (put-text-property part-beg part-end 'part-side (cond ((member tagopen '("" "{% stylesheet %}")) 'css) (t 'javascript))) (setq pos part-beg part-beg nil part-end nil) ) ;when ) ;when close (if pos (goto-char pos)) ) ;when closing-string ) ;while (cond ((>= i 2000) (message "scan-blocks ** warning (%S) **" i)) ((string= web-mode-engine "razor") (web-mode-block-foreach reg-beg reg-end 'web-mode-block-scan)) ((string= web-mode-engine "django") (web-mode-scan-engine-comments reg-beg reg-end "{% comment %}" "{% endcomment %}")) ((string= web-mode-engine "mako") (web-mode-scan-engine-comments reg-beg reg-end "<%doc>" "")) ((string= web-mode-engine "mason") (web-mode-scan-engine-comments reg-beg reg-end "<%doc>" "")) ) ;cond ))) (setf (map-elt web-mode-engine-open-delimiter-regexps "vue") "{{\\|[:@][-[:alpha:].]+=\"")) (require 'oni-js) (with-eval-after-load 'sh-script (require 'oni-sh)) (with-eval-after-load 'sql (require 'oni-sql)) (with-eval-after-load 'outline (require 'oni-outline)) (with-eval-after-load 'logview (require 'oni-logview)) (eval-when-compile (require 'magit-section)) (with-eval-after-load 'magit (defun oni-magit-insert-locked-files () (let ((locked-files (split-string (string-trim-right (let ((default-directory (project-root (project-current)))) (shell-command-to-string "git ls-files -v | grep ^S | cut -d ' ' -f 2-")))))) (when (length> locked-files 0) (magit-insert-section (locked-files) (magit-insert-heading (length locked-files) "Locked Files") (dolist (file locked-files) (insert file) (insert ?\n)))))) (add-hook 'magit-status-sections-hook #'oni-magit-insert-locked-files 20)) (with-eval-after-load 'elfeed (setq elfeed-feeds '(("https://www.reddit.com/r/PHP/.rss" php) ("https://phpreads.com/feed" php) ("https://phpstan.org/rss.xml" php) ("https://lobste.rs/t/php.rss" php)) elfeed-curl-program-name "curl")) (setq git-messenger:show-detail t) (global-set-key (kbd "C-c g .") '("Show commit at point" . git-messenger:popup-message)) (global-set-key (kbd "C-c g b") '("Git Blame current file" . magit-blame)) (global-set-key (kbd "C-c g l") '("Show file's git log" . magit-log-buffer-file)) (defun my-set-agenda-files (&rest _) (setq org-agenda-files (cl-loop for file in (org-mem-all-files) unless (string-search "archive" file) when (seq-find (lambda (entry) (or (org-mem-entry-active-timestamps entry) (org-mem-entry-todo-state entry) (org-mem-entry-scheduled entry) (org-mem-entry-deadline entry))) (org-mem-entries-in file)) collect file))) (add-hook 'org-mem-post-full-scan-functions #'my-set-agenda-files) ;;; Prodigy services (with-eval-after-load 'prodigy (prodigy-define-tag :name 'tunnel :command "~/code/diamond-interactive/social-api/toolbox/connect_db.sh" :args (lambda (&rest args) (let ((service (map-elt args :service))) (list "-e" (if (prodigy-service-tagged-with? service 'production) "prd" "stg") "-a" (cond ((prodigy-service-tagged-with? service 'chanced) "chanced") ((prodigy-service-tagged-with? service 'punt) "punt") (t (error "Unknown project"))) "-k" (expand-file-name "~/.ssh/id_ed25519.pub")))) :cwd "~/code/diamond-interactive/social-api" :stop-signal 'kill :ready-message "Waiting for connections...") (prodigy-define-service :name "Chanced Production Database Connection" :tags '(chanced production tunnel)) (prodigy-define-service :name "Chanced Staging Database Connection" :tags '(chanced staging tunnel)) (prodigy-define-service :name "Punt Production Database Connection" :tags '(punt production tunnel)) (prodigy-define-service :name "Punt Staging Database Connection" :tags '(punt staging tunnel))) (autoload 'vue-ts-mode "vue-ts-mode" nil t) (add-to-list 'auto-mode-alist (cons (rx ".vue" eos) 'vue-ts-mode))