Giter VIP home page Giter VIP logo

swift-mode's Introduction

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.

Other example is regex literals and custom operators. The following example is valid Swift code with regex literals and custom operators.

let x = /^/ /^/ /^/

We parse them as regex literals rather than custom operators for now.

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-2021 taku0, Chris Barrett, Bozhidar Batsov, Arthur Evstifeev.

swift-mode's People

Contributors

ap4y avatar apiology avatar bbatsov avatar dalgong avatar danielmartin avatar dougbeal avatar it-boyer avatar jmibanez avatar jpgrayson avatar msanders avatar n4tr0n avatar nathankot avatar nhojb avatar swsnr avatar syohex avatar taku0 avatar uk-ar avatar wiruzx avatar woolsweater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swift-mode's Issues

problem with nested braces in \()

sorry, accidentally hit enter. Problem description:

When I have nested braces in a \() expression, swift-mode ends the \() expression after the first closing brace

Parsing bug: `_` breaks identifiers

Hi,

with the _ commit a new bug has been introduced: _ within an identifier breaks the identifier:

screen shot 2014-11-07 at 11 36 03

As you can see, the identifier seems to end at the _ char.

Regards,

Incorrect syntax class for underscore char

Received via email from Sean O'Rourke:

Underscore is a word character in Swift, not whitespace, so

(modify-syntax-entry ?_ "-" table)

in "swift-mode-syntax-table" is wrong.

Indentation: bug with multiline string concatenation

When writing code which concatenates strings over multiple lines, swift-mode indents like following:

    var x = "abc"
    x += "cde" +
        "fgh" +
          "ijk" +
            "lmn" +
              "opq"

Correct indentation would be like this:

    x += "cde" +
           "fgh" +
           "ijk" +
           "lmn" +
           "opq"

REPL shows duplicate prompts when loading code from buffer

Two things:

  1. Small issue: The repl seems to eat up 7 or so outputs for each time one sends the buffer for evaluation.

  2. More annoying: Sending a buffer for evaluation where the buffer's code using all-man style bracing upsets the repl and it doesn't evaluate. K&R style works fine, of course.

Repl support

Write a mode to support the Swift REPL. Implement commands for loading code and regions into the REPL.

Indention bug: multi-line expressions for protocols/inheritance don't indent

Hi,

when writing a class with multiple inherited items one may want to add a line break:

class ProductsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITabBarDelegate {
}

currently swift-mode indents like this:

