emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] overlay showing computed value of macro?


From: Matt Price
Subject: Re: [O] overlay showing computed value of macro?
Date: Thu, 22 Nov 2018 17:37:48 -0500



On Thu, Nov 22, 2018 at 4:06 PM Matt Price <address@hidden> wrote:


On Thu, Nov 22, 2018 at 1:19 PM Matt Price <address@hidden> wrote:
It would be nice for me to overlay the macro invocations with the values that they will evaluate to on export. I guess I would have to figure out when to trigger recalculation of the values (maybe not too often, say only when the macro is first created, when it's edited or deleted/deformed, and perhaps on structure editing.  

I do not understand emacs overlays very well so this feels a little daunting to me.  Does anyone out there have ideas about how to do it effectively?


This is what I've come up with; it feels somewhat close but not quite there yet. I can create, remove, and the overlays, which is great.  What I miss is the awesomeness of the way that overlays work with org links. I love how the link target and the enclosing [[  ][  ]] are invisible until I delete one of the "[" elements.  However, with my code, the whole macro _expression_ {{{macroname}}} ius invisible until I delete the whole thing, at which point the overlay helpfully disappears.  Is htere a way to get something like the link behaviour?  

Oops! Here is the actual code (a bit long actually!  Largely stolen from org source code).


#+begin_src emacs-lisp

(defun mwp-show-macros ()
  (interactive)
  (remove-overlays (point-min) (point-max) 'macro-ov-p t)
  (save-excursion
    (goto-char (point-min))
    ;; keeping this properties/keywordsstuff b/c I don't quite understand it
    (let* ((keywords nil)
           (properties-regexp (format "\\`EXPORT_%s\\+?\\'"
                      (regexp-opt keywords)))
       record)
      (while (re-search-forward "{{{[-A-Za-z0-9_]" nil t)
        (unless (save-match-data (org-in-commented-heading-p))
          (let* ((datum (save-match-data (org-element-context)))
             (type (org-element-type datum))
             (macro
              (cond
           ((eq type 'macro) datum)
           ;; In parsed keywords and associated node
           ;; properties, force macro recognition.
           ((or (and (eq type 'keyword)
                 (member (org-element-property :key datum) keywords))
                (and (eq type 'node-property)
                 (string-match-p properties-regexp
                         (org-element-property :key datum))))
            (save-excursion
              (goto-char (match-beginning 0))
              (org-element-macro-parser))))))
        (when macro
          (let* ((key (org-element-property :key macro))
             (value (org-macro-expand macro org-macro-templates))
             (begin (org-element-property :begin macro))
                     (end (save-excursion
                            (goto-char (org-element-property :end macro))
                    (skip-chars-backward " \t")
                    (point)))
             (signature (list begin
                      macro
                      (org-element-property :args macro))))
            ;; Avoid circular dependencies by checking if the same
            ;; macro with the same arguments is expanded at the
            ;; same position twice.
            (cond ((member signature record)
               (error "Circular macro expansion: %s" key))
              (value
               (push signature record)
               (let ((ov (make-overlay begin end)))
                         (overlay-put ov 'invisible t)
                         (overlay-put ov 'evaporate t)
                         (overlay-put ov 'macro-ov-p t)
                 (overlay-put ov 'before-string value )))
              ;; Special "results" macro: if it is not defined,
              ;; simply leave it as-is.  It will be expanded in
              ;; a second phase.
              ((equal key "results"))
              (t
               ;; (error "Undefined Org macro: %s; aborting"
               ;;        (org-element-property :key macro))
                       )))))))))
  (org-macro--counter-initialize)
  (setq-local mwp-macro-overlays t)
  )


(defun mwp-hide-macros ()
  (interactive)
(remove-overlays (point-min) (point-max) 'macro-ov-p t)
(setq-local mwp-macro-overlays nil)
;; (cl-loop for o in (overlays-in (point-min) (point-max))
;;          if (overlay-get o 'macro-ov-p)
;;          ())
)

(defun mwp-toggle-macros ()
  (interactive)
  (if mwp-macro-overlays
      (mwp-hide-macros)
    (mwp-show-macros)) )

(defvar-local mwp-macro-overlays nil)
#+end_src


reply via email to

[Prev in Thread] Current Thread [Next in Thread]