Xcode Reformat Code

0 views
Skip to first unread message

Boyan Atanaschev

unread,
Aug 5, 2024, 5:56:20 AM8/5/24
to unlimeno
Iam a newbie on Xcode/swiftUI. It is difficult to keep the editor code aligned properly. I know I can select the code I want to reformat and the use ctrl+I to re-indent it, but that is pretty inconvenient.

The fun part of this exercise for me was writing a pushdown automaton parser where all of the parser logic was expressed through the case patterns of a single Swift switch statement. Accordingly, most of this article is not really about Xcode Source Editor Command extensions or whitespace issues but is actually about design choices related to large, complex switch statements in Swift: choosing data types to switch upon, designing case patterns to handle a deep decision tree in a single switch statement, when to use custom pattern matching and when to use where clauses.


Code edited in Xcode is particularly prone to whitespace problems. Xcode file templates hard code indentation, ignoring your project settings. Code snippets sometimes hard code indents. Copy and paste code and Xcode will reformat your neatly formatted code according to its own whims (unless you carefully paste and preserve formatting). If SourceKit crashes, Xcode will forget all your indentation preferences.


Ultimately I made the decision that the design was wrong; that .space where length == 1 and .space where length > 1 were different tokens. This eliminated the need to test the length, since that test would already be implicit when matching on .multiSpace.


The ValidIndent predicate pattern type is constructed with self and the current column and it is matched against the last read token. What this means is that it is essentially given the whole function and parser state to evaluate its result.


The code for the Xcode Source Editor Command extension and whitespace parser discussed in this article is available as part of the CwlWhitespace project on Github. This project is written for Swift 3 and requires Xcode 8 to build.


The application is the delivery mechanism. Run the application once and the extension will be installed. (If running Xcode 8 on El Capitan, you need to enable Xcode extensions. See the Xcode 8 release notes for more.) To uninstall, drag the application to the Trash.


The first command uses multiple selections to select every text range in your file that it believes is violating a whitespace rule. If a line contains a zero-length problem (missing whitespace or missing indent) then the whole line will be selected.


When you build a Unity project for the iOS platform, Unity creates a folder that contains an Xcode project. You need to build and sign this project before you deploy it on a device or distribute it on the App Store.


The Xcode project includes the Xcode project file xcodeproj, and framework links that only appear in the Xcode project navigator. Apart from the default folders, you can create custom folders to add your custom files.


The Classes folder contains code that integrates the Unity runtime and Objective-C. Unity stores the entry points of the application in the main.mm and UnityAppController.mm/h files inside this folder. You can create your own AppDelegate derived from UnityAppController, or, if any of your plug-ins include AppController.h, you can include UnityAppController.h instead. If your Plugins/iOS folder includes AppController.mm/h, you can merge and rename them.


The /UnityFramework/Info.plist file, accessed via bundleWithIdentifier:@"com.unity3d.framework", is a part of UnityFramework. You can keep values in this file instead of the Info.plist file of the mainBundle. This makes sure that you can still get these values if UnityFramework is moved into another application, for example, when using Unity as a Library.


Alternatively you can use the installer from the Free Pascal site.However this will take much more space and time because you mustfirst download and install Apple's Xcode,which is a required dependency. You can get Xcode for free from theApp Store on macOS. It is a 5 Gb download, and will take 20-30minutes to install after it's downloaded! After you've installedXcode, open a terminal window and run "xcode-select--install". Then go to the FreePascal download page, choose a mirror (except SourceForge) anddownload the first installation package at the bottom of the page.Run the downloaded installer.


On Linux or macOS, you can configure Geany so that it canautomatically format your Pascal code with just a couple ofkeystrokes, using the ptop code formatter that comeswith Free Pascal. To set this up:


On Windows and possibly macOS, you can now launch yourprogram from Lazarus via the Run/Run command. On UNIX I have beenunable to get this to work, so you'll need to run your program fromthe command line as described under "Other editors" below.


You may use any other editor you like. If you cannot compilePascal programs from within your editor, you'll need to do that onthe command line. To do that, open a terminal window, use the cdcommand to move to the directory where your program file is stored,and type


If there are errors, you'll need to look at the line number in theerror messages and use your editor to manually find these lines.That's a pain, which is why I recommend using Geany, Lazarus oranother editor with built-in support for compiling Pascal programs.


Whenever I work on a project with others, I'm losing an annoying amount of time and effort on resolving merge conflicts. So, I began wondering how true that adage is. I am aware of techniques like GitFlow and agile which are able to make developers efficiently split up their work, commit more often, and maintain multiple branches of code, so merge conflicts are a lot less likely. But surely they still happen and can potentially wreak havoc?


In other words, how much time and effort do seasoned developers lose to resolving merge conflicts (when they could be working on their projects)? Are available techniques able to really negate any effects of merge conflicts?


I think it's a little disingenuous to say that good developers never have merge conflicts, but they can surely reduce the number of times it happens. It's also very important to remember that software development is a team activity. Actions of other members of the teams can also increase or decrease the likelihood of merge conflicts.


Seriously, though, the only way to avoid merge conflicts is to work alone (and even that doesn't help; happened to me to have merge conflicts with myself on personal projects). In a company hiring experienced developers, there are however three factors which reduce the pain of merge conflicts:


That is, you know what your coworkers are working on, and they know what you do. Therefore, when you're possibly modifying an area that somebody from your team is working on, you ask (or you tell). This way, you reduce a lot the risk of a painful commit.


This applies especially to those of the refactoring tasks which could substantially affect a large part of the code base, or do changes which are painful to merge. Say you're changing the type of a given variable everywhere, while your colleague is implementing a feature where this variable is used. Not only you risk to have a painful merge conflict, but also to break the build during the merge.


On the other hand, when the architecture is good enough, you reduce the risk of having a merge conflict to two situations: (1) where you modify an interface, or (2) where two coworkers are modifying the exact same part of the application. In the first case, you communicate, reducing even more the risk of a painful merge. In the second case, you do pair programming, removing the merge completely.


Experienced developers would tend to have adopt proper interfaces, such as SOA, which would make separate parts of the system more technically independent. Moreover, they will rely much more on specific practices such as push requests to avoid modifying someone else's code directly.


That's when he had a long talk with his manager, who in turn had a long talk with the other team's manager, which may or may not have included threats of physical violence, and the other team's manager apparently had a long talk with the developer in question, and the behaviour stopped.


You get merge conflicts if two people change code in the same place. So if you add to a file, don't add at the end, but add at the logically correct place. That way if another developer does the same, merge conflicts are much less likely.


Merging from your branch to the common code base must never cause a conflict. That's because you did (4) just before you tried to do the merge, so the merge will end up taking your code without any change.


Other answers have noted ways that skilled developers can learn to help make merge conflicts less likely, from preventing formatting chaos to frequent merges to better team coordination, but I do think there's some truth to the broader concept you raise: skilled developers can become better at dealing with merge conflicts when they do occur.


Resolving merge conflicts is tricky. You have to find the conflicts, understand the conflict markers, figure out what changed on each side considering the context of the code (possibly involving hard-to-spot issues like formatting), perhaps look up individual commits from both sides of the merge to understand the original intent, actually resolve the conflict, address possible implications of the change elsewhere in the codebase (or even in other repositories if APIs or interfaces are involved), compile, test, commit, etc... You have to remember how to get the version control system to do what you want during this process. And then there are more complicated cases: conflicts involving moved/deleted files and directories; conflicts involving binary files; conflicts involving generated files (including things like Visual Studio and Xcode config files; even if the conflict is simple, the file itself will be unfamiliar until you have some experience with it); conflicts nasty enough where you go find the person on the other side of the merge and figure it out together; all sorts of fun.

3a8082e126
Reply all
Reply to author
Forward
0 new messages