From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Stephen Leake Newsgroups: gmane.emacs.devel Subject: New ELPA package ada-lite Date: Mon, 15 Aug 2022 10:56:07 -0700 Message-ID: <86y1vpfl1k.fsf@stephe-leake.org> 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="18779"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (windows-nt) To: emacs-devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Mon Aug 15 19:59:08 2022 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 1oNeMl-0004dP-F7 for ged-emacs-devel@m.gmane-mx.org; Mon, 15 Aug 2022 19:59:08 +0200 Original-Received: from localhost ([::1]:57312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oNeMk-0001Qy-AI for ged-emacs-devel@m.gmane-mx.org; Mon, 15 Aug 2022 13:59:06 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:54084) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oNeL5-0000iQ-Fd for emacs-devel@gnu.org; Mon, 15 Aug 2022 13:57:25 -0400 Original-Received: from qproxy6-pub.mail.unifiedlayer.com ([69.89.23.12]:35152) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oNeL2-0004lZ-Ui for emacs-devel@gnu.org; Mon, 15 Aug 2022 13:57:23 -0400 Original-Received: from gproxy3-pub.mail.unifiedlayer.com (unknown [69.89.30.42]) by qproxy6.mail.unifiedlayer.com (Postfix) with ESMTP id 2AAC4803EF8A for ; Mon, 15 Aug 2022 17:57:01 +0000 (UTC) Original-Received: from cmgw13.mail.unifiedlayer.com (unknown [10.0.90.128]) by progateway5.mail.pro1.eigbox.com (Postfix) with ESMTP id 1C8DC10049230 for ; Mon, 15 Aug 2022 17:56:10 +0000 (UTC) Original-Received: from host2007.hostmonster.com ([67.20.76.71]) by cmsmtp with ESMTP id NeJtoj9mYG7RFNeJto4kU5; Mon, 15 Aug 2022 17:56:10 +0000 X-Authority-Reason: nr=8 X-Authority-Analysis: v=2.4 cv=EscXEQQA c=1 sm=1 tr=0 ts=62fa88ba a=dWLzHQi6WpdymmZIwiVdBw==:117 a=Fln8i1WyhtedwaIJAdHvmw==:17 a=dLZJa+xiwSxG16/P+YVxDGlgEgI=:19 a=biHskzXt2R4A:10:nop_rcvd_month_year a=vvvmwbhNdt4A:10:endurance_base64_authed_username_1 a=FLl9saOoAAAA:8 a=AkYovGJKRKsQYU1aJqgA:9 a=txGzE-zhEJr0dPZu5zgA:9 a=2UHBUG7yBa-TViABPFTm:22 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=stephe-leake.org; s=default; h=Content-Type:MIME-Version:Message-ID:Date: Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=vO5oEvAOVjRZTU+xX3a7UHxM5kHNY7a2VAV6VcA3cQw=; b=QPWYfjnCPNoD0oNDA4/3HYV3oB HXHi4qYNdHV1e6yg1oNgzXYlDFNltQlhQn72nrDgP2FcRjsFRh7ydaXI99XgLq4+hHx5nYPYscWjr Adnm79vKGoc1S2DXHZAVodrIE616BQGKJrY1RpNF+yUMbULn6psgt7uwG3VtQQt7yb11u64w+zTQr S3hhgy6spM+Nq8ctvtI5GUMawDUa8Uc8PvxFJiIkV+lkd8xJ+SHLJPI4JLRWgxS76Gu7YjKXuS3rM 1z/95lECaZ9/V7d7uKZPaVIc8ArwMe3q+a9cbjdkEejoWgHWb/EDZwD/cg6OxnVFCwNEANgYW8cop fd2L7Hfw==; Original-Received: from 135-180-197-170.fiber.dynamic.sonic.net ([135.180.197.170]:51282 helo=DESKTOP-G20DCG1) by host2007.hostmonster.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1oNeJt-000ZWY-Kk for emacs-devel@gnu.org; Mon, 15 Aug 2022 11:56:09 -0600 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - host2007.hostmonster.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - stephe-leake.org X-BWhitelist: no X-Source-IP: 135.180.197.170 X-Source-L: No X-Exim-ID: 1oNeJt-000ZWY-Kk X-Source-Sender: 135-180-197-170.fiber.dynamic.sonic.net (DESKTOP-G20DCG1) [135.180.197.170]:51282 X-Source-Auth: stephen_leake@stephe-leake.org X-Email-Count: 1 X-Source-Cap: c3RlcGhlbGU7c3RlcGhlbGU7aG9zdDIwMDcuaG9zdG1vbnN0ZXIuY29t X-Local-Domain: yes Received-SPF: pass client-ip=69.89.23.12; envelope-from=stephen_leake@stephe-leake.org; helo=qproxy6-pub.mail.unifiedlayer.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no 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" Xref: news.gmane.io gmane.emacs.devel:293486 Archived-At: --=-=-= Content-Type: text/plain I'd like to add a package ada-lite-mode to ELPA; code attached. The intent is to be a mode for Ada files that's easier to install than the current ELPA ada-mode. This can be used as-is, in which case all you get is reserved word highlighting. Or it can be used with eglot and an Ada language server, which gives many more features (some of which ada-mode does not have). Installing the AdaCore ada_language_server is easier than installing the executables for ada-mode; it can be done via Alire (https://alire.ada.dev/). -- -- Stephe --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=ada-lite-mode.el Content-Transfer-Encoding: quoted-printable ;;; ada-lite-mode.el --- A very light-weight major mode for Ada source. -*-= lexical-binding:t -*- ;; ;; Copyright (C) 2022 Free Software Foundation, Inc. ;; ;; Author: Stephen Leake ;; Maintainer: Stephen Leake ;; Keywords: languages ;; ada ;; Version: 0.1 ;; package-requires: ((emacs "27.0")) ;; ;; This file is part of GNU Emacs. ;; ;; GNU Emacs 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. ;; ;; GNU Emacs 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 GNU Emacs. If not, see . ;;; Commentary ;; ;; A very light-weight major mode for Ada source code, suitable for ;; use with an LSP server ;; ;; To use ada-lite-mode for Ada files, put the following in your ;; emacs startup: ;; ;; (require 'ada-lite-mode) ;; ;; For use with an LSP server, configure project-find-functions to ;; return a project whose (project-root) returns the directory ;; containing the main gpr file. If your project has one main gpr ;; file, and it is in the root directory of your configuration manager ;; workspace, then the default project-try-vc works. For other ;; situations, ada-lite-find-project may be useful. ;; ;; If you are using eglot, and your project requires other gpr files ;; outside the main project directory tree, set the environment ;; variable GPR_PROJECT_PATH, and add: ;; ;; (setq eglot-extend-to-xref t) ;; ;; Then visit an Ada file and enable eglot (only need to enable eglot ;; once): ;; C-x C-f ;; M-x eglot ;; ;; By default this packages assumes the AdaCore ada_language_server; ;; to use with another LSP server for Ada, set ada-lite-server-exec, ;; or change the setting in eglot-server-programs. ;; ;; To install ada_language_server, install gnatstudio from ;; https://www.adacore.com/community, or install the ;; ada_language_server crate in Alire ;; (https://github.com/alire-project/alire/releases). ;; ;; For help with this package, ask on the comp.lang.ada newsgroup, or ;; the ada-mode email list ;; (https://savannah.nongnu.org/projects/ada-mode/). (defvar ada-lite-mode-syntax-table (let ((table (make-syntax-table))) ;; (info "(elisp)Syntax Class Table" "*info syntax class table*") ;; (info "(elisp) Syntax Flags") for comment start/end ;; make-syntax-table sets all alphanumeric to w, etc; so we only ;; have to add ada-specific things. ;; string brackets. `%' is the obsolete alternative string ;; bracket (arm J.2); if we make it syntax class ", it throws ;; font-lock and indentation off the track, so we use syntax class ;; $. (modify-syntax-entry ?% "$" table) (modify-syntax-entry ?\" "\"" table) ;; punctuation; operators etc (modify-syntax-entry ?# "." table); based number (modify-syntax-entry ?& "." table) (modify-syntax-entry ?* "." table) (modify-syntax-entry ?+ "." table) (modify-syntax-entry ?- ". 12" table); double hyphen as comment start (modify-syntax-entry ?. "." table) (modify-syntax-entry ?/ "." table) (modify-syntax-entry ?: "." table) (modify-syntax-entry ?< "." table) (modify-syntax-entry ?=3D "." table) (modify-syntax-entry ?> "." table) (modify-syntax-entry ?@ "." table) (modify-syntax-entry ?\' "." table); attribute; see ada-syntax-properti= ze for character literal (modify-syntax-entry ?\; "." table) (modify-syntax-entry ?\\ "." table); default is escape; not correct for= Ada strings (modify-syntax-entry ?\| "." table) ;; \f and \n end a comment. (modify-syntax-entry ?\f ">" table) (modify-syntax-entry ?\n ">" table) (modify-syntax-entry ?_ "_" table); symbol constituents, not word. (modify-syntax-entry ?\( "()" table) (modify-syntax-entry ?\) ")(" table) ;; skeleton placeholder delimiters; see ada-skel.el. We use generic ;; comment delimiter class, not comment starter/comment ender, so ;; these can be distinguished from line end. (modify-syntax-entry ?{ "!" table) (modify-syntax-entry ?} "!" table) table ) "Syntax table to be used for editing Ada source code.") (defconst ada-lite-keywords '(;; Ada 83: "abort" "abs" "accept" "access" "all" "and" "array" "at" "begin" "body" "case" "constant" "declare" "delay" "delta" "digits" "do" "else" "elsif" "end" "entry" "exception" "exit" "for" "function" "generic" "goto" "if" "in" "is" "limited" "loop" "mod" "new" "not" "null" "of" "or" "others" "out" "package" "pragma" "private" "procedure" "raise" "range" "record" "rem" "renames" "return" "reverse" "select" "separate" "subtype" "task" "terminate" "then" "type" "use" "when" "while" "with" "xor" ;; Ada 95: "abstract" "aliased" "protected" "requeue" "tagged" "until" ;; Ada 2001 "interface" "overriding" "synchronized" ;; Ada 2012: "some" ;; Ada 2022: "parallel") "List of Ada keywords.") (defun ada-lite-font-lock-keywords () "Ada mode value for `font-lock-keywords'." (list (list (concat "\\_<" (regexp-opt ada-lite-keywords t) "\\_>") '(0 font-l= ock-keyword-face)) )) (defun ada-lite-syntax-propertize (start end) "For `syntax-propertize-function'. Assign `syntax-table' properties in region START .. END. In particular, character constants are set to have string syntax." ;; (info "(elisp)Syntax Properties") ;; ;; called from `syntax-propertize', inside save-excursion with-silent-mod= ifications (let ((inhibit-read-only t) (inhibit-point-motion-hooks t)) (goto-char start) (save-match-data (while (re-search-forward (concat "[^[:alnum:])]\\('\\)[^'\n]\\('\\)"; 1, 2: character literal, not a= ttribute "\\|[^[:alnum:])]\\('''\\)"; 3: character literal ''' ) end t) ;; syntax-propertize-extend-region-functions is set to ;; syntax-propertize-wholelines by default. We assume no ;; coding standard will permit a character literal at the ;; start of a line (not preceded by whitespace). (cond ((match-beginning 1) (put-text-property (match-beginning 1) (match-end 1) 'syntax-table '(7 . ?')) (put-text-property (match-beginning 2) (match-end 2) 'syntax-table '(7 . ?'))) ((match-beginning 3) (put-text-property (match-beginning 3) (1+ (match-beginning 3)) 'syntax-table '(7 . ?')) (put-text-property (1- (match-end 3)) (match-end 3) 'syntax-table '(7 . ?'))) ))))) (define-derived-mode ada-lite-mode prog-mode "ada-lite" "A major mode for editing Ada code, using eglot." :group 'ada (set (make-local-variable 'syntax-propertize-function) #'ada-lite-syntax-= propertize) (syntax-ppss-flush-cache (point-min));; reparse with new function (set (make-local-variable 'parse-sexp-ignore-comments) t) (set (make-local-variable 'parse-sexp-lookup-properties) t) (set 'case-fold-search t); Ada is case insensitive (set 'completion-ignore-case t) (set (make-local-variable 'comment-start) "--") (set (make-local-variable 'comment-end) "") (set (make-local-variable 'comment-start-skip) "---*[ \t]*") (set (make-local-variable 'comment-multi-line) nil) ;; AdaCore standard style (enforced by -gnaty) requires two spaces ;; after '--' in comments; this makes it easier to distinguish ;; special comments that have something else after '--' (set (make-local-variable 'comment-padding) " ") (setq font-lock-defaults '(ada-lite-font-lock-keywords ;; keywords nil ;; keywords-only; font-lock set comment, string faces t ;; case-fold )) ;; FIXME: eglot-which-function? ) (defcustom ada-lite-server-exec nil "Location of an Ada language server. If non-nil, should be an absolute path to an executable for the server; this allows specifying a development version. See `ada-lite-find-server' for default behaviour.") (defun ada-lite-find-server (&optional _interactive) ;; in eglot 1.8, eglot--connect calls CONTACT with 1 arg ;; in devel eglot, eglot--connect calls CONTACT with no args "Find the language server executable. If `ada-lite-server-exec' is set, uses that. Otherwise defaults to AdaCore ada_language_server in `exec-path', then in a gnat installation found in `exec-path'." (if ada-lite-server-exec (if (file-readable-p ada-lite-server-exec) (list ada-lite-server-exec) (user-error "ada-lite-server-exec '%s' not a readable file" ada-lite-server-exec)) ;; else look for AdaCore ada_language_server ;; ;; ada_language_server is provided by a GNAT compiler installation, in a ;; directory under GNAT/libexec, which is typically not in PATH. (let ((gnat (executable-find "gnat")) (path exec-path)) (when gnat (setq path (append path (list (expand-file-name (concat (file-name-directory gnat) "../libexec/gnatstudio/als")))))) (let ((guess (locate-file "ada_language_server" path exec-suffixes 1))) (if guess (list guess) (user-error "ada_language_server not found")))))) ;;; projects integration (defcustom ada-lite-gnat-prj-file nil "The GNAT project file for the current ada-lite project. Must be an absolute file name; the directory is the language server process directory.") (defun ada-lite-find-project (_dir) "If ada-lite-mode, return ada-lite project. For `project-find-functions'" (and (eq major-mode 'ada-lite-mode) ;; We just assume the current Ada_Language_Server handles all ;; Ada files. The user must kill and restart the server to ;; change projects. FIXME: We sometimes deliberately open a ;; file that is not in the same project (for example, to ;; compare two versions of a file); what does ALS do then? 'ada-lite-project)) (cl-defmethod project-root ((_prj (eql ada-lite-project))) (unless ada-lite-gnat-prj-file ;; ada_language_server must find a .gpr file on startup. Prompting ;; for it here doesn't work, so throw an error. (user-error "set `ada-lite-gnat-prj-file'.")) (file-name-directory ada-lite-gnat-prj-file)) ;;;;; Global initializations ;;;###autoload (add-to-list 'auto-mode-alist '("\\.ad[abs]\\'" . ada-lite-mode)) (if (featurep 'eglot) (add-to-list 'eglot-server-programs (cons 'ada-lite-mode #'ada-lite-fin= d-server)) (eval-after-load "eglot" '(add-to-list 'eglot-server-programs (cons 'ada-= lite-mode #'ada-lite-find-server)))) (provide 'ada-lite-mode) ;;; ada-lite-mode.el ends here --=-=-=--