From d3b313a8be9974a213cdf13f8dabae222f56a6e5 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <rama.krishnan@concur.com>
Date: Tue, 17 Feb 2015 12:00:35 +0530
Subject: [PATCH] misc changes, hlint

---
 hs-lint/hs-lint.el | 126 +++++++++++++++++++++++++++++++++++++++++++++
 init.el            |  12 +++--
 2 files changed, 134 insertions(+), 4 deletions(-)
 create mode 100644 hs-lint/hs-lint.el

diff --git a/hs-lint/hs-lint.el b/hs-lint/hs-lint.el
new file mode 100644
index 0000000..f69ef0c
--- /dev/null
+++ b/hs-lint/hs-lint.el
@@ -0,0 +1,126 @@
+;;; hs-lint.el --- minor mode for HLint code checking
+
+;; Copyright 2009 (C) Alex Ott
+;;
+;; Author: Alex Ott <alexott@gmail.com>
+;; Keywords: haskell, lint, HLint
+;; Requirements:
+;; Status: distributed under terms of GPL2 or above
+
+;; Typical message from HLint looks like:
+;;
+;; /Users/ott/projects/lang-exp/haskell/test.hs:52:1: Eta reduce
+;; Found:
+;;   count1 p l = length (filter p l)
+;; Why not:
+;;   count1 p = length . filter p
+
+
+(require 'compile)
+
+(defgroup hs-lint nil
+  "Run HLint as inferior of Emacs, parse error messages."
+  :group 'tools
+  :group 'haskell)
+
+(defcustom hs-lint-command "hlint"
+  "The default hs-lint command for \\[hlint]."
+  :type 'string
+  :group 'hs-lint)
+
+(defcustom hs-lint-save-files t
+  "Save modified files when run HLint or no (ask user)"
+  :type 'boolean
+  :group 'hs-lint)
+
+(defcustom hs-lint-replace-with-suggestions nil
+  "Replace user's code with suggested replacements"
+  :type 'boolean
+  :group 'hs-lint)
+
+(defcustom hs-lint-replace-without-ask nil
+  "Replace user's code with suggested replacements automatically"
+  :type 'boolean
+  :group 'hs-lint)
+
+(defun hs-lint-process-setup ()
+  "Setup compilation variables and buffer for `hlint'."
+  (run-hooks 'hs-lint-setup-hook))
+
+;; regex for replace suggestions
+;;
+;; ^\(.*?\):\([0-9]+\):\([0-9]+\): .*
+;; Found:
+;; \s +\(.*\)
+;; Why not:
+;; \s +\(.*\)
+
+(defvar hs-lint-regex
+  "^\\(.*?\\):\\([0-9]+\\):\\([0-9]+\\): .*[\n\C-m]Found:[\n\C-m]\\s +\\(.*\\)[\n\C-m]Why not:[\n\C-m]\\s +\\(.*\\)[\n\C-m]"
+  "Regex for HLint messages")
+
+(defun make-short-string (str maxlen)
+  (if (< (length str) maxlen)
+      str
+    (concat (substring str 0 (- maxlen 3)) "...")))
+
+(defun hs-lint-replace-suggestions ()
+  "Perform actual replacement of suggestions"
+  (goto-char (point-min))
+  (while (re-search-forward hs-lint-regex nil t)
+    (let* ((fname (match-string 1))
+          (fline (string-to-number (match-string 2)))
+          (old-code (match-string 4))
+          (new-code (match-string 5))
+          (msg (concat "Replace '" (make-short-string old-code 30)
+                       "' with '" (make-short-string new-code 30) "'"))
+          (bline 0)
+          (eline 0)
+          (spos 0)
+          (new-old-code ""))
+      (save-excursion
+        (switch-to-buffer (get-file-buffer fname))
+        (goto-line fline)
+        (beginning-of-line)
+        (setf bline (point))
+        (when (or hs-lint-replace-without-ask
+                  (yes-or-no-p msg))
+          (end-of-line)
+          (setf eline (point))
+          (beginning-of-line)
+          (setf old-code (regexp-quote old-code))
+          (while (string-match "\\\\ " old-code spos)
+            (setf new-old-code (concat new-old-code
+                                 (substring old-code spos (match-beginning 0))
+                                 "\\ *"))
+            (setf spos (match-end 0)))
+          (setf new-old-code (concat new-old-code (substring old-code spos)))
+          (remove-text-properties bline eline '(composition nil))
+          (when (re-search-forward new-old-code eline t)
+            (replace-match new-code nil t)))))))
+
+(defun hs-lint-finish-hook (buf msg)
+  "Function, that is executed at the end of HLint execution"
+  (if hs-lint-replace-with-suggestions
+      (hs-lint-replace-suggestions)
+      (next-error 1 t)))
+
+(define-compilation-mode hs-lint-mode "HLint"
+  "Mode for check Haskell source code."
+  (set (make-local-variable 'compilation-process-setup-function)
+       'hs-lint-process-setup)
+  (set (make-local-variable 'compilation-disable-input) t)
+  (set (make-local-variable 'compilation-scroll-output) nil)
+  (set (make-local-variable 'compilation-finish-functions)
+       (list 'hs-lint-finish-hook))
+  )
+
+(defun hs-lint ()
+  "Run HLint for current buffer with haskell source"
+  (interactive)
+  (save-some-buffers hs-lint-save-files)
+  (compilation-start (concat hs-lint-command " \"" buffer-file-name "\"")
+                     'hs-lint-mode))
+
+(provide 'hs-lint)
+;;; hs-lint.el ends here
diff --git a/init.el b/init.el
index c954fbc..5a29e5e 100644
--- a/init.el
+++ b/init.el
@@ -1,5 +1,3 @@
-; Prevent the cursor from blinking
-(blink-cursor-mode 0)
 (show-paren-mode 1)
 ;; y-or-n instead of yes-or-no
 (defalias 'yes-or-no-p 'y-or-n-p)
@@ -40,7 +38,7 @@
   (package-refresh-contents))
 
 ;; make sure my list of packages are installed
-(setq package-list '(rust-mode haskell-mode go-mode monokai-theme ghc restclient))
+(setq package-list '(rust-mode haskell-mode clojure-mode monokai-theme ghc restclient))
 
 ; install the missing packages
 (dolist (package package-list)
@@ -57,7 +55,7 @@
 
 (erc-autojoin-mode t)
 (setq erc-autojoin-channels-alist
-  '((".*\\.freenode.net" "#tahoe-lafs" "#haskell-beginners")
+  '((".*\\.freenode.net" "#tahoe-lafs")
     (".*\\.oftc.net" "#LeastAuthority")))
 
 ;; check channels
@@ -115,3 +113,9 @@
 (setq c-default-style "k&r"
       c-basic-offset 4)
 
+;; hlint
+(add-to-list 'load-path "~/.emacs.d/hs-lint")
+(require 'hs-lint)
+(defun my-haskell-mode-hook ()
+   (local-set-key "\C-cl" 'hs-lint))
+(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)
-- 
2.45.2