forked from christophermaier/sqitch-for-emacs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsqitch-mode.el
161 lines (134 loc) · 5.61 KB
/
sqitch-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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
;;; sqitch-mode.el --- Minor-mode for interacting with Sqitch SQL scripts
;; Copyright (C) 2014 Christopher Maier
;; Author: Christopher Maier <[email protected]>
;; Maintainer: Christopher Maier <[email protected]>
;; Version: 0.0.1
;; Keywords: sql, sqitch
;; URL: https://github.com/christophermaier/sqitch-for-emacs
;; This file is NOT part of GNU Emacs.
;;; License:
;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; Provides basic navigation across files of a Sqitch project.
;; See http://www.sqitch.org for details
;;
;; To use this file, make sure that the following code (or its
;; equivalent) is in your Emacs configuration:
;;
;; (add-to-list 'load-path "/path/to/sqitch-for-emacs")
;; (require 'sqitch-mode)
;;
;; When you open a SQL file (i.e., '*.sql') in `sql-mode` that is in a
;; 'deploy', 'verify', or 'revert' directory, and that has a
;; 'sqitch.plan' file as a sibling of those directories, the
;; 'sqitch-mode' minor mode will be activated automatically.
;;; Code:
(defun sqitch-find-script (script-type)
"Opens the corresponding SCRIPT-TYPE Sqitch script for
the current Sqitch script file.
SCRIPT-TYPE should be one of \"deploy\", \"verify\",
\"revert\" or \"test\"."
(let* ((current-script (buffer-file-name))
(current-dir (file-name-directory current-script))
(base-name (file-name-nondirectory current-script))
(sqitch-file (expand-file-name
(concat current-dir
(file-name-as-directory "..")
(file-name-as-directory script-type)
base-name))))
(if (file-exists-p sqitch-file)
(find-file sqitch-file)
(message "Could not find a Sqitch %s script for '%s'" script-type (buffer-file-name)))))
(defun sqitch-find-deploy-script ()
"Open the corresponding deploy script for the current Sqitch
script."
(interactive)
(sqitch-find-script "deploy"))
(defun sqitch-find-verify-script ()
"Open the corresponding verify script for the current Sqitch
script."
(interactive)
(sqitch-find-script "verify"))
(defun sqitch-find-revert-script ()
"Open the corresponding revert script for the current Sqitch
script."
(interactive)
(sqitch-find-script "revert"))
(defun sqitch-find-test-script ()
"Open the corresponding test script for the current Sqitch
script."
(interactive)
(sqitch-find-script "test"))
(defun sqitch-plan-file ()
"Return the path to the sqitch.plan for the current buffer, if it exists"
(let ((proj-dir (locate-dominating-file (buffer-file-name) "sqitch.plan")))
(if proj-dir
(concat (file-name-as-directory proj-dir) "sqitch.plan"))))
(defun sqitch-find-plan ()
"Open the sqitch.plan file for the Sqitch script, if it
exists."
(interactive)
(let ((plan (sqitch-plan-file)))
(if plan
(let (changeset change-re tag)
(setq changeset
(split-string (file-name-base (buffer-file-name)) "@" t split-string-default-separators))
(setq change-re (concat "^\s*" (car changeset) "\s+"))
(setq tag (car (cdr changeset)))
(find-file plan)
(if tag
(progn
(goto-char (point-min))
(search-forward-regexp (concat "^\s*@" tag "\s+"))
(search-forward-regexp change-re))
(goto-char (point-max))
(search-backward-regexp change-re))
(back-to-indentation))
(message "Could not find a Sqitch plan file for '%s'" (file-name-base (buffer-file-name))))))
(defvar sqitch-mode-keymap nil "sqitch-mode keymap")
(if sqitch-mode-keymap
nil
(setq sqitch-mode-keymap (make-sparse-keymap))
(define-key sqitch-mode-keymap (kbd "C-c C-d") 'sqitch-find-deploy-script)
(define-key sqitch-mode-keymap (kbd "C-c C-v") 'sqitch-find-verify-script)
(define-key sqitch-mode-keymap (kbd "C-c C-r") 'sqitch-find-revert-script)
(define-key sqitch-mode-keymap (kbd "C-c C-t") 'sqitch-find-test-script)
(define-key sqitch-mode-keymap (kbd "C-c C-p") 'sqitch-find-plan))
;;;###autoload
(define-minor-mode sqitch-mode
"Minor mode for interacting with Sqitch SQL scripts."
:init-value nil
:lighter " sqitch"
:keymap sqitch-mode-keymap)
(defun sqitch-script-p ()
"Indicate whether the current buffer corresponds to a deploy,
verify, revert or test script in a Sqitch project"
(and (sqitch-plan-file)
(member (file-name-base (directory-file-name
(file-name-directory (buffer-file-name))))
'("deploy" "verify" "revert" "test"))))
;;;###autoload
(defun sqitch-maybe-enable-mode ()
"Call this as an sql-mode-hook to determine whether or not to
turn on the sqitch-mode for the current file."
(interactive)
(if (sqitch-script-p)
(sqitch-mode)
(message "The current buffer is NOT a Sqitch script!")))
;;;###autoload
(add-hook 'sql-mode-hook 'sqitch-maybe-enable-mode)
(provide 'sqitch-mode)
;;; sqitch-mode.el ends here