Logo

dev-resources.site

for different kinds of informations.

Customizing IEx: Personalizing Your Elixir Shell Environment

Published at
12/8/2024
Categories
elixir
Author
João Paulo Abreu
Categories
1 categories in total
elixir
open
Customizing IEx: Personalizing Your Elixir Shell Environment

In this article, we'll explore how to customize the Interactive Elixir (IEx) shell to enhance your development workflow. We'll cover everything from basic configuration to advanced customization techniques that can make your IEx sessions more productive and enjoyable.

Note: The examples in this article use Elixir 1.17.3. While most features should work across different versions, some functionality might vary.

Table of Contents

  • Understanding IEx Configuration
  • Basic Shell Customization
  • Configuring the IEx Prompt
  • Creating Custom Helpers
  • Setting Up .iex.exs
  • Color Schemes and Styling
  • Best Practices
  • Conclusion
  • Next Steps

Understanding IEx Configuration

IEx configuration can be set up in multiple ways:

  • Through the .iex.exs file in your home directory (~/.iex.exs)
  • Through a project-specific .iex.exs file
  • Via runtime configuration in your IEx session

The configuration files are loaded in the following order:

  1. User's home directory configuration (~/.iex.exs)
  2. Current directory configuration (./.iex.exs)
  3. Project-specific configuration (if present)

Basic Shell Customization

Let's start with basic shell configurations. Create a .iex.exs file in your home directory:

# Configure IEx basic settings
IEx.configure(
  history_size: 100,
  inspect: [
    limit: 5_000,
    pretty: true,
    width: 80
  ],
  colors: [enabled: true]
)

# Common imports that you use frequently
import Enum, only: [map: 2, reduce: 3]
import String, only: [upcase: 1, downcase: 1]

# Default aliases
alias MyApp.Repo
alias MyApp.User

You can verify if these configurations are working correctly by running the following tests in your IEx session:

# Test history_size configuration
iex(1)> IEx.configuration()[:history_size]
100  # Should return 100

# Test inspect configurations
iex(2)> list = Enum.to_list(1..10_000)
iex(3)> IO.inspect(list, width: 30)  # Compare with your width: 80 setting

# Test Enum imports
iex(4)> map([1, 2, 3], fn x -> x * 2 end)  # Should work without Enum.
[2, 4, 6]
iex(5)> reduce([1, 2, 3], 0, fn x, acc -> x + acc end)
6

# Test String imports
iex(6)> upcase("hello")  # Should work without String.
"HELLO"
iex(7)> downcase("WORLD")
"world"

# Test if colors are enabled
iex(8)> IO.ANSI.enabled?()
true

# Test aliases (will show error if modules don't exist, confirming alias setup)
iex(9)> Repo  # Should show MyApp.Repo module or error if not exists
iex(10)> User # Should show MyApp.User module or error if not exists

# Show complete current configuration
iex(11)> IEx.configuration()
# Displays all current IEx configurations

Configuring the IEx Prompt

Customize your prompt to make it more informative and visually appealing:

# Custom prompt configuration
IEx.configure(
  default_prompt:
    "#{IO.ANSI.green}%prefix#{IO.ANSI.reset}" <>
    "(#{IO.ANSI.cyan}%counter#{IO.ANSI.reset}) >",
  alive_prompt:
    "#{IO.ANSI.green}%prefix#{IO.ANSI.reset}" <>
    "(#{IO.ANSI.cyan}%node#{IO.ANSI.reset}) " <>
    "(#{IO.ANSI.cyan}%counter#{IO.ANSI.reset}) >"
)

# Available prompt variables:
# %counter - command counter
# %prefix  - iex
# %node    - node name (when running distributed)

Creating Custom Helpers

Custom helpers can significantly improve your workflow. Here are some useful examples:

# ~/.iex.exs

defmodule IExHelpers do
  def reload! do
    Mix.Task.reenable("compile.elixir")
    Application.stop(Mix.Project.config()[:app])
    Mix.Task.run("compile.elixir")
    Application.start(Mix.Project.config()[:app])
  end

  def list_app_modules(app) do
    case :application.get_key(app, :modules) do
      {:ok, modules} -> 
        modules 
        |> Enum.sort() 
        |> IO.inspect(pretty: true)
      :undefined -> 
        IO.puts "Application #{app} not found or has no modules"
    end
  end
end

import IExHelpers

You can use these functions in IEx like this:

iex> reload!  # Recompiles and restarts your application for code changes
iex> list_app_modules(:phoenix)  # Lists all available modules in the Phoenix application

Setting Up .iex.exs

Here's a complete example of a .iex.exs configuration file:

# ~/.iex.exs
# Configure IEx basic settings

# Common imports that you use frequently
import Enum, only: [map: 2, reduce: 3]
import String, only: [upcase: 1, downcase: 1]

# Set up aliases
alias MyApp.Repo
alias MyApp.User

# Configure shell appearance
Application.put_env(:elixir, :ansi_enabled, true)

IEx.configure(
  history_size: 100,
  inspect: [
    limit: 5_000,
    pretty: true,
    width: 80
  ],
  colors: [
    syntax_colors: [
      number: :yellow,
      atom: :cyan,
      string: :green,
      boolean: :red,
      nil: :red
    ],
    eval_result: [:green, :bright],
    eval_error: [:red, :bright],
    eval_info: [:blue, :bright]
  ],
  default_prompt:
    "#{IO.ANSI.green()}%prefix#{IO.ANSI.reset()}" <>
      "(#{IO.ANSI.cyan()}%counter#{IO.ANSI.reset()}) >"
)

defmodule IExHelpers do
  def reload! do
    Mix.Task.reenable("compile.elixir")
    Application.stop(Mix.Project.config()[:app])
    Mix.Task.run("compile.elixir")
    Application.start(Mix.Project.config()[:app])
  end

  def list_app_modules(app) do
     case :application.get_key(app, :modules) do
       {:ok, modules} -> 
         modules 
         |> Enum.sort() 
         |> IO.inspect(pretty: true)
       :undefined -> 
         IO.puts("Application #{app} not found or has no modules")
     end
  end
end

# Import helper functions into IEx session scope
import IExHelpers

Color Schemes and Styling

IEx supports ANSI colors for various elements. Here's how to configure them:

# Color configuration
IEx.configure(
  colors: [
    enabled: true,
    syntax_colors: [
      number: :yellow,
      atom: :cyan,
      string: :green,
      boolean: :red,
      nil: :red,
    ],
    ls_directory: :cyan,
    ls_device: :yellow,
    doc_code: :green,
    doc_inline_code: :magenta,
    doc_headings: [:cyan, :underline],
    doc_title: [:cyan, :bright, :underline],
  ]
)

Best Practices

  1. Organization

    • Keep your .iex.exs file organized and well-commented
    • Group related configurations together
    • Document custom helpers
  2. Project-Specific Configuration

    • Use project-level .iex.exs for project-specific settings
    • Keep general configurations in your home directory's .iex.exs
  3. Performance

    • Avoid loading unnecessary modules or making expensive computations
    • Use lazy loading when possible
    • Keep helper functions simple and focused
  4. Maintenance

    • Regularly review and update your configurations
    • Remove unused helpers and aliases
    • Keep configurations in version control

Conclusion

Customizing IEx can significantly improve your Elixir development experience. By properly configuring your shell environment, you can work more efficiently and effectively. Remember that the best configuration is one that suits your specific needs and workflow.

Next Steps

In the upcoming articles, we'll explore:

  • Numbers in Elixir
  • Integer, floats, and mathematical operations

Featured ones: