From 7b1e482530c76dcf856ec4a20aee6586eb2e8ccf Mon Sep 17 00:00:00 2001 From: Matus Goljer Date: Wed, 1 Mar 2023 16:02:43 +0100 Subject: [PATCH] feat(core): add setup for outline-minor-mode Fixes #20 --- README.md | 38 +++++++++++++++++++++++++++++++++++++- terraform-mode.el | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 352974b..8f66c3a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,24 @@ You can install `terraform-mode.el` from [MELPA](https://melpa.org/) by `package - Indentation - imenu - Formatting using `terraform fmt` +- Block folding +### Block folding + +`terraform-mode` sets up `outline-mode` variables for block folding. +To use `outline-mode` for block folding, enable `outline-minor-mode` +in `terraform-mode-hook`: + +``` emacs-lisp +(add-hook 'terraform-mode-hook #'outline-minor-mode) +``` + +You can use `outline-toggle-children` bound to `C-c C-f` to toggle +visibility of a block at point. + +We also provide function `terraform-toggle-or-indent` which +folds-or-indents. It is not bound by default, but you can bind it to +`TAB` or any other key. ## Customize Variables @@ -36,11 +53,30 @@ Set to `t` to automatically format the buffer on save. ## Sample Configuration -```lisp +```emacs-lisp (custom-set-variables '(terraform-indent-level 4)) ``` +With `use-package` + +``` emacs-lisp +(use-package terraform-mode + ;; if using straight + ;; :straight t + + ;; if using package.el + ;; :ensure t + :custom (terraform-indent-level 4) + :config + (defun my-terraform-mode-init () + ;; if you want to use outline-minor-mode + ;; (outline-minor-mode 1) + ) + + (add-hook 'terraform-mode-hook 'my-terraform-mode-init)) +``` + ## See Also - [hcl-mode](https://github.com/syohex/emacs-hcl-mode) diff --git a/terraform-mode.el b/terraform-mode.el index 4793278..4a06fa1 100644 --- a/terraform-mode.el +++ b/terraform-mode.el @@ -36,6 +36,7 @@ (require 'hcl-mode) (require 'dash) (require 'thingatpt) +(require 'outline) (defgroup terraform nil "Major mode of Terraform configuration file." @@ -276,9 +277,45 @@ (interactive) (browse-url (terraform--resource-url-at-point))) +(defun terraform--outline-level () + "Return the depth to which a statement is nested in the outline. + +See also `outline-level'." + (or (cdr (assoc (match-string 1) outline-heading-alist)) + (- (match-end 1) (match-beginning 1)))) + +(defun terraform--setup-outline-mode () + (set (make-local-variable 'outline-level) #'terraform--outline-level) + + (let ((terraform-keywords + (list "terraform" "locals" "required_providers" "atlas" "connection" + "backend" "provider" "provisioner" + "variable" "module" "output" + "data" "resource"))) + (set (make-local-variable 'outline-regexp) + (concat + "^" + (regexp-opt terraform-keywords 'symbols) + "[[:blank:]].*{[[:blank:]]*$")) + (set (make-local-variable 'outline-heading-alist) + (mapcar + (lambda (item) (cons item 2)) + terraform-keywords)))) + +(defun terraform-toggle-or-indent (&optional arg) + "Toggle visibility of block under point or indent. + +If the point is not at the heading, call +`indent-for-tab-command'." + (interactive) + (if (and outline-minor-mode (outline-on-heading-p)) + (outline-toggle-children) + (indent-for-tab-command arg))) + (defvar terraform-mode-map (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-h") #'terraform-open-doc) + (define-key map (kbd "C-c C-f") #'outline-toggle-children) map)) ;;;###autoload @@ -293,6 +330,9 @@ (make-local-variable 'terraform-indent-level) (setq hcl-indent-level terraform-indent-level) + ;; outline + (terraform--setup-outline-mode) + ;; imenu (setq imenu-sort-function 'imenu--sort-by-name) (setq imenu-create-index-function 'terraform--generate-imenu)