unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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



  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).