index all rss twitter github linkedin email

Álvaro Ramírez

25 August 2020 Smarter Swift snippets

Jari Safi published a wonderful Emacs video demoing python yasnippets in action. The constructor snippet, automatically setting ivars, is just magical. I wanted it for Swift!

I took a look at the __init__ snippet from Jorgen Schäfer's elpy. It uses elpy-snippet-init-assignments to generate the assignments.

With small tweaks, we can get the same action going on for Swift \o/

snippet.gif

init.yasnippet:

# -*- mode: snippet -*-
# name: init with assignments
# key: init
# --
init(${1:, args}) {
  ${1:$(swift-snippet-init-assignments yas-text)}
}
$0

.yas-setup.el:

(defun swift-snippet-init-assignments (arg-string)
  (let ((indentation (make-string (save-excursion
                                    (goto-char start-point)
                                    (current-indentation))
                                  ?\s)))
    (string-trim (mapconcat (lambda (arg)
                              (if (string-match "^\\*" arg)
                                  ""
                                (format "self.%s = %s\n%s"
                                        arg arg indentation)))
                            (swift-snippet-split-args arg-string)
                            ""))))

(defun swift-snippet-split-args (arg-string)
  (mapcar (lambda (x)
            (if (and x (string-match "\\([[:alnum:]]*\\):" x))
                (match-string-no-properties 1 x)
              x))
          (split-string arg-string "[[:blank:]]*,[[:blank:]]*" t)))