-
Notifications
You must be signed in to change notification settings - Fork 1
/
bitbake-ts-mode.el
137 lines (103 loc) · 4.35 KB
/
bitbake-ts-mode.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
137
;;; bitbake-ts-mode.el --- A major mode to use bitbake tree-sitter -*- lexical-binding: t; -*-
;; Copyright (C) 2024 Sukbeom Kim
;; Author: Jason Kim <[email protected]>
;; Maintainer: Jason Kim <[email protected]>
;; Created: September 8, 2024
;; Keywords: bitbake, tree-sitter, languages
;; Version: 0.0.2
;; Homepage: https://github.com/seokbeomKim/bitbake-ts-mode
;; Package-Requires: ((emacs "29.1"))
;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this file. If not, see <https://www.gnu.org/licenses/>.
;;; Setup:
;; 1. install tree-sitter parser for Yocto bitbake
;; (add-to-list
;; 'treesit-language-source-alist
;; '(bitbake "https://github.com/tree-sitter-grammars/tree-sitter-bitbake"))
;;
;; 2. install bitbake-ts-mode major mode
;; (require 'bitbake-ts-mode)
;;; Commentary:
;; For now, the package does not support indentation rule, but only supports
;; syntax highlighting and imenu integration.
;;; Code:
(require 'treesit)
(eval-when-compile (require 'rx))
(declare-function treesit-parser-create "treesit.c")
(declare-function treesit-node-child-by-field-name "treesit.c")
(defconst bitbake-ts-mode--treesit-keywords
'("inherit" "require" "include" "INHERIT"))
(defvar bitbake-ts-font-lock-rules
`(:language bitbake
:override t
:feature attribute
((attribute) @font-lock-builtin-face)
:language bitbake
:override t
:feature identifier
((identifier) @font-lock-variable-keyword-face)
:language bitbake
:override t
:feature string_content
((string_content) @font-lock-string-face)
:language bitbake
:override t
:feature comment
((comment) @font-lock-comment-face)
:language bitbake
:override t
:feature keyword
([,@bitbake-ts-mode--treesit-keywords] @font-lock-keyword-face)))
(defvar bitbake-ts-mode-indent-offset 8
"Number of spaces for each indentation step in `bitbake-ts-mode'.")
(defun bitbake-ts-imenu-identifier-name-function (node)
"A function to return the name of identifier `NODE'."
(treesit-node-text node))
(defun bitbake-ts-imenu-identifier-node-p (node)
"A function to check whether the `NODE' is identifier."
(string-match-p "^identifier$" (treesit-node-type node)))
(defun bitbake-ts-imenu-directive-name-function (node)
"A function to obtain the name of directive `NODE'."
(treesit-node-text node))
(defun bitbake-ts-imenu-directive-node-p (node)
"A function to check whether the `NODE' is directive."
(string-match-p "_directive$" (treesit-node-type node)))
;;;###autoload
(define-derived-mode bitbake-ts-mode prog-mode "bitbake"
"Major mode for editing Yocto recipe, powered by tree-sitter."
(when (treesit-ready-p 'bitbake)
(treesit-parser-create 'bitbake)
;; Define a list of features of what it is going to be highlighted
(setq-local treesit-font-lock-feature-list
'((comment)
(keyword)
(identifier attribute string_content)))
;; Font-lock
(setq-local treesit-font-lock-settings
(apply #'treesit-font-lock-rules
bitbake-ts-font-lock-rules))
;; Comments
(setq-local comment-start "# ")
;; Imenu
(setq-local treesit-simple-imenu-settings
`(("Directive" bitbake-ts-imenu-directive-node-p nil bitbake-ts-imenu-directive-name-function)
("Identifier" bitbake-ts-imenu-identifier-node-p nil bitbake-ts-imenu-identifier-name-function)))
;; Which function
(setq-local which-func-functions nil)
;; Indentation
(setq-local indent-tabs-mode nil)
(treesit-major-mode-setup)))
(when (treesit-ready-p 'bitbake)
(add-to-list 'auto-mode-alist '("\\.bb?\\'" . bitbake-ts-mode))
(add-to-list 'auto-mode-alist '("\\.bbappend?\\'" . bitbake-ts-mode)))
(provide 'bitbake-ts-mode)
;;; bitbake-ts-mode.el ends here