-
Notifications
You must be signed in to change notification settings - Fork 3
/
hgignore-mode.el
104 lines (86 loc) · 3.74 KB
/
hgignore-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
;;; hgignore-mode.el --- a major mode for editing hgignore files -*- lexical-binding: t -*-
;;; Copyright (C) 2014-2015 Omair Majid
;; Author: Omair Majid <[email protected]>
;; URL: http://github.com/omajid/hgignore-mode
;; Keywords: convenience vc hg
;; Version: 0.1.20150329
;; This file is NOT part of GNU Emacs.
;; This program 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 of the
;; License, or (at your option) any later version.
;; This program 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 program. If not, see
;; <http://www.gnu.org/licenses/>.
;;; Commentary:
;; A major mode for editing hgignore files. Adds basic syntax
;; highlighting, commenting and completion support.
;;; Code:
(require 'newcomment)
(defconst hgignore--keywords
(list
(cons (regexp-opt '("syntax" "regexp" "glob") 'symbols)
'font-lock-keyword-face))
"Keywords recognized by font-lock for `hgignore-mode'.")
(defun hgignore--completion-at-point ()
"`completion-at-point' support for hgignore-mode."
(if (looking-back "^syntax: ?" nil)
(hgignore--complete-syntax)
(hgignore--complete-raw-path)))
(defun hgignore--complete-syntax ()
"Complete the `syntax' parts of hgignore."
(when (looking-back "^syntax: ?" nil)
(list (line-beginning-position) (point)
(list "syntax: regexp" "syntax: glob"))))
(defun hgignore--complete-raw-path ()
"Complete paths, escaping according to the currently active syntax."
(let* ((line-start (save-excursion
(beginning-of-line)
(point)))
(completion-start (save-excursion
(condition-case nil
(progn
(end-of-line)
(1+ (re-search-backward "/" line-start)))
(error line-start))))
(root-path (file-name-directory (buffer-file-name)))
(base-path (buffer-substring-no-properties line-start completion-start))
(path (concat root-path base-path "/"))
(how-to-quote (save-excursion
(condition-case nil
(progn
(re-search-backward "^syntax: \\(regexp\\|glob\\)$")
(if (string-equal (match-string 1) "regexp")
#'regexp-quote
#'identity))
(error #'regexp-quote)))))
(list completion-start
(point)
(mapcar how-to-quote (directory-files path)))))
;; prog-mode was introduced in emacs 24.1
(defalias 'hgignore--parent-mode
(if (fboundp 'prog-mode)
'prog-mode
'fundamental-mode))
;;;###autoload
(define-derived-mode hgignore-mode hgignore--parent-mode "hgignore"
"Major mode for editing .hgignore files."
;; set up font-lock
(setq font-lock-defaults (list hgignore--keywords))
;; syntax table
(let ((table hgignore-mode-syntax-table))
(modify-syntax-entry ?\# "<" table)
(modify-syntax-entry ?\n ">" table))
;; comment/uncomment correctly
(setq comment-start "#")
(setq comment-end "")
;; auto completion
(add-hook 'completion-at-point-functions #'hgignore--completion-at-point nil t))
;;;###autoload
(add-to-list 'auto-mode-alist '("\\.hgignore\\'" . hgignore-mode))
(provide 'hgignore-mode)
;;; hgignore-mode.el ends here