An implementation of ls in Swift
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ben Nied 1bd9426d02 Add extension filtering (-e/--ext) and test suite
Add -e and --ext flags to filter directory listings by file extension.
Fix and add tests using the Testing framework, organized into Tests/.
2026-05-10 09:38:02 -07:00
ls-swift Add extension filtering (-e/--ext) and test suite 2026-05-10 09:38:02 -07:00
ls-swift.xcodeproj Add extension filtering (-e/--ext) and test suite 2026-05-10 09:38:02 -07:00
.gitignore Add extension filtering (-e/--ext) and test suite 2026-05-10 09:38:02 -07:00
LICENSE Change license to BSD 2-Clause "Simplified". 2025-09-09 21:27:51 -07:00
README.md Change license to BSD 2-Clause "Simplified". 2025-09-09 21:27:51 -07:00

ls-swift

A modern implementation of the Unix ls command written in Swift. This project provides a cross-platform directory listing utility with color support, detailed file information, human-readable formatting, and advanced display options.

This project is very much a work-in-progress, and is mostly my "learn to Swift" application.

Features

  • Basic directory listing - List files and directories in the current or specified path
  • Long format display (-l) - Show detailed file information including permissions, size, and modification dates
  • Hidden file support (-a) - Display hidden files (those starting with .)
  • Human-readable sizes (-h) - Show file sizes in KB, MB, GB format when used with -l
  • Block size display (-s) - Show allocated disk space in 512-byte blocks
  • Time-based sorting (-t) - Sort files by modification time (newest first)
  • Reverse sorting (-r) - Reverse the sort order
  • One file per line (-1) - Display one file per line
  • Recursive listing (-R) - List subdirectories recursively
  • Multiple path support - List multiple directories with proper headers
  • Symlink support - Display symlink targets in long format (file -> target)
  • Non-printing character escape (-b) - Escape non-printing characters using C-style escape sequences
  • Enhanced color-coded output - Visual distinction between all file types:
    • Blue - Directories
    • Red - Executable files
    • Cyan - Symbolic links
    • Yellow - Character devices, FIFOs, sockets
    • Magenta - Block devices
    • Green - World-readable/writable files
    • White - Normal files
  • Color disable option (--no-color) - Turn off colored output
  • Error resilience - Continues processing on errors and reports them at the end
  • Help system (--help) - Built-in usage information

Usage

ls [OPTION]... [FILE]...

Options

Option Description
-a Do not ignore entries starting with .
-b Escape non-printing characters in C-style escape sequences
-h With -l, print sizes in human readable format
-l Use a long listing format
-r Reverse sort order
-s Print the allocated size of each file, in blocks
-t Sort by time, newest first
-1 List one file per line
-R List subdirectories recursively
--help Display help information and exit
--no-color Disable colored output

Examples

# List files in current directory
ls

# List files with detailed information
ls -l

# List all files (including hidden) with details
ls -la

# List files with human-readable file sizes
ls -lh

# List files with allocated block sizes
ls -s

# List files with long format and block sizes
ls -ls

# List files with escaped non-printing characters
ls -b

# Sort by modification time (newest first)
ls -t

# Sort by time in reverse order (oldest first)
ls -tr

# List one file per line
ls -1

# List directories recursively
ls -R

# List multiple directories with headers
ls dir1 dir2 dir3

# List files without colors
ls --no-color

# List files in a specific directory
ls /path/to/directory

# Combine multiple options
ls -lsah /usr/local

# Recursive listing with detailed info and human-readable sizes
ls -lRh

# Show symlink targets
ls -l  # Shows: symlink -> target

# Escape special characters in filenames
ls -lb

Advanced Features

Block Size Display (-s)

The -s option shows the allocated disk space for each file in 512-byte blocks:

# Simple format with block sizes
ls -s
     8 file1.txt
     1 small.txt
    16 large.dat

# Long format with block sizes and total
ls -ls
total 25
     8 -rw-r--r--  1 user  staff 3876 Dec 29 10:30 file1.txt
     1 -rw-r--r--  1 user  staff   45 Dec 29 10:31 small.txt
    16 -rw-r--r--  1 user  staff 7234 Dec 29 10:32 large.dat

Sorting Options

Sort files by different criteria:

# Sort by modification time (newest first)
ls -lt
-rw-r--r--  1 user  staff 1024 Dec 29 15:30 newest.txt
-rw-r--r--  1 user  staff  512 Dec 29 12:15 middle.txt
-rw-r--r--  1 user  staff 2048 Dec 29 09:45 oldest.txt

# Reverse any sort order
ls -lr  # Alphabetical reverse
ls -ltr # Time reverse (oldest first)

Recursive Listing (-R)

List all subdirectories and their contents:

ls -R
.:
dir1  dir2  file.txt

./dir1:
subfile1.txt  subdir1

./dir1/subdir1:
deepfile.txt

./dir2:
subfile2.txt

Multiple Path Support

List multiple directories with clear headers:

ls -l /usr/local /home/user
/usr/local:
drwxr-xr-x  8 root  wheel   256 Dec 29 10:00 bin
drwxr-xr-x  4 root  wheel   128 Dec 29 10:00 lib

/home/user:
-rw-r--r--  1 user  group  1024 Dec 29 15:00 document.txt
drwxr-xr-x  2 user  group    64 Dec 29 14:00 projects

Symbolic links show their targets in long format:

ls -l
lrwxrwxrwx  1 user  group    12 Dec 29 10:00 link -> target_file
-rw-r--r--  1 user  group  1024 Dec 29 10:00 target_file

Non-Printing Character Escaping (-b)

The -b option escapes non-printing characters in filenames using C-style escape sequences:

# Files with special characters
ls -b
file\nwith\nnewlines.txt
file\twith\ttabs.txt
file\"with\"quotes.txt
normal_file.txt

Common escape sequences:

  • \n - Newline
  • \t - Tab
  • \r - Carriage return
  • \\ - Backslash
  • \" - Double quote
  • \nnn - Octal representation for other non-printing characters

Error Handling

The program continues processing even when encountering errors:

ls dir1 nonexistent dir2
dir1:
file1.txt
file2.txt

dir2:
file3.txt

ls: nonexistent: No such file or directory

Installation

Building from Source

  1. Clone the repository:
git clone <repository-url>
cd ls-swift
  1. Build the project using Swift:
swift build -c release
  1. The executable will be available at .build/release/ls-swift

  2. Optionally, copy to your PATH:

cp .build/release/ls-swift /usr/local/bin/ls-swift

Project Structure

The project is organized into several Swift modules:

  • main.swift - Application entry point

  • LSCommand.swift - Main command controller and orchestrator

  • ArgumentParser.swift - Command-line argument parsing logic

  • LSOptions.swift - Configuration structure for command options

  • FileSystemManager.swift - File system operations and directory listing

  • DisplayManager.swift - Output formatting and display logic

  • ColorManager.swift - Color coding for different file types

  • HelpManager.swift - Help text and usage information

  • PermissionFormatter.swift - Unix permission string formatting

  • FileInfo.swift - Data structure for file metadata

Technical Details

File Type Detection

  • Supports all Unix file types: regular files, directories, symlinks, character/block devices, FIFOs, and sockets
  • Properly detects executable files based on permissions
  • Resolves symlink targets and displays them

Block Size Calculation

  • Uses 512-byte blocks (POSIX standard)
  • Rounds up to nearest block (ceiling division)
  • Shows actual disk space allocation vs logical file size

Sorting Algorithms

  • Alphabetical sorting (default)
  • Time-based sorting by modification date
  • Reverse sorting for any sort method
  • Special handling for . and .. entries

Character Escaping

  • Supports standard C-style escape sequences
  • Uses octal notation for non-standard characters
  • Unicode escapes for extended character sets
  • Preserves printable characters including accented letters

Color Coding

  • Uses ANSI escape codes for terminal colors
  • Comprehensive file type color mapping
  • Can be disabled with --no-color option
  • Works across different terminal emulators

Error Handling

  • Collects errors during processing
  • Continues operation on individual file errors
  • Reports all errors at the end for multiple paths
  • Immediate error reporting for single path operations

Requirements

  • Swift 5.5 or later
  • macOS 10.15+, Linux, or other Swift-supported platforms

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

This project is licensed under the BSD 2-Clause "Simplified" License - see the LICENSE file for details.

This project was created by Ben Nied (bnied@spaceduck.org) on August 29, 2025.

Acknowledgments

This implementation aims to provide a modern, Swift-native alternative to the traditional Unix ls command while maintaining familiar behavior and command-line compatibility. Special attention has been paid to:

  • Performance - Efficient file system operations
  • Compatibility - Standard Unix ls behavior
  • Extensibility - Clean, modular architecture
  • Usability - Clear output formatting and helpful error messages