From: Philip Kaludercic <philipk@posteo.net>
To: Jeremy Bryant <jb@jeremybryant.net>
Cc: Jeremy Bryant via "Emacs development discussions."
<emacs-devel@gnu.org>, Eli Zaretskii <eliz@gnu.org>,
monnier@iro.umontreal.ca, j.j.oddie@gmail.com,
stefankangas@gmail.com, jonas@bernoul.li
Subject: Re: Incorporate package macrostep into Emacs core
Date: Tue, 19 Mar 2024 06:36:35 +0000 [thread overview]
Message-ID: <87o7basp70.fsf@posteo.net> (raw)
In-Reply-To: <87le6f9m8b.fsf@jeremybryant.net> (Jeremy Bryant's message of "Mon, 18 Mar 2024 23:03:16 +0000")
Jeremy Bryant <jb@jeremybryant.net> writes:
> Philip Kaludercic <philipk@posteo.net> writes:
>
> Philip,
> Thanks for all the comments on the macrostep.el code, I'll work on what
> I can.
>
>> Isn't there also a C-preprecossor implementation for macrostep? Would
>> the plan be to include that as well?
>
> Presumably, also. Any comments on macrostep-c.el (attached)?
>
> ;;; macrostep-c.el --- macrostep interface to C preprocessor -*- lexical-binding: t; -*-
>
> ;; Copyright (C) 2015 Jon Oddie
If included, then this should be updated.
> ;; Author: Jon Oddie <j.j.oddie@gmail.com>
> ;; Url: https://github.com/emacsorphanage/macrostep
And this removed.
> ;; Keywords: c, languages, macro, debugging
>
> ;; SPDX-License-Identifier: GPL-3.0-or-later
>
> ;; This file 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.
> ;;
> ;; This file 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 this file. If not, see <https://www.gnu.org/licenses/>.
>
> ;;; Commentary:
>
> ;; A thin wrapper around Emacs's built-in `cmacexp' library to provide
> ;; basic support for expanding C macros using the `macrostep' user
> ;; interface. To use, position point on a macro use in a C buffer and
> ;; type `M-x macrostep-expand'. The variables `c-macro-preprocessor'
> ;; and especially `c-macro-cppflags' may need to be set correctly for
> ;; accurate expansion.
>
> ;; This is fairly basic compared to the Emacs Lisp `macrostep'. In
> ;; particular, there is no step-by-step expansion, since C macros are
> ;; expanded in a single "cpp" pass, and no pretty-printing.
>
> ;; To hide the buffer containing "cpp" warnings (not recommended), you
> ;; could do something like:
> ;;
> ;; (push `(,(regexp-quote macrostep-c-warning-buffer)
> ;; (display-buffer-no-window))
> ;; display-buffer-alist)
>
> ;;; Code:
>
> (require 'macrostep)
> (require 'cmacexp)
> (require 'cl-lib)
>
> (require 'subr-x nil t)
> (defalias 'macrostep-c-string-trim
> (if (fboundp 'string-trim)
> #'string-trim
> (lambda (string)
> (when (string-match "\\`[ \t\n\r]+" string)
> (setq string (replace-match "" t t string)))
> (when (string-match "[ \t\n\r]+\\'" string)
> (setq string (replace-match "" t t string)))
> string)))
We can drop this (or use Compat to provide the function if the package
is distributeted on ELPA).
> (put 'macrostep-c-non-macro 'error-conditions
> '(macrostep-c-non-macro error))
> (put 'macrostep-c-non-macro 'error-message
> "Text around point is not a macro call.")
>
> (put 'macrostep-c-expansion-failed 'error-conditions
> '(macrostep-c-expansion-failed error))
> (put 'macrostep-c-expansion-failed 'error-message
> "Macro-expansion failed.")
>
> (defvar macrostep-c-warning-buffer "*Macroexpansion Warnings*")
>
> ;;;###autoload
> (defun macrostep-c-mode-hook ()
> (setq macrostep-sexp-bounds-function
> #'macrostep-c-sexp-bounds)
> (setq macrostep-sexp-at-point-function
> #'macrostep-c-sexp-at-point)
> (setq macrostep-environment-at-point-function
> #'ignore)
> (setq macrostep-expand-1-function
> #'macrostep-c-expand-1)
> (setq macrostep-print-function
> #'macrostep-c-print-function)
> (add-hook 'macrostep-mode-off-hook
> #'macrostep-c-mode-off nil t))
>
> (defun macrostep-c-mode-off (&rest _ignore)
> (when (derived-mode-p 'c-mode)
> (let ((warning-window
> (get-buffer-window macrostep-c-warning-buffer)))
> (when warning-window
> (quit-window nil warning-window)))))
>
> ;;;###autoload
> (add-hook 'c-mode-hook #'macrostep-c-mode-hook)
This part is suspicious. First of all, it looks like one is adding a
hook to a hook, but this would unconditionally modify
c-mode-hook, which I don't think is reliable. Can we find some other
way to update the variables, depending on the major mode? E.g. in
macrostep.el one could try to intern (format "macrostep-%s-init"
major-mode) and check if the symbol is fboundp?
> (defun macrostep-c-sexp-bounds ()
> (save-excursion
> (cl-loop
> (let ((region (macrostep-c-sexp-bounds-1)))
> (cond
> ((null region)
> (signal 'macrostep-c-non-macro nil))
> ((macrostep-c-expandable-p region)
> (cl-return region))
> (t
> (condition-case nil
> (progn
> (backward-up-list)
> (skip-syntax-backward "-"))
> (scan-error
> (signal 'macrostep-c-non-macro nil)))))))))
>
> (defun macrostep-c-sexp-bounds-1 ()
> (let ((region (bounds-of-thing-at-point 'symbol)))
> (when region
One could use when-let* in places like this.
> (cl-destructuring-bind (symbol-start . symbol-end) region
> (save-excursion
> (goto-char symbol-end)
> (if (looking-at "[[:space:]]*(")
> (cons symbol-start (scan-sexps symbol-end 1))
> region))))))
The indentation is off here, right? Might be worth reindenting
everything once.
>
> (defun macrostep-c-expandable-p (region)
> (cl-destructuring-bind (start . end) region
> (condition-case nil
> (cl-destructuring-bind (expansion _warnings)
> (macrostep-c-expand-region start end)
> (and (cl-plusp (length expansion))
> (not (string= expansion (buffer-substring start end)))))
> (macrostep-c-expansion-failed nil))))
>
> (defun macrostep-c-sexp-at-point (start end)
> (cons start end))
>
> (defun macrostep-c-expand-1 (region _ignore)
> (cl-destructuring-bind (start . end) region
> (cl-destructuring-bind (expansion warnings)
> (macrostep-c-expand-region start end)
> (when (cl-plusp (length warnings))
> (with-current-buffer
> (get-buffer-create macrostep-c-warning-buffer)
> (let ((inhibit-read-only t))
> (erase-buffer)
> (insert warnings)
> (goto-char (point-min)))
> (special-mode)
> (display-buffer (current-buffer)
> '(display-buffer-pop-up-window
> (inhibit-same-window . t)
> (allow-no-window . t)))))
> expansion)))
>
> (defun macrostep-c-expand-region (start end)
> (let ((expansion
> (condition-case nil
> (c-macro-expansion start end
> (concat c-macro-preprocessor " "
> c-macro-cppflags))
> (search-failed
> (signal 'macrostep-c-expansion-failed nil)))))
> (with-temp-buffer
> (save-excursion
> (insert expansion))
> (when (looking-at (regexp-quote "/*"))
> (search-forward "*/"))
> (let ((warnings (buffer-substring (point-min) (point)))
> (expansion (buffer-substring (point) (point-max))))
> (mapcar #'macrostep-c-string-trim (list expansion warnings))))))
>
> (defun macrostep-c-print-function (expansion &rest _ignore)
> (with-temp-buffer
> (insert expansion)
> (let ((exit-code
> (shell-command-on-region (point-min) (point-max) "indent" nil t)))
When calling indent, it might be nice to provide an option for optional
flags, in case someone prefers some other indentation scheme.
> (when (zerop exit-code)
> (setq expansion (macrostep-c-string-trim (buffer-string))))))
> (insert expansion))
>
> (provide 'macrostep-c)
>
> ;;; macrostep-c.el ends here
>
--
Philip Kaludercic on peregrine
next prev parent reply other threads:[~2024-03-19 6:36 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <87zfvl8r4e.fsf@jeremybryant.net>
[not found] ` <874jdspsqb.fsf@bernoul.li>
2024-02-28 20:56 ` Incorporate package macrostep into Emacs or NonGNU ELPA? Jeremy Bryant via Emacs development discussions.
2024-02-28 21:16 ` Stefan Monnier
2024-02-28 23:04 ` Jeremy Bryant
2024-02-29 20:44 ` Jeremy Bryant
2024-03-01 4:15 ` Adam Porter
2024-03-01 23:26 ` Stefan Monnier
2024-03-02 21:50 ` Jeremy Bryant
2024-03-02 22:51 ` Stefan Monnier
2024-03-03 7:26 ` Adam Porter
2024-03-03 7:51 ` Eli Zaretskii
2024-03-03 7:53 ` Adam Porter
2024-03-03 8:57 ` Eli Zaretskii
2024-03-03 14:28 ` Stefan Monnier
2024-03-04 11:25 ` Ihor Radchenko
2024-03-04 15:35 ` Stefan Monnier
2024-03-03 22:40 ` Jeremy Bryant
2024-03-04 12:00 ` Eli Zaretskii
2024-03-11 22:47 ` Jeremy Bryant
2024-03-02 6:51 ` Eli Zaretskii
2024-03-02 21:36 ` Jeremy Bryant
2024-03-17 21:48 ` Incorporate package macrostep into Emacs core Jeremy Bryant via Emacs development discussions.
2024-03-18 9:09 ` Philip Kaludercic
2024-03-18 23:03 ` Jeremy Bryant
2024-03-19 6:36 ` Philip Kaludercic [this message]
2024-03-19 7:11 ` Gerd Möllmann
2024-03-19 7:26 ` Philip Kaludercic
2024-03-19 7:30 ` Gerd Möllmann
2024-03-19 9:33 ` Philip Kaludercic
2024-03-19 9:48 ` Gerd Möllmann
2024-03-19 17:03 ` Jonathan Oddie
2024-03-19 21:57 ` Jeremy Bryant via Emacs development discussions.
2024-03-22 20:47 ` Jeremy Bryant
2024-03-22 20:50 ` Stefan Monnier
2024-03-18 12:48 ` Eli Zaretskii
2024-03-18 13:22 ` Stefan Monnier
2024-03-18 22:58 ` Jeremy Bryant
2024-03-19 12:26 ` Eli Zaretskii
2024-04-18 21:19 ` Jeremy Bryant
2024-04-19 6:38 ` Eli Zaretskii
2024-04-19 19:30 ` Jeremy Bryant
2024-04-19 22:26 ` Stefan Monnier
2024-04-20 6:07 ` Eli Zaretskii
2024-04-20 17:14 ` Adam Porter
2024-04-20 6:00 ` Eli Zaretskii
2024-04-23 21:37 ` Jeremy Bryant
2024-04-25 15:30 ` Eli Zaretskii
2024-04-25 21:27 ` Jeremy Bryant
2024-04-26 8:15 ` Eshel Yaron
2024-04-27 9:52 ` Eli Zaretskii
2024-04-29 21:38 ` Jeremy Bryant
2024-05-02 9:32 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o7basp70.fsf@posteo.net \
--to=philipk@posteo.net \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=j.j.oddie@gmail.com \
--cc=jb@jeremybryant.net \
--cc=jonas@bernoul.li \
--cc=monnier@iro.umontreal.ca \
--cc=stefankangas@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).