akirak / frame-workflow

Frame-oriented workflow management for Emacs
GNU General Public License v3.0
25 stars 2 forks source link

Rewrite using EIEIO #5

Open akirak opened 6 years ago

akirak commented 6 years ago

I've just pushed a new branch named eieio. It is a rewrite from scratch using EIEIO (see #2). Its functionality is minimal for now, but the code seem to be much cleaner than before, so I will continue to work on this branch. I won't continue development on the current mater branch.

The terminology in the README is no longer effective. It has been changed as follows:

I will document these changes soon on the wiki.

The current version lacks some of the features that existed in the previous version. I have to (re-)implement the following features:

akirak commented 6 years ago

frame-workflow-mode has been added. Now you have to turn on it before using any commands in frame-workflow. It also has a mode line (hopefully) got (almost) right. The previous mode line was done wrong, so I looked into the source code of projectile.

The following is a usage:

akirak commented 6 years ago

Readme in eieio branch has been updated.

alphapapa commented 6 years ago

Code looks really nice and clean, well-organized! :)

akirak commented 6 years ago

Your idea was great. I wouldn't be able to come up with it by myself. Thank you.

akirak commented 6 years ago

Now you can specify function to make a frame in a form of S expression (https://github.com/akirak/frame-workflow/commit/c7f92d5be8b209995d3ff669a7ffbd34d8206fa2). This allows you to integrate frame-workflow with frame-purpose concisely, as in the following example:

(frame-workflow-define-subject "emacs-lisp"
  :make-frame '(frame-purpose-make-mode-frame 'emacs-lisp-mode))

I personally want to strip the quote symbol (') from the slot value, but I don't know how.

alphapapa commented 6 years ago

Cool!

To remove the quote, you'll need to make frame-workflow-define-subject a macro.

akirak commented 6 years ago

Thanks. It was a macro, but I mistakenly quoted its entire macro body. Fixed at https://github.com/akirak/frame-workflow/commit/3f62c81f8a2b331e6539712b236375d85b05cf3f

Possibly relevant section in the manual: https://www.gnu.org/software/emacs/manual/html_node/elisp/Problems-with-Macros.html#Problems-with-Macros

alphapapa commented 6 years ago

That's kind of awkward, because macros are intended to produce code at compile time. This macro isn't producing a Lisp form, so it's acting like a function at runtime. Also, if users call the macro in their config, and if they then byte-compile their config, it will probably produce errors or just not result in the desired behavior, because it will eval at compile time instead of runtime.

akirak commented 6 years ago

So, it should be converted into a function to require a quote? use-package doesn't require quotes in :init and :config, but I don't understand how it works.

akirak commented 6 years ago

I've added a new commit. How do you think of this solution? https://github.com/akirak/frame-workflow/commit/adb2399f6c24038c052b09fd5a709f0f94f97ebc

alphapapa commented 6 years ago

Well, I think that will work correctly, but you should test to make sure. ;) It's really up to you how badly you want to avoid using a quote in the call. If you want to avoid the quote, it should be a macro. If not, it can be a function. Generally, AFAIK, the accepted wisdom is that you shouldn't use a macro when a function will do. But if you want to avoid the quote, it will have to be a macro.

On the other hand, making it a macro means that it will be evaluated at compile time, and that actually removes a bit of flexibility from the user. If the user wants to pass a form to the :make-frame arg, then it's fine. But if the user wants the :make-frame arg to be evaluated before being passed to frame-workflow-define-subject, then it being a macro will make that more difficult, as the user would have to let-bind the arg outside the macro call.

If you were to ask me which is best, I would probably suggest making frame-workflow-define-subject a function, and letting users quote the argument to :make-frame if it's a form. That way it's very clear that frame-workflow-define-subject is called at runtime and the argument is evaluated immediately, unless quoted.

You might even cl-case the argument, so users could pass either a form or a function, like:

(frame-workflow-define-subject "emacs-lisp"
  :make-frame #'user-make-frame-fn)

But only you know which is best, because it's your package. :) Hope this helps, rather than being confusing...

akirak commented 6 years ago

Thank you for your advice. I will make it a normal defun to allow programmatical use of the function. general.el defines general-define-key as a function but also defines general-def which is a macro that wraps the function as well as a few other functions. If it's necessary, I may add a shorthand like that.