LoginSignup
8
8

More than 5 years have passed since last update.

EmacsでSwiftのコードスタイル、コンパイルエラーをチェック

Posted at

Emacsのコード関連のチェックは、flymakeやflycheckがありますが
flymake使ってチェックを進めます。

コードスタイルについては、Swiftlintを利用して
コンパイルエラーは、Swiftコマンドでチェックを行います。

swift-flymake.gif

設定方法

init.elで入力毎にflymakeコマンドが走るように設定します。
swift-project-pathにはswiftのプロジェクトへのPathを設定し
swift-objc-header-pathにはBridging-Headerを設定します。
Bridging-Headerを利用してない場合は空文字を入れます。

init.el
;; flymake
(defvar swift-project-path "/path/to/swift-project")
(defvar swift-objc-header-path "/path/to/Bridging-Header")
(defvar swfit-flymake-command "~/.emacs.d/bin/swift-flymake.sh")
(defun flymake-swift-init ()
  (let* ((temp-file (flymake-init-create-temp-buffer-copy
                     'flymake-create-temp-inplace))
         (local-file (file-relative-name
                      temp-file
                      (file-name-directory buffer-file-name)))
         (objc-header-target (concat swift-objc-header-path "/*-Bridging-Header.h"))
         (objc-header-file-list (eshell-extended-glob objc-header-target)))
    (if (listp objc-header-file-list)
        (let ((objc-header-file (expand-file-name (car objc-header-file-list))))
          (list swfit-flymake-command (list swift-project-path local-file objc-header-file)))
      (list swfit-flymake-command (list swift-project-path local-file)))))
(add-to-list 'flymake-allowed-file-name-masks '("\\.swift\\'" flymake-swift-init))

;; flymakeにswiftチェックパターンはないので追加
(add-to-list 'flymake-err-line-patterns
             '("^.+swift\:\\([0-9]+\\)\:\\([0-9]+\\)?\: \\(error\\|warning\\)\: \\(.+\\)$" nil 1 2 4))

flymakeで実行するコマンドでは、コードスタイル、コンパイルエラーのチェックを一緒に行います。

swift-flymake.sh
#! /bin/bash

if [ "$3" ]; then
  ~/.emacs.d/bin/swift-code-checker.py --root-path "$1" --targetfile "$2" --objcheader "$3"
else
  ~/.emacs.d/bin/swift-code-checker.py --root-path "$1" --targetfile "$2"
fi

cd "$1" && swiftlint | grep "$2"

コンパイルエラーのチェックコマンド

swift-code-checker.py
#! /usr/bin/env python
# coding: utf-8

from commands import getoutput
from optparse import OptionParser

# パラメータ設定
usage = "usage: %prog [options]"
parser = OptionParser(usage, version="ver:%s" % "%prog 1.0")
parser.add_option('-b', '--root-path', dest='root_path')
parser.add_option('-t', '--targetfile', dest='target_file')
parser.add_option('-o', '--objcheader', dest='objc_header')
opts, args = parser.parse_args()

swift_option_list = []

swift_option_list.append('/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift')
swift_option_list.append('-frontend -parse')
swift_option_list.append('-sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk')
swift_option_list.append('-F libPods.a')
swift_option_list.append('-target i386-apple-ios8.1')
if opts.objc_header:
    swift_option_list.append('-import-objc-header')
    swift_option_list.append(opts.objc_header)

# code-checkの対象ファイル
swift_option_list.append(opts.target_file)

# Swiftプロジェクトにobjectiv-cのヘッダーがあればimportする
regex = r"find {} -name '*.h' | sed -e 's/^\(.*\/\).*/\1/' | uniq | sed -e 's/^\.//'"
result = getoutput(regex.format(opts.root_path))
include_list = [u'-I {}'.format(x.replace(' ', r'\ ')) for x in result.split('\n')]
include_str = ' '.join(include_list)
swift_option_list.append(include_str)

# コマンド実行
command_result = getoutput(' '.join(swift_option_list))
print command_result
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8