Last active
January 14, 2024 09:20
-
-
Save vfsoraki/4f3658defc930b655df125087114ec3b to your computer and use it in GitHub Desktop.
ELisp code to switch between controller, view and templates in an Elixir Phoenix project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(setq | |
vfex--view-regex-old "^lib/\\(.+\\)/views/\\(.+\\)_view.ex" | |
vfex--template-regex-old "^lib/\\(.+\\)/templates/\\(.+\\)/" | |
vfex--view-regex-new "^lib/\\(.+\\)/controllers/\\(.+\\)_html.ex" | |
vfex--template-regex-new "^lib/\\(.+\\)/controllers/\\(.+\\)_html/" | |
vfex--controller-regex "^lib/\\(.+\\)/controllers/\\(.+\\)_controller.ex" | |
vfex--liveview-regex "^lib/\\(.+\\)/live/\\(.+\\)_live.ex" | |
vfex--liveview-template-regex "^lib/\\(.+\\)/live/\\(.+\\)_live.html.heex") | |
(defun vfex--dot-p (name) | |
"Predicate to know if a name is dot file or not" | |
(or (string-equal name ".") (string-equal name ".."))) | |
(defun vfex--view-p (path) | |
"Predicate to know if a path is view or not" | |
(or | |
(string-match vfex--view-regex-new path) | |
(string-match vfex--view-regex-old path))) | |
(defun vfex--template-p (path) | |
"Predicate to know if a path is template or not" | |
(or | |
(string-match vfex--template-regex-new path) | |
(string-match vfex--template-regex-old path))) | |
(defun vfex--controller-p (path) | |
"Predicate to know if a path is controller or not" | |
(string-match vfex--controller-regex path)) | |
(defun vfex--liveview-p (path) | |
"Predicate to know if a path is liveview or not" | |
(string-match vfex--liveview-regex path)) | |
(defun vfex--liveview-template-p (path) | |
"Predicate to know if a path is liveview template or not" | |
(string-match vfex--liveview-template-regex path)) | |
(defun vfex--switch-to-old-view-from-controller (filename-r) | |
"Switch to old view of current controller" | |
(let* ((controller-p (vfex--controller-p filename-r))) | |
(when (and filename-r controller-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(view_path (concat "lib/" app "/views/" name "_view.ex")) | |
(view (file-relative-name view_path (file-name-parent-directory filename-r)))) | |
(if (file-exists-p view) | |
(find-file view) | |
(message "View %s not found" view)))))) | |
(defun vfex--switch-to-view-from-controller (filename-r) | |
"Switch to view of current controller" | |
(let* ((controller-p (vfex--controller-p filename-r))) | |
(when (and filename-r controller-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(view (concat name "_html.ex"))) | |
(if (file-exists-p view) | |
(find-file view) | |
(message "View %s not found" view)))))) | |
(defun vfex--switch-to-old-view-from-template (filename-r) | |
"Switch to old view of current template" | |
(let* ((template-p (vfex--template-p filename-r))) | |
(when (and filename-r template-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(view_path (concat "lib/" app "/views/" name "_view.ex")) | |
(view (file-relative-name view_path (file-name-parent-directory filename-r)))) | |
(if (file-exists-p view) | |
(find-file view) | |
(message "View %s not found" view)))))) | |
(defun vfex--switch-to-view-from-template (filename-r) | |
"Switch to view of current template" | |
(let* ((controller-p (vfex--template-p filename-r))) | |
(when (and filename-r controller-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(view (concat "../" name "_html.ex"))) | |
(if (file-exists-p view) | |
(find-file view) | |
(message "View %s not found" view)))))) | |
(defun vfex-switch-to-view () | |
"Switch to view from controller or template" | |
(interactive) | |
(let* ((root (project-root (project-current))) | |
(filename (buffer-file-name)) | |
(filename-r (file-relative-name filename root)) | |
(controller-p (vfex--controller-p filename-r)) | |
(template-p (vfex--template-p filename-r))) | |
(when controller-p | |
(vfex--switch-to-view-from-controller filename-r) | |
(vfex--switch-to-old-view-from-controller filename-r)) | |
(when template-p | |
(vfex--switch-to-view-from-template filename-r) | |
(vfex--switch-to-old-view-from-template filename-r)))) | |
(defun vfex--switch-to-controller-from-old-view (filename-r) | |
"Switch to controller of current old view" | |
(let* ((view-p (vfex--view-p filename-r))) | |
(when (and filename-r view-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(controller_path (concat "lib/" app "/controllers/" name "_controller.ex")) | |
(controller (file-relative-name controller_path (file-name-parent-directory filename-r)))) | |
(if (file-exists-p controller) | |
(find-file controller) | |
(message "Controller %s not found" controller)))))) | |
(defun vfex--switch-to-controller-from-view (filename-r) | |
"Switch to controller of current view" | |
(let* ((view-p (vfex--view-p filename-r))) | |
(when (and filename-r view-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(controller (concat name "_controller.ex"))) | |
(if (file-exists-p controller) | |
(find-file controller) | |
(message "Controller %s not found" controller)))))) | |
(defun vfex--switch-to-controller-from-old-template (filename-r) | |
"Switch to controller of current old template" | |
(let* ((template-p (vfex--template-p filename-r))) | |
(when (and filename-r template-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(controller_path (concat "lib/" app "/controllers/" name "_controller.ex")) | |
(controller (file-relative-name controller_path (file-name-parent-directory filename-r)))) | |
(if (file-exists-p controller) | |
(find-file controller) | |
(message "Controller %s not found" controller)))))) | |
(defun vfex--switch-to-controller-from-template (filename-r) | |
"Switch to controller of current template" | |
(let* ((template-p (vfex--template-p filename-r))) | |
(when (and filename-r template-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(controller (concat "../" name "_controller.ex"))) | |
(if (file-exists-p controller) | |
(find-file controller) | |
(message "Controller %s not found" controller)))))) | |
(defun vfex-switch-to-controller () | |
"Switch to controller from view or template" | |
(interactive) | |
(let* ((root (project-root (project-current))) | |
(filename (buffer-file-name)) | |
(filename-r (file-relative-name filename root)) | |
(view-p (vfex--view-p filename-r)) | |
(template-p (vfex--template-p filename-r))) | |
(when view-p | |
(vfex--switch-to-controller-from-view filename-r) | |
(vfex--switch-to-controller-from-old-view filename-r)) | |
(when template-p | |
(vfex--switch-to-controller-from-template filename-r) | |
(vfex--switch-to-controller-from-old-template filename-r)))) | |
(defun vfex--select-template (path) | |
"Provide a selection to switch to templates in dir" | |
(let* ((files (directory-files path)) | |
(templates (cl-remove-if #'vfex--dot-p files)) | |
(template (completing-read "Select an template: " templates))) | |
(when template (find-file (concat path template))))) | |
(defun vfex--switch-to-template-from-old-view (filename-r) | |
"Switch to a template of current old view" | |
(let* ((view-p (vfex--view-p filename-r))) | |
(when (and filename-r view-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(path-a (concat "lib/" app "/templates/" name "/")) | |
(path (file-relative-name path-a (file-name-parent-directory filename-r)))) | |
(if (file-exists-p path) | |
(vfex--select-template path) | |
(message "Templates not found in %s" path)))))) | |
(defun vfex--switch-to-template-from-view (filename-r) | |
"Switch to a template of current view" | |
(let* ((view-p (vfex--view-p filename-r))) | |
(when (and filename-r view-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(path (concat name "_html/"))) | |
(if (file-exists-p path) | |
(vfex--select-template path) | |
(message "Templates not found in %s" path)))))) | |
(defun vfex--switch-to-old-template-from-controller (filename-r) | |
"Switch to an old template of current controller" | |
(let* ((controller-p (vfex--controller-p filename-r))) | |
(when (and filename-r controller-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(path-a (concat "lib/" app "/templates/" name "/")) | |
(path (file-relative-name path-a (file-name-parent-directory filename-r)))) | |
(if (file-exists-p path) | |
(vfex--select-template path) | |
(message "Templates not found in %s" path)))))) | |
(defun vfex--switch-to-template-from-controller (filename-r) | |
"Switch to a template of current controller" | |
(let* ((controller-p (vfex--controller-p filename-r))) | |
(when (and filename-r controller-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(path (concat name "_html/"))) | |
(if (file-exists-p path) | |
(vfex--select-template path) | |
(message "Templates not found in %s" path)))))) | |
(defun vfex-switch-to-template () | |
"Switch to a template of view or controller" | |
(interactive) | |
(let* ((root (project-root (project-current))) | |
(filename (buffer-file-name)) | |
(filename-r (file-relative-name filename root)) | |
(controller-p (vfex--controller-p filename-r)) | |
(view-p (vfex--view-p filename-r))) | |
(when controller-p | |
(vfex--switch-to-template-from-controller filename-r) | |
(vfex--switch-to-old-template-from-controller filename-r)) | |
(when view-p | |
(vfex--switch-to-template-from-view filename-r) | |
(vfex--switch-to-template-from-old-view filename-r)))) | |
(defun vfex--switch-to-template-from-liveview (filename-r) | |
"Switch to template of current liveview" | |
(let* ((liveview-p (vfex--liveview-p filename-r))) | |
(when (and filename-r liveview-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(template (concat name "_live.html.heex"))) | |
(if (file-exists-p template) | |
(find-file template) | |
(message "Template not found in %s" path)))))) | |
(defun vfex--switch-to-liveview-from-template (filename-r) | |
"Switch to liveview of current template" | |
(let* ((template-p (vfex--liveview-template-p filename-r))) | |
(when (and filename-r template-p) | |
(let* ((app (match-string 1 filename-r)) | |
(name (match-string 2 filename-r)) | |
(liveview (concat name "_live.ex"))) | |
(if (file-exists-p liveview) | |
(find-file liveview) | |
(message "LiveView not found in %s" path)))))) | |
(defun vfex-switch-lv-template () | |
"Switch between a LiveView and its template" | |
(interactive) | |
(let* ((root (project-root (project-current))) | |
(filename (buffer-file-name)) | |
(filename-r (file-relative-name filename root)) | |
(liveview-p (vfex--liveview-p filename-r)) | |
(template-p (vfex--liveview-template-p filename-r))) | |
(when liveview-p (vfex--switch-to-template-from-liveview filename-r)) | |
(when template-p (vfex--switch-to-liveview-from-template filename-r)))) | |
(global-set-key (kbd "C-c s c") 'vfex-switch-to-controller) | |
(global-set-key (kbd "C-c s v") 'vfex-switch-to-view) | |
(global-set-key (kbd "C-c s t") 'vfex-switch-to-template) | |
(global-set-key (kbd "C-c s l") 'vfex-switch-lv-template) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment