Browse Source

Haskell: Greatly simplify my haskell-mode configuration

And a few other changes:

  * Go back to using a company delay

  * Remove unused company backends

  * Don't override RET for all modes

  * Use evil-leader overrides for Haskell
master
Peter J. Jones 1 month ago
parent
commit
0d7192e745
Signed by: Peter Jones <pjones@devalot.com> GPG Key ID: 9DAFAA8D01941E49
8 changed files with 47 additions and 142 deletions
  1. 0
    26
      hydras/haskell-mode.el
  2. 0
    1
      lisp/code.el
  3. 0
    1
      lisp/keys.el
  4. 2
    2
      modes/company-conf.el
  5. 0
    6
      modes/company-ghc-conf.el
  6. 1
    1
      modes/flycheck-conf.el
  7. 44
    103
      modes/haskell-mode-conf.el
  8. 0
    2
      nix/packages.nix

+ 0
- 26
hydras/haskell-mode.el View File

@@ -1,26 +0,0 @@
1
-;;; haskell-mode.el ;; Hydras for haskell-mode
2
-
3
-;;; Commentary:
4
-
5
-;;; Code:
6
-(require 'hydra)
7
-
8
-(defhydra pjones:hydras:haskell-mode (:hint nil)
9
-  "
10
-^Imports^          ^GHCi^              ^Insert/Edit^          ^Run
11
-^^^^^^^^^-------------------------------------------------------------------------
12
-_C-c C-i_: jump    _C-c C-;_: info     _C-c C-0_: cost center  _C-c c_: compile
13
-_C-c C-l_: return  _C-c C-r_: reload   _C-c C-n_: kill module
14
-_C-c C-s_: sort    _C-c C-t_: type     _C-c C-e_: edit cabal
15
-"
16
-  ("C-c C-;" dante-info)
17
-  ("C-c C-0" haskell-mode-toggle-scc-at-point :color blue)
18
-  ("C-c C-e" pjones:haskell-edit-cabal-file :color blue)
19
-  ("C-c C-i" haskell-navigate-imports)
20
-  ("C-c C-l" haskell-navigate-imports-return :color blue)
21
-  ("C-c C-n" pjones:haskell-module-name-to-kill-ring :color blue)
22
-  ("C-c C-r" dante-restart)
23
-  ("C-c C-s" pjones:haskell-sort-imports)
24
-  ("C-c C-t" dante-type-at :color blue))
25
-
26
-;;; haskell-mode ends here

+ 0
- 1
lisp/code.el View File

@@ -81,7 +81,6 @@ already been cached."
81 81
   (setq comment-empty-lines t)
82 82
   (set (make-local-variable 'comment-auto-fill-only-comments) t)
83 83
   (local-set-key (kbd "C-c <tab>") 'pjones:comment-bar)
84
-  (local-set-key (kbd "RET") 'reindent-then-newline-and-indent)
85 84
   (hs-minor-mode)
86 85
   (show-paren-mode)
87 86
   (whitespace-mode)

+ 0
- 1
lisp/keys.el View File

@@ -110,7 +110,6 @@
110 110
 (require 'evil-leader)
111 111
 
112 112
 (evil-leader/set-key
113
-  "SPC" #'pjones:switch-to-previous-buffer
114 113
   "A"   #'align
115 114
   "a"   #'ialign
116 115
   "b"   #'ivy-switch-buffer

+ 2
- 2
modes/company-conf.el View File

@@ -11,7 +11,7 @@
11 11
 
12 12
 ;; Settings for company-mode:
13 13
 (custom-set-variables
14
-  '(company-idle-delay nil)
14
+  '(company-idle-delay 1)
15 15
   '(company-show-numbers nil)
16 16
   '(company-selection-wrap-around t)
17 17
   '(company-lighter-base "")
@@ -50,7 +50,7 @@
50 50
     (define-key map (kbd "M-j")      #'company-select-next)
51 51
     (define-key map (kbd "M-k")      #'company-select-previous))
52 52
 
53
-  (company-quickhelp-mode +1)
53
+  (company-quickhelp-mode)
54 54
   (company-statistics-mode))
55 55
 
56 56
 (add-hook 'company-mode-hook 'pjones:company-mode-hook)

+ 0
- 6
modes/company-ghc-conf.el View File

@@ -1,6 +0,0 @@
1
-;;; company-ghc-conf.el --- company-mode ghc-mod backend.
2
-(eval-when-compile
3
-  (require 'company-ghc))
4
-
5
-(setq company-ghc-show-info t
6
-      ghc-command "nix-hs-ghc-mod")

+ 1
- 1
modes/flycheck-conf.el View File

@@ -6,7 +6,7 @@
6 6
 (require 'flycheck)
7 7
 
8 8
 (custom-set-variables
9
- '(flycheck-disabled-checkers '(javascript-eslint javascript-gjslint))
9
+ '(flycheck-disabled-checkers '(javascript-gjslint))
10 10
  '(flycheck-standard-error-navigation nil)
11 11
  '(flymake-no-changes-timeout nil)
12 12
  '(flymake-start-syntax-check-on-newline nil)

+ 44
- 103
modes/haskell-mode-conf.el View File

@@ -2,135 +2,76 @@
2 2
 ;;
3 3
 ;;; Commentary:
4 4
 ;;
5
+;; My goal with this configuration is to reduce the write->compile
6
+;; cycle with Haskell code, without requiring a ton of dependencies or
7
+;; complicated set up.  I'm also not interested in fancy completion or
8
+;; refactoring tools.
9
+;;
5 10
 ;;; Code:
6 11
 (eval-when-compile
7 12
   (require 'cl))
8 13
 
9
-(require 'company-ghc)
10 14
 (require 'dante)
15
+(require 'direnv)
16
+(require 'evil-leader)
11 17
 (require 'flycheck)
12
-(require 'ghc)
13 18
 (require 'haskell)
19
+(require 'haskell-interactive-mode)
14 20
 (require 'haskell-mode)
21
+(require 'haskell-process)
15 22
 
16 23
 (declare-function pjones:prog-mode-hook "../lisp/code.el")
17
-(declare-function pjones:define-keys-from-hydra "../lisp/functions.el")
18 24
 
19 25
 ;; Settings for haskell-mode and friends:
20 26
 (custom-set-variables
21 27
   '(haskell-stylish-on-save nil)
22
-  '(haskell-tags-on-save nil)
23
-  '(haskell-completing-read-function 'ido-completing-read)
24
-  '(shm-auto-insert-skeletons nil)
25
-  '(dante-repl-command-line '("nix-hs" "repl")))
26
-
27
-(defun pjones:haskell-find-cabal-file ()
28
-  "Return the full path to the *.cabal file for the current project."
29
-  (let* ((dir default-directory)
30
-         (default (concat dir "/" (file-name-base dir) ".cabal"))
31
-         (name))
32
-    (while (and (not (string= dir "/"))
33
-                (not (setq name (file-expand-wildcards (concat dir "?*.cabal")))))
34
-      (setq dir (file-name-directory (substring dir 0 -1))))
35
-    (if (string= dir "/") default (car name))))
36
-
37
-(defun pjones:haskell-edit-cabal-file ()
38
-  "Open the project's cabal file for editing."
39
-  (interactive)
40
-  (find-file (pjones:haskell-find-cabal-file)))
41
-
42
-(defun pjones:haskell-beginning-of-defun (&optional arg)
43
-  "Move to the beginning of the current function ARG times."
44
-  (dotimes (i (or arg 1))
45
-    (beginning-of-line)
46
-    (while (and (not (bobp)) (or (eolp) (looking-at "^\\s-")))
47
-      (forward-line -1))
48
-    (if (save-excursion (forward-line -1) (looking-at "^\\w"))
49
-        (forward-line -1))) t)
50
-
51
-(defun pjones:haskell-end-of-defun (&optional arg)
52
-  "Move to the end of the current function ARG times."
53
-  (dotimes (i (or arg 1))
54
-    (beginning-of-line)
55
-    (while (and (not (eobp)) (looking-at "^\\w"))
56
-      (forward-line)) ;; Move past the function name.
57
-    (while (and (not (eobp)) (or (eolp) (looking-at "^\\s-")))
58
-      (forward-line))) t)
59
-
60
-(defun pjones:haskell-module-name ()
61
-  "Return the module name for the current buffer."
62
-  (save-mark-and-excursion
63
-    (goto-char (point-min))
64
-    (let ((start (search-forward-regexp "module "))
65
-          (end (search-forward-regexp "[[:space:]]")))
66
-      (buffer-substring start (- end 2)))))
67
-
68
-(defun pjones:haskell-module-name-to-kill-ring ()
69
-  "Save the module name of the current buffer to the kill ring."
70
-  (interactive)
71
-  (kill-new (pjones:haskell-module-name)))
72
-
73
-(defun pjones:haskell-sort-imports ()
74
-  "If point is in a block of import statements then sort them.
75
-Otherwise go totally crazy."
76
-  (interactive)
77
-  (let ((b (save-excursion
78
-             (move-beginning-of-line nil)
79
-             (while (looking-at "^import") (forward-line -1))
80
-             (forward-line 1)
81
-             (point)))
82
-        (e (save-excursion
83
-             (move-beginning-of-line nil)
84
-             (while (looking-at "^import") (forward-line 1))
85
-             (forward-line -1)
86
-             (move-end-of-line nil)
87
-             (point))))
88
-    (sort-regexp-fields
89
-       nil "^import +\\(qualified \\)?\\(.+\\)$" "\\2" b e)))
90
-
91
-
92
-(defun pjones-haskell-process-wrapper-function (argv)
93
-  "Run Haskell tools through nix-shell by modifying ARGV.
94
-See `haskell-process-wrapper-function' for details."
95
-  (append (list "nix-hs")
96
-          (list (mapconcat 'identity argv " "))))
28
+  '(haskell-tags-on-save t)
29
+  '(haskell-completing-read-function 'ivy-completing-read)
30
+  '(haskell-process-type 'cabal-new-repl)
31
+  '(haskell-process-suggest-hoogle-imports t)
32
+  '(dante-repl-command-line '("cabal" "new-repl")))
33
+
34
+;; A few extra key bindings:
35
+(evil-leader/set-key-for-mode 'haskell-mode
36
+  "SPC e" #'haskell-cabal-visit-file
37
+  "SPC i" #'haskell-navigate-imports
38
+  "SPC s" #'haskell-sort-imports
39
+  "SPC t" #'dante-info)
40
+
41
+;; This overwrite fixes a bug where imports are not sorted because I
42
+;; put a comment line above them.
43
+(defun haskell-sort-imports-goto-group-start ()
44
+  "Overwrite the version from haskell-sort-imports.el."
45
+  (while (looking-at "^import") (forward-line -1))
46
+  (forward-line 1))
97 47
 
98 48
 (defun pjones:haskell-mode-hook ()
99 49
   "Hook run on new Haskell buffers."
100
-  (make-local-variable 'tab-always-indent)
101
-
102
-  ;; These need to be set before calling `pjones:prog-mode-hook'.
103
-  (setq tab-always-indent t
104
-        beginning-of-defun-function 'pjones:haskell-beginning-of-defun
105
-        end-of-defun-function 'pjones:haskell-end-of-defun)
50
+  ;; Update environment variables (i.e. PATH) first!
51
+  (direnv-update-environment)
106 52
 
107
-  ;; Load helper packages:
53
+  ;; Boot `haskell-mode':
108 54
   (haskell-indentation-mode)
109
-  (pjones:prog-mode-hook)
110
-  (subword-mode)
111
-  (abbrev-mode)
112
-  (dante-mode)
113
-  (flycheck-mode)
114
-  (flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint))
55
+  (interactive-haskell-mode)
56
+  (haskell-process-load-file)
115 57
 
116 58
   ;; Configure completion:
117 59
   (make-local-variable 'company-backends)
118
-  (add-to-list 'company-backends '(company-ghc company-dabbrev company-abbrev))
60
+  (add-to-list 'company-backends '(company-capf company-dabbrev company-abbrev))
119 61
 
120
-  ;; A few extra key bindings:
121
-  (let ((map haskell-mode-map))
122
-    (define-key map (kbd "C-c C-e") #'pjones:haskell-edit-cabal-file)
123
-    (define-key map (kbd "C-c C-s") #'pjones:haskell-sort-imports)))
62
+  ;; Load helper packages:
63
+  (pjones:prog-mode-hook)
64
+  (flycheck-mode)
65
+  (dante-mode)
66
+  (subword-mode)
67
+  (abbrev-mode))
124 68
 
125 69
 (defun pjones:dante-mode-hook ()
126 70
   "Peter's hook for Dante."
127
-  (let ((map dante-mode-map))
128
-    (define-key map (kbd "C-c ,") nil)))
71
+  (flycheck-add-next-checker 'haskell-dante '(warning . haskell-hlint)))
129 72
 
130
-(add-hook 'haskell-mode-hook #'pjones:haskell-mode-hook)
73
+(add-hook 'haskell-mode-hook       #'pjones:haskell-mode-hook)
131 74
 (add-hook 'haskell-cabal-mode-hook #'pjones:prog-mode-hook)
132
-(add-hook 'dante-mode-hook #'pjones:dante-mode-hook)
75
+(add-hook 'dante-mode-hook         #'pjones:dante-mode-hook)
133 76
 
134
-;; Local Variables:
135
-;; byte-compile-warnings: (not noruntime)
136
-;; End:
77
+;;; haskell-mode-conf.el ends here

+ 0
- 2
nix/packages.nix View File

@@ -28,8 +28,6 @@ overrides.emacsWithPackages (epkgs: with epkgs; [
28 28
   beginend                      # Redefine M-< and M-> for some modes
29 29
   captain                       # CAPiTalization is Automatic IN emacs
30 30
   company                       # Modular text completion framework
31
-  company-ghc                   # company-mode ghc-mod backend
32
-  company-ghci                  # company backend which uses the current ghci process
33 31
   company-quickhelp             # Popup documentation for completion candidates
34 32
   company-statistics            # Sort candidates using completion history
35 33
   counsel                       # Various completion functions using Ivy

Loading…
Cancel
Save