-
Notifications
You must be signed in to change notification settings - Fork 82
/
apheleia-utils.el
136 lines (117 loc) · 5.1 KB
/
apheleia-utils.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
;;; apheleia-utils.el --- Formatter helpers. -*- lexical-binding: t -*-
;; SPDX-License-Identifier: MIT
;;; Commentary:
;; Helper functions for defining apheleia formatters.
;;; Code:
(require 'cl-lib)
(require 'subr-x)
(defcustom apheleia-formatters-respect-indent-level t
"Whether formatters should respect Emacs' indent configuration."
:type 'boolean
:group 'apheleia
:safe #'booleanp)
(defun apheleia-formatters-indent (tab-flag indent-flag &optional indent-var)
"Set flag for indentation.
Helper function for `apheleia-formatters' which allows you to supply
alternating flags based on the current buffers indent configuration. If the
buffer is indented with tabs then returns TAB-FLAG. Otherwise if INDENT-VAR
is set in the buffer return INDENT-FLAG and the value of INDENT-VAR. Use this
to easily configure the indentation level of a formatter. If INDENT-VAR is
unset then intelligently try to determine the indentation variable based on
the current mode.
If `apheleia-formatters-respect-indent-level' is nil then this
always returns nil to defer to the formatter."
(cond
((not apheleia-formatters-respect-indent-level) nil)
(indent-tabs-mode tab-flag)
(t
(unless indent-var
(setq indent-var
(cl-case major-mode
(cperl-mode 'cperl-indent-level)
(css-mode 'css-indent-offset)
(css-ts-mode 'css-indent-offset)
(graphql-mode 'graphql-indent-level)
(html-mode 'sgml-basic-offset)
(js-jsx-mode 'js-indent-level)
(js-ts-mode 'js-indent-level)
(js-mode 'js-indent-level)
(js2-jsx-mode 'js2-basic-offset)
(js2-mode 'js2-basic-offset)
(js3-mode 'js3-indent-level)
(json-mode 'js-indent-level)
(json-ts-mode 'json-ts-mode-indent-offset)
(nxml-mode 'nxml-child-indent)
(robot-mode 'robot-mode-basic-offset)
(perl-mode 'perl-indent-level)
(python-mode 'python-indent-offset)
(ruby-mode 'ruby-indent-level)
(ruby-ts-mode 'ruby-indent-level)
(scss-mode 'css-indent-offset)
(svelte-mode 'svelte-basic-offset)
(web-mode 'web-mode-indent-style)
(tsx-ts-mode 'typescript-ts-mode-indent-offset)
(typescript-mode 'typescript-indent-level)
(typescript-ts-mode 'typescript-ts-mode-indent-offset)
(yaml-mode 'yaml-indent-offset))))
(when-let ((indent (and indent-var
(boundp indent-var)
(symbol-value indent-var))))
(list indent-flag (number-to-string indent))))))
(define-obsolete-function-alias 'apheleia-formatters-js-indent
'apheleia-formatters-indent "4.1")
(defcustom apheleia-formatters-respect-fill-column nil
"Whether formatters should set `fill-column' related flags."
:type 'boolean
:group 'apheleia
:safe #'booleanp)
(defun apheleia-formatters-fill-column (fill-flag)
"Set flag for wrap column.
Helper function to set a flag based on `fill-column'. When `fill-column' is set
and `apheleia-formatters-respect-fill-column' return a list of FILL-FLAG and
`fill-column'."
(when (and apheleia-formatters-respect-fill-column
(bound-and-true-p fill-column))
(list fill-flag (number-to-string fill-column))))
(defun apheleia-formatters-locate-file (file-flag file-name)
"Set a flag based on a dominating-file.
Look for a file up recursively from the current directory until FILE-NAME is
found. If found return a list of FILE-FLAG and the absolute path to the located
FILE-NAME."
(when-let ((file (locate-dominating-file default-directory file-name)))
(list file-flag (concat (expand-file-name file) file-name))))
(defun apheleia-formatters-extension-p (&rest exts)
"Assert whether current buffer has an extension in EXTS."
(when-let ((name buffer-file-name)
(ext (file-name-extension name)))
(cl-find-if (apply-partially #'string-equal ext)
exts)))
(defcustom apheleia-formatters-mode-extension-assoc
'((c-mode . ".c")
(c-ts-mode . ".c")
(c++-mode . ".cpp")
(c++-ts-mode . ".cpp")
(glsl-mode . ".glsl")
(java-mode . ".java")
(java-ts-mode . ".java"))
"Association list between major-modes and common file extensions for them."
:type 'alist
:group 'apheleia)
(defun apheleia-formatters-mode-extension (&optional flag)
"Get a file-extension based on the current `major-mode'.
If FLAG is set this function returns a list of FLAG and then the extension.
Otherwise return the extension only."
(when-let ((ext
(alist-get major-mode apheleia-formatters-mode-extension-assoc)))
(if flag
(list flag ext)
ext)))
(defun apheleia-formatters-local-buffer-file-name (&optional file-name)
"Get FILE-NAME without any remote components.
FILE-NAME defaults to variable `buffer-file-name'."
(when-let ((file-name (or file-name buffer-file-name)))
(if-let ((remote (file-remote-p file-name)))
(substring file-name (length remote))
file-name)))
(provide 'apheleia-utils)
;;; apheleia-utils.el ends here