feat(emacs): haskell-ts-mode
This commit is contained in:
@@ -12,8 +12,20 @@ in {
|
|||||||
builtins.readFile ./haskell/ghc-with-packages.sh;
|
builtins.readFile ./haskell/ghc-with-packages.sh;
|
||||||
|
|
||||||
home.file.".ghc/ghci.conf".text = ''
|
home.file.".ghc/ghci.conf".text = ''
|
||||||
:set prompt "\x1b[38;5;5mλ>\x1b[0m "
|
:{
|
||||||
:set prompt-cont "\x1b[38;5;5m|>\x1b[0m "
|
ghci_set_prompt :: IO String
|
||||||
|
ghci_set_prompt = do
|
||||||
|
term <- System.Environment.Blank.getEnvDefault "TERM" ""
|
||||||
|
let (prompt,promptCont) =
|
||||||
|
if Data.List.isPrefixOf "xterm-" term
|
||||||
|
then ("\x1b[38;5;5mλ>\x1b[0m ", "\x1b[38;5;5m|>\x1b[0m ")
|
||||||
|
else ("λ> ", "|> ")
|
||||||
|
pure . unlines $
|
||||||
|
[ ":set prompt " ++ show prompt
|
||||||
|
, ":set prompt-cont " ++ show promptCont
|
||||||
|
]
|
||||||
|
:}
|
||||||
|
:cmd ghci_set_prompt
|
||||||
:set -interactive-print=Text.Pretty.Simple.pPrint
|
:set -interactive-print=Text.Pretty.Simple.pPrint
|
||||||
:m + Text.Show.Functions
|
:m + Text.Show.Functions
|
||||||
:unset +r
|
:unset +r
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
:states '(normal insert)
|
:states '(normal insert)
|
||||||
"C-k" #'comint-previous-input
|
"C-k" #'comint-previous-input
|
||||||
"C-j" #'comint-next-input
|
"C-j" #'comint-next-input
|
||||||
"C-s" #'consult-history)
|
"C-s" #'consult-history
|
||||||
|
"<return>" #'comint-send-input)
|
||||||
(general-def
|
(general-def
|
||||||
:keymaps 'comint-mode-map
|
:keymaps 'comint-mode-map
|
||||||
:states 'insert
|
:states 'insert
|
||||||
|
|||||||
@@ -9,6 +9,18 @@
|
|||||||
(require 'inf-haskell)
|
(require 'inf-haskell)
|
||||||
(run-haskell))
|
(run-haskell))
|
||||||
|
|
||||||
|
(defun syd-haskell-ts-open-repl ()
|
||||||
|
"Open a Haskell REPL."
|
||||||
|
(interactive)
|
||||||
|
(haskell-ts-run)
|
||||||
|
(pop-to-buffer haskell-ts-ghci-buffer-name))
|
||||||
|
|
||||||
|
(defun syd-haskell-ts-eval-region (beg end)
|
||||||
|
(haskell-ts--send-region beg end))
|
||||||
|
|
||||||
|
(defun syd-haskell-ts-load-buffer ()
|
||||||
|
(haskell-ts-load-file))
|
||||||
|
|
||||||
(defun syd-haskell-evil-open-above ()
|
(defun syd-haskell-evil-open-above ()
|
||||||
"Opens a line above the current, following Haskell-mode's indentation"
|
"Opens a line above the current, following Haskell-mode's indentation"
|
||||||
(interactive)
|
(interactive)
|
||||||
@@ -38,7 +50,9 @@
|
|||||||
:custom (; Show errors in REPL, not popup buffers.
|
:custom (; Show errors in REPL, not popup buffers.
|
||||||
(haskell-interactive-popup-errors nil)
|
(haskell-interactive-popup-errors nil)
|
||||||
(haskell-process-suggest-remove-import-line t)
|
(haskell-process-suggest-remove-import-line t)
|
||||||
(haskell-process-auto-import-loaded-modules t))
|
(haskell-process-auto-import-loaded-modules t)
|
||||||
|
(haskell-ts-inferior-history-file
|
||||||
|
(file-name-concat syd-data-dir "haskell-ts-inferior-history")))
|
||||||
:general
|
:general
|
||||||
(:keymaps 'haskell-mode-map
|
(:keymaps 'haskell-mode-map
|
||||||
:states '(normal visual motion emacs insert)
|
:states '(normal visual motion emacs insert)
|
||||||
@@ -62,13 +76,56 @@
|
|||||||
(add-to-list 'haskell-font-lock-quasi-quote-modes '("wats" . wat-mode))
|
(add-to-list 'haskell-font-lock-quasi-quote-modes '("wats" . wat-mode))
|
||||||
(add-to-list 'haskell-font-lock-quasi-quote-modes '("expr" . wat-mode)))
|
(add-to-list 'haskell-font-lock-quasi-quote-modes '("expr" . wat-mode)))
|
||||||
|
|
||||||
|
(use-package consult-hoogle
|
||||||
|
:config
|
||||||
|
(syd-push shackle-rules
|
||||||
|
`("*hoogle-search*"
|
||||||
|
:select t :size 0.5 :popup t :align bottom)))
|
||||||
|
|
||||||
|
(use-package haskell-ts-mode
|
||||||
|
:straight (:type git
|
||||||
|
:host github
|
||||||
|
:repo "dschrempf/haskell-ts-mode")
|
||||||
|
:custom ((haskell-ts-font-lock-level 4)
|
||||||
|
(haskell-ts-ghci "ghci")
|
||||||
|
(haskell-ts-inferior-prompt-regexp
|
||||||
|
(rx bol (or "λ> " "|> "))))
|
||||||
|
:general
|
||||||
|
(:keymaps 'haskell-ts-mode-map
|
||||||
|
:states '(normal motion)
|
||||||
|
:major-modes t
|
||||||
|
:prefix syd-localleader-key
|
||||||
|
:non-normal-prefix syd-alt-localleader-key
|
||||||
|
"h s" #'syd-haskell-hoogle-start-server
|
||||||
|
"h q" #'haskell-hoogle-kill-server
|
||||||
|
"c" #'haskell-cabal-visit-file)
|
||||||
|
:config
|
||||||
|
(add-to-list 'completion-ignored-extensions ".hi")
|
||||||
|
(syd-add-hook 'haskell-ts-mode-hook
|
||||||
|
(defun syd-haskell-configure-indent-h ()
|
||||||
|
(setq-local tab-width 2)
|
||||||
|
;; (setq-local indent-line-function #'tab-to-tab-stop)
|
||||||
|
(indent-tabs-mode -1))
|
||||||
|
(defun syd-haskell-configure-evil-h ()
|
||||||
|
(setq-local evil-symbol-word-search nil)))
|
||||||
|
(syd-handle '(haskell-ts-mode)
|
||||||
|
:repl #'syd-haskell-ts-open-repl
|
||||||
|
:eval-region #'syd-haskell-ts-eval-region
|
||||||
|
:load-buffer #'syd-haskell-ts-load-buffer)
|
||||||
|
(syd-defadvice syd-haskell-hide-repl-h (old &rest rs)
|
||||||
|
:around #'haskell-ts-show-repl
|
||||||
|
(save-window-excursion
|
||||||
|
(apply old rs))))
|
||||||
|
|
||||||
(use-package lsp-haskell
|
(use-package lsp-haskell
|
||||||
:defer t
|
:defer t
|
||||||
:custom ((lsp-haskell-server-path "haskell-language-server"))
|
:custom ((lsp-haskell-server-path "haskell-language-server"))
|
||||||
:init
|
:init
|
||||||
(add-hook 'haskell-mode-hook #'lsp-deferred 'append)
|
(add-hook 'haskell-mode-hook #'lsp-deferred 'append)
|
||||||
(add-hook 'haskell-literate-mode-hook #'lsp-deferred 'append)
|
(add-hook 'haskell-literate-mode-hook #'lsp-deferred 'append)
|
||||||
(syd-add-hook '(haskell-mode-hook haskell-literate-mode-hook)
|
(add-hook 'haskell-ts-mode-hook #'lsp-deferred 'append)
|
||||||
|
(syd-add-hook '(haskell-ts-mode-hook
|
||||||
|
haskell-mode-hook haskell-literate-mode-hook)
|
||||||
(defun syd-haskell-configure-lsp-h ()
|
(defun syd-haskell-configure-lsp-h ()
|
||||||
;; it often highlights list literals and quasiquotes which
|
;; it often highlights list literals and quasiquotes which
|
||||||
;; gets reaaaally annoying.
|
;; gets reaaaally annoying.
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
;;; -*- lexical-binding: t -*-
|
;;; -*- lexical-binding: t -*-
|
||||||
(require 'syd/base)
|
(require 'syd/base)
|
||||||
|
|
||||||
;; Disable tabs by default.
|
;; Tabs, not spaces.
|
||||||
(setq-default indent-tabs-mode nil)
|
(setq-default indent-tabs-mode nil)
|
||||||
|
(setq-default tab-width 2)
|
||||||
|
|
||||||
|
(use-package kakapo-mode
|
||||||
|
:hook ((prog-mode . kakapo-mode)))
|
||||||
|
|
||||||
(provide 'syd/tabs)
|
(provide 'syd/tabs)
|
||||||
|
|||||||
@@ -6,9 +6,34 @@ in {
|
|||||||
enable = lib.mkEnableOption "Treesitter grammars";
|
enable = lib.mkEnableOption "Treesitter grammars";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable
|
||||||
sydnix.emacs.emacsPackages = epkgs: [
|
# https://github.com/dschrempf/haskell-ts-mode/blob/1c236f00dc214e546124a5dac90902ba62500c15/flake.nix#L40-L55
|
||||||
epkgs.treesit-grammars.with-all-grammars
|
(let
|
||||||
];
|
grammars = pkgs.tree-sitter-grammars.overrideScope (ts-final: ts-prev: {
|
||||||
};
|
tree-sitter-haskell = ts-prev.tree-sitter-haskell.overrideAttrs (prev:
|
||||||
|
let rev = "1ad6077a1fb776c255836e00aeb6da57ba564b6a";
|
||||||
|
in {
|
||||||
|
version = "unstable-2026-07-07-${builtins.substring 0 7 rev}";
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "dschrempf";
|
||||||
|
repo = "tree-sitter-haskell";
|
||||||
|
inherit rev;
|
||||||
|
hash = "sha256-kC6HwImFRx5HUY7NDLAA0I/DaSstQ94dWxA9+lMx2gI=";
|
||||||
|
};
|
||||||
|
nativeBuildInputs = (prev.nativeBuildInputs or [ ]) ++ [
|
||||||
|
pkgs.nodejs
|
||||||
|
pkgs.tree-sitter
|
||||||
|
];
|
||||||
|
preBuild = ''
|
||||||
|
tree-sitter generate
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
in {
|
||||||
|
sydnix.emacs.emacsPackages = epkgs: [
|
||||||
|
(epkgs.treesit-grammars.with-grammars (_ps:
|
||||||
|
grammars.allGrammars
|
||||||
|
))
|
||||||
|
];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user