-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
395 additions
and
0 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
elpa/flycheck-haskell-20150406.327/flycheck-haskell-autoloads.el
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
;;; flycheck-haskell-autoloads.el --- automatically extracted autoloads | ||
;; | ||
;;; Code: | ||
(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) | ||
|
||
;;;### (autoloads nil "flycheck-haskell" "flycheck-haskell.el" (21836 | ||
;;;;;; 37615 467297 803000)) | ||
;;; Generated autoloads from flycheck-haskell.el | ||
|
||
(autoload 'flycheck-haskell-setup "flycheck-haskell" "\ | ||
Setup Haskell support for Flycheck. | ||
If the current file is part of a Cabal project, configure | ||
Flycheck to take the module paths of the Cabal projects into | ||
account. | ||
Also search for Cabal sandboxes and add them to the module search | ||
path as well. | ||
\(fn)" nil nil) | ||
|
||
;;;*** | ||
|
||
;;;### (autoloads nil nil ("flycheck-haskell-pkg.el") (21836 37615 | ||
;;;;;; 481651 694000)) | ||
|
||
;;;*** | ||
|
||
;; Local Variables: | ||
;; version-control: never | ||
;; no-byte-compile: t | ||
;; no-update-autoloads: t | ||
;; End: | ||
;;; flycheck-haskell-autoloads.el ends here |
10 changes: 10 additions & 0 deletions
10
elpa/flycheck-haskell-20150406.327/flycheck-haskell-pkg.el
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
(define-package "flycheck-haskell" "20150406.327" "Flycheck: Cabal projects and sandboxes" | ||
'((flycheck "0.22") | ||
(haskell-mode "13.7") | ||
(dash "2.4.0") | ||
(let-alist "1.0.1")) | ||
:url "https://github.com/flycheck/flycheck-haskell" :keywords | ||
'("tools" "convenience")) | ||
;; Local Variables: | ||
;; no-byte-compile: t | ||
;; End: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
;;; flycheck-haskell.el --- Flycheck: Cabal projects and sandboxes -*- lexical-binding: t; -*- | ||
|
||
;; Copyright (C) 2014, 2015 Sebastian Wiesner <swiesner@lunaryorn.com> | ||
;; Copyright (C) 2014 Gracjan Polak <gracjanpolak@gmail.com> | ||
|
||
;; Author: Sebastian Wiesner <swiesner@lunaryorn.com> | ||
;; URL: https://github.com/flycheck/flycheck-haskell | ||
;; Keywords: tools, convenience | ||
;; Version: 0.7-cvs | ||
;; Package-Requires: ((flycheck "0.22") (haskell-mode "13.7") (dash "2.4.0") (let-alist "1.0.1")) | ||
|
||
;; 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: | ||
|
||
;; Configure Haskell syntax checking by Flycheck. | ||
|
||
;;;; Cabal support | ||
|
||
;; Try to find Cabal project files for Haskell buffers, and configure the | ||
;; Haskell syntax checkers in Flycheck according to the contents of the Cabal | ||
;; file: | ||
;; | ||
;; - Add all source directories to the GHC search path | ||
;; - Add build directories from Cabal to the GHC search path to speed up | ||
;; checking and support non-Haskell modules such as hsc files | ||
;; - Add auto-generated files from Cabal to the GHC search path | ||
;; - Set the language from Cabal | ||
;; - Enable language extensions from Cabal | ||
|
||
;;;; Cabal sandboxes | ||
|
||
;; Try to find a Cabal sandbox configuration for this project, and configure the | ||
;; Haskell syntax checkers in Flycheck to use the package database from the | ||
;; Sandbox. | ||
|
||
;;;; Setup | ||
|
||
;; (add-hook 'flycheck-mode-hook #'flycheck-haskell-setup) | ||
|
||
;;; Code: | ||
|
||
(eval-when-compile | ||
(require 'rx) | ||
(require 'let-alist)) | ||
|
||
(require 'haskell-cabal) | ||
(require 'flycheck) | ||
(require 'dash) | ||
|
||
|
||
;;; Customization | ||
|
||
(defgroup flycheck-haskell nil | ||
"Haskell support for Flycheck." | ||
:prefix "flycheck-haskell-" | ||
:group 'flycheck | ||
:link '(url-link :tag "Github" "https://github.com/flycheck/flycheck-haskell")) | ||
|
||
(defcustom flycheck-haskell-runhaskell "runhaskell" | ||
"Path to the `runhaskell' executable. | ||
This library uses `runhaskell' to run various Haskell helper | ||
scripts to extract information from Cabal files." | ||
:type `(file :must-match t) | ||
:group 'flycheck-haskell) | ||
|
||
|
||
;;; Cabal support | ||
(defconst flycheck-haskell-helper | ||
(expand-file-name "get-cabal-configuration.hs" | ||
(file-name-directory (if load-in-progress | ||
load-file-name | ||
(buffer-file-name)))) | ||
"The helper to dump the Cabal configuration.") | ||
|
||
(defconst flycheck-haskell-config-cache (make-hash-table :test 'equal) | ||
"Cache of Cabal configuration. | ||
A hash table, mapping the name of a cabal file to a | ||
cons-cell `(MODTIME . CONFIG)', where MODTIME is the modification | ||
time of the cabal file, and CONFIG the extracted configuration.") | ||
|
||
(defun flycheck-haskell-clear-config-cache () | ||
"Clear the cache of configurations." | ||
(interactive) | ||
(clrhash flycheck-haskell-config-cache)) | ||
|
||
(defun flycheck-haskell-get-cached-configuration (cabal-file) | ||
"Get the cached configuration for CABAL-FILE. | ||
Return the cached configuration, or nil, if there is no cache | ||
entry, or if the cache entry is outdated." | ||
(pcase-let* ((cache-entry (gethash cabal-file flycheck-haskell-config-cache)) | ||
(`(,modtime . ,config) cache-entry)) | ||
(when (and modtime (file-exists-p cabal-file)) | ||
(let ((current-modtime (nth 5 (file-attributes cabal-file)))) | ||
(if (time-less-p modtime current-modtime) | ||
;; The entry is outdated, drop it. `remhash' always | ||
;; returns nil, so we are safe to use it here. | ||
(remhash cabal-file flycheck-haskell-config-cache) | ||
;; The configuration is up to date, use it | ||
config))))) | ||
|
||
(defun flycheck-haskell-read-cabal-configuration (cabal-file) | ||
"Read the Cabal configuration from CABAL-FILE." | ||
(with-temp-buffer | ||
(let ((result (call-process flycheck-haskell-runhaskell nil t nil | ||
flycheck-haskell-helper cabal-file))) | ||
(when (= result 0) | ||
(goto-char (point-min)) | ||
(read (current-buffer)))))) | ||
|
||
(defun flycheck-haskell-read-and-cache-configuration (cabal-file) | ||
"Read and cache configuration from CABAL-FILE. | ||
Return the configuration." | ||
(let ((modtime (nth 5 (file-attributes cabal-file))) | ||
(config (flycheck-haskell-read-cabal-configuration cabal-file))) | ||
(puthash cabal-file (cons modtime config) flycheck-haskell-config-cache) | ||
config)) | ||
|
||
(defun flycheck-haskell-get-configuration (cabal-file) | ||
"Get the Cabal configuration from CABAL-FILE. | ||
Get the configuration either from our cache, or by reading the | ||
CABAL-FILE. | ||
Return the configuration." | ||
(or (flycheck-haskell-get-cached-configuration cabal-file) | ||
(flycheck-haskell-read-and-cache-configuration cabal-file))) | ||
|
||
(defconst flycheck-haskell-sandbox-config "cabal.sandbox.config" | ||
"The file name of a Cabal sandbox configuration.") | ||
|
||
(defconst flycheck-haskell-package-db-re | ||
(rx line-start (zero-or-more (any space)) "package-db:" | ||
(zero-or-more (any space)) | ||
(group (one-or-more (not (any space)))) | ||
(zero-or-more (any space) line-end)) | ||
"Regular expression to parse the package db directory.") | ||
|
||
(defun flycheck-haskell-get-package-db (sandbox-config-file) | ||
"Get the package database directory from SANDBOX-CONFIG-FILE. | ||
Return the package database directory as string, or nil, if the | ||
database was not found." | ||
(with-temp-buffer | ||
(insert-file-contents sandbox-config-file) | ||
(goto-char (point-min)) | ||
(when (re-search-forward flycheck-haskell-package-db-re nil 'noerror) | ||
(match-string 1)))) | ||
|
||
(defun flycheck-haskell-find-sandbox-config () | ||
"Find Cabal sandbox configuration for the current buffer. | ||
Return the absolute path of the sandbox configuration file as | ||
string, or nil, if no sandbox configuration file was found." | ||
(-when-let (root-dir (locate-dominating-file (buffer-file-name) | ||
flycheck-haskell-sandbox-config)) | ||
(expand-file-name flycheck-haskell-sandbox-config root-dir))) | ||
|
||
(defun flycheck-haskell-process-configuration (config) | ||
"Process the a Cabal CONFIG." | ||
(let-alist config | ||
(setq-local flycheck-ghc-search-path | ||
(append .build-directories .source-directories | ||
flycheck-ghc-search-path)) | ||
(setq-local flycheck-ghc-language-extensions | ||
(append .extensions .languages | ||
flycheck-ghc-language-extensions)) | ||
(setq-local flycheck-ghc-args | ||
(append .other-options flycheck-ghc-args)))) | ||
|
||
(defun flycheck-haskell-configure () | ||
"Set paths and package database for the current project." | ||
(interactive) | ||
(when (and (buffer-file-name) (file-directory-p default-directory)) | ||
(-when-let* ((cabal-file (haskell-cabal-find-file)) | ||
(config (flycheck-haskell-get-configuration cabal-file))) | ||
(flycheck-haskell-process-configuration config)) | ||
|
||
(-when-let* ((config (flycheck-haskell-find-sandbox-config)) | ||
(package-db (flycheck-haskell-get-package-db config))) | ||
(setq-local flycheck-ghc-package-databases | ||
(cons package-db flycheck-ghc-package-databases)) | ||
(setq-local flycheck-ghc-no-user-package-database t)))) | ||
|
||
;;;###autoload | ||
(defun flycheck-haskell-setup () | ||
"Setup Haskell support for Flycheck. | ||
If the current file is part of a Cabal project, configure | ||
Flycheck to take the module paths of the Cabal projects into | ||
account. | ||
Also search for Cabal sandboxes and add them to the module search | ||
path as well." | ||
(add-hook 'hack-local-variables-hook #'flycheck-haskell-configure)) | ||
|
||
(provide 'flycheck-haskell) | ||
|
||
;; Local Variables: | ||
;; indent-tabs-mode: nil | ||
;; coding: utf-8 | ||
;; End: | ||
|
||
;;; flycheck-haskell.el ends here |
Binary file not shown.
128 changes: 128 additions & 0 deletions
128
elpa/flycheck-haskell-20150406.327/get-cabal-configuration.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
-- Copyright (C) 2014 Sebastian Wiesner <swiesner@lunaryorn.com> | ||
-- Copyright (C) 2014 Gracjan Polak <gracjanpolak@gmail.com> | ||
|
||
-- 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/>. | ||
|
||
{-# LANGUAGE TypeSynonymInstances #-} | ||
{-# LANGUAGE FlexibleInstances #-} | ||
|
||
import Control.Monad (liftM) | ||
import Data.List (nub, isPrefixOf) | ||
import Data.Maybe (listToMaybe) | ||
import Distribution.Compiler (CompilerFlavor(GHC)) | ||
import Distribution.Package (PackageName(..),Dependency(..)) | ||
import Distribution.PackageDescription (PackageDescription(..),allBuildInfo | ||
,BuildInfo(..) | ||
,usedExtensions,allLanguages | ||
,hcOptions | ||
,exeName) | ||
import Distribution.PackageDescription.Configuration (flattenPackageDescription) | ||
import Distribution.PackageDescription.Parse (readPackageDescription) | ||
import Distribution.Simple.BuildPaths (defaultDistPref) | ||
import Distribution.Verbosity (silent) | ||
import Language.Haskell.Extension (Extension(..),Language(..)) | ||
import System.Environment (getArgs) | ||
import System.Exit (exitFailure) | ||
import System.FilePath ((</>),dropFileName,normalise) | ||
|
||
data Sexp = SList [Sexp] | ||
| SString String | ||
| SSymbol String | ||
|
||
sym :: String -> Sexp | ||
sym = SSymbol | ||
|
||
instance Show Sexp where | ||
show (SSymbol s) = s | ||
show (SString s) = show s -- Poor man's escaping | ||
show (SList s) = "(" ++ unwords (map show s) ++ ")" | ||
|
||
class ToSexp a where | ||
toSexp :: a -> Sexp | ||
|
||
instance ToSexp String where | ||
toSexp = SString | ||
|
||
instance ToSexp Extension where | ||
toSexp (EnableExtension ext) = toSexp (show ext) | ||
toSexp (DisableExtension ext) = toSexp ("No" ++ show ext) | ||
toSexp (UnknownExtension ext) = toSexp ext | ||
|
||
instance ToSexp Language where | ||
toSexp (UnknownLanguage lang) = toSexp lang | ||
toSexp lang = toSexp (show lang) | ||
|
||
instance ToSexp Dependency where | ||
toSexp (Dependency (PackageName dependency) _) = toSexp dependency | ||
|
||
instance ToSexp Sexp where | ||
toSexp = id | ||
|
||
cons :: (ToSexp a, ToSexp b) => a -> [b] -> Sexp | ||
cons h t = SList (toSexp h : map toSexp t) | ||
|
||
getBuildDirectories :: PackageDescription -> FilePath -> [String] | ||
getBuildDirectories pkgDesc cabalDir = case library pkgDesc of | ||
Just _ -> buildDir : buildDirs | ||
Nothing -> buildDirs | ||
where distDir = cabalDir </> defaultDistPref | ||
buildDir = distDir </> "build" | ||
autogenDir = buildDir </> "autogen" | ||
executableBuildDir e = buildDir </> exeName e </> (exeName e ++ "-tmp") | ||
buildDirs = autogenDir : map executableBuildDir (executables pkgDesc) | ||
|
||
getSourceDirectories :: [BuildInfo] -> FilePath -> [String] | ||
getSourceDirectories buildInfo cabalDir = | ||
map (cabalDir </>) (concatMap hsSourceDirs buildInfo) | ||
|
||
usefulOptions :: [String] | ||
usefulOptions = ["-W", "-w", "-Wall", "-fglasgow-exts", "-fpackage-trust", "-fhelpful-errors", "-F", "-cpp"] | ||
|
||
usefulOptionPrefixes :: [String] | ||
usefulOptionPrefixes = ["-fwarn-", "-fno-warn-", "-fcontext-stack=", "-firrefutable-tuples", "-D", "-U", "-I", "-fplugin=", "-fplugin-opt=", "-pgm", "-opt"] | ||
|
||
isFlycheckUsefulOption :: String -> Bool | ||
isFlycheckUsefulOption opt = elem opt usefulOptions || any (`isPrefixOf` opt) usefulOptionPrefixes | ||
|
||
dumpPackageDescription :: PackageDescription -> FilePath -> Sexp | ||
dumpPackageDescription pkgDesc cabalFile = SList [ | ||
cons (sym "build-directories") buildDirs | ||
, cons (sym "source-directories") sourceDirs | ||
, cons (sym "extensions") exts | ||
, cons (sym "languages") langs | ||
, cons (sym "dependencies") deps | ||
, cons (sym "other-options") otherOptions | ||
] | ||
where cabalDir = dropFileName cabalFile | ||
buildInfo = allBuildInfo pkgDesc | ||
buildDirs = nub (map normalise (getBuildDirectories pkgDesc cabalDir)) | ||
sourceDirs = nub (map normalise (getSourceDirectories buildInfo cabalDir)) | ||
exts = nub (concatMap usedExtensions buildInfo) | ||
langs = nub (concatMap allLanguages buildInfo) | ||
deps = nub (buildDepends pkgDesc) | ||
otherOptions = nub (filter isFlycheckUsefulOption (concatMap (hcOptions GHC) buildInfo)) | ||
|
||
dumpCabalConfiguration :: String -> IO () | ||
dumpCabalConfiguration cabalFile = do | ||
pkgDesc <- liftM flattenPackageDescription | ||
(readPackageDescription silent cabalFile) | ||
print (dumpPackageDescription pkgDesc cabalFile) | ||
|
||
main :: IO () | ||
main = do | ||
args <- getArgs | ||
let cabalFile = listToMaybe args | ||
maybe exitFailure dumpCabalConfiguration cabalFile |
Oops, something went wrong.