class ProductsViewController: UIViewController, UITableViewDataSource,
UITableViewDelegate, UITabBarDelegate {

This doesn't look right, better would be something like this:

class ProductsViewController: UIViewController, UITableViewDataSource,
                              UITableViewDelegate, UITabBarDelegate {
}

Best regards,
CK

Incorrect indentation if a method declaration is the first item of a class declaration.

The indentation is correct with the var xyz

class Foo {
    var xyz
    func Bar {
        let x = 1
        let y = 2
    }
}

However, the indication is incorrect if the func Foo method is the first element of the class.

class Foo {
    func Bar {
    let x = 1
    let y = 2
}
}

Experimentation seems to indicate that a method definition immediately following an opening brace produces incorrect results.

func g() {
    func x() {
    let x = 1
}
}

I tried to decipher the issue, but wasn't able to make much progress without at least a few pointers in the right direction.

Indention bug: enums

Hi,

indention for enums is totally bugged:

enum OrderViewTableTakeAwayCells: Int {
  case DeliveryCell = 0,
                      nameCell = 1,
                                 emailCell = 2,
                                             phoneCell = 3,
                                                         couponCodeCell = 4,
                                                                          lastCellIndex
}
enum OrderViewTableDeliveryCells: Int {
  case DeliveryCell = 0,
                      nameCell,
                      emailCell,
                      phoneCell,
                      couponCodeCell,
                      addressCell,
                      address1Cell,
                      zipCell,
                      cityCell,
                      lastCellIndex
}
enum OtherEnum {
  case Val1
  case Val2
  case Val3
}

Completion with company-mode

Find a way to get code-completion working with completion-at-point to enable auto-completion using company-mode.

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.

Remove setq-local usages

Replace with (set (make-local-variable ...) ...). This is compatible with older emacsen and will allow removal of the reimplementation of setq-local.

Make offset for multi-line dot expressions customisable

As mentioned in #37, default offset for multi-line dot expressions can be sometimes too deep, because it defaults to be aligned with assignment operator (=). I personally like such indentation, but as @ckruse mentioned, he would prefer different style of indentation. I would be great to make this offset customisable (similar to swift-indent-switch-case-offset).

Follow Emacs idioms for customizing indentation

Summary

Please allow the user's tab-width preference (when present) to automatically override swift's default value.

Background

I am officially agnostic on indentation settings.

For much of my code, I happen to prefer soft tabs (spaces), of width 2. For most major modes, I can simply (setq-default tab-width 2) near the beginning of my ~/.emacs, and just about every mode obeys this preference.

For some finnicky modes, I can write a hook to forcibly assign the local tab-width definition to 2.

However, swift-mode is even more finnicky, due to many internal functions referring to swift-indent-offset rather than tab-width.

Mitigation

Currently, I have to override both variables in order to indent how I like:

(add-hook 'swift-mode-hook
          (lambda ()
            (setq-local tab-width 2)
            (defvar swift-indent-offset)
            (setq-local swift-indent-offset 2)))

System

$ specs cask:swift-mode emacs os
Specs:

specs 0.12
https://github.com/mcandre/specs#readme

find $HOME/.emacs.d/.cask -name '*swift-mode*' | head -n 1
/Users/andrew/.emacs.d/.cask/24.3.1/elpa/swift-mode-20141107.300

emacs --version
GNU Emacs 24.3.1
Copyright (C) 2013 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.

system_profiler SPSoftwareDataType | grep 'System Version'
      System Version: OS X 10.10.1 (14B25)

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

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.

Fix enum case indentation

All case statements are currently aligned to the same level as the enclosing block. This is appropriate for switch statements but not for enum cases.

Indention bug: Implicitly Unwrapped Optional Type

something wrong when i used Implicitly Unwrapped Optional Type:

    var manager:User   
    var name:String
    var cars:Array<RentItem>!
                   var users:Dictionary<String, User>!
                                        var carscount:Dictionary<String, Int>!
                                                                 var orders:Dictionary<Int, Order>

Need an indentation function

The mode currently lacks an indentation function. Swift uses a rigid block structure, so this shouldn't be too hard.

Other block-structured languages like C or Ruby might make good references for implementation.

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.

Comments not correctly font-locked

Commented lines are not being font locked correctly. They retain their existing font locking, rather than having the comment face applied.

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.

Need a flycheck checker

Research whether the compiler can perform type checking without code generation, then make a flycheck checker to provide syntax checking.

Indention bug: multi-line expressions with a `|` aren't indented correctly

Hi,

when working with regular expressions I noticed that breaking after a logical or indents really weird:

    let options = NSRegularExpressionOptions.CaseInsensitive |
                                             NSRegularExpressionOptions.DotMatchesLineSeparators

It should indent like this:

    let options = NSRegularExpressionOptions.CaseInsensitive |
                  NSRegularExpressionOptions.DotMatchesLineSeparators

or alternatively like this:

    let options = NSRegularExpressionOptions.CaseInsensitive |
                    NSRegularExpressionOptions.DotMatchesLineSeparators

I like the latter ;-)

Indention bug: return statement with ternary operator

Hi,

a ternary operator is a common thing in return statements, and often they contain line breaks. A ternary operator should therefore be indented:

instead of this (current behaviour):

return order!.deliver ?
OrderViewTableDeliveryCells.lastCellIndex.rawValue :
OrderViewTableTakeAwayCells.LastCellIndex.rawValue

I'd like to get this:

return order!.deliver ?
  OrderViewTableDeliveryCells.lastCellIndex.rawValue :
  OrderViewTableTakeAwayCells.LastCellIndex.rawValue

Merge mode code in a single file

It's extremely uncommon for major modes to be split into several files. I'd suggest simply merging swift-indent into swift-mode.

Indention bug: method call in for loop

The following statement gets indented wrong:

for item in order {
  moc
  .deleteObject(item)
}

It should indent the method call one level more deep. When leaving out the for loop indention works:

moc
  .deleteObject(item)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.