Skip to content

xenodium/ob-swiftui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

👉 Support this work via GitHub Sponsors

ob-swiftui

UPDATE: See blog post for latest changes.

Evaluate SwiftUI snippets using Emacs org babel.

Big thanks to Chris Eidhof, who tweeted a snippet to run any SwiftUI view as a macOS app. Much of ob-swiftui’s Swift code is based on that snippet as well as some additional tweaks he made (like writing to png).

ob-swiftui.gif

Install

(require 'ob-swiftui)
(ob-swiftui-setup)

Header arguments

:results window

Runs SwiftUI in a separate window (default and can be omitted).

Use a generated root view and render in external window (default):

#+begin_src swiftui
  Rectangle()
    .fill(Color.yellow)
    .frame(maxWidth: .infinity, maxHeight: .infinity)
#+end_src

is equivalent to:

#+begin_src swiftui :results window :view none
  Rectangle()
    .fill(Color.yellow)
    .frame(maxWidth: .infinity, maxHeight: .infinity)
#+end_src

:view FooView

If view: is given, use FooView as the root view. Otherwise, generate a root view and embed source block in view body.

#+begin_src swiftui :results window :view FooView
  struct FooView: View {
    var body: some View {
      VStack(spacing: 10) {
        BarView()
        BazView()
      }
    }
  }

  struct BarView: View {
    var body: some View {
      Rectangle()
        .fill(Color.yellow)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
  }

  struct BazView: View {
    var body: some View {
      Rectangle()
        .fill(Color.blue)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
  }
#+end_src

Note: Defining a view named ContentView, implies view: ContentView

:results file

Runs SwiftUI in the background and saves an image snapshot to a file. You can save the image to the location specified by the :file header argument, otherwise, it will be saved to a temporary location if :file is omitted. Please note that currently, png is the only supported image format.

#+begin_src swiftui :results file
  Rectangle()
    .fill(Color.yellow)
    .frame(maxWidth: .infinity, maxHeight: .infinity)
#+end_src

Auto refresh :results file image

If executing the block does not refresh the inlined image, try adding org-redisplay-inline-images in a hook. org-babel-after-execute-hook

(add-hook 'org-babel-after-execute-hook (lambda ()
                                          (when org-inline-image-overlays
                                            (org-redisplay-inline-images))))

Display retina image

For retina (high-resolution) displays, if you found the output image is too large, you can instruct Org to scale the image to 0.5 to display in its native size:

(advice-add 'org--create-inline-image :filter-return
            (defun org--create-inline-image/filter-return (x)
              (setcdr x (plist-put (cdr x) :scale 0.5))
              x))

👉 Support my work via GitHub Sponsors

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published