Emacs support for Apple's Swift programming language.

Overview

License GPL 3 Run Tests MELPA MELPA

swift-mode

Major-mode for Apple's Swift programming language.

Installation

Install swift-mode package from MELPA.

To install without MELPA, download latest release and execute M-x package-install-file for the .tar archive.

Features

  • Font Lock

  • Indentation

    switch foo {
    case let .P1(x)
           where
             x > 0,
         let .P2(x)
           where
             x > 0:
        bar()
          .then { x in
              return baz(x)
          }
          .then {(
                   x,
                   y
                 ) in
              return moo(x + y)
          }
    }
    
    // Hanging brace
    let x = [
      1,
      2,
      3
    ]
    
    // Brace on its own line
    let y =
      [
        1,
        2,
        3
      ]
    
    // Utrecht style
    let z =
      [ 1
      , 2
      , 3
      ]
  • forward-sexp

  • beginning-of-defun, end-of-defun, mark-defun, and narrow-to-defun.

  • beginning-of-sentence, end-of-sentence, kill-sentence, backward-kill-sentence, mark-sentence, and narrow-to-sentence. A sentence is a statement outside comments or strings, or an ordinal sentence inside comments or strings.

  • indent-new-comment-line

  • Imenu

  • Running Swift REPL in a buffer (M-x run-swift)

  • Build Swift module (M-x swift-mode:build-swift-module)

  • Build iOS app (M-x swift-mode:build-ios-app)

  • Running debugger on Swift module (M-x swift-mode:debug-swift-module)

  • Running debugger on iOS app in simulator or device (M-x swift-mode:debug-ios-app) (ios-deploy is required to debug on device).

This package does not provide flycheck. See flycheck-swift.

Limitations

Some syntax constructs removed from Swift 3.0 are not supported:

  • C-style for-loop: for var i = 1; i < 10; i++ { }

  • Multiple assignments in single if let:

    if let x = x,
           y = y {
    }

    Use multiple let instead:

    if let x = x,
       let y = y {
    }

Indentation may not accurate. For example, foo(Bar < A, B > (c)) can be indented like either

foo(Bar < A,
    B > (c)) // Passing two Boolean arguments to foo

or

foo(Bar < A,
          B > (c)) // Passing a new Bar with two type arguments and a value

The Swift compiler disambiguates this case using tokens after >, but those tokens may not available at editing time. We use some heuristic for this.

Another example is difficulty of handling of colons. We have to pair all ? and : of conditional operators to decide indentation of the below snippet. This is a future work.

switch foo {
  case let P(x) where x is Foo? ? a ? b : c ?? d : e ? f : g :
    h ? i?.j() : k()
}

switch foo {
  case let P(x) where (x is Foo?) ? (a ? b : c ?? d) : (e ? f : g) :
    h ? i?.j() : k()
}

Yet another difficult case is consistency of blocks. We want to indent method chains like this:

var x = foo
  .then { x in
      aaa
  }
  .then { x in
      aaa
  }

while we also want to indent the body of if like this:

if anotherVeryLongVariableName
     .veryLongPropertyName {
    aaa
}

That is, we have to indent the closing brace with offset if it is a part of expressions while it should be aligned with the beginning of the statement/declaration if it is a part of a statement/declaration.

Then, how should we indent the following code when the cursor is before @?

var x = foo
  .bar {
    @

This could be

var x = foo
  .bar {
    @abc willSet {
        aaa
    }
}
// property declaration

or

var x = foo
  .bar {
      @abc var x = 1
      x
  }
// property initialization

Both are syntactically correct code. We cannot handle this case properly. This is also a future work.

Hacking

To build the package locally, run make package.

To install the built package, run make install.

To run tests, run make test.

For other commands, run make help.

Related projects

Contributing

Yes, please do! See CONTRIBUTING for guidelines.

Acknowledgements

The REPL code is based on js-comint.

Thanks to the following original developer and users for their contributions:

You can find a full list of those people here.

Thanks to @purcell (Steve Purcell) for advices on the code and arrangement for merging swift3-mode and swift-mode.

License

GPLv3. See COPYING for details. Copyright (C) 2014-2016 taku0, Chris Barrett, Bozhidar Batsov, Arthur Evstifeev.

Comments
  • Simplify the grammar

    Simplify the grammar

    I'm sorry for this large patch. But it is hard to fix some defects with current grammar. So, I modified the grammar and related lexer. And this PR fixes #85 #59 #72 #35. How about this?

    opened by uk-ar 15
  • Indentation

    Indentation

    This patch updates most of indentation logic.

    The current implementation defines a complex syntax for SIME and depends on the indentation logic of SMIE. Unfortunately, SMIE is a black magic and controlling SMIE is very hard, so that results in a fragile and inconsistent logic:

    func foo() {
        foo
      .bar() // :(
        foo
          .bar()
    }
    
    CGPoint(x: aaaaaaaaaaaaaaa.x +
             bbbbbbbbbbbbbbbb, // 1 space
            y: aaaaaaaaaaaaaaa.y +
              bbbbbbbbbbbbbbbb) // 2 spaces
    
    class Foo: Bar,
        Baz { // 4 spaces from "class"
    }
    
    class Foo:
          Bar, Baz { // aligns with "Foo"
    }
    
    a
      .b // 2 spaces
    
    if (a
         .b) { // 1 spaces
    }
    
    protocol Foo {
        func foo()
    func bar() // :(
    }
    
    public class Foo {
               func foo() { // :(
    } // :(
           } // :(
    
    let a = [
    [ // :(
        a
    ]
    ]
    
    UIView.animateWithDuration(1.0,
                               animations: {
                                   foo.center =
                                   CGPoint(x: x, y: y) // :(
                                  } // :(
                              )
    
    protocol Foo {
        func foo() -> Foo<(A,
                           B),
    [C]>  // :(
    }
    

    This patch defines a simple syntax enough for indentation and use a simple manual logic for most cases.

    The new logic also supports different wrapping styles:

    let x =
      1 +
      1 +
      1
    
    let x
      = 1
        + 1
        + 1
    
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
                                                   target: self,
                                                   selector: Selector("onTimer"),
                                                   userInfo: nil,
                                                   repeats: true)
    
    timer = NSTimer.scheduledTimerWithTimeInterval(
      1.0,
      target: self,
      selector: Selector("onTimer"),
      userInfo: nil,
      repeats: true
    )
    
    let x = [
        foo:
          bar,
        foo
          : bar
    ]
    
    
    func a() ->
      [a] {
        a
    }
    
    func a()
      -> [a] {
        a
    }
    

    The new logic passes all existing tests and new tests (on Emacs 24.4.1).

    Sorry for a huge monolithic patch.

    opened by taku0 14
  • mismatched parentheses

    mismatched parentheses

    I keep getting this error only when using swift mode. I opened up a fresh install of emacs and only installed swift-mode and I get the same problem. This happens after the class declaration. Basically, I can create a class without issues but as soon as I finish typing func I get the warning and indentation, etc. stops working correctly.

    bug 
    opened by akoaysigod 14
  • Make multi-line dot statement offset customisable value

    Make multi-line dot statement offset customisable value

    Introduced new custom indentation offset value for multi-line dot expression: swift-indent-multiline-dot-offset. It defaults to nil to match default smiebehaviour.

    Fixes #41

    opened by ap4y 12
  • Fix indent when after comment

    Fix indent when after comment

    I fixed indent after comment.

    • expected result:
    func foo() {
        foo()
        //
        |foo()
    }
    
    • actual:
    func foo() {
        foo()
        //
            |foo()
    }
    
    opened by uk-ar 10
  • Indention bug with line breaks in method chaining

    Indention bug with line breaks in method chaining

    When chaining method calls and inserting a line break, the indention breaks. With the following code:

    let json_ary = NSJSONSerialization
    .JSONObjectWithData(data, options: nil,
                        error: &json_err) as NSArray
    

    I expect it to get indented like this:

    let json_ary = NSJSONSerialization
      .JSONObjectWithData(data, options: nil,
                          error: &json_err) as NSArray
    
    opened by ckruse 10
  • Swift 2 support

    Swift 2 support

    • [ ] guard
    • [ ] do blocks
    • [ ] Error handling
      • [ ] throws in function declaration
      • [ ] do catch syntax
      • [ ] try keyword
    • [ ] defer
    • [ ] Pattern matching
      • [ ] if
      • [ ] for
    • [ ] @testable
    • [ ] repeat
    • [ ] new Extensions with predicates
    • [ ] indirect cases in enums
    enhancement 
    opened by wiruzx 8
  • Flycheck error: `wrong-type-argument stringp`

    Flycheck error: `wrong-type-argument stringp`

    With the latest changes I get the following error whenever I open a Swift file:

    Error: (wrong-type-argument stringp ("/var/folders/x2/rr8_tk0169n9w8_lmjv6rg300000gn/T/flycheck63731PnK/AppDelegate.swift"))
    

    The exact folder differs, but the message is always the same.

    bug 
    opened by ckruse 8
  • Error message when opening swift files

    Error message when opening swift files

    Whenever I open a Swift file I get this error:

    File mode specification error: (void-variable flycheck-swift-sdk-path)
    

    I have to comment the eval-after-load block to avoid this error message and make Emacs usable again.

    bug 
    opened by ckruse 7
  • Implement indentation in terms of SMIE

    Implement indentation in terms of SMIE

    SMIE pretty much aims to end the practice of every package rolling out custom indentation logic. You can see ruby-mode in Emacs's trunk for a good example of SMIE usage.

    enhancement 
    opened by bbatsov 7
  • Fix warnings

    Fix warnings

    • Add an email address to Maintainer header for elpa.nongnu.org.
    • Fix linter script to check dependency errors.
    • Fix dependency errors and other warnings.
    • Rename test/swift-files/imenu/imenu-expected.el to test/swift-files/imenu/imenu-expected.eld since it only contains data rather than code.

    Co-authored-by: @monnier

    opened by taku0 6
  • Consider pilfering functionality

    Consider pilfering functionality

    I was the primary developer of this file when I was on the Swift project, and there are some nice bits in there that might benefit your mode. In particular, the -skip- functions approximately parse swift pretty reliably and efficiently (I see you have your own code for that and I haven't tried to compare it, but the hangs with which-function mode make me suspect you might want to try a different approach), and there are useful functions for folding away the details of files when you want to easily understand an API.

    I sucked those into my personal configuration so I could still use that functionality with your mode.

    If there's any interest, I'm happy to help. OTOH, if you've already evaluated what's in there and decided none of it is useful, then, sorry for the noise!

    opened by dabrahams 3
  • Does not work on M1 Macs

    Does not work on M1 Macs

    After some investigation of my own swift-stuff for emacs I noticed that "uname -a" is different in iTerm compared to emacs shell. iTerm (rosetta) returns x86_64 while Emacs returns arm64.

    The only way I could get xcodebuild to run correctly on M1 is if its prepended with "env /usr/bin/arch - x86_64 \\". Just to be clear, the command runs oki but the -destination with iOS Simulator doesnt work without it.

    Skärmavbild 2022-03-19 kl  12 01 53
    opened by konrad1977 2
  • Lisp nesting exceeds ‘max-lisp-eval-depth’ error

    Lisp nesting exceeds ‘max-lisp-eval-depth’ error

    When trying to call functionjit-lock-fontify-now, this errror will occur.

    Here is the backtrace log:
    Debugger entered--Lisp error: (error "Lisp nesting exceeds ‘max-lisp-eval-depth’")
      #f(compiled-function (matched names) #)(nil #)
      #f(compiled-function (elt) #)(#)
      mapc(#f(compiled-function (elt) #) (# #))
      seq-do(#f(compiled-function (elt) #) (# #))
      seq-reduce(#f(compiled-function (matched names) #) (# #) nil)
      #f(compiled-function (pos limit) #)(7758 18354)
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      ...
      ....[lots of same lines]...
      ....
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      swift-mode:font-lock-match-expr(18354 #f(compiled-function (pos limit) #))
      swift-mode:font-lock-match-builtin-enum-case-names(18354)
      font-lock-fontify-keywords-region(1519 18354 nil)
      font-lock-default-fontify-region(1519 18354 nil)
      font-lock-fontify-region(1519 18354)
      #f(compiled-function (fun) #)(font-lock-fontify-region)
      run-hook-wrapped(#f(compiled-function (fun) #) font-lock-fontify-region)
      jit-lock--run-functions(1519 18354)
      jit-lock-fontify-now()

    Restart emacs, and when it tries to restore the previously opened swift file, it will freeze. By executing the C-g key serveral times, it will return to normal, and there will be the following output in *Messages* buffer:

    Error during redisplay: (internal--syntax-propertize 1442) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 4000) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 6042) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 8248) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 10546) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 12685) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 14710) signaled (quit)
    Error during redisplay: (internal--syntax-propertize 16795) signaled (quit)
    
    opened by galeo 3
  • mark-sexp marks more than sexp within comment blocks

    mark-sexp marks more than sexp within comment blocks

    Example code with cursor as []:

      // []Start my application.  
      public func application(
    

    Hit C-M-SPC, C-M-@ or mark-sexp, marked region in between []

      // [Start my application.  
      public] func application(
    

    Expected (eg from objc-mode)

      // [Start] my application.  
      public func application(
    
    opened by vellvisher 1
  • Refactor mode for Swift

    Refactor mode for Swift

    I've been trying to start a refactoring mode for Swift that would work something like js2r-refactor by Magnar. I keep thinking that Swift-mode would need to be updated to find nodes, etc. Just wanted to know what any of you thought about this mode and if anybody would like to help.

    Thanks!

    opened by nicklanasa 6
Releases(v8.6.0)
Owner
null
Vim runtime files for Swift

Swift.vim Syntax and indent files for Swift If you don't have a preferred installation method check out vim-plug. Examples Syntastic Integration swift

Keith Smiley 787 Dec 1, 2022
A modern Swift (5.6) syntax definition for Sublime Text 4

Swift for Sublime This is a WIP version of a modern Swift (5.6) syntax for Sublime Text 4. It uses the latest features of the Sublime Text syntax engi

Will Bond 13 Dec 5, 2022
🪞 Swift wrapper for CodeMirror 6

?? Swift wrapper for CodeMirror 6

khoi 4 Jan 3, 2023
🔥 🔥 🔥Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

?? ?? ??Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

null 60 Dec 12, 2022
🐵Fooling around with Apples private framework AvatarKit

Fooling around with Apples private framework AvatarKit, the framework used in Messages.app for recording Animoji videos. If you are looking to create your own Animoji, take a look at SBSCustomAnimoji.

Simon Støvring 968 Dec 25, 2022
Write Emacs packages in Swift!

EmacsSwiftModule A Swift library to write Emacs plugins in Swift! Overview Emacs Swift module provides a convenient API for writing dynamic modules fo

Valeriy Savchenko 15 Nov 29, 2022
A repository for showcasing my knowledge of the Swift programming language, and continuing to learn the language.

Learning Swift (programming language) I know very little about programming in the Swift programming language. This document will go over all my knowle

Sean P. Myrick V19.1.7.2 2 Nov 8, 2022
A repository for showcasing my knowledge of the Objective-C++ programming language, and continuing to learn the language.

Learning Objective-C-Plus-Plus I hardly know anything about the Objective-C++ programming language. This document will go over all of my knowledge of

Sean P. Myrick V19.1.7.2 3 Nov 8, 2022
A repository for showcasing my knowledge of the Objective-C programming language, and continuing to learn the language.

Learning Objective-C I hardly know anything about the Objective-C programming language. This document will go over all of my knowledge of the Objectiv

Sean P. Myrick V19.1.7.2 3 Nov 8, 2022
Localization of the application with ability to change language "on the fly" and support for plural form in any language.

L10n-swift is a simple framework that improves localization in swift app, providing cleaner syntax and in-app language switching. Overview ?? Features

Adrian Bobrowski 287 Dec 24, 2022
Swift-extensions - Swift package extending the Swift programming language.

swift-extensions A package containing extensions for the Swift programming language. Contribution Reporting a bug If you find a bug, please open a bug

Alexandre H. Saad 2 Jun 12, 2022
Explanations and samples about the Swift programming language

About Swift Contents Explanations and samples about: Swift Programming Language Swift Standard Library Target audience Developers familiar with object

Nicola Lancellotti - About 74 Dec 29, 2022
The Package Manager for the Swift Programming Language

Swift Package Manager Project The Swift Package Manager is a tool for managing distribution of source code, aimed at making it easy to share your code

Apple 9.1k Dec 29, 2022
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

null 3.6k Jan 3, 2023
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

null 3.6k Dec 31, 2022
RSNetworking is a networking library written entirly for the Swift programming language.

RSNetworking is a networking library written entirly for the Swift programming language.

null 18 Feb 25, 2018
The Package Manager for the Swift Programming Language

Swift Package Manager Project The Swift Package Manager is a tool for managing distribution of source code, aimed at making it easy to share your code

Apple 9.1k Jan 5, 2023
Numerals is a package containing additional numeric types for the Swift programming language.

swift-numerals Numerals is a package containing additional numeric types for the Swift programming language. Contents The package currently provides t

Alexandre H. Saad 0 Jul 28, 2022
An experimental functional programming language with dependent types, inspired by Swift and Idris.

Kara An experimental functional programming language with dependent types, inspired by Swift and Idris. Motivation Development of Kara is motivated by

null 40 Sep 17, 2022