Klimi's new dotfiles with stow.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
7.9 KiB

  1. ;;; haskell-session.el --- Haskell sessions -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2011-2012 Chris Done
  3. ;; Author: Chris Done <chrisdone@gmail.com>
  4. ;; This file is not part of GNU Emacs.
  5. ;; This file is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation; either version 3, or (at your option)
  8. ;; any later version.
  9. ;; This file is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with GNU Emacs; see the file COPYING. If not, write to
  15. ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. ;; Boston, MA 02110-1301, USA.
  17. ;;; Commentary:
  18. ;;; Todo:
  19. ;;; Code:
  20. (require 'cl-lib)
  21. (require 'haskell-cabal)
  22. (require 'haskell-customize)
  23. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  24. ;; Globals
  25. ;; Used internally
  26. (defvar-local haskell-session nil)
  27. (defvar haskell-sessions (list)
  28. "All Haskell sessions in the Emacs session.")
  29. (defun haskell-session-tags-filename (session)
  30. "Get the filename for the TAGS file."
  31. (concat (haskell-session-cabal-dir session) "/TAGS"))
  32. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  33. ;; Finding/clearing the session
  34. ;;;###autoload
  35. (defun haskell-session-maybe ()
  36. "Maybe get the Haskell session, return nil if there isn't one."
  37. (if (default-boundp 'haskell-session)
  38. haskell-session
  39. (setq haskell-session nil)))
  40. (defun haskell-session-from-buffer ()
  41. "Get the session based on the buffer."
  42. (when (and (buffer-file-name)
  43. (consp haskell-sessions))
  44. (cl-reduce (lambda (acc a)
  45. (let ((dir (haskell-session-get a 'cabal-dir)))
  46. (if dir
  47. (if (string-prefix-p dir
  48. (file-name-directory (buffer-file-name)))
  49. (if acc
  50. (if (and
  51. (> (length (haskell-session-get a 'cabal-dir))
  52. (length (haskell-session-get acc 'cabal-dir))))
  53. a
  54. acc)
  55. a)
  56. acc)
  57. acc)))
  58. haskell-sessions
  59. :initial-value nil)))
  60. (defun haskell-session-default-name ()
  61. "Generate a default project name for the new project prompt."
  62. (let ((file (haskell-cabal-find-file)))
  63. (or (when file
  64. (downcase (file-name-sans-extension
  65. (file-name-nondirectory file))))
  66. "haskell")))
  67. (defun haskell-session-assign (session)
  68. "Assing current buffer to SESSION.
  69. This could be helpful for temporary or auxiliary buffers such as
  70. presentation mode buffers (e.g. in case when session is killed
  71. with all relevant buffers)."
  72. (setq-local haskell-session session))
  73. (defun haskell-session-choose ()
  74. "Find a session by choosing from a list of the current sessions."
  75. (when haskell-sessions
  76. (let* ((session-name (funcall haskell-completing-read-function
  77. "Choose Haskell session: "
  78. (cl-remove-if (lambda (name)
  79. (and haskell-session
  80. (string= (haskell-session-name haskell-session)
  81. name)))
  82. (mapcar 'haskell-session-name haskell-sessions))))
  83. (session (cl-find-if (lambda (session)
  84. (string= (haskell-session-name session)
  85. session-name))
  86. haskell-sessions)))
  87. session)))
  88. (defun haskell-session-clear ()
  89. "Clear the buffer of any Haskell session choice."
  90. (setq-local haskell-session nil))
  91. (defun haskell-session-lookup (name)
  92. "Get the session by name."
  93. (cl-remove-if-not (lambda (s)
  94. (string= name (haskell-session-name s)))
  95. haskell-sessions))
  96. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  97. ;; Session modules
  98. (defun haskell-session-strip-dir (session file)
  99. "Strip the load dir from the file path."
  100. (let ((cur-dir (haskell-session-current-dir session)))
  101. (if (> (length file) (length cur-dir))
  102. (if (string= (substring file 0 (length cur-dir))
  103. cur-dir)
  104. (replace-regexp-in-string
  105. "^[/\\]" ""
  106. (substring file
  107. (length cur-dir)))
  108. file)
  109. file)))
  110. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  111. ;; Accessing the session
  112. (defun haskell-session-current-dir (s)
  113. "Get the session current directory."
  114. (let ((dir (haskell-session-get s 'current-dir)))
  115. (or dir
  116. (error "No current directory."))))
  117. (defun haskell-session-name (s)
  118. "Get the session name."
  119. (haskell-session-get s 'name))
  120. (defun haskell-session-target (s)
  121. "Get the session build target.
  122. If `haskell-process-load-or-reload-prompt' is nil, accept `default'."
  123. (let* ((maybe-target (haskell-session-get s 'target))
  124. (target (if maybe-target maybe-target
  125. (let ((new-target
  126. (if haskell-process-load-or-reload-prompt
  127. (read-string "build target (empty for default):")
  128. "")))
  129. (haskell-session-set-target s new-target)))))
  130. (if (not (string= target "")) target nil)))
  131. (defun haskell-session-set-target (s target)
  132. "Set the session build target."
  133. (haskell-session-set s 'target target))
  134. (defun haskell-session-set-interactive-buffer (s v)
  135. "Set the session interactive buffer."
  136. (haskell-session-set s 'interactive-buffer v))
  137. (defun haskell-session-set-process (s v)
  138. "Set the session process."
  139. (haskell-session-set s 'process v))
  140. ;;;###autoload
  141. (defun haskell-session-process (s)
  142. "Get the session process."
  143. (haskell-session-get s 'process))
  144. (defun haskell-session-set-cabal-dir (s v)
  145. "Set the session cabal-dir."
  146. (let ((true-path (file-truename v)))
  147. (haskell-session-set s 'cabal-dir true-path)
  148. (haskell-session-set-cabal-checksum s true-path)))
  149. (defun haskell-session-set-current-dir (s v)
  150. "Set the session current directory."
  151. (let ((true-path (file-truename v)))
  152. (haskell-session-set s 'current-dir true-path)))
  153. (defun haskell-session-set-cabal-checksum (s cabal-dir)
  154. "Set the session checksum of .cabal files"
  155. (haskell-session-set s 'cabal-checksum
  156. (haskell-cabal-compute-checksum cabal-dir)))
  157. (defun haskell-session-cabal-dir (s)
  158. "Get the session cabal-dir."
  159. (or (haskell-session-get s 'cabal-dir)
  160. (let ((set-dir (haskell-cabal-get-dir (not haskell-process-load-or-reload-prompt))))
  161. (if set-dir
  162. (progn (haskell-session-set-cabal-dir s set-dir)
  163. set-dir)
  164. (haskell-session-cabal-dir s)))))
  165. (defun haskell-session-modify (session key update)
  166. "Update the value at KEY in SESSION with UPDATE."
  167. (haskell-session-set
  168. session
  169. key
  170. (funcall update
  171. (haskell-session-get session key))))
  172. (defun haskell-session-get (session key)
  173. "Get the SESSION's KEY value.
  174. Returns nil if KEY not set."
  175. (cdr (assq key session)))
  176. (defun haskell-session-set (session key value)
  177. "Set the SESSION's KEY to VALUE.
  178. Returns newly set VALUE."
  179. (let ((cell (assq key session)))
  180. (if cell
  181. (setcdr cell value) ; modify cell in-place
  182. (setcdr session (cons (cons key value) (cdr session))) ; new cell
  183. value)))
  184. (provide 'haskell-session)
  185. ;;; haskell-session.el ends here