From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Philip Kaludercic Newsgroups: gmane.emacs.devel Subject: Re: New package: haskell-ts-mode Date: Wed, 28 Aug 2024 15:18:05 +0000 Message-ID: <874j74u15e.fsf@posteo.net> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="26265"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Pranshu Sharma Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Aug 28 17:19:08 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sjKRu-0006dW-3W for ged-emacs-devel@m.gmane-mx.org; Wed, 28 Aug 2024 17:19:06 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sjKRC-0001FW-9z; Wed, 28 Aug 2024 11:18:22 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sjKR8-0001F2-LC for emacs-devel@gnu.org; Wed, 28 Aug 2024 11:18:19 -0400 Original-Received: from mout02.posteo.de ([185.67.36.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sjKR4-0004Vh-4y for emacs-devel@gnu.org; Wed, 28 Aug 2024 11:18:18 -0400 Original-Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 0A262240103 for ; Wed, 28 Aug 2024 17:18:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.net; s=2017; t=1724858287; bh=+I5zvcWxU7LyrfoEBXasMJaggjEijX9MyuFjmrNEqd8=; h=From:To:Cc:Subject:Autocrypt:OpenPGP:Date:Message-ID:MIME-Version: Content-Type:From; b=h1wJ6zsVXI24Lon1983faVE5W9gyjvBAAiL2w8xI5SEIcw6YRkC+pN0J5VOLeLhyB fyKVfSLF7i24JAluBF4kg3YnwHthOGu3YuU0JyqRhEqaDAPvdDDcV0k8/UP4bmH+Na +EWglUgPZ2Bwn+7lvoz4Mz7K9V+a9uiMHTmEd6F5YHbEg+r5h2TyreQ4EOVA2glu+y v9C+WtGfzDo55o7DFwaE8a79jZazaP/zudiHThshCanfbH4chZt3lhQp3r3WJPQ5Cs +gbDvrHTfcnoOJLz/WgAt+4kGVfT9/SA9xJ3RvwSV4sEM7BR2fLhi0mdwEQbZ3iYZ3 Mh/tFBKWsE60A== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Wv7Mf2972z6tvx; Wed, 28 Aug 2024 17:18:06 +0200 (CEST) In-Reply-To: (Pranshu Sharma's message of "Wed, 28 Aug 2024 16:07:30 +1000") Autocrypt: addr=philipk@posteo.net; keydata= mDMEZBBQQhYJKwYBBAHaRw8BAQdAHJuofBrfqFh12uQu0Yi7mrl525F28eTmwUDflFNmdui0QlBo aWxpcCBLYWx1ZGVyY2ljIChnZW5lcmF0ZWQgYnkgYXV0b2NyeXB0LmVsKSA8cGhpbGlwa0Bwb3N0 ZW8ubmV0PoiWBBMWCAA+FiEEDg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwMFCQHhM4AFCwkI BwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8xYDWXahwulikAEA77hloUiSrXgFkUVJhlKBpLCHUjA0 mWZ9j9w5d08+jVwBAK6c4iGP7j+/PhbkxaEKa4V3MzIl7zJkcNNjHCXmvFcEuDgEZBBQQhIKKwYB BAGXVQEFAQEHQI5NLiLRjZy3OfSt1dhCmFyn+fN/QKELUYQetiaoe+MMAwEIB4h+BBgWCAAmFiEE Dg7HY17ghYlni8XN8xYDWXahwukFAmQQUEICGwwFCQHhM4AACgkQ8xYDWXahwukm+wEA8cml4JpK NeAu65rg+auKrPOP6TP/4YWRCTIvuYDm0joBALw98AMz7/qMHvSCeU/hw9PL6u6R2EScxtpKnWof z4oM OpenPGP: id=7126E1DE2F0CE35C770BED01F2C3CC513DB89F66; url="https://keys.openpgp.org/vks/v1/by-fingerprint/7126E1DE2F0CE35C770BED01F2C3CC513DB89F66"; preference=signencrypt Received-SPF: pass client-ip=185.67.36.66; envelope-from=philipk@posteo.net; helo=mout02.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:323151 Archived-At: --=-=-= Content-Type: text/plain Pranshu Sharma writes: > Hello all > > haskell-ts-mode is a major mode for haskell that uses treesitter to provide > features such as indentation and colouring. The mode can be found at > pranshu/haskell-ts-mode: > A haskelll mode that uses treesitter - Codeberg.org > . First of all, the spacing and indentation is inconsistent. Please address that, and perhaps add a directory local option to enforce indentation with spaces to ensure a consistent look. I cannot comment on the tree-sitter stuff since I don't really understand it, but otherwise I have a few comments that I would like you to consider: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable diff --git a/haskell-ts-mode.el b/haskell-ts-mode.el index 4ba7f42..391db66 100644 --- a/haskell-ts-mode.el +++ b/haskell-ts-mode.el @@ -2,7 +2,6 @@ =20 ;; Copyright (C) 2024 Pranshu Sharma =20 - ;; Author: Pranshu Sharma ;; URL: https://codeberg.org/pranshu/haskell-ts-mode ;; Package-Requires: ((emacs "29.3")) @@ -23,6 +22,7 @@ ;; along with this program. If not, see . =20 ;;; Commentary: + ;; This is a WIP mode that uses treesitter to provide all the basic ;; major mode stuff, like indentation, font lock, etc... =20 @@ -31,6 +31,7 @@ (require 'comint) (require 'treesit) =20 +;; From what I understand this is necessary for tree-sitter modes, but can= you at least also add the ARGLIST argument. Also, some functions such as = `treesit-induce-sparse-tree' appear not to be used? (declare-function treesit-parser-create "treesit.c") (declare-function treesit-induce-sparse-tree "treesit.c") (declare-function treesit-node-child "treesit.c") @@ -46,10 +47,11 @@ (otherwise signature))) =20 (defvar haskell-ts-use-indent t - "Set to nil if you don't want to use Emacs indent.") + "Set to nil if you don't want to use Emacs indent.") ;rephrase this woul= d the double negation =20 (defvar haskell-ts-font-lock-level 4 "Level of font lock, 1 for minimum highlghting and 4 for maximum.") +;; both of these variables are actually user options and should be declare= d using `'defcustom'! =20 (defvar haskell-ts-prettify-symbols-alits '(("\\" . "=CE=BB") @@ -60,6 +62,7 @@ ("<=3D" . "=E2=89=A5") (">=3D" . "=E2=89=A4"))) =20 +;; Checkdoc complains that=20 (defun haskell-ts-font-lock () (treesit-font-lock-rules :language 'haskell @@ -157,7 +160,7 @@ ((parent-is "apply") parent -1) ((node-is "quasiquote") grand-parent 2) ((parent-is "quasiquote_body") (lambda (_ _ c) c) 0) - ;; Do Hg + ;; Do Hg ;; what does "Hg" mean? ((lambda (node parent bol) (let ((n (treesit-node-prev-sibling node))) (while (string=3D "comment" (treesit-node-type n)) @@ -232,6 +235,7 @@ =20 ;; Copied from haskell-tng-mode, changed a bit (defvar haskell-ts-mode-syntax-table + ;; Should this be wrapped in an `eval-when-compile'? (let ((table (make-syntax-table))) (map-char-table (lambda (k v) @@ -241,7 +245,7 @@ (modify-syntax-entry k "_" table)))) (char-table-parent table)) ;; whitechar - (seq-do + (seq-do ;seq-do has a relatively high overhead, try to avoid it (lambda (it) (modify-syntax-entry it " " table)) (string-to-list "\r\n\f\v \t")) ;; ascSymbol @@ -268,46 +272,40 @@ (modify-syntax-entry ?\{ "(}1nb" table) (modify-syntax-entry ?\} "){4nb" table) (modify-syntax-entry ?- "_ 123" table) ;; TODO --> is not a comment - (seq-do - (lambda (it) (modify-syntax-entry it ">" table)) - (string-to-list "\r\n\f\v")) + (dolist (c (string-to-list "\r\n\f\v")) ;though unrolling wouldn't be bad= either + (modify-syntax-entry c ">" table)) +=09 table)) =20 +(defun haskell-ts-imenu-name-function (check-func) + (lambda (node) + (if (funcall check-func node) + (haskell-ts-defun-name node) + nil))) =20 -(defmacro haskell-ts-imenu-name-function (check-func) - `(lambda (node) - (if (funcall ,check-func node) - (haskell-ts-defun-name node) - nil))) - -(defun haskell-ts-indent-para() +(defun haskell-ts-indent-para () "Indent the current paragraph." (interactive) - (save-excursion - (backward-paragraph) - (let ((p (point))) - (forward-paragraph) - (indent-region p (point))))) + (when-let ((par (bounds-of-thing-at-point 'paragraph))) + (indent-region (car par) (cdr par)))) =20 (defvar haskell-ts-mode-map (let ((km (make-sparse-keymap))) (define-key km (kbd "C-c C-c") 'haskell-ts-compile-region-and-go) (define-key km (kbd "C-c C-r") 'haskell-ts-run-haskell) - (define-key km (kbd "C-M-q") 'haskell-ts-indent-para) + (define-key km (kbd "C-M-q") 'haskell-ts-indent-para) ;is this necessa= ry when `prog-fill-reindent-defun' is bound to M-q? km) - "Map for haskell-ts-mode") + "Map for haskell-ts-mode.") =20 ;;;###autoload (define-derived-mode haskell-ts-mode prog-mode "haskell ts mode" "Major mode for Haskell files using tree-sitter." - :syntax-table haskell-ts-mode-syntax-table - :interactive t (unless (treesit-ready-p 'haskell) (error "Tree-sitter for Haskell is not available")) (treesit-parser-create 'haskell) (setq-local treesit-defun-type-regexp "\\(?:\\(?:function\\|struct\\)_de= finition\\)") ;; Indent - (and haskell-ts-use-indent + (and haskell-ts-use-indent ;do you mean `when'? (setq-local treesit-simple-indent-rules haskell-ts-indent-rules) (setq-local indent-tabs-mode nil)) ;; Comment @@ -316,21 +314,21 @@ (setq-local comment-start-skip "\\(?: \\|^\\)-+") ;; Elecric (setq-local electric-pair-pairs - (list (cons ?` ?`) (cons ?\( ?\)) (cons ?{ ?}) (cons ?\" ?\") (cons= ?\[ ?\]))) + '((?` . ?`) (?\( . ?\)) (?{ . ?}) (?\" . ?\") (?\[ . ?\]))) ;; Nav - (setq-local treesit-defun-name-function 'haskell-ts-defun-name) + (setq-local treesit-defun-name-function #'haskell-ts-defun-name) (setq-local treesit-defun-type-regexp "function") (setq-local prettify-symbols-alist haskell-ts-prettify-symbols-alits) ;; Imenu (setq-local treesit-simple-imenu-settings `((nil haskell-ts-imenu-func-node-p nil - ,(haskell-ts-imenu-name-function 'haskell-ts-imenu-func-node-p)) + ,(haskell-ts-imenu-name-function #'haskell-ts-imenu-func-node-p)) ("Signatures.." haskell-ts-imenu-sig-node-p nil - ,(haskell-ts-imenu-name-function 'haskell-ts-imenu-sig-node-p)) + ,(haskell-ts-imenu-name-function #'haskell-ts-imenu-sig-node-p)) ("Data..." haskell-ts-imenu-data-type-p nil (lambda (node) (treesit-node-text (treesit-node-child node 1)))))) - ;; font-lock. + ;; font-lock (setq-local treesit-font-lock-level haskell-ts-font-lock-level) (setq-local treesit-font-lock-settings (haskell-ts-font-lock)) (setq-local treesit-font-lock-feature-list @@ -379,23 +377,32 @@ =20 (defun haskell-ts-run-haskell() (interactive) - (when (not (comint-check-proc "*haskell*")) - (set-buffer (apply (function make-comint) - "haskell" "ghci" nil `(,buffer-file-name)))) - (pop-to-buffer-same-window "*haskell*")) + (pop-to-buffer-same-window ;really in the same window? + (or + (comint-check-proc "*haskell*") + (make-comint "*haskell* repl" "ghci" nil buffer-file-name)))) + =20 (defun haskell-ts-haskell-session () (get-buffer-process "*haskell*")) =20 +(defvar eglot-server-programs) ;to avoid the byte-compiler error (defun haskell-ts-setup-eglot() (when (featurep 'eglot) - (add-to-list 'eglot-server-programs + ;; Eglot was added to the core along with tree-siter, so there is + ;; no case where tree-sitter is available, but eglot is not. + (add-to-list 'eglot-server-programs '(haskell-ts-mode . ("haskell-language-server-wrapper" "--lsp"))))) =20 +;; Note that you write (eval-when-load 'eglot +;; (haskell-ts-setup-eglot)) in README.org, but that doesn't do what +;; you want it to. That will modify eglot-server-programs and +;; evaluate the result when eglot is loaded. You presumably wanted to +;; use `with-eval-after-load'? + (when (treesit-ready-p 'haskell) (add-to-list 'auto-mode-alist '("\\.hs\\'" . haskell-ts-mode))) =20 (provide 'haskell-ts-mode) =20 ;;; haskell-ts-mode.el ends here - --=-=-= Content-Type: text/plain (Also, a general question, do you use LLMs to generate some of the code?) > > The attached patch is for the elpa repo > Thanks, > Pranshu > diff --git a/elpa-packages b/elpa-packages > index 137fef0348..451a67d395 100644 > --- a/elpa-packages > +++ b/elpa-packages > @@ -368,6 +368,9 @@ > (gtags-mode :url "https://github.com/Ergus/gtags-mode") > (guess-language :url "https://github.com/tmalsburg/guess-language.el" > :merge t) > + (haskell-ts-mode :url "https://codeberg.org/pranshu/haskell-ts-mode" > + :doc "README.org" Are you sure that you want the README to be installed as a manual? > + :ignored-files ("*.png" "LICENSE")) You can list the files you wish to ignore in an .elpaignore file in your repository; its preferable to using :ignored-files as it is more flexible and easier to adjust if something changes on your end. > (hcel :url "https://g.ypei.me/hc.el.git") > (heap :url nil) ;"http://www.dr-qubit.org/git/predictive.git" > (hiddenquote :url "https://gitlab.com/mauroaranda/hiddenquote/hiddenquote") > -- Philip Kaludercic on peregrine --=-=-=--