├── test ├── test_helper.exs └── test_modules │ ├── module_doc_false.ex │ ├── starting_doctest_wrong.ex │ ├── non_elixir_backticks.ex │ ├── behave.ex │ ├── blank_line_doctest.ex │ ├── indented_code_are_elixir_cells.ex │ ├── finishing_doctest_wrong.ex │ ├── protocols.ex │ ├── macro_with_no_doc.ex │ ├── implemented_proto.ex │ ├── indented_invalid_elixir.ex │ ├── fns_for_none.ex │ ├── macro_with_doc.ex │ ├── fns_for_all.ex │ ├── doctest_in_doctest.ex │ ├── implementation.ex │ ├── type_docs.ex │ ├── mod.ex │ ├── doctest_spans_lines.ex │ ├── bullets.ex │ └── thing.ex ├── .tool-versions ├── elixir_livebooks ├── hex.livemd ├── hex_api.livemd ├── hex_http.livemd ├── hex_netrc.livemd ├── hex_repo.livemd ├── hex_scm.livemd ├── hex_set.livemd ├── hex_shell.livemd ├── hex_state.livemd ├── hex_tar.livemd ├── hex_utils.livemd ├── i_ex_app.livemd ├── key_error.livemd ├── mix_error.livemd ├── uri_error.livemd ├── erlang_error.livemd ├── file_error.livemd ├── fns_for_none.livemd ├── hex_api_key.livemd ├── hex_config.livemd ├── hex_crypto.livemd ├── hex_httpssl.livemd ├── hex_sponsor.livemd ├── hex_stdlib.livemd ├── hex_version.livemd ├── i_ex_state.livemd ├── inspect_any.livemd ├── inspect_map.livemd ├── inspect_pid.livemd ├── match_error.livemd ├── mix_scm_git.livemd ├── syntax_error.livemd ├── argument_error.livemd ├── bad_arity_error.livemd ├── bad_map_error.livemd ├── compile_error.livemd ├── enumerable_map.livemd ├── hex_api_auth.livemd ├── hex_api_user.livemd ├── hex_http_certs.livemd ├── hex_registry.livemd ├── hex_resolver.livemd ├── i_ex_info_any.livemd ├── i_ex_info_atom.livemd ├── i_ex_info_date.livemd ├── i_ex_info_list.livemd ├── i_ex_info_map.livemd ├── i_ex_info_pid.livemd ├── i_ex_info_port.livemd ├── i_ex_info_time.livemd ├── inspect_atom.livemd ├── inspect_date.livemd ├── inspect_float.livemd ├── inspect_list.livemd ├── inspect_port.livemd ├── inspect_range.livemd ├── inspect_regex.livemd ├── inspect_stream.livemd ├── inspect_time.livemd ├── inspect_tuple.livemd ├── logger_config.livemd ├── logger_handler.livemd ├── mix_scm_path.livemd ├── module_types.livemd ├── path_wildcard.livemd ├── runtime_error.livemd ├── string_break.livemd ├── string_unicode.livemd ├── version_parser.livemd ├── arithmetic_error.livemd ├── bad_boolean_error.livemd ├── bad_struct_error.livemd ├── case_clause_error.livemd ├── code_load_error.livemd ├── collectable_list.livemd ├── collectable_map.livemd ├── cond_clause_error.livemd ├── enum_empty_error.livemd ├── enumerable_list.livemd ├── enumerable_range.livemd ├── file_copy_error.livemd ├── file_link_error.livemd ├── file_rename_error.livemd ├── gen_event_stream.livemd ├── hex_api_package.livemd ├── hex_api_release.livemd ├── hex_api_short_url.livemd ├── hex_application.livemd ├── hex_crypto_pkcs5.livemd ├── hex_netrc_cache.livemd ├── hex_netrc_parser.livemd ├── hex_option_parser.livemd ├── i_ex_info_float.livemd ├── i_ex_info_integer.livemd ├── i_ex_info_tuple.livemd ├── inspect_date_time.livemd ├── inspect_function.livemd ├── inspect_hash_dict.livemd ├── inspect_hash_set.livemd ├── inspect_integer.livemd ├── inspect_map_set.livemd ├── inspect_version.livemd ├── io_stream_error.livemd ├── ioansi_sequence.livemd ├── list_chars_atom.livemd ├── list_chars_float.livemd ├── list_chars_list.livemd ├── mix_no_task_error.livemd ├── module_doc_false.livemd ├── record_extractor.livemd ├── stream_reducers.livemd ├── string_chars_uri.livemd ├── string_tokenizer.livemd ├── task_supervised.livemd ├── try_clause_error.livemd ├── with_clause_error.livemd ├── bad_function_error.livemd ├── collectable_map_set.livemd ├── enumerable_function.livemd ├── enumerable_hash_set.livemd ├── enumerable_map_set.livemd ├── enumerable_stream.livemd ├── hex_crypto_aes_gcm.livemd ├── hex_shell_process.livemd ├── i_ex_info_bit_string.livemd ├── i_ex_info_function.livemd ├── i_ex_info_reference.livemd ├── inspect_bit_string.livemd ├── inspect_date_range.livemd ├── inspect_macro_env.livemd ├── inspect_reference.livemd ├── list_chars_integer.livemd ├── mix_dep_elixir_scm.livemd ├── mix_no_project_error.livemd ├── module_types_error.livemd ├── module_types_expr.livemd ├── regex_compile_error.livemd ├── string_chars_atom.livemd ├── string_chars_date.livemd ├── string_chars_float.livemd ├── string_chars_list.livemd ├── string_chars_time.livemd ├── supervisor_default.livemd ├── system_limit_error.livemd ├── token_missing_error.livemd ├── collectable_bit_string.livemd ├── collectable_hash_dict.livemd ├── collectable_hash_set.livemd ├── collectable_io_stream.livemd ├── collectable_mix_shell.livemd ├── enumerable_date_range.livemd ├── enumerable_hash_dict.livemd ├── enumerable_io_stream.livemd ├── function_clause_error.livemd ├── hex_api_package_owner.livemd ├── hex_api_release_docs.livemd ├── hex_crypto_encryption.livemd ├── hex_crypto_key_manager.livemd ├── hex_crypto_public_key.livemd ├── hex_remote_converger.livemd ├── kernel_error_handler.livemd ├── mix_invalid_task_error.livemd ├── mix_tasks_compile_all.livemd ├── mix_tasks_hex_install.livemd ├── string_chars_date_time.livemd ├── string_chars_integer.livemd ├── string_chars_version.livemd ├── system_signal_handler.livemd ├── collectable_file_stream.livemd ├── enum_out_of_bounds_error.livemd ├── enumerable_file_stream.livemd ├── hex_api_key_organization.livemd ├── hex_http_verify_hostname.livemd ├── hex_mix_task_description.livemd ├── hex_resolver_backtracks.livemd ├── hex_version_requirement.livemd ├── i_ex_info_naive_date_time.livemd ├── inspect_naive_date_time.livemd ├── kernel_parallel_require.livemd ├── mix_elixir_version_error.livemd ├── option_parser_parse_error.livemd ├── protocol_undefined_error.livemd ├── string_chars_bit_string.livemd ├── undefined_function_error.livemd ├── unicode_conversion_error.livemd ├── enumerable_gen_event_stream.livemd ├── hex_crypto_pbes2_hmac_sha2.livemd ├── hex_crypto_aes_cbc_hmac_sha2.livemd ├── hex_crypto_content_encryptor.livemd ├── inspect_version_requirement.livemd ├── mix_tasks_local.livemd ├── string_chars_naive_date_time.livemd ├── version_invalid_version_error.livemd ├── macro_with_no_doc.livemd ├── mix_compilers_application_tracer.livemd ├── hex_version_invalid_version_error.livemd ├── implementation.livemd ├── string_chars_version_requirement.livemd ├── version_invalid_requirement_error.livemd ├── hex_version_invalid_requirement_error.livemd ├── behave.livemd ├── inspect_error.livemd ├── non_elixir_backticks.livemd ├── mix_tasks_iex.livemd ├── mix_cli.livemd ├── set.livemd ├── logger_app.livemd ├── proto.livemd ├── hash_set.livemd ├── indented_code_are_elixir_cells.livemd ├── kernel_lexical_tracker.livemd ├── macro_with_doc.livemd ├── mix_tasks_will_recompile.livemd ├── list_chars_bit_string.livemd ├── implemented_proto.livemd ├── kernel_typespec.livemd ├── hex_server.livemd ├── i_ex_config.livemd ├── mix_state.livemd ├── agent_server.livemd ├── hex_parallel.livemd ├── mix_tasks_server.livemd ├── code_normalizer.livemd ├── hex_update_checker.livemd ├── mix_project_stack.livemd ├── hex_registry_server.livemd ├── registry_supervisor.livemd ├── hash_dict.livemd ├── implemented_proto_implementation.livemd ├── calendar_utc_only_time_zone_database.livemd ├── mix_dep_fetcher.livemd ├── mix_tasks_escript.livemd ├── doctest_in_doctest.livemd ├── fns_for_all.livemd ├── mix_dep_lock.livemd ├── version_requirement.livemd ├── mix_compilers_test.livemd ├── dict.livemd ├── code_formatter.livemd ├── mix_dep_umbrella.livemd ├── mix_tasks_clean.livemd ├── logger_watcher.livemd ├── mix_tasks_hex_audit.livemd ├── type_docs.livemd ├── i_ex_autocomplete.livemd ├── logger_filter.livemd ├── module_types_pattern.livemd ├── date_range.livemd ├── mix_public_key.livemd ├── mix_tasks_archive.livemd ├── mix_dep_converger.livemd ├── i_ex_cli.livemd ├── mix_hex.livemd ├── i_ex_history.livemd ├── list_chars.livemd ├── io_stream.livemd ├── mod.livemd ├── doctest_spans_lines.livemd ├── i_ex_introspection.livemd ├── logger_backend_supervisor.livemd ├── module_types_of.livemd ├── registry_partition.livemd ├── string_chars.livemd ├── mix_remote_converger.livemd ├── logger_utils.livemd ├── behaviour.livemd ├── mix_tasks_loadconfig.livemd ├── kernel_cli.livemd ├── i_ex_broker.livemd ├── mix_tasks_deps_clean.livemd ├── mix_compilers_elixir.livemd ├── mix_dep_loader.livemd ├── mix_tasks_local_hex.livemd ├── mix_rebar.livemd ├── module_locals_tracker.livemd ├── mix_local.livemd ├── mix_tasks_cmd.livemd ├── mix_tasks_local_rebar.livemd ├── code_typespec.livemd ├── module_parallel_checker.livemd ├── logger_translator.livemd ├── mix_shell_io.livemd ├── ioansi_docs.livemd ├── atom.livemd ├── hex_mix.livemd ├── bullets.livemd ├── mix_task_compiler.livemd ├── module_types_helpers.livemd ├── gen_event.livemd ├── i_ex_pry.livemd ├── kernel_utils.livemd ├── file_stat.livemd ├── thing.livemd ├── livebook_helpers.livemd ├── calendar_time_zone_database.livemd ├── mix_shell_process.livemd ├── inspect.livemd ├── mix_generator.livemd ├── string_io.livemd ├── logger_backends_console.livemd ├── mix_scm.livemd ├── collectable.livemd ├── tuple.livemd ├── bitwise.livemd ├── mix_tasks_compile_app.livemd ├── range.livemd ├── function.livemd ├── map_set.livemd ├── exception.livemd └── config.livemd ├── .formatter.exs ├── .gitignore ├── mix.exs ├── forum_announcement.md ├── mix.lock ├── lib └── create_livebook_from_module.ex └── README.md /test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | elixir 1.13.3-otp-24 2 | erlang 24.1.7 3 | -------------------------------------------------------------------------------- /elixir_livebooks/hex.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_http.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.HTTP 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_netrc.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Netrc 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_repo.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Repo 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_scm.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.SCM 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Set 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_shell.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Shell 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_state.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.State 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_tar.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Tar 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_utils.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Utils 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_app.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.App 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/key_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # KeyError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Error 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/uri_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # URI.Error 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/erlang_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ErlangError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/file_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # File.Error 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/fns_for_none.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # FnsForNone 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_key.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.Key 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_config.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Config 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_httpssl.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.HTTP.SSL 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_sponsor.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Sponsor 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_stdlib.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Stdlib 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_version.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Version 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_state.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.State 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_any.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Any 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_map.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Map 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_pid.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.PID 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/match_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # MatchError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_scm_git.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.SCM.Git 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/syntax_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # SyntaxError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/argument_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ArgumentError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/bad_arity_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # BadArityError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/bad_map_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # BadMapError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/compile_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # CompileError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_map.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.Map 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_auth.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.Auth 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_user.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.User 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_http_certs.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.HTTP.Certs 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_registry.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Registry 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_resolver.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Resolver 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_any.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Any 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_atom.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Atom 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_date.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Date 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_list.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.List 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_map.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Map 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_pid.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.PID 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_port.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Port 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Time 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_atom.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Atom 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_date.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Date 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_float.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Float 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_list.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.List 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_port.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Port 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_range.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Range 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_regex.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Regex 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Time 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_tuple.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Tuple 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_config.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Config 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_handler.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Handler 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_scm_path.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.SCM.Path 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/module_types.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.Types 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/path_wildcard.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Path.Wildcard 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/runtime_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # RuntimeError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_break.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Break 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_unicode.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Unicode 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/version_parser.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Version.Parser 4 | 5 | -------------------------------------------------------------------------------- /test/test_modules/module_doc_false.ex: -------------------------------------------------------------------------------- 1 | defmodule ModuleDocFalse do 2 | @moduledoc false 3 | end 4 | -------------------------------------------------------------------------------- /elixir_livebooks/arithmetic_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ArithmeticError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/bad_boolean_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # BadBooleanError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/bad_struct_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # BadStructError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/case_clause_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # CaseClauseError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/code_load_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Code.LoadError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_list.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.List 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_map.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.Map 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/cond_clause_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # CondClauseError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enum_empty_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enum.EmptyError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_list.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.List 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_range.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.Range 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/file_copy_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # File.CopyError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/file_link_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # File.LinkError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/file_rename_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # File.RenameError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/gen_event_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # GenEvent.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_package.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.Package 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_release.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.Release 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_short_url.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.ShortURL 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_application.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Application 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_pkcs5.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.PKCS5 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_netrc_cache.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Netrc.Cache 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_netrc_parser.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Netrc.Parser 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_option_parser.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.OptionParser 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_float.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Float 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_integer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Integer 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_tuple.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Tuple 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_date_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.DateTime 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_function.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Function 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_hash_dict.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.HashDict 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_hash_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.HashSet 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_integer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Integer 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_map_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.MapSet 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_version.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Version 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/io_stream_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IO.StreamError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/ioansi_sequence.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IO.ANSI.Sequence 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/list_chars_atom.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # List.Chars.Atom 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/list_chars_float.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # List.Chars.Float 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/list_chars_list.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # List.Chars.List 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_no_task_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.NoTaskError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/module_doc_false.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ModuleDocFalse 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/record_extractor.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Record.Extractor 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/stream_reducers.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Stream.Reducers 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_uri.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.URI 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_tokenizer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Tokenizer 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/task_supervised.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Task.Supervised 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/try_clause_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # TryClauseError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/with_clause_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # WithClauseError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/bad_function_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # BadFunctionError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_map_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.MapSet 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_function.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.Function 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_hash_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.HashSet 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_map_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.MapSet 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_aes_gcm.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.AES_GCM 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_shell_process.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Shell.Process 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_bit_string.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.BitString 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_function.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Function 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_reference.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.Reference 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_bit_string.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.BitString 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_date_range.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Date.Range 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_macro_env.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Macro.Env 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_reference.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Reference 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/list_chars_integer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # List.Chars.Integer 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_dep_elixir_scm.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Dep.ElixirSCM 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_no_project_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.NoProjectError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/module_types_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.Types.Error 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/module_types_expr.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.Types.Expr 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/regex_compile_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Regex.CompileError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_atom.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Atom 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_date.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Date 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_float.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Float 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_list.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.List 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Time 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/supervisor_default.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Supervisor.Default 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/system_limit_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # SystemLimitError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/token_missing_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # TokenMissingError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_bit_string.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.BitString 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_hash_dict.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.HashDict 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_hash_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.HashSet 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_io_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.IO.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_mix_shell.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.Mix.Shell 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_date_range.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.Date.Range 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_hash_dict.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.HashDict 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_io_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.IO.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/function_clause_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # FunctionClauseError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_package_owner.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.Package.Owner 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_release_docs.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.ReleaseDocs 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_encryption.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.Encryption 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_key_manager.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.KeyManager 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_public_key.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.PublicKey 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_remote_converger.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.RemoteConverger 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/kernel_error_handler.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kernel.ErrorHandler 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_invalid_task_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.InvalidTaskError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_compile_all.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Compile.All 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_hex_install.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Hex.Install 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_date_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.DateTime 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_integer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Integer 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_version.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Version 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/system_signal_handler.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # System.SignalHandler 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable_file_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable.File.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enum_out_of_bounds_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enum.OutOfBoundsError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_file_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.File.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_api_key_organization.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.API.Key.Organization 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_http_verify_hostname.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.HTTP.VerifyHostname 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_mix_task_description.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Mix.TaskDescription 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_resolver_backtracks.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Resolver.Backtracks 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_version_requirement.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Version.Requirement 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_info_naive_date_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Info.NaiveDateTime 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_naive_date_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.NaiveDateTime 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/kernel_parallel_require.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kernel.ParallelRequire 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_elixir_version_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.ElixirVersionError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/option_parser_parse_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # OptionParser.ParseError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/protocol_undefined_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Protocol.UndefinedError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_bit_string.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.BitString 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/undefined_function_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # UndefinedFunctionError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/unicode_conversion_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # UnicodeConversionError 4 | 5 | -------------------------------------------------------------------------------- /.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /elixir_livebooks/enumerable_gen_event_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Enumerable.GenEvent.Stream 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_pbes2_hmac_sha2.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.PBES2_HMAC_SHA2 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_aes_cbc_hmac_sha2.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.AES_CBC_HMAC_SHA2 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_crypto_content_encryptor.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Crypto.ContentEncryptor 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_version_requirement.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Version.Requirement 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_local.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Local 4 | 5 | Lists local tasks. 6 | 7 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_naive_date_time.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.NaiveDateTime 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/version_invalid_version_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Version.InvalidVersionError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/macro_with_no_doc.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # MacroWithNoDoc 4 | 5 | A wild doc appeared! 6 | 7 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_compilers_application_tracer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Compilers.ApplicationTracer 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_version_invalid_version_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Version.InvalidVersionError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/implementation.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Implementation 4 | 5 | This is the actual moduledoc 6 | 7 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars_version_requirement.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars.Version.Requirement 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/version_invalid_requirement_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Version.InvalidRequirementError 4 | 5 | -------------------------------------------------------------------------------- /test/test_modules/starting_doctest_wrong.ex: -------------------------------------------------------------------------------- 1 | defmodule StartingDoctestWrong do 2 | @moduledoc """ 3 | ...>1 + 1 4 | """ 5 | end 6 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_version_invalid_requirement_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Version.InvalidRequirementError 4 | 5 | -------------------------------------------------------------------------------- /elixir_livebooks/behave.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Behave 4 | 5 | ## thing/1 6 | 7 | This is a doc for a callback, dope right? 8 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect_error.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect.Error 4 | 5 | Raised when a struct cannot be inspected. 6 | 7 | -------------------------------------------------------------------------------- /elixir_livebooks/non_elixir_backticks.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # NonElixirBackticks 4 | 5 | ```xml 6 | 7 | ``` 8 | 9 | -------------------------------------------------------------------------------- /test/test_modules/non_elixir_backticks.ex: -------------------------------------------------------------------------------- 1 | defmodule NonElixirBackticks do 2 | @moduledoc """ 3 | ```xml 4 | 5 | ``` 6 | """ 7 | end 8 | -------------------------------------------------------------------------------- /test/test_modules/behave.ex: -------------------------------------------------------------------------------- 1 | defmodule Behave do 2 | @doc "This is a doc for a callback, dope right?" 3 | @callback thing(String.t()) :: integer() 4 | end 5 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_iex.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Iex 4 | 5 | A task that simply instructs users to run `iex -S mix`. 6 | 7 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_cli.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.CLI 4 | 5 | ## Function main/1 6 | 7 | Runs Mix according to the command line arguments. 8 | 9 | -------------------------------------------------------------------------------- /test/test_modules/blank_line_doctest.ex: -------------------------------------------------------------------------------- 1 | defmodule BlankLineDoctest do 2 | @moduledoc """ 3 | This is the end of a doctest 4 | 5 | iex> "thing" 6 | """ 7 | end 8 | -------------------------------------------------------------------------------- /elixir_livebooks/set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Set 4 | 5 | Generic API for sets. 6 | 7 | This module is deprecated, use the `MapSet` module instead. 8 | 9 | -------------------------------------------------------------------------------- /test/test_modules/indented_code_are_elixir_cells.ex: -------------------------------------------------------------------------------- 1 | defmodule IndentedCodeAreElixirCells do 2 | @moduledoc """ 3 | 4 | "This is elixir" <> "And should be a cell" 5 | """ 6 | end 7 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_app.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.App 4 | 5 | ## Function stop/0 6 | 7 | Stops the application without sending messages to error logger. 8 | 9 | -------------------------------------------------------------------------------- /elixir_livebooks/proto.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Proto 4 | 5 | Just a normal mod doc I assume 6 | 7 | ## Function thing/1 8 | 9 | Anything special here? 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/hash_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # HashSet 4 | 5 | Tuple-based HashSet implementation. 6 | 7 | This module is deprecated. Use the `MapSet` module instead. 8 | 9 | -------------------------------------------------------------------------------- /elixir_livebooks/indented_code_are_elixir_cells.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IndentedCodeAreElixirCells 4 | 5 | 6 | ```elixir 7 | "This is elixir" <> "And should be a cell" 8 | ``` 9 | -------------------------------------------------------------------------------- /elixir_livebooks/kernel_lexical_tracker.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kernel.LexicalTracker 4 | 5 | ## Function references/1 6 | 7 | Returns all references in this lexical scope. 8 | 9 | -------------------------------------------------------------------------------- /elixir_livebooks/macro_with_doc.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # MacroWithDoc 4 | 5 | ## Macro with_a_doc/0 6 | 7 | Returns 1 probably. 8 | 9 | ```elixir 10 | 1 + 1 11 | ``` 12 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_will_recompile.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.WillRecompile 4 | 5 | ## Function run/1 6 | 7 | Annotates the current project will recompile. 8 | 9 | -------------------------------------------------------------------------------- /test/test_modules/finishing_doctest_wrong.ex: -------------------------------------------------------------------------------- 1 | defmodule FinishingDoctestWrong do 2 | @moduledoc """ 3 | iex> 1 4 | ...> 1 + 1 5 | 6 | This will fail, need an assertion. 7 | """ 8 | end 9 | -------------------------------------------------------------------------------- /elixir_livebooks/list_chars_bit_string.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # List.Chars.BitString 4 | 5 | ## Function to_charlist/1 6 | 7 | Returns the given binary `term` converted to a charlist. 8 | 9 | -------------------------------------------------------------------------------- /test/test_modules/protocols.ex: -------------------------------------------------------------------------------- 1 | defprotocol Proto do 2 | @moduledoc """ 3 | Just a normal mod doc I assume 4 | """ 5 | @doc """ 6 | Anything special here? 7 | """ 8 | def thing(one) 9 | end 10 | -------------------------------------------------------------------------------- /elixir_livebooks/implemented_proto.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ImplementedProto 4 | 5 | Just a normal mod doc I assume 6 | 7 | ## Function thing/1 8 | 9 | Anything special here? 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/kernel_typespec.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kernel.Typespec 4 | 5 | ## Function deftypespec/6 6 | 7 | Defines a typespec. 8 | 9 | Invoked by `Kernel.@/1` expansion. 10 | 11 | -------------------------------------------------------------------------------- /test/test_modules/macro_with_no_doc.ex: -------------------------------------------------------------------------------- 1 | defmodule MacroWithNoDoc do 2 | @moduledoc """ 3 | A wild doc appeared! 4 | """ 5 | defmacro no_doc() do 6 | quote do 7 | 1 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/test_modules/implemented_proto.ex: -------------------------------------------------------------------------------- 1 | defprotocol ImplementedProto do 2 | @moduledoc """ 3 | Just a normal mod doc I assume 4 | """ 5 | @doc """ 6 | Anything special here? 7 | """ 8 | def thing(one) 9 | end 10 | -------------------------------------------------------------------------------- /test/test_modules/indented_invalid_elixir.ex: -------------------------------------------------------------------------------- 1 | defmodule IndentedInvalidElixir do 2 | @moduledoc """ 3 | 4 | "This is elixir" <> "And should be a cell" 5 | 6 | 7 | "this is" invalid elixir 8 | """ 9 | end 10 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_server.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Server 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_config.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Config 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_state.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.State 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/agent_server.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Agent.Server 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_parallel.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Parallel 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_server.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.TasksServer 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /test/test_modules/fns_for_none.ex: -------------------------------------------------------------------------------- 1 | defmodule FnsForNone do 2 | def one, do: 1 3 | @doc false 4 | def two, do: three() - one() 5 | 6 | defp three, do: 3 7 | 8 | @doc "actually returns 3" && false 9 | def four, do: 3 10 | end 11 | -------------------------------------------------------------------------------- /elixir_livebooks/code_normalizer.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Code.Normalizer 4 | 5 | ## Function normalize/2 6 | 7 | Wraps literals in the quoted expression to conform to the AST format expected 8 | by the formatter. 9 | 10 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_update_checker.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.UpdateChecker 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_project_stack.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.ProjectStack 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /test/test_modules/macro_with_doc.ex: -------------------------------------------------------------------------------- 1 | defmodule MacroWithDoc do 2 | @doc """ 3 | Returns 1 probably. 4 | 5 | iex> 1 + 1 6 | 2 7 | """ 8 | defmacro with_a_doc() do 9 | quote do 10 | 1 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_registry_server.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Registry.Server 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/registry_supervisor.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Registry.Supervisor 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | -------------------------------------------------------------------------------- /elixir_livebooks/hash_dict.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # HashDict 4 | 5 | Tuple-based HashDict implementation. 6 | 7 | This module is deprecated. Use the `Map` module instead. 8 | 9 | ## Function new/0 10 | 11 | Creates a new empty dict. 12 | 13 | -------------------------------------------------------------------------------- /elixir_livebooks/implemented_proto_implementation.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # ImplementedProto.Implementation 4 | 5 | Doc for implementation. 6 | not sure you should do this but it probably works. 7 | 8 | ## Function thing/1 9 | 10 | this is a doc 11 | -------------------------------------------------------------------------------- /elixir_livebooks/calendar_utc_only_time_zone_database.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Calendar.UTCOnlyTimeZoneDatabase 4 | 5 | Built-in time zone database that works only in Etc/UTC. 6 | 7 | For all other time zones, it returns `{:error, :utc_only_time_zone_database}`. 8 | 9 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_dep_fetcher.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Dep.Fetcher 4 | 5 | ## Function all/3 6 | 7 | Fetches all dependencies. 8 | 9 | ## Function by_name/4 10 | 11 | Fetches the dependencies with the given names and their children recursively. 12 | 13 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_escript.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Escript 4 | 5 | Lists all installed escripts. 6 | 7 | Escripts are installed at `~/.mix/escripts`. Add that path to your `PATH` environment variable 8 | to be able to run installed escripts from any directory. 9 | 10 | -------------------------------------------------------------------------------- /elixir_livebooks/doctest_in_doctest.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # DoctestInDoctest 4 | 5 | This is allowed: 6 | 7 | ```elixir 8 | 1 * 1 9 | 2 10 | ``` 11 | This is: 12 | 13 | ```elixir 14 | 1 * 1 15 | 2 16 | ``` 17 | And this: 18 | 19 | ```elixir 20 | 1 * 1 21 | ``` 22 | ```elixir 23 | 2 24 | ``` 25 | -------------------------------------------------------------------------------- /elixir_livebooks/fns_for_all.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # FnsForAll 4 | 5 | ## Function one/0 6 | 7 | This is a doc 8 | 9 | ## Function two/0 10 | 11 | There are many like it, but this one is mine. 12 | 13 | ```xml 14 | 15 | ``` 16 | 17 | ```elixir 18 | "some elixir code example" 19 | ``` 20 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_dep_lock.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Dep.Lock 4 | 5 | ## Function read/0 6 | 7 | Reads the lockfile, returns a map containing 8 | each app name and its current lock information. 9 | 10 | ## Function write/1 11 | 12 | Receives a map and writes it as the latest lock. 13 | 14 | -------------------------------------------------------------------------------- /test/test_modules/fns_for_all.ex: -------------------------------------------------------------------------------- 1 | defmodule FnsForAll do 2 | @doc """ 3 | This is a doc 4 | """ 5 | def one, do: 1 6 | 7 | @doc """ 8 | There are many like it, but this one is mine. 9 | 10 | ```xml 11 | 12 | ``` 13 | 14 | "some elixir code example" 15 | """ 16 | def two, do: 2 17 | end 18 | -------------------------------------------------------------------------------- /elixir_livebooks/version_requirement.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Version.Requirement 4 | 5 | A struct that holds version requirement information. 6 | 7 | The struct fields are private and should not be accessed. 8 | 9 | See the "Requirements" section in the `Version` module 10 | for more information. 11 | 12 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_compilers_test.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Compilers.Test 4 | 5 | ## Function require_and_run/3 6 | 7 | Requires and runs test files. 8 | 9 | It expects all of the test patterns, the test files that were matched for the 10 | test patterns, the test paths, and the opts from the test task. 11 | 12 | -------------------------------------------------------------------------------- /elixir_livebooks/dict.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Dict 4 | 5 | Generic API for dictionaries. 6 | 7 | If you need a general dictionary, use the `Map` module. 8 | If you need to manipulate keyword lists, use `Keyword`. 9 | 10 | To convert maps into keywords and vice-versa, use the 11 | `new` function in the respective modules. 12 | 13 | -------------------------------------------------------------------------------- /test/test_modules/doctest_in_doctest.ex: -------------------------------------------------------------------------------- 1 | defmodule DoctestInDoctest do 2 | @moduledoc """ 3 | This is allowed: 4 | 5 | iex> 1 * 1 6 | iex> 2 7 | 2 8 | 9 | This is: 10 | 11 | iex> 1 * 1 12 | ...> 2 13 | 2 14 | 15 | And this: 16 | 17 | iex> 1 * 1 18 | 1 19 | 20 | iex> 2 21 | 2 22 | """ 23 | end 24 | -------------------------------------------------------------------------------- /test/test_modules/implementation.ex: -------------------------------------------------------------------------------- 1 | defmodule Implementation do 2 | @moduledoc """ 3 | This is the actual moduledoc 4 | """ 5 | defimpl ImplementedProto do 6 | @moduledoc """ 7 | Doc for implementation. 8 | not sure you should do this but it probably works. 9 | """ 10 | @doc "this is a doc" 11 | def thing(_), do: 1 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /elixir_livebooks/code_formatter.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Code.Formatter 4 | 5 | ## Function local_without_parens?/3 6 | 7 | Checks if a function is a local without parens. 8 | 9 | ## Function locals_without_parens/0 10 | 11 | Lists all default locals without parens. 12 | 13 | ## Function to_algebra/2 14 | 15 | Converts the quoted expression into an algebra document. 16 | 17 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_dep_umbrella.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Dep.Umbrella 4 | 5 | ## Function cached/0 6 | 7 | Gets all umbrella dependencies in the loaded format from cache (if available). 8 | 9 | ## Function loaded/0 10 | 11 | Gets all umbrella dependencies in the loaded format. 12 | 13 | ## Function unloaded/0 14 | 15 | Gets all umbrella dependencies in unloaded format. 16 | 17 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_clean.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Clean 4 | 5 | Deletes generated application files. 6 | 7 | This command deletes all build artifacts for the current project. 8 | Dependencies' sources and build files are cleaned only if the 9 | `--deps` option is given. 10 | 11 | By default this task works across all environments, unless `--only` 12 | is given. 13 | 14 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_watcher.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Watcher 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | ## Function start_link/1 12 | 13 | Starts a watcher server. 14 | 15 | This is useful when there is a need to start a handler 16 | outside of the handler supervision tree. 17 | 18 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_hex_audit.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Hex.Audit 4 | 5 | Shows all Hex dependencies that have been marked as retired. 6 | 7 | Retired packages are no longer recommended to be used by their 8 | maintainers. The task will display a message describing 9 | the reason for retirement and exit with a non-zero code 10 | if any retired dependencies are found. 11 | 12 | -------------------------------------------------------------------------------- /elixir_livebooks/type_docs.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # TypeDocs 4 | 5 | ## Function fun_time/1 6 | 7 | doc AND a spec?! 8 | 9 | ## Type other_thing 10 | 11 | This is a type 12 | ## Type final 13 | 14 | This is a type lower down the module, can it have elixir cells in it? 15 | 16 | ```elixir 17 | 1 + 1 18 | ``` 19 | This probably wont test? 20 | 21 | ```elixir 22 | "example elixir though" 23 | ``` 24 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_autocomplete.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Autocomplete 4 | 5 | ## Function expand/2 6 | 7 | The expansion logic. 8 | 9 | Some of the expansion has to be use the current shell 10 | environment, which is found via the broker. 11 | 12 | ## Function remsh/1 13 | 14 | Provides one helper function that is injected into connecting 15 | remote nodes to properly handle autocompletion. 16 | 17 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_filter.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Filter 4 | 5 | ## Function filter_elixir_domain/2 6 | 7 | Filter messages logged via `Logger` module when not logging OTP reports. 8 | 9 | ## Function process_disabled/2 10 | 11 | Filter out logs if current process opted out of log reports. 12 | 13 | ## Function silence_logger_exit/2 14 | 15 | A filter that waits until Logger exits and then removes itself. 16 | 17 | -------------------------------------------------------------------------------- /elixir_livebooks/module_types_pattern.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.Types.Pattern 4 | 5 | ## Function of_guard/4 6 | 7 | Refines the type variables in the typing context using type check guards 8 | such as `is_integer/1`. 9 | 10 | ## Function of_head/4 11 | 12 | Handles patterns and guards at once. 13 | 14 | ## Function of_pattern/3 15 | 16 | Return the type and typing context of a pattern expression or an error 17 | in case of a typing conflict. 18 | 19 | -------------------------------------------------------------------------------- /elixir_livebooks/date_range.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Date.Range 4 | 5 | ## Section 6 | 7 | Returns an inclusive range between dates. 8 | 9 | Ranges must be created with the `Date.range/2` or `Date.range/3` function. 10 | 11 | The following fields are public: 12 | 13 | * `:first` - the initial date on the range 14 | * `:last` - the last date on the range 15 | * `:step` - (since v1.12.0) the step 16 | 17 | The remaining fields are private and should not be accessed. 18 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_public_key.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.PublicKey 4 | 5 | ## Function decode!/2 6 | 7 | Decodes a public key and raises if the key is invalid. 8 | 9 | ## Function public_keys/0 10 | 11 | Returns all public keys as a list. 12 | 13 | ## Function public_keys_path/0 14 | 15 | Returns the file system path for public keys. 16 | 17 | ## Function verify/3 18 | 19 | Verifies the given binary has the proper signature using the system public keys. 20 | 21 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_archive.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Archive 4 | 5 | Lists all installed archives. 6 | 7 | Archives are typically installed at `~/.mix/archives` 8 | although the installation path can be customized by 9 | setting the `MIX_ARCHIVES` environment variable. 10 | 11 | Since archives are specific to Elixir versions, it is 12 | expected from build tools to swap the `MIX_ARCHIVES` 13 | variable to different locations based on a particular 14 | Elixir installation. 15 | 16 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_dep_converger.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Dep.Converger 4 | 5 | ## Function converge/4 6 | 7 | Converges all dependencies from the current project, 8 | including nested dependencies. 9 | 10 | There is a callback that is invoked for each dependency and 11 | must return an updated dependency in case some processing 12 | is done. 13 | 14 | See `Mix.Dep.Loader.children/1` for options. 15 | 16 | ## Function topological_sort/1 17 | 18 | Topologically sorts the given dependencies. 19 | 20 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_cli.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.CLI 4 | 5 | ## Function start/0 6 | 7 | In order to work properly, IEx needs to be set as the 8 | proper `-user` when starting the Erlang VM and we do so 9 | by pointing exactly to this function. 10 | 11 | If possible, Elixir will start a tty (smart terminal) 12 | which makes all control commands available in tty 13 | available to the developer. 14 | 15 | In case `tty` is not available (for example, Windows), 16 | a dumb terminal version is started instead. 17 | 18 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_hex.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Hex 4 | 5 | ## Function ensure_installed?/1 6 | 7 | Returns `true` if `Hex` is loaded or installed. Otherwise returns `false`. 8 | 9 | ## Function ensure_updated?/0 10 | 11 | Returns `true` if it has the required `Hex`. If an update is performed, it then exits. 12 | Otherwise returns `false` without updating anything. 13 | 14 | ## Function mirror/0 15 | 16 | Returns the URL to the Hex mirror. 17 | 18 | ## Function start/0 19 | 20 | Ensures `Hex` is started. 21 | 22 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_history.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.History 4 | 5 | ## Function append/3 6 | 7 | Appends one entry to the history. 8 | 9 | ## Function each/2 10 | 11 | Enumerates over all items in the history starting from the oldest one and 12 | applies `fun` to each one in turn. 13 | 14 | ## Function init/0 15 | 16 | Initializes IEx history state. 17 | 18 | ## Function nth/2 19 | 20 | Gets the nth item from the history. 21 | 22 | If `n` < 0, the count starts from the most recent item and goes back in time. 23 | 24 | -------------------------------------------------------------------------------- /elixir_livebooks/list_chars.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # List.Chars 4 | 5 | The `List.Chars` protocol is responsible for 6 | converting a structure to a charlist (only if applicable). 7 | 8 | The only function that must be implemented is 9 | `to_charlist/1` which does the conversion. 10 | 11 | The `to_charlist/1` function automatically imported 12 | by `Kernel` invokes this protocol. 13 | 14 | ## Function to_charlist/1 15 | 16 | Converts `term` to a charlist. 17 | 18 | ## to_charlist/1 19 | 20 | Converts `term` to a charlist. 21 | 22 | -------------------------------------------------------------------------------- /elixir_livebooks/io_stream.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IO.Stream 4 | 5 | Defines an `IO.Stream` struct returned by `IO.stream/2` and `IO.binstream/2`. 6 | 7 | The following fields are public: 8 | 9 | * `device` - the IO device 10 | * `raw` - a boolean indicating if bin functions should be used 11 | * `line_or_bytes` - if reading should read lines or a given number of bytes 12 | 13 | It is worth noting that an IO stream has side effects and every time you goover the stream you may get different results. 14 | 15 | 16 | -------------------------------------------------------------------------------- /elixir_livebooks/mod.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mod 4 | 5 | This is a livebook. 6 | 7 | ```elixir 8 | a = 1 + 1 9 | b = 2 * a 10 | 15 11 | 12 | b = 2 * a 13 | ``` 14 | 15 | ```elixir 16 | 15 17 | ``` 18 | ```elixir 19 | a = [1, 2, 4] 20 | a ++ [5] 21 | ``` 22 | ### With a bit of stuff in it.... 23 | 24 | ```elixir 25 | 1 26 | ``` 27 | ## Function dummy_function/1 28 | 29 | This is a thing, with examples. 30 | 31 | ### Examples 32 | 33 | ```elixir 34 | a = 1 + 1 35 | b = 2 * a 36 | ``` 37 | ## Function second_function/0 38 | 39 | ANOTHER ONE 40 | -------------------------------------------------------------------------------- /elixir_livebooks/doctest_spans_lines.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # DoctestSpansLines 4 | 5 | of said module: 6 | 7 | ```elixir 8 | users = [ 9 | %{name: "Ellis", birthday: ~D[1943-05-11]}, 10 | %{name: "Lovelace", birthday: ~D[1815-12-10]}, 11 | %{name: "Turing", birthday: ~D[1912-06-23]} 12 | ] 13 | 14 | Enum.min_max_by(users, & &1.birthday, Date) 15 | ``` 16 | Finally, if you don't want to raise on empty enumerables, you can pass 17 | the empty fallback: 18 | 19 | ```elixir 20 | Enum.min_max_by([], &String.length/1, fn -> nil end) 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_introspection.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Introspection 4 | 5 | ## Function b/1 6 | 7 | Prints the list of behaviour callbacks or a given callback. 8 | 9 | ## Function decompose/2 10 | 11 | Decomposes an introspection call into `{mod, fun, arity}`, 12 | `{mod, fun}` or `mod`. 13 | 14 | ## Function h/1 15 | 16 | Prints documentation. 17 | 18 | ## Function open/1 19 | 20 | Opens the given module, mfa, file/line, binary. 21 | 22 | ## Function t/1 23 | 24 | Prints the types for the given module and type documentation. 25 | 26 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_backend_supervisor.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.BackendSupervisor 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | ## Function start_link/1 12 | 13 | Starts the backend supervisor. 14 | 15 | ## Function translate_backend/1 16 | 17 | Translates the shortcut backend name into its handler. 18 | 19 | ## Function unwatch/1 20 | 21 | Removes the given `backend`. 22 | 23 | ## Function watch/1 24 | 25 | Watches the given `backend`. 26 | 27 | -------------------------------------------------------------------------------- /elixir_livebooks/module_types_of.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.Types.Of 4 | 5 | ## Function binary/4 6 | 7 | Handles binaries. 8 | 9 | In the stack, we add nodes such as <>, <<..., expr>>, etc, 10 | based on the position of the expression within the binary. 11 | 12 | ## Function closed_map/4 13 | 14 | Handles closed maps (without dynamic => dynamic). 15 | 16 | ## Function open_map/4 17 | 18 | Handles open maps (with dynamic => dynamic). 19 | 20 | ## Function remote/5 21 | 22 | Handles remote calls. 23 | 24 | ## Function struct/3 25 | 26 | Handles structs. 27 | 28 | -------------------------------------------------------------------------------- /elixir_livebooks/registry_partition.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Registry.Partition 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | ## Function key_name/2 12 | 13 | Returns the name of key partition table. 14 | 15 | ## Function pid_name/2 16 | 17 | Returns the name of pid partition table. 18 | 19 | ## Function start_link/2 20 | 21 | Starts the registry partition. 22 | 23 | The process is only responsible for monitoring, demonitoring 24 | and cleaning up when monitored processes crash. 25 | 26 | -------------------------------------------------------------------------------- /test/test_modules/type_docs.ex: -------------------------------------------------------------------------------- 1 | defmodule TypeDocs do 2 | @typedoc "This is a private type" 3 | @typep thing :: String.t() 4 | @typedoc "This is a type" 5 | @type other_thing :: String.t() 6 | 7 | @spec fun_time(String.t()) :: integer() 8 | @doc """ 9 | doc AND a spec?! 10 | """ 11 | def fun_time(_s), do: 1 12 | 13 | @typedoc """ 14 | This is a type lower down the module, can it have elixir cells in it? 15 | 16 | iex>1 + 1 17 | 2 18 | 19 | This probably wont test? 20 | 21 | "example elixir though" 22 | """ 23 | @type final :: String.t() 24 | @spec thing(final) :: integer() 25 | def thing(_), do: 2 26 | end 27 | -------------------------------------------------------------------------------- /elixir_livebooks/string_chars.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # String.Chars 4 | 5 | The `String.Chars` protocol is responsible for 6 | converting a structure to a binary (only if applicable). 7 | 8 | The only function required to be implemented is 9 | `to_string/1`, which does the conversion. 10 | 11 | The `to_string/1` function automatically imported 12 | by `Kernel` invokes this protocol. String 13 | interpolation also invokes `to_string/1` in its 14 | arguments. For example, `"foo#{bar}"` is the same 15 | as `"foo" <> to_string(bar)`. 16 | 17 | ## Function to_string/1 18 | 19 | Converts `term` to a string. 20 | 21 | ## to_string/1 22 | 23 | Converts `term` to a string. 24 | 25 | -------------------------------------------------------------------------------- /test/test_modules/mod.ex: -------------------------------------------------------------------------------- 1 | defmodule Mod do 2 | @moduledoc """ 3 | This is a livebook. 4 | 5 | a = 1 + 1 6 | b = 2 * a 7 | 15 8 | 9 | b = 2 * a 10 | 11 | iex>15 12 | 15 13 | 14 | iex> a = [1, 2, 4] 15 | ...> a ++ [5] 16 | [1,2,3,4,5] 17 | 18 | ### With a bit of stuff in it.... 19 | 20 | iex> 1 21 | 1 22 | """ 23 | 24 | @doc """ 25 | This is a thing, with examples. 26 | 27 | ### Examples 28 | 29 | iex> a = 1 + 1 30 | ...> b = 2 * a 31 | 15 32 | """ 33 | def dummy_function(1), do: :k 34 | def dummy_function(x), do: x 35 | 36 | @doc "ANOTHER ONE" 37 | def second_function(), do: 2 38 | end 39 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_remote_converger.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.RemoteConverger 4 | 5 | ## Function get/0 6 | 7 | Gets registered remote converger. 8 | 9 | ## Function register/1 10 | 11 | Registers a remote converger. 12 | 13 | ## converge/2 14 | 15 | Runs the remote converger. 16 | 17 | Return updated lock. 18 | 19 | ## deps/2 20 | 21 | Returns child dependencies the converger has for the 22 | dependency. This list should filter the loaded children. 23 | 24 | ## post_converge/0 25 | 26 | Called after all convergers have run so that the remote 27 | converger can perform cleanup. 28 | 29 | ## remote?/1 30 | 31 | Returns `true` if given dependency is handled by 32 | remote converger. 33 | 34 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_utils.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Utils 4 | 5 | ## Function scan_inspect/4 6 | 7 | Receives a format string and arguments, scans them, and then replace `~p`, 8 | `~P`, `~w` and `~W` by its inspected variants. 9 | 10 | For information about format scanning and how to consume them, 11 | check `:io_lib.scan_format/2` 12 | 13 | ## Function timestamp/2 14 | 15 | Returns a timestamp that includes milliseconds. 16 | 17 | ## Function truncate/2 18 | 19 | Truncates a `chardata` into `n` bytes. 20 | 21 | There is a chance we truncate in the middle of a grapheme 22 | cluster but we never truncate in the middle of a binary 23 | code point. For this reason, truncation is not exact. 24 | 25 | -------------------------------------------------------------------------------- /elixir_livebooks/behaviour.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Behaviour 4 | 5 | Mechanism for handling behaviours. 6 | 7 | This module is deprecated. Instead of `defcallback/1` and 8 | `defmacrocallback/1`, the `@callback` and `@macrocallback` 9 | module attributes can be used respectively. See the 10 | documentation for `Module` for more information on these 11 | attributes. 12 | 13 | Instead of `MyModule.__behaviour__(:callbacks)`, 14 | `MyModule.behaviour_info(:callbacks)` can be used. 15 | 16 | ## Macro defcallback/1 17 | 18 | Defines a function callback according to the given type specification. 19 | 20 | ## Macro defmacrocallback/1 21 | 22 | Defines a macro callback according to the given type specification. 23 | 24 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_loadconfig.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Loadconfig 4 | 5 | Loads and persists the given configuration. 6 | 7 | ```elixir 8 | mix(loadconfig(path / to / config.exs)) 9 | ``` 10 | Any configuration file loaded with `loadconfig` is treated 11 | as a compile-time configuration. 12 | 13 | Note that "config/config.exs" is always loaded automatically 14 | by the Mix CLI when it boots. "config/runtime.exs" is loaded 15 | automatically by `mix app.config` before starting the current 16 | application. Therefore there is no need to load those config 17 | files directly. 18 | 19 | This task is automatically reenabled, so it can be called 20 | multiple times to load different configs. 21 | 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | livebook_helpers-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | -------------------------------------------------------------------------------- /test/test_modules/doctest_spans_lines.ex: -------------------------------------------------------------------------------- 1 | defmodule DoctestSpansLines do 2 | @moduledoc """ 3 | of said module: 4 | 5 | iex> users = [ 6 | ...> %{name: "Ellis", birthday: ~D[1943-05-11]}, 7 | ...> %{name: "Lovelace", birthday: ~D[1815-12-10]}, 8 | ...> %{name: "Turing", birthday: ~D[1912-06-23]} 9 | ...> ] 10 | iex> Enum.min_max_by(users, &(&1.birthday), Date) 11 | { 12 | %{name: "Lovelace", birthday: ~D[1815-12-10]}, 13 | %{name: "Ellis", birthday: ~D[1943-05-11]} 14 | } 15 | 16 | Finally, if you don't want to raise on empty enumerables, you can pass 17 | the empty fallback: 18 | 19 | iex> Enum.min_max_by([], &String.length/1, fn -> nil end) 20 | nil 21 | 22 | """ 23 | end 24 | -------------------------------------------------------------------------------- /elixir_livebooks/kernel_cli.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kernel.CLI 4 | 5 | ## Function format_error/3 6 | 7 | Shared helper for error formatting on CLI tools. 8 | 9 | ## Function main/1 10 | 11 | This is the API invoked by Elixir boot process. 12 | 13 | ## Function parse_argv/1 14 | 15 | Parses the CLI arguments. Made public for testing. 16 | 17 | ## Function process_commands/1 18 | 19 | Process CLI commands. Made public for testing. 20 | 21 | ## Function rpc_eval/1 22 | 23 | Function invoked across nodes for `--rpc-eval`. 24 | 25 | ## Function run/1 26 | 27 | Runs the given function by catching any failure 28 | and printing them to stdout. `at_exit` hooks are 29 | also invoked before exiting. 30 | 31 | This function is used by Elixir's CLI and also 32 | by escripts generated by Elixir. 33 | 34 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_broker.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Broker 4 | 5 | ## Function child_spec/1 6 | 7 | Returns a specification to start this module under a supervisor. 8 | 9 | See `Supervisor`. 10 | 11 | ## Function evaluator/1 12 | 13 | Finds the evaluator and server running inside `:user_drv`, on this node exclusively. 14 | 15 | ## Function register/1 16 | 17 | Registers an IEx server in the broker. 18 | 19 | All instances, except shell ones, are registered. 20 | 21 | ## Function respond/3 22 | 23 | Client responds to a takeover request. 24 | 25 | The broker's PID is needed to support remote shells. 26 | 27 | ## Function shell/0 28 | 29 | Finds the IEx server running inside `:user_drv`, on this node exclusively. 30 | 31 | ## Function take_over/3 32 | 33 | Client requests a takeover. 34 | 35 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_deps_clean.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Deps.Clean 4 | 5 | Deletes the given dependencies' files, including build artifacts and fetched 6 | sources. 7 | 8 | Since this is a destructive action, cleaning of dependencies 9 | only occurs when passing arguments/options: 10 | 11 | * `dep1 dep2` - the names of dependencies to be deleted separated by a space 12 | * `--unlock` - also unlocks the deleted dependencies 13 | * `--build` - deletes only compiled files (keeps source files) 14 | * `--all` - deletes all dependencies 15 | * `--unused` - deletes only unused dependencies 16 | (i.e. dependencies no longer mentioned in `mix.exs`) 17 | 18 | By default this task works across all environments,unless `--only` is given which will clean all dependencies 19 | for the chosen environment. 20 | 21 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_compilers_elixir.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Compilers.Elixir 4 | 5 | ## Function clean/2 6 | 7 | Removes compiled files for the given `manifest`. 8 | 9 | ## Function compile/7 10 | 11 | Compiles stale Elixir files. 12 | 13 | It expects a `manifest` file, the source directories, the destination 14 | directory, the cache key based on compiler configuration, external 15 | manifests, and external modules, followed by opts. 16 | 17 | The `manifest` is written down with information including dependencies 18 | between modules, which helps it recompile only the modules that 19 | have changed at runtime. 20 | 21 | ## Function protocols_and_impls/2 22 | 23 | Returns protocols and implementations for the given `manifest`. 24 | 25 | ## Function read_manifest/1 26 | 27 | Reads the manifest for external consumption. 28 | 29 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_dep_loader.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Dep.Loader 4 | 5 | ## Function children/0 6 | 7 | Gets all direct children of the current `Mix.Project` 8 | as a `Mix.Dep` struct. Umbrella project dependencies 9 | are included as children. 10 | 11 | By default, it will filter all dependencies that does not match 12 | current environment, behaviour can be overridden via options. 13 | 14 | ## Function load/2 15 | 16 | Loads the given dependency information, including its 17 | latest status and children. 18 | 19 | ## Function skip?/2 20 | 21 | Checks if a dependency must be skipped according to the environment. 22 | 23 | ## Function split_by_env_and_target/2 24 | 25 | Partitions loaded dependencies by environment. 26 | 27 | ## Function vsn_match/3 28 | 29 | Checks if a requirement from a dependency matches 30 | the given version. 31 | 32 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_local_hex.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Local.Hex 4 | 5 | Installs Hex locally. 6 | 7 | ```elixir 8 | mix(local.hex) 9 | ``` 10 | If installing a precompiled Hex does not work, you can compile and install 11 | Hex directly with this command: 12 | 13 | ```elixir 14 | mix(archive.install(github(hexpm / hex(branch(latest))))) 15 | ``` 16 | ## Command line options 17 | 18 | * `--force` - forces installation without a shell prompt; primarily 19 | intended for automation in build systems like `make` 20 | 21 | * `--if-missing` - performs installation only if Hex is not installed yet; 22 | intended to avoid repeatedly reinstalling Hex in automation when a script 23 | may be run multiple times 24 | 25 | If both options are set, the shell prompt is skipped and Hex is notre-installed if it was already installed. 26 | 27 | ## Mirrors 28 | 29 | If you want to change the [default mirror](https://repo.hex.pm) 30 | used for fetching Hex, set the `HEX_MIRROR` environment variable. 31 | 32 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_rebar.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Rebar 4 | 5 | ## Function apply_overrides/3 6 | 7 | Applies the given overrides for app config. 8 | 9 | ## Function dependency_config/1 10 | 11 | Updates Rebar configuration to be more suitable for dependencies. 12 | 13 | ## Function deps/1 14 | 15 | Parses the dependencies in given `rebar.config` to Mix's dependency format. 16 | 17 | ## Function global_rebar_cmd/1 18 | 19 | Returns the path to the global copy of `rebar`, defined by the 20 | environment variables `MIX_REBAR` or `MIX_REBAR3`. 21 | 22 | ## Function load_config/1 23 | 24 | Loads `rebar.config` and evaluates `rebar.config.script` if it 25 | exists in the given directory. 26 | 27 | ## Function local_rebar_cmd/1 28 | 29 | Returns the path to the local copy of `rebar`, if one exists. 30 | 31 | ## Function local_rebar_path/1 32 | 33 | Returns the path supposed to host the local copy of `rebar`. 34 | 35 | ## Function rebar_cmd/1 36 | 37 | Returns the path to the available `rebar` command. 38 | 39 | ## Function serialize_config/1 40 | 41 | Serializes a Rebar config to a term file. 42 | 43 | -------------------------------------------------------------------------------- /elixir_livebooks/module_locals_tracker.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.LocalsTracker 4 | 5 | ## Function add_defaults/5 6 | 7 | Adds and tracks defaults for a definition into the tracker. 8 | 9 | ## Function add_import/4 10 | 11 | Adds an import dispatch to the given target. 12 | 13 | ## Function add_local/5 14 | 15 | Adds a local dispatch from-to the given target. 16 | 17 | ## Function collect_imports_conflicts/2 18 | 19 | Collect all conflicting imports with the given functions 20 | 21 | ## Function collect_undefined_locals/2 22 | 23 | Collect undefined functions based on local calls and existing definitions. 24 | 25 | ## Function collect_unused_locals/3 26 | 27 | Collect all unused definitions based on the private 28 | given, also accounting the expected number of default 29 | clauses a private function have. 30 | 31 | ## Function reachable_from/2 32 | 33 | Returns all local nodes reachable from `vertex`. 34 | 35 | By default, all public functions are reachable. 36 | A private function is only reachable if it has 37 | a public function that it invokes directly. 38 | 39 | ## Function reattach/6 40 | 41 | Reattach a previously yanked node. 42 | 43 | ## Function yank/2 44 | 45 | Yanks a local node. Returns its in and out vertices in a tuple. 46 | 47 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_local.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Local 4 | 5 | ## Function append_archives/0 6 | 7 | Appends archive paths to the Erlang code path. 8 | 9 | ## Function append_paths/0 10 | 11 | Appends Mix paths to the Erlang code path. 12 | 13 | ## Function archive_ebin/1 14 | 15 | Returns the ebin path of an archive. 16 | 17 | ## Function archive_name/1 18 | 19 | Returns the name of an archive given a path. 20 | 21 | ## Function archives_tasks/0 22 | 23 | Returns all tasks in local archives. 24 | 25 | ## Function check_elixir_version_in_ebin/1 26 | 27 | Checks Elixir version requirement stored in the ebin directory 28 | and print a warning if it is not satisfied. 29 | 30 | ## Function find_matching_versions_from_signed_csv!/2 31 | 32 | Fetches the given signed CSV files, verifies and returns the matching 33 | Elixir version, artifact version and artifact's checksum. 34 | 35 | Used to install both Rebar and Hex from S3. 36 | 37 | ## Function name_for/2 38 | 39 | Returns the name for an archive or an escript, based on the project config. 40 | 41 | ## Examples 42 | 43 | ```elixir 44 | Mix.Local.name_for(:archives, app: "foo", version: "0.1.0") 45 | ``` 46 | ```elixir 47 | Mix.Local.name_for(:escripts, escript: [name: "foo"]) 48 | ``` 49 | 50 | ## Function remove_archives/0 51 | 52 | Removes archive paths from Erlang code path. 53 | 54 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_cmd.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Cmd 4 | 5 | Executes the given command. 6 | 7 | Useful in umbrella applications to execute a command 8 | on each child app: 9 | 10 | ```elixir 11 | mix(cmd(pwd)) 12 | ``` 13 | You can limit which apps the cmd runs in by passing the app names 14 | before the cmd using --app: 15 | 16 | ```elixir 17 | mix(cmd -- app(app1 -- app(app2(pwd)))) 18 | ``` 19 | Aborts when a command exits with a non-zero status. 20 | 21 | This task is automatically reenabled, so it can be called multiple times 22 | with different arguments. 23 | 24 | ## Command line options 25 | 26 | * `--app` - limit running the command to the given app. This option 27 | may be given multiple times 28 | 29 | * `--cd` - (since v1.10.4) the directory to run the command in 30 | 31 | ## Zombie operating system processes 32 | Beware that the Erlang VM does not terminate child processes 33 | when it shuts down. Therefore, if you use `mix cmd` to start 34 | long running processes and then shut down the VM, it is likely 35 | that those child processes won't be terminated with the VM. 36 | 37 | A solution is to make sure the child processes listen to the 38 | standard input and terminate when standard input is closed. 39 | We discuss this topic at length in the "Zombie operating system processes" 40 | of the `Port` module documentation. 41 | 42 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_local_rebar.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Local.Rebar 4 | 5 | Fetches a copy of `rebar` or `rebar3` from the given path or URL. 6 | 7 | It defaults to safely download a Rebar copy from Hex's CDN. 8 | However, a URL can be given as an argument, usually for an existing 9 | local copy of Rebar: 10 | 11 | ```elixir 12 | mix(local.rebar(rebar(path / to / rebar))) 13 | mix(local.rebar(rebar3(path / to / rebar))) 14 | ``` 15 | If neither `rebar` or `rebar3` are specified, both versions will be fetched. 16 | 17 | The local copy is stored in your `MIX_HOME` (defaults to `~/.mix`). 18 | This version of Rebar will be used as required by `mix deps.compile`. 19 | 20 | ## Command line options 21 | 22 | * `rebar PATH` - specifies a path for `rebar` 23 | 24 | * `rebar3 PATH` - specifies a path for `rebar3` 25 | 26 | * `--sha512` - checks the Rebar script matches the given SHA-512 checksum 27 | 28 | * `--force` - forces installation without a shell prompt; primarily 29 | intended for automation in build systems like `make` 30 | 31 | * `--if-missing` - performs installation only if not installed yet; 32 | intended to avoid repeatedly reinstalling in automation when a script 33 | may be run multiple times 34 | 35 | ## Mirrors 36 | If you want to change the [default mirror](https://repo.hex.pm) 37 | to use for fetching `rebar` please set the `HEX_MIRROR` environment variable. 38 | 39 | -------------------------------------------------------------------------------- /elixir_livebooks/code_typespec.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Code.Typespec 4 | 5 | ## Function fetch_callbacks/1 6 | 7 | Returns all callbacks available from the module's BEAM code. 8 | 9 | The result is returned as a list of tuples where the first 10 | element is spec name and arity and the second is the spec. 11 | 12 | The module must have a corresponding BEAM file 13 | which can be located by the runtime system. The types will be 14 | in the Erlang Abstract Format. 15 | 16 | ## Function fetch_specs/1 17 | 18 | Returns all specs available from the module's BEAM code. 19 | 20 | The result is returned as a list of tuples where the first 21 | element is spec name and arity and the second is the spec. 22 | 23 | The module must have a corresponding BEAM file which can be 24 | located by the runtime system. The types will be in the Erlang 25 | Abstract Format. 26 | 27 | ## Function fetch_types/1 28 | 29 | Returns all types available from the module's BEAM code. 30 | 31 | The result is returned as a list of tuples where the first 32 | element is the type (`:typep`, `:type` and `:opaque`). 33 | 34 | The module must have a corresponding BEAM file which can be 35 | located by the runtime system. The types will be in the Erlang 36 | Abstract Format. 37 | 38 | ## Function spec_to_quoted/2 39 | 40 | Converts a spec clause back to Elixir quoted expression. 41 | 42 | ## Function type_to_quoted/1 43 | 44 | Converts a type clause back to Elixir AST. 45 | 46 | -------------------------------------------------------------------------------- /elixir_livebooks/module_parallel_checker.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.ParallelChecker 4 | 5 | ## Function all_exports/2 6 | 7 | Returns all exported functions and macros for the given module from 8 | the cache. 9 | 10 | ## Function fetch_export/4 11 | 12 | Returns the export kind and deprecation reason for the given MFA from 13 | the cache. If the module does not exist return `{:error, :module}`, 14 | or if the function does not exist return `{:error, :function}`. 15 | 16 | ## Function get/0 17 | 18 | Gets the parallel checker data from pdict. 19 | 20 | ## Function preload_module/2 21 | 22 | Preloads a module into the cache. Call this function before any other 23 | cache lookups for the module. 24 | 25 | ## Function put/2 26 | 27 | Stores the parallel checker information. 28 | 29 | ## Function spawn/3 30 | 31 | Spawns a process that runs the parallel checker. 32 | 33 | ## Function start_link/1 34 | 35 | Initializes the parallel checker process. 36 | 37 | ## Function stop/1 38 | 39 | Stops the parallel checker process. 40 | 41 | ## Function test_cache/0 42 | 43 | Test cache. 44 | 45 | ## Function verify/1 46 | 47 | Verifies the given compilation function 48 | by starting a checker if one does not exist. 49 | See `verify/3`. 50 | 51 | ## Function verify/3 52 | 53 | Receives pairs of module maps and BEAM binaries. In parallel it verifies 54 | the modules and adds the ExCk chunk to the binaries. Returns the updated 55 | list of warnings from the verification. 56 | 57 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_translator.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Translator 4 | 5 | Default translation for Erlang log messages. 6 | 7 | Logger allows developers to rewrite log messages provided by 8 | OTP applications into a format more compatible with Elixir 9 | log messages by providing a translator. 10 | 11 | A translator is simply a tuple containing a module and a function 12 | that can be added and removed via the `Logger.add_translator/1` and 13 | `Logger.remove_translator/1` functions and is invoked for every Erlang 14 | message above the minimum log level with four arguments: 15 | 16 | * `min_level` - the current Logger level 17 | * `level` - the level of the message being translated 18 | * `kind` - if the message is a `:report` or `:format` 19 | * `message` - the message to format. If it is `:report`, it is a tuple 20 | with `{report_type, report_data}`, if it is `:format`, it is a 21 | tuple with `{format_message, format_args}`. 22 | 23 | The function must return: 24 | * `{:ok, chardata, metadata}` - if the message translation with its metadata 25 | * `{:ok, chardata}` - the translated message 26 | * `:skip` - if the message is not meant to be translated nor logged 27 | * `:none` - if there is no translation, which triggers the next translator 28 | 29 | See the function `translate/4` in this module for an example implementationand the default messages translated by Logger. 30 | 31 | ## Function translate/4 32 | 33 | Built-in translation function. 34 | 35 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_shell_io.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Shell.IO 4 | 5 | This is Mix's default shell. 6 | 7 | It simply prints messages to stdio and stderr. 8 | 9 | ## Function cmd/2 10 | 11 | Executes the given command and prints its output 12 | to stdout as it comes. 13 | 14 | ## Function error/1 15 | 16 | Prints the given ANSI error to the shell followed by a newline. 17 | 18 | ## Function info/1 19 | 20 | Prints the given ANSI message to the shell followed by a newline. 21 | 22 | ## Function print_app/0 23 | 24 | Prints the current application to the shell if it 25 | was not printed yet. 26 | 27 | ## Function prompt/1 28 | 29 | Prints a message and prompts the user for input. 30 | 31 | Input will be consumed until Enter is pressed. 32 | 33 | ## Function yes?/2 34 | 35 | Prints a message and asks the user to confirm if they 36 | want to proceed. The user must type and submit one of 37 | "y", "yes", "Y", "YES" or "Yes". 38 | 39 | The user may also press Enter; this can be configured 40 | to either accept or reject the prompt. The latter case 41 | may be useful for a potentially dangerous operation that 42 | should require explicit confirmation from the user. 43 | 44 | ## Options 45 | 46 | * `:default` - (:yes or :no) if `:yes` pressing Enter 47 | accepts the prompt; if `:no` pressing Enter rejects 48 | the prompt instead. Defaults to `:yes`. 49 | 50 | ## Examples 51 | ```elixir 52 | if Mix.shell().yes?("Are you sure?") do 53 | # do something... 54 | end 55 | ``` 56 | -------------------------------------------------------------------------------- /elixir_livebooks/ioansi_docs.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IO.ANSI.Docs 4 | 5 | ## Function default_options/0 6 | 7 | The default options used by this module. 8 | 9 | The supported keys are: 10 | 11 | * `:enabled` - toggles coloring on and off (true) 12 | * `:doc_bold` - bold text (bright) 13 | * `:doc_code` - code blocks (cyan) 14 | * `:doc_headings` - h1, h2, h3, h4, h5, h6 headings (yellow) 15 | * `:doc_metadata` - documentation metadata keys (yellow) 16 | * `:doc_quote` - leading quote character `> ` (light black) 17 | * `:doc_inline_code` - inline code (cyan) 18 | * `:doc_table_heading` - the style for table headings 19 | * `:doc_title` - top level heading (reverse, yellow) 20 | * `:doc_underline` - underlined text (underline) 21 | * `:width` - the width to format the text (80) 22 | 23 | Values for the color settings are strings withcomma-separated ANSI values. 24 | 25 | ## Function print/3 26 | 27 | Prints the documentation body `doc` according to `format`. 28 | 29 | It takes a set of `options` defined in `default_options/0`. 30 | 31 | ## Function print_headings/2 32 | 33 | Prints the head of the documentation (i.e. the function signature). 34 | 35 | See `default_options/0` for docs on the supported options. 36 | 37 | ## Function print_metadata/2 38 | 39 | Prints documentation metadata (only `delegate_to`, `deprecated`, `guard`, and `since` for now). 40 | 41 | See `default_options/0` for docs on the supported options. 42 | 43 | -------------------------------------------------------------------------------- /elixir_livebooks/atom.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Atom 4 | 5 | Atoms are constants whose values are their own name. 6 | 7 | They are often useful to enumerate over distinct values, such as: 8 | 9 | ```elixir 10 | :apple 11 | ``` 12 | ```elixir 13 | :orange 14 | ``` 15 | ```elixir 16 | :watermelon 17 | ``` 18 | Atoms are equal if their names are equal. 19 | 20 | ```elixir 21 | :apple == :apple 22 | ``` 23 | ```elixir 24 | :apple == :orange 25 | ``` 26 | Often they are used to express the state of an operation, by using 27 | values such as `:ok` and `:error`. 28 | 29 | The booleans `true` and `false` are also atoms: 30 | 31 | ```elixir 32 | true == true 33 | ``` 34 | ```elixir 35 | is_atom(false) 36 | ``` 37 | ```elixir 38 | is_boolean(false) 39 | ``` 40 | Elixir allows you to skip the leading `:` for the atoms `false`, `true`, 41 | and `nil`. 42 | 43 | Atoms must be composed of Unicode characters such as letters, numbers, 44 | underscore, and `@`. If the keyword has a character that does not 45 | belong to the category above, such as spaces, you can wrap it in 46 | quotes: 47 | 48 | ```elixir 49 | :"this is an atom with spaces" 50 | ``` 51 | 52 | ## Function to_charlist/1 53 | 54 | Converts an atom to a charlist. 55 | 56 | Inlined by the compiler. 57 | 58 | ## Examples 59 | 60 | ```elixir 61 | Atom.to_charlist(:"An atom") 62 | ``` 63 | 64 | ## Function to_string/1 65 | 66 | Converts an atom to a string. 67 | 68 | Inlined by the compiler. 69 | 70 | ## Examples 71 | 72 | ```elixir 73 | Atom.to_string(:foo) 74 | ``` 75 | 76 | -------------------------------------------------------------------------------- /elixir_livebooks/hex_mix.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Hex.Mix 4 | 5 | ## Function dep/1 6 | 7 | Normalises a dependency definition to its 3-tuple form. 8 | 9 | ## Function deps_to_requests/1 10 | 11 | Converts a list of dependencies to a requests to the resolver. Skips 12 | dependencies overriding with another SCM (but include dependencies 13 | overriding with Hex) and dependencies that are not Hex packages. 14 | 15 | ## Function flatten_deps/2 16 | 17 | Given a tree of dependencies return a flat list of all dependencies in 18 | the tree. 19 | 20 | The returned flattened list is going to contain duplicated dependencies 21 | because we want to accumulate all of the different requirements. 22 | However we must skip overridden dependencies as their requirements 23 | are no longer relevant. We also skip dependencies that are not included 24 | in the original list of dependencies as they were likely filtered out 25 | due to options like `:only`. 26 | 27 | ## Function from_lock/1 28 | 29 | Takes all Hex packages from the lock and returns them 30 | as `{name, app, version, repo}` tuples. 31 | 32 | ## Function prepare_deps/1 33 | 34 | Prepare Mix dependencies for the format the resolver expects. 35 | 36 | ## Function to_lock/1 37 | 38 | Takes a map of `{name, version}` and returns them as a 39 | lock of Hex packages. 40 | 41 | ## Function top_level/1 42 | 43 | Returns all top level dependencies. 44 | 45 | ## Function version_match?/2 46 | 47 | Returns `true` if the version and requirement match. 48 | 49 | See `Version.match?/2`. 50 | 51 | -------------------------------------------------------------------------------- /mix.exs: -------------------------------------------------------------------------------- 1 | defmodule LivebookHelpers.MixProject do 2 | use Mix.Project 3 | 4 | @version "0.0.8" 5 | @source_url "https://github.com/Adzz/livebook_helpers" 6 | def project do 7 | [ 8 | app: :livebook_helpers, 9 | version: @version, 10 | elixir: "~> 1.13", 11 | package: package(), 12 | start_permanent: Mix.env() == :prod, 13 | elixirc_paths: elixirc_paths(Mix.env()), 14 | description: description(), 15 | source_url: @source_url, 16 | aliases: aliases(), 17 | deps: deps(), 18 | docs: [ 19 | extras: ["README.md"], 20 | main: "readme" 21 | ] 22 | ] 23 | end 24 | 25 | defp package() do 26 | [licenses: ["Apache 2.0"], links: %{"GitHub" => @source_url}] 27 | end 28 | 29 | defp description() do 30 | "Helper functions related to Livebook." 31 | end 32 | 33 | defp elixirc_paths(:test) do 34 | ["lib", "test/test_modules"] 35 | end 36 | 37 | defp elixirc_paths(:dev) do 38 | ["lib", "test/test_modules"] 39 | end 40 | 41 | defp elixirc_paths(_), do: ["lib"] 42 | 43 | defp aliases() do 44 | [docs: ["docs", ©_pictures/1, &create_livebook/1]] 45 | end 46 | 47 | defp copy_pictures(_) do 48 | File.cp_r(Path.expand("./images/"), Path.expand("./doc/images/")) 49 | end 50 | 51 | defp create_livebook(_) do 52 | Mix.Task.run("create_livebook_from_module", ["LivebookHelpers", "my_livebook"]) 53 | end 54 | 55 | def application do 56 | [extra_applications: [:logger]] 57 | end 58 | 59 | defp deps do 60 | [ 61 | {:ex_doc, ">= 0.0.0", only: :docs, runtime: false} 62 | ] 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /forum_announcement.md: -------------------------------------------------------------------------------- 1 | I made a simple mix task that will create a livebook from a module's documentation. 2 | It will turn the doctests to elixir cells and will turn 4-space indented code blocks into elixir cells. 3 | It's available on mix to play around with. 4 | 5 | https://github.com/Adzz/livebook_helpers 6 | 7 | This could be useful for ensuring a single source of truth for all your documentation in a library, so rather than writing a README, then a moduledoc, then creating a livebook, you could do this: 8 | 9 | 1. Demark the moduledoc in the README and use moduledoc syntax there: 10 | 11 | ```md 12 | # My Readme 13 | 14 | This is my module doc 15 | 16 | ### Examples 17 | 18 | 1 + 1 = 2 19 | 20 | iex> 1 + 1 21 | 2 22 | 23 | 24 | 25 | ### Installation 26 | 27 | .... 28 | ``` 29 | 30 | Then in your module: 31 | 32 | ```elixir 33 | defmodule MyModule do 34 | @moduledoc File.read!(Path.expand("./README.md")) 35 | |> String.split("") 36 | |> List.first() 37 | end 38 | ``` 39 | 40 | ================================================================================================== 41 | 42 | Announcing https://github.com/Adzz/livebook_helpers 43 | 44 | This is a library that generates a livebook from a module. It turns the module and function docs into a livebook, turning any doctests and elixir snippets into elixir cells. 45 | 46 | This is really helpful for creating 47 | 48 | 49 | add it to docs alias. Link to blog when it's out. 50 | 51 | It adds the magic github command that ensures the livebook renders as markdown on github (giving nice syntax highlighting) and 52 | -------------------------------------------------------------------------------- /elixir_livebooks/bullets.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Bullets 4 | 5 | ## Function test_fun/0 6 | 7 | Chunks the `enumerable` with fine grained control when every chunk is emitted. 8 | `chunk_fun` receives the current element and the accumulator and must return: 9 | 10 | * `{:cont, chunk, acc}` to emit a chunk and continue with the accumulator 11 | line wraps are fine too. 12 | * `{:cont, acc}` to not emit any chunk and continue with the accumulator 13 | * nested bullet points are cool 14 | * `{:halt, acc}` to halt chunking over the `enumerable`. 15 | what about linew wraps AND 16 | * nested bullet points??? a mad mad 17 | wrapped nested bullet point. what a time. 18 | * guess again 19 | 20 | `after_fun` is invoked with the final accumulator when iteration isfinished (or `halt`ed) to handle any trailing elements that were returned 21 | as part of an accumulator, but were not emitted as a chunk by `chunk_fun`. 22 | It must return: 23 | 24 | * `{:cont, chunk, acc}` to emit a chunk. The chunk will be appended to the 25 | list of already emitted chunks. 26 | * `{:cont, acc}` to not emit a chunk 27 | 28 | The `acc` in `after_fun` is required in order to mirror the tuple formatfrom `chunk_fun` but it will be discarded since the traversal is complete. 29 | 30 | Returns a list of emitted chunks. 31 | 32 | ## Examples 33 | 34 | ```elixir 35 | chunk_fun = fn element, acc -> 36 | if rem(element, 2) == 0 do 37 | {:cont, Enum.reverse([element | acc]), []} 38 | else 39 | {:cont, [element | acc]} 40 | end 41 | end 42 | 43 | after_fun = fn 44 | [] -> {:cont, []} 45 | acc -> {:cont, Enum.reverse(acc), []} 46 | end 47 | 48 | Enum.chunk_while(1..10, [], chunk_fun, after_fun) 49 | ``` 50 | ```elixir 51 | Enum.chunk_while([1, 2, 3, 5, 7], [], chunk_fun, after_fun) 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_task_compiler.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Task.Compiler 4 | 5 | This module defines the behaviour for a Mix task that does compilation. 6 | 7 | A Mix compiler task can be defined by simply using `Mix.Task.Compiler` 8 | in a module whose name starts with `Mix.Tasks.Compile.` and defining 9 | the [`run/1`](`c:run/1`) function: 10 | 11 | ```elixir 12 | defmodule Mix.Tasks.Compile.MyLanguage do 13 | use Mix.Task.Compiler 14 | 15 | def run(_args) do 16 | :ok 17 | end 18 | end 19 | ``` 20 | The [`run/1`](`c:run/1`) function returns an atom indicating the status of the 21 | compilation, and optionally can also return a list of "diagnostics" 22 | such as warnings or compilation errors. Doing this enables code 23 | editors to display issues inline without having to analyze the 24 | command-line output. 25 | 26 | If the compiler uses manifest files to track stale sources, it should 27 | define `manifests/0`, and if it writes any output to disk it should 28 | also define `clean/0`. 29 | 30 | A compiler supports the same attributes for configuration and 31 | documentation as a regular Mix task. See `Mix.Task` for more information. 32 | 33 | ## Function after_compiler/2 34 | 35 | Adds a callback that runs after a given compiler. 36 | 37 | The callback is invoked after the compiler runs and 38 | it receives a tuple with current status and the list 39 | of diagnostic. It must return the updated status and 40 | diagnostics. 41 | 42 | ## clean/0 43 | 44 | Removes build artifacts and manifests. 45 | 46 | ## manifests/0 47 | 48 | Lists manifest files for the compiler. 49 | 50 | ## run/1 51 | 52 | Receives command-line arguments and performs compilation. If it 53 | produces errors, warnings, or any other diagnostic information, 54 | it should return a tuple with the status and a list of diagnostics. 55 | 56 | -------------------------------------------------------------------------------- /elixir_livebooks/module_types_helpers.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Module.Types.Helpers 4 | 5 | ## Function flat_map_ok/2 6 | 7 | Like `Enum.flat_map/2` but only continues while `fun` returns `{:ok, list}` 8 | and stops on `{:error, reason}`. 9 | 10 | ## Function flat_map_reduce_ok/3 11 | 12 | Like `Enum.flat_map_reduce/3` but only continues while `fun` returns `{:ok, list, acc}` 13 | and stops on `{:error, reason}`. 14 | 15 | ## Function get_meta/1 16 | 17 | Returns the AST metadata. 18 | 19 | ## Function guards_to_or/1 20 | 21 | Combines a list of guard expressions `when x when y when z` to an expression 22 | combined with `or`, `x or y or z`. 23 | 24 | ## Function map_ok/2 25 | 26 | Like `Enum.map/2` but only continues while `fun` returns `{:ok, elem}` 27 | and stops on `{:error, reason}`. 28 | 29 | ## Function map_reduce_ok/3 30 | 31 | Like `Enum.map_reduce/3` but only continues while `fun` returns `{:ok, elem, acc}` 32 | and stops on `{:error, reason}`. 33 | 34 | ## Function oks_or_errors/1 35 | 36 | Given a list of `[{:ok, term()} | {:error, term()}]` it returns a list of 37 | errors `{:error, [term()]}` in case of at least one error or `{:ok, [term()]}` 38 | if there are no errors. 39 | 40 | ## Function reduce_ok/3 41 | 42 | Like `Enum.reduce/3` but only continues while `fun` returns `{:ok, acc}` 43 | and stops on `{:error, reason}`. 44 | 45 | ## Function unzip_ok/1 46 | 47 | Like `Enum.unzip/1` but only continues while `fun` returns `{:ok, elem1, elem2}` 48 | and stops on `{:error, reason}`. 49 | 50 | ## Function var_name/1 51 | 52 | Returns unique identifier for the current assignment of the variable. 53 | 54 | ## Function zip_many/1 55 | 56 | Like `Enum.zip/1` but will zip multiple lists together instead of only two. 57 | 58 | ## Macro is_var/1 59 | 60 | Guard function to check if an AST node is a variable. 61 | 62 | -------------------------------------------------------------------------------- /elixir_livebooks/gen_event.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # GenEvent 4 | 5 | A event manager with event handlers behaviour. 6 | 7 | If you are interested in implementing an event manager, please read the 8 | "Alternatives" section below. If you have to implement an event handler to 9 | integrate with an existing system, such as Elixir's Logger, please use 10 | [`:gen_event`](`:gen_event`) instead. 11 | 12 | ## Alternatives 13 | 14 | There are a few suitable alternatives to replace GenEvent. Each of them can be 15 | the most beneficial based on the use case. 16 | 17 | ### Supervisor and GenServers 18 | 19 | One alternative to GenEvent is a very minimal solution consisting of using a 20 | supervisor and multiple GenServers started under it. The supervisor acts as 21 | the "event manager" and the children GenServers act as the "event handlers". 22 | This approach has some shortcomings (it provides no backpressure for example) 23 | but can still replace GenEvent for low-profile usages of it. [This blog post 24 | by José 25 | Valim](http://blog.plataformatec.com.br/2016/11/replacing-genevent-by-a-supervisor-genserver/) 26 | has more detailed information on this approach. 27 | 28 | ### GenStage 29 | 30 | If the use case where you were using GenEvent requires more complex logic, 31 | [GenStage](https://github.com/elixir-lang/gen_stage) provides a great 32 | alternative. GenStage is an external Elixir library maintained by the Elixir 33 | team; it provides a tool to implement systems that exchange events in a 34 | demand-driven way with built-in support for backpressure. See the [GenStage 35 | documentation](https://hexdocs.pm/gen_stage) for more information. 36 | 37 | ### `:gen_event` 38 | 39 | If your use case requires exactly what GenEvent provided, or you have to 40 | integrate with an existing `:gen_event`-based system, you can still use the 41 | [`:gen_event`](`:gen_event`) Erlang module. 42 | 43 | -------------------------------------------------------------------------------- /mix.lock: -------------------------------------------------------------------------------- 1 | %{ 2 | "data_schema": {:hex, :data_schema, "0.2.8", "1f17b66c5b603331fd037579752584fbc76d561b0fce1eda9e419d2eb673d2e3", [:mix], [], "hexpm", "abc37baae1c20be10425e33703d04aa217a80e853ca09310a1194e9481d213cd"}, 3 | "earmark_parser": {:hex, :earmark_parser, "1.4.19", "de0d033d5ff9fc396a24eadc2fcf2afa3d120841eb3f1004d138cbf9273210e8", [:mix], [], "hexpm", "527ab6630b5c75c3a3960b75844c314ec305c76d9899bb30f71cb85952a9dc45"}, 4 | "ex_doc": {:hex, :ex_doc, "0.28.0", "7eaf526dd8c80ae8c04d52ac8801594426ae322b52a6156cd038f30bafa8226f", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e55cdadf69a5d1f4cfd8477122ebac5e1fadd433a8c1022dafc5025e48db0131"}, 5 | "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, 6 | "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, 7 | "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, 8 | "nimble_parsec": {:hex, :nimble_parsec, "1.2.1", "264fc6864936b59fedb3ceb89998c64e9bb91945faf1eb115d349b96913cc2ef", [:mix], [], "hexpm", "23c31d0ec38c97bf9adde35bc91bc8e1181ea5202881f48a192f4aa2d2cf4d59"}, 9 | } 10 | -------------------------------------------------------------------------------- /elixir_livebooks/i_ex_pry.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # IEx.Pry 4 | 5 | The low-level API for prying sessions and setting up breakpoints. 6 | 7 | ## Function break/4 8 | 9 | Sets up a breakpoint on the given module/function/arity. 10 | 11 | ## Function break/6 12 | 13 | Sets up a breakpoint on the given module/function/args with the given `guard`. 14 | 15 | It requires an `env` to be given to make the expansion of the guards. 16 | 17 | ## Function break!/4 18 | 19 | Raising variant of `break/4`. 20 | 21 | ## Function break!/6 22 | 23 | Raising variant of `break/6`. 24 | 25 | ## Function breaks/0 26 | 27 | Returns all breakpoints. 28 | 29 | ## Function pry/2 30 | 31 | Callback for `IEx.pry/0`. 32 | 33 | You can invoke this function directly when you are not able to invoke 34 | `IEx.pry/0` as a macro. This function expects the binding (from 35 | `Kernel.binding/0`) and the environment (from `__ENV__/0`). 36 | 37 | ## Function remove_breaks/0 38 | 39 | Removes all breakpoints on all modules. 40 | 41 | This effectively loads the non-instrumented version of 42 | currently instrumented modules into memory. 43 | 44 | ## Function remove_breaks/1 45 | 46 | Removes breakpoints in the given module. 47 | 48 | This effectively loads the non-instrumented version of 49 | the module into memory. 50 | 51 | ## Function reset_break/1 52 | 53 | Resets the breaks on a given breakpoint ID. 54 | 55 | ## Function reset_break/3 56 | 57 | Resets the breaks for the given `module`, `function` and `arity`. 58 | 59 | If the `module` is not instrumented or if the given `function` 60 | does not have a breakpoint, it is a no-op and it returns 61 | `:not_found`. Otherwise it returns `:ok`. 62 | 63 | ## Function whereami/3 64 | 65 | Formats the location for `whereami/3` prying. 66 | 67 | It receives the `file`, `line` and the snippet `radius` and 68 | returns `{:ok, lines}`, where lines is a list of chardata 69 | containing each formatted line, or `:error`. 70 | 71 | The actual line is especially formatted in bold. 72 | 73 | -------------------------------------------------------------------------------- /test/test_modules/bullets.ex: -------------------------------------------------------------------------------- 1 | defmodule Bullets do 2 | @doc """ 3 | Chunks the `enumerable` with fine grained control when every chunk is emitted. 4 | `chunk_fun` receives the current element and the accumulator and must return: 5 | 6 | * `{:cont, chunk, acc}` to emit a chunk and continue with the accumulator 7 | line wraps are fine too. 8 | * `{:cont, acc}` to not emit any chunk and continue with the accumulator 9 | * nested bullet points are cool 10 | * `{:halt, acc}` to halt chunking over the `enumerable`. 11 | what about linew wraps AND 12 | * nested bullet points??? a mad mad 13 | wrapped nested bullet point. what a time. 14 | * guess again 15 | 16 | `after_fun` is invoked with the final accumulator when iteration is 17 | finished (or `halt`ed) to handle any trailing elements that were returned 18 | as part of an accumulator, but were not emitted as a chunk by `chunk_fun`. 19 | It must return: 20 | 21 | * `{:cont, chunk, acc}` to emit a chunk. The chunk will be appended to the 22 | list of already emitted chunks. 23 | * `{:cont, acc}` to not emit a chunk 24 | 25 | The `acc` in `after_fun` is required in order to mirror the tuple format 26 | from `chunk_fun` but it will be discarded since the traversal is complete. 27 | 28 | Returns a list of emitted chunks. 29 | 30 | ## Examples 31 | 32 | iex> chunk_fun = fn element, acc -> 33 | ...> if rem(element, 2) == 0 do 34 | ...> {:cont, Enum.reverse([element | acc]), []} 35 | ...> else 36 | ...> {:cont, [element | acc]} 37 | ...> end 38 | ...> end 39 | iex> after_fun = fn 40 | ...> [] -> {:cont, []} 41 | ...> acc -> {:cont, Enum.reverse(acc), []} 42 | ...> end 43 | iex> Enum.chunk_while(1..10, [], chunk_fun, after_fun) 44 | [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 45 | iex> Enum.chunk_while([1, 2, 3, 5, 7], [], chunk_fun, after_fun) 46 | [[1, 2], [3, 5, 7]] 47 | 48 | """ 49 | def test_fun, do: 1 50 | end 51 | -------------------------------------------------------------------------------- /elixir_livebooks/kernel_utils.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kernel.Utils 4 | 5 | ## Function announce_struct/1 6 | 7 | Announcing callback for defstruct. 8 | 9 | ## Function defdelegate/2 10 | 11 | Callback for defdelegate. 12 | 13 | ## Function defstruct/2 14 | 15 | Callback for defstruct. 16 | 17 | ## Function destructure/2 18 | 19 | Callback for destructure. 20 | 21 | ## Function raise/1 22 | 23 | Callback for raise. 24 | 25 | ## Macro defguard/2 26 | 27 | Callback for defguard. 28 | 29 | Rewrites an expression so it can be used both inside and outside a guard. 30 | 31 | Take, for example, the expression: 32 | 33 | ```elixir 34 | is_integer(value) and rem(value, 2) == 0 35 | ``` 36 | If we wanted to create a macro, `is_even`, from this expression, that could be 37 | used in guards, we'd have to take several things into account. 38 | 39 | First, if this expression is being used inside a guard, `value` needs to be 40 | unquoted each place it occurs, since it has not yet been at that point in our 41 | macro. 42 | 43 | Secondly, if the expression is being used outside of a guard, we want to unquote 44 | `value`, but only once, and then re-use the unquoted form throughout the expression. 45 | 46 | This helper does exactly that: takes the AST for an expression and a list of 47 | variable references it should be aware of, and rewrites it into a new expression 48 | that checks for its presence in a guard, then unquotes the variable references as 49 | appropriate. 50 | 51 | The following code 52 | 53 | ```elixir 54 | expression = quote do: is_integer(value) and rem(value, 2) == 0 55 | variable_references = [value: Elixir] 56 | Kernel.Utils.defguard(expression, variable_references) |> Macro.to_string() |> IO.puts() 57 | ``` 58 | would print a code similar to: 59 | 60 | ```elixir 61 | case Macro.Env.in_guard?(__CALLER__) do 62 | true -> 63 | quote do 64 | is_integer(unquote(value)) and rem(unquote(value), 2) == 0 65 | end 66 | 67 | false -> 68 | quote do 69 | value = unquote(value) 70 | is_integer(value) and rem(value, 2) == 0 71 | end 72 | end 73 | ``` 74 | -------------------------------------------------------------------------------- /elixir_livebooks/file_stat.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # File.Stat 4 | 5 | A struct that holds file information. 6 | 7 | In Erlang, this struct is represented by a `:file_info` record. 8 | Therefore this module also provides functions for converting 9 | between the Erlang record and the Elixir struct. 10 | 11 | Its fields are: 12 | 13 | * `size` - size of file in bytes. 14 | 15 | * `type` - `:device | :directory | :regular | :other | :symlink`; the type of the 16 | file. 17 | 18 | * `access` - `:read | :write | :read_write | :none`; the current system 19 | access to the file. 20 | 21 | * `atime` - the last time the file was read. 22 | 23 | * `mtime` - the last time the file was written. 24 | 25 | * `ctime` - the interpretation of this time field depends on the operating 26 | system. On Unix-like operating systems, it is the last time the file or the inode was changed. 27 | In Windows, it is the time of creation. 28 | 29 | * `mode` - the file permissions. 30 | 31 | * `links` - the number of links to this file. This is always 1 for file 32 | systems which have no concept of links. 33 | 34 | * `major_device` - identifies the file system where the file is located. 35 | In Windows, the number indicates a drive as follows: 0 means A:, 1 means 36 | B:, and so on. 37 | 38 | * `minor_device` - only valid for character devices on Unix-like systems. In all other 39 | cases, this field is zero. 40 | 41 | * `inode` - gives the inode number. On non-Unix-like file systems, this field 42 | will be zero. 43 | 44 | * `uid` - indicates the owner of the file. Will be zero for non-Unix-like file 45 | systems. 46 | 47 | * `gid` - indicates the group that owns the file. Will be zero for 48 | non-Unix-like file systems. 49 | 50 | The time type returned in `atime`, `mtime`, and `ctime` is dependent on thetime type set in options. `{:time, type}` where type can be `:local`, 51 | `:universal`, or `:posix`. Default is `:universal`. 52 | 53 | ## Function from_record/1 54 | 55 | Converts a `:file_info` record into a `File.Stat`. 56 | 57 | ## Function to_record/1 58 | 59 | Converts a `File.Stat` struct to a `:file_info` record. 60 | 61 | -------------------------------------------------------------------------------- /elixir_livebooks/thing.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Thing 4 | 5 | 6 | ```elixir 7 | # field {:content, "text", &cast_string/1} 8 | # ^ ^ ^ 9 | # struct field | | 10 | # path to data in the source | 11 | # casting function 12 | ``` 13 | 14 | 15 | This says in the source data there will be a field called `:text`. When creating a struct we should get the data under that field and pass it too `cast_string/1`. The result of that function will be put in the resultant struct under the key `:content`. 16 | 17 | There are 5 kinds of struct fields we could want: 18 | 19 | 1. `field` - The value will be a casted value from the source data. 20 | 2. `list_of` - The value will be a list of casted values created from the source data. 21 | 3. `has_one` - The value will be created from a nested data schema (so will be a struct) 22 | 4. `has_many` - The value will be created by casting a list of values into a data schema. 23 | (You end up with a list of structs defined by the provided schema). Similar to has_many in ecto 24 | 5. `aggregate` - The value will be a casted value formed from multiple bits of data in the source. 25 | 26 | Available options are: 27 | 28 | * `:optional?` - specifies whether or not the field in the struct should be included in 29 | the `@enforce_keys` for the struct. By default all fields are required but you can mark 30 | them as optional by setting this to `true`. This will also be checked when creating a 31 | struct with `DataSchema.to_struct/2` returning an error if the required field is null. 32 | 33 | For example: 34 | 35 | ```elixir 36 | defmodule Sandwich do 37 | require DataSchema 38 | 39 | DataSchema.data_schema(field: {:type, "the_type", &{:ok, String.upcase(&1)}, optional?: true}) 40 | end 41 | ``` 42 | To see this better let's look at a very simple example. Assume our input data looks like this: 43 | 44 | ```elixir 45 | source_data = %{ 46 | "content" => "This is a blog post", 47 | "comments" => [%{"text" => "This is a comment"}, %{"text" => "This is another comment"}], 48 | "draft" => %{"content" => "This is a draft blog post"}, 49 | "date" => "2021-11-11", 50 | "time" => "14:00:00", 51 | "metadata" => %{"rating" => 0} 52 | } 53 | ``` 54 | 55 | 56 | -------------------------------------------------------------------------------- /lib/create_livebook_from_module.ex: -------------------------------------------------------------------------------- 1 | defmodule Mix.Tasks.CreateLivebookFromModule do 2 | @moduledoc """ 3 | Takes a module and a path to a file creates a livebook from the moduledocs in the given 4 | module. The `.livemd` extension is automatically added. If any deps are provided then 5 | a section at the start will be created that will `Mix.install` all deps. 6 | 7 | This function will take a module and turn the module doc found there into a livebook. 8 | This make it really easy to create one set of information and have it be represented 9 | in different formats. For example you can write a README, use it as the moduledoc then 10 | run this function to spit out a livebook with all the same info. 11 | 12 | Below is a summary of what we do to create the Livebook: 13 | 14 | * The module is used as the title for the Livebook. 15 | * Each function's @doc is put under a section with the function's name and arity. 16 | * doctests become (formatted) elixir cells 17 | * The magic line to make github render livebooks as markdown is added. 18 | * A section is placed at the start that will call `Mix.install` with any supplied deps. 19 | 20 | ### Examples 21 | 22 | mix create_livebook_from_module LivebookHelpers "my_livebook" 23 | 24 | With deps: 25 | 26 | mix create_livebook_from_module LivebookHelpers "my_livebook" "[:livebook_helpers]" 27 | 28 | mix create_livebook_from_module LivebookHelpers "my_livebook" "[livebook_helpers: \">= 0.0.0\"]" 29 | 30 | """ 31 | use Mix.Task 32 | 33 | @shortdoc "Creates a livebook from the docs in the given module." 34 | @impl Mix.Task 35 | def run([module, file_path, deps]) do 36 | Mix.Task.run("app.start") 37 | 38 | path = 39 | LivebookHelpers.livebook_from_module( 40 | Module.safe_concat([module]), 41 | file_path, 42 | deps 43 | ) 44 | 45 | IO.puts("") 46 | IO.puts("Success!") 47 | IO.puts("Livebook created from " <> module <> " here: " <> path) 48 | end 49 | 50 | def run([module, file_path]) do 51 | Mix.Task.run("app.start") 52 | 53 | path = LivebookHelpers.livebook_from_module(Module.safe_concat([module]), file_path) 54 | IO.puts("") 55 | IO.puts("Success!") 56 | IO.puts("Livebook created from " <> module <> " here: " <> path) 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/test_modules/thing.ex: -------------------------------------------------------------------------------- 1 | defmodule Thing do 2 | @moduledoc """ 3 | 4 | ```elixir 5 | # field {:content, "text", &cast_string/1} 6 | # ^ ^ ^ 7 | # struct field | | 8 | # path to data in the source | 9 | # casting function 10 | ``` 11 | 12 | This says in the source data there will be a field called `:text`. When creating a struct we should get the data under that field and pass it too `cast_string/1`. The result of that function will be put in the resultant struct under the key `:content`. 13 | 14 | There are 5 kinds of struct fields we could want: 15 | 16 | 1. `field` - The value will be a casted value from the source data. 17 | 2. `list_of` - The value will be a list of casted values created from the source data. 18 | 3. `has_one` - The value will be created from a nested data schema (so will be a struct) 19 | 4. `has_many` - The value will be created by casting a list of values into a data schema. 20 | (You end up with a list of structs defined by the provided schema). Similar to has_many in ecto 21 | 5. `aggregate` - The value will be a casted value formed from multiple bits of data in the source. 22 | 23 | Available options are: 24 | 25 | * `:optional?` - specifies whether or not the field in the struct should be included in 26 | the `@enforce_keys` for the struct. By default all fields are required but you can mark 27 | them as optional by setting this to `true`. This will also be checked when creating a 28 | struct with `DataSchema.to_struct/2` returning an error if the required field is null. 29 | 30 | For example: 31 | 32 | defmodule Sandwich do 33 | require DataSchema 34 | 35 | DataSchema.data_schema([ 36 | field: {:type, \"the_type\", &{:ok, String.upcase(&1)}, optional?: true}, 37 | ]) 38 | end 39 | 40 | To see this better let's look at a very simple example. Assume our input data looks like this: 41 | 42 | ```elixir 43 | source_data = %{ 44 | \"content\" => \"This is a blog post\", 45 | \"comments\" => [%{\"text\" => \"This is a comment\"},%{\"text\" => \"This is another comment\"}], 46 | \"draft\" => %{\"content\" => \"This is a draft blog post\"}, 47 | \"date\" => \"2021-11-11\", 48 | \"time\" => \"14:00:00\", 49 | \"metadata\" => %{ \"rating\" => 0} 50 | } 51 | ``` 52 | """ 53 | end 54 | -------------------------------------------------------------------------------- /elixir_livebooks/livebook_helpers.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # LivebookHelpers 4 | 5 | Documentation for `LivebookHelpers`. 6 | 7 | ## Function livebook_from_module/2 8 | 9 | Takes a module and a path to a file, creates a livebook from the moduledocs in the given 10 | module. The `.livemd` extension is automatically added. Returns the file path for the 11 | created livebook. 12 | 13 | This function will take a module and turn the module doc found there into a livebook. 14 | This make it really easy to create one set of information and have it be represented 15 | in different formats. For example you can write a README, use it as the moduledoc then 16 | run this function to spit out a livebook with all the same info. 17 | 18 | Below is a summary of what we do to create the Livebook: 19 | 20 | * The module is used as the title for the Livebook. 21 | * Each function's @doc is put under a section with the function's name and arity. 22 | * doctests become (formatted) elixir cells 23 | * The magic line to make github render livebooks as markdown is added. 24 | 25 | ### Examples 26 | 27 | ```sh 28 | mix create_livebook_from_module LivebookHelpers "my_livebook" 29 | ``` 30 | 31 | ## Function livebook_from_module/3 32 | 33 | Takes a module and a path to a file, creates a livebook from the moduledocs in the given 34 | module. The `.livemd` extension is automatically added. The provided deps are put into a 35 | `Mix.install` section at the start of the livebook, so the deps should be in the format 36 | that `Mix.install` allows. 37 | 38 | This function will take a module and turn the module doc found there into a livebook. 39 | This make it really easy to create one set of information and have it be represented 40 | in different formats. For example you can write a README, use it as the moduledoc then 41 | run this function to spit out a livebook with all the same info. 42 | 43 | Below is a summary of what we do to create the Livebook: 44 | 45 | * The module is used as the title for the Livebook. 46 | * Each function's @doc is put under a section with the function's name and arity. 47 | * doctests become (formatted) elixir cells 48 | * The magic line to make github render livebooks as markdown is added. 49 | 50 | ### Examples 51 | 52 | ```sh 53 | mix create_livebook_from_module LivebookHelpers "my_livebook" "[livebook_helpers: ">= 0.0.0"]" 54 | ``` 55 | 56 | ## Function livebook_string/2 57 | 58 | Returns the text that can be used to create a livebook using the docs in the supplied 59 | module. 60 | 61 | -------------------------------------------------------------------------------- /elixir_livebooks/calendar_time_zone_database.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Calendar.TimeZoneDatabase 4 | 5 | This module defines a behaviour for providing time zone data. 6 | 7 | IANA provides time zone data that includes data about different 8 | UTC offsets and standard offsets for time zones. 9 | 10 | ## time_zone_period_from_utc_iso_days/2 11 | 12 | Time zone period for a point in time in UTC for a specific time zone. 13 | 14 | Takes a time zone name and a point in time for UTC and returns a 15 | `time_zone_period` for that point in time. 16 | 17 | ## time_zone_periods_from_wall_datetime/2 18 | 19 | Possible time zone periods for a certain time zone and wall clock date and time. 20 | 21 | When the provided `datetime` is ambiguous a tuple with `:ambiguous` and two possible 22 | periods. The periods in the list are sorted with the first element being the one that begins first. 23 | 24 | When the provided `datetime` is in a gap - for instance during the "spring forward" when going 25 | from winter time to summer time, a tuple with `:gap` and two periods with limits are returned 26 | in a nested tuple. The first nested two-tuple is the period before the gap and a naive datetime 27 | with a limit for when the period ends (wall time). The second nested two-tuple is the period 28 | just after the gap and a datetime (wall time) for when the period begins just after the gap. 29 | 30 | If there is only a single possible period for the provided `datetime`, then a tuple with `:ok` 31 | and the `time_zone_period` is returned. 32 | 33 | ## Type time_zone_period 34 | 35 | A period where a certain combination of UTC offset, standard offset and zone 36 | abbreviation is in effect. 37 | 38 | For instance one period could be the summer of 2018 in "Europe/London" where summer time / 39 | daylight saving time is in effect and lasts from spring to autumn. At autumn the `std_offset` 40 | changes along with the `zone_abbr` so a different period is needed during winter. 41 | 42 | ## Type time_zone_period_limit 43 | 44 | Limit for when a certain time zone period begins or ends. 45 | 46 | A beginning is inclusive. An ending is exclusive. Eg. if a period is from 47 | 2015-03-29 01:00:00 and until 2015-10-25 01:00:00, the period includes and 48 | begins from the beginning of 2015-03-29 01:00:00 and lasts until just before 49 | 2015-10-25 01:00:00. 50 | 51 | A beginning or end for certain periods are infinite. For instance the latest 52 | period for time zones without DST or plans to change. However for the purpose 53 | of this behaviour they are only used for gaps in wall time where the needed 54 | period limits are at a certain time. 55 | 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LivebookHelpers 2 | 3 | Some useful helpers that you can use to interact with livebook. 4 | 5 | See [this blog post](https://blog.appsignal.com/2022/05/24/livebook-for-elixir-just-what-the-docs-ordered.html) for more 6 | 7 | ## Generating Livebooks From Module Functions. 8 | 9 | The easiest way to use this is to include `LivebookHelpers` as a dev dependency: 10 | 11 | ```elixir 12 | {:livebook_helpers, "~> 0.0.6", only: :dev} 13 | ``` 14 | 15 | Now you can run the mix task as follows: 16 | 17 | ```sh 18 | mix CreateLivebookFromModule YourModule "path_to_destination_livebook" 19 | ``` 20 | 21 | You can try it out with like this: 22 | 23 | ```sh 24 | mix CreateLivebookFromModule LivebookHelpers "livebook_helpers_livebook" 25 | ``` 26 | 27 | ### Protocol Implementations 28 | 29 | When you implement a protocol a new module is created: 30 | 31 | ```elixir 32 | defmodule Thing do 33 | defimpl Enum do 34 | ... 35 | end 36 | end 37 | ``` 38 | 39 | This would create a module called `Enum.Thing`. If I were documenting all the functions in `Thing`, it would be great if it included any protocols that were implemented there also, but because a new module is created it's not trivial to do. We would have to find all protocols, then see if our module implemented any of them, then construct the module name and generate the docs for that module. I plan on trying this at some point. 40 | 41 | That means currently you will have to generate a livebook for each protocol implementation. You can find the name of the created module by doing this: 42 | 43 | ```elixir 44 | defmodule Thing do 45 | defimpl Enum do 46 | __MODULE__ |> IO.inspect(limit: :infinity, label: "protocol module name") 47 | ... 48 | end 49 | end 50 | ``` 51 | 52 | ## Installation 53 | 54 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed 55 | by adding `livebook_helpers` to your list of dependencies in `mix.exs`: 56 | 57 | ```elixir 58 | def deps do 59 | [ 60 | {:livebook_helpers, "~> 0.0.8", only: :dev} 61 | ] 62 | end 63 | ``` 64 | 65 | ### Contributing 66 | 67 | **NB** Set the `MIX_ENV` to `:docs` when publishing the package. This will ensure that modules inside `test/support` won't get their documentation published with the library (as they are included in the :dev env). 68 | 69 | ```sh 70 | MIX_ENV=docs mix hex.publish 71 | ``` 72 | 73 | You will also have to set that env if you want to run `mix docs` 74 | 75 | ```sh 76 | MIX_ENV=docs mix docs 77 | ``` 78 | 79 | 80 | Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) 81 | and published on [HexDocs](https://hexdocs.pm). Once published, the docs can 82 | be found at . 83 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_shell_process.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Shell.Process 4 | 5 | Mix shell that uses the current process mailbox for communication. 6 | 7 | This module provides a Mix shell implementation that uses 8 | the current process mailbox for communication instead of IO. 9 | 10 | As an example, when `Mix.shell().info("hello")` is called, 11 | the following message will be sent to the calling process: 12 | 13 | ```elixir 14 | {:mix_shell, :info, ["hello"]} 15 | ``` 16 | This is mainly useful in tests, allowing us to assert 17 | if given messages were received or not instead of performing 18 | checks on some captured IO. Since we need to guarantee a clean 19 | slate between tests, there is also a `flush/1` function 20 | responsible for flushing all `:mix_shell` related messages 21 | from the process inbox. 22 | 23 | ## Examples 24 | 25 | ```elixir 26 | Mix.shell().info("hello") 27 | 28 | receive do 29 | {:mix_shell, :info, [msg]} -> msg 30 | end 31 | 32 | # => "hello" 33 | 34 | send(self(), {:mix_shell_input, :prompt, "Pretty cool"}) 35 | Mix.shell().prompt?("How cool was that?!") 36 | # => "Pretty cool" 37 | ``` 38 | ## Function cmd/2 39 | 40 | Executes the given command and forwards its messages to 41 | the current process. 42 | 43 | ## Function error/1 44 | 45 | Forwards the error to the current process. 46 | 47 | ## Function flush/1 48 | 49 | Flushes all `:mix_shell` and `:mix_shell_input` messages from the current process. 50 | 51 | If a callback is given, it is invoked for each received message. 52 | 53 | ## Examples 54 | 55 | ```elixir 56 | flush(&IO.inspect/1) 57 | ``` 58 | ## Function info/1 59 | 60 | Forwards the message to the current process. 61 | 62 | ## Function print_app/0 63 | 64 | Prints the current application if it 65 | was not printed yet. 66 | 67 | ## Function prompt/1 68 | 69 | Forwards the message to the current process. 70 | 71 | It also checks the inbox for an input message matching: 72 | 73 | ```elixir 74 | {:mix_shell_input, :prompt, value} 75 | ``` 76 | If one does not exist, it will abort since there was no shell 77 | process inputs given. `value` must be a string. 78 | 79 | ## Examples 80 | 81 | The following will answer with `"Meg"` to the prompt 82 | `"What's your name?"`: 83 | 84 | ```elixir 85 | # The response is sent before calling prompt/1 so that prompt/1 can read it 86 | send(self(), {:mix_shell_input, :prompt, "Meg"}) 87 | Mix.shell().prompt("What's your name?") 88 | ``` 89 | ## Function yes?/2 90 | 91 | Forwards the message to the current process. 92 | 93 | It also checks the inbox for an input message matching: 94 | 95 | ```elixir 96 | {:mix_shell_input, :yes?, value} 97 | ``` 98 | If one does not exist, it will abort since there was no shell 99 | process inputs given. `value` must be `true` or `false`. 100 | 101 | ## Example 102 | 103 | ```elixir 104 | # Send the response to self() first so that yes?/2 will be able to read it 105 | send(self(), {:mix_shell_input, :yes?, true}) 106 | Mix.shell().yes?("Are you sure you want to continue?") 107 | ``` 108 | -------------------------------------------------------------------------------- /elixir_livebooks/inspect.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Inspect 4 | 5 | The `Inspect` protocol converts an Elixir data structure into an 6 | algebra document. 7 | 8 | This documentation refers to implementing the `Inspect` protocol 9 | for your own data structures. To learn more about using inspect, 10 | see `Kernel.inspect/2` and `IO.inspect/2`. 11 | 12 | The `inspect/2` function receives the entity to be inspected 13 | followed by the inspecting options, represented by the struct 14 | `Inspect.Opts`. Building of the algebra document is done with 15 | `Inspect.Algebra`. 16 | 17 | ## Examples 18 | 19 | Many times, inspecting a structure can be implemented in function 20 | of existing entities. For example, here is `MapSet`'s `inspect/2` 21 | implementation: 22 | 23 | ```elixir 24 | defimpl Inspect, for: MapSet do 25 | import Inspect.Algebra 26 | 27 | def inspect(map_set, opts) do 28 | concat(["#MapSet<", to_doc(MapSet.to_list(map_set), opts), ">"]) 29 | end 30 | end 31 | ``` 32 | The [`concat/1`](`Inspect.Algebra.concat/1`) function comes from 33 | `Inspect.Algebra` and it concatenates algebra documents together. 34 | In the example above it is concatenating the string `"#MapSet<"`, 35 | the document returned by `Inspect.Algebra.to_doc/2`, and the final 36 | string `">"`. We prefix the module name `#` to denote the inspect 37 | presentation is not actually valid Elixir syntax. 38 | 39 | Finally, note strings themselves are valid algebra documents that 40 | keep their formatting when pretty printed. This means your `Inspect` 41 | implementation may simply return a string, although that will devoid 42 | it of any pretty-printing. 43 | 44 | ## Error handling 45 | 46 | In case there is an error while your structure is being inspected, 47 | Elixir will raise an `ArgumentError` error and will automatically fall back 48 | to a raw representation for printing the structure. 49 | 50 | You can however access the underlying error by invoking the `Inspect` 51 | implementation directly. For example, to test `Inspect.MapSet` above, 52 | you can invoke it as: 53 | 54 | ```elixir 55 | Inspect.MapSet.inspect(MapSet.new(), %Inspect.Opts{}) 56 | ``` 57 | ## Deriving 58 | 59 | The `Inspect` protocol can be derived to hide certain fields from 60 | structs, so they don't show up in logs, inspects and similar. This 61 | is especially useful for fields containing private information. 62 | 63 | The options `:only` and `:except` can be used with `@derive` to 64 | specify which fields should and should not appear in the 65 | algebra document: 66 | 67 | ```elixir 68 | defmodule User do 69 | @derive {Inspect, only: [:id, :name]} 70 | defstruct [:id, :name, :address] 71 | end 72 | 73 | inspect(%User{id: 1, name: "Homer", address: "742 Evergreen Terrace"}) 74 | # => #User 75 | ``` 76 | ## Function inspect/2 77 | 78 | Converts `term` into an algebra document. 79 | 80 | This function shouldn't be invoked directly, unless when implementing 81 | a custom `inspect_fun` to be given to `Inspect.Opts`. Everywhere else, 82 | `Inspect.Algebra.to_doc/2` should be preferred as it handles structs 83 | and exceptions. 84 | 85 | ## inspect/2 86 | 87 | Converts `term` into an algebra document. 88 | 89 | This function shouldn't be invoked directly, unless when implementing 90 | a custom `inspect_fun` to be given to `Inspect.Opts`. Everywhere else, 91 | `Inspect.Algebra.to_doc/2` should be preferred as it handles structs 92 | and exceptions. 93 | 94 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_generator.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Generator 4 | 5 | Conveniences for working with paths and generating content. 6 | 7 | ## Function copy_file/3 8 | 9 | Copies `source` to `target`. 10 | 11 | If `target` already exists and the contents are not the same, 12 | it asks for user confirmation. 13 | 14 | ## Options 15 | 16 | * `:force` - forces copying without a shell prompt 17 | * `:quiet` - does not log command output 18 | 19 | ## Examples 20 | ```elixir 21 | Mix.Generator.copy_file("source/gitignore", ".gitignore") 22 | ``` 23 | 24 | ## Function copy_template/4 25 | 26 | Evaluates and copy templates at `source` to `target`. 27 | 28 | The template in `source` is evaluated with the given `assigns`. 29 | 30 | If `target` already exists and the contents are not the same, 31 | it asks for user confirmation. 32 | 33 | ## Options 34 | 35 | * `:force` - forces copying without a shell prompt 36 | * `:quiet` - does not log command output 37 | 38 | ## Examples 39 | ```elixir 40 | assigns = [project_path: "/Users/joe/newproject"] 41 | Mix.Generator.copy_template("source/gitignore", ".gitignore", assigns) 42 | ``` 43 | 44 | ## Function create_directory/2 45 | 46 | Creates a directory if one does not exist yet. 47 | 48 | This function does nothing if the given directory already exists; in this 49 | case, it still logs the directory creation. 50 | 51 | ## Options 52 | 53 | * `:quiet` - does not log command output 54 | 55 | ## Examples 56 | ```elixir 57 | Mix.Generator.create_directory("path/to/dir") 58 | ``` 59 | 60 | ## Function create_file/3 61 | 62 | Creates a file with the given contents. 63 | 64 | If the file already exists and the contents are not the same, 65 | it asks for user confirmation. 66 | 67 | ## Options 68 | 69 | * `:force` - forces creation without a shell prompt 70 | * `:quiet` - does not log command output 71 | 72 | ## Examples 73 | ```elixir 74 | Mix.Generator.create_file(".gitignore", "_build\ndeps\n") 75 | ``` 76 | 77 | ## Function overwrite?/1 78 | 79 | Prompts the user to overwrite the file if it exists. 80 | 81 | Returns false if the file exists and the user forbade 82 | to override it. Returns true otherwise. 83 | 84 | ## Function overwrite?/2 85 | 86 | Prompts the user to overwrite the file if it exists. 87 | 88 | The contents are compared to avoid asking the user to 89 | override if the contents did not change. Returns false 90 | if the file exists and the content is the same or the 91 | user forbade to override it. Returns true otherwise. 92 | 93 | ## Macro embed_template/2 94 | 95 | Embeds a template given by `contents` into the current module. 96 | 97 | It will define a private function with the `name` followed by 98 | `_template` that expects assigns as arguments. 99 | 100 | This function must be invoked passing a keyword list. 101 | Each key in the keyword list can be accessed in the 102 | template using the `@` macro. 103 | 104 | For more information, check `EEx.SmartEngine`. 105 | 106 | ## Examples 107 | 108 | ```elixir 109 | defmodule Mix.Tasks.MyTask do 110 | require Mix.Generator 111 | Mix.Generator.embed_template(:log, "Log: <%= @log %>") 112 | end 113 | ``` 114 | ## Macro embed_text/2 115 | 116 | Embeds a text given by `contents` into the current module. 117 | 118 | It will define a private function with the `name` followed by 119 | `_text` that expects no arguments. 120 | 121 | ## Examples 122 | 123 | ```elixir 124 | defmodule Mix.Tasks.MyTask do 125 | require Mix.Generator 126 | Mix.Generator.embed_text(:error, "There was an error!") 127 | end 128 | ``` 129 | -------------------------------------------------------------------------------- /elixir_livebooks/string_io.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # StringIO 4 | 5 | Controls an IO device process that wraps a string. 6 | 7 | A `StringIO` IO device can be passed as a "device" to 8 | most of the functions in the `IO` module. 9 | 10 | ## Examples 11 | 12 | ```elixir 13 | {:ok, pid} = StringIO.open("foo") 14 | IO.read(pid, 2) 15 | ``` 16 | 17 | ## Function child_spec/1 18 | 19 | Returns a specification to start this module under a supervisor. 20 | 21 | See `Supervisor`. 22 | 23 | ## Function close/1 24 | 25 | Stops the IO device and returns the remaining input/output 26 | buffers. 27 | 28 | ## Examples 29 | 30 | ```elixir 31 | {:ok, pid} = StringIO.open("in") 32 | IO.write(pid, "out") 33 | StringIO.close(pid) 34 | ``` 35 | 36 | ## Function contents/1 37 | 38 | Returns the current input/output buffers for the given IO 39 | device. 40 | 41 | ## Examples 42 | 43 | ```elixir 44 | {:ok, pid} = StringIO.open("in") 45 | IO.write(pid, "out") 46 | StringIO.contents(pid) 47 | ``` 48 | 49 | ## Function flush/1 50 | 51 | Flushes the output buffer and returns its current contents. 52 | 53 | ## Examples 54 | 55 | ```elixir 56 | {:ok, pid} = StringIO.open("in") 57 | IO.write(pid, "out") 58 | StringIO.flush(pid) 59 | ``` 60 | ```elixir 61 | StringIO.contents(pid) 62 | ``` 63 | 64 | ## Function open/2 65 | 66 | Creates an IO device. 67 | 68 | `string` will be the initial input of the newly created 69 | device. 70 | 71 | `options_or_function` can be a keyword list of options or 72 | a function. 73 | 74 | If options are provided, the result will be `{:ok, pid}`, returning the 75 | IO device created. The option `:capture_prompt`, when set to `true`, causes 76 | prompts (which are specified as arguments to `IO.get*` functions) to be 77 | included in the device's output. 78 | 79 | If a function is provided, the device will be created and sent to the 80 | function. When the function returns, the device will be closed. The final 81 | result will be a tuple with `:ok` and the result of the function. 82 | 83 | ## Examples 84 | 85 | ```elixir 86 | {:ok, pid} = StringIO.open("foo") 87 | IO.gets(pid, ">") 88 | ``` 89 | ```elixir 90 | StringIO.contents(pid) 91 | ``` 92 | ```elixir 93 | {:ok, pid} = StringIO.open("foo", capture_prompt: true) 94 | IO.gets(pid, ">") 95 | ``` 96 | ```elixir 97 | StringIO.contents(pid) 98 | ``` 99 | ```elixir 100 | StringIO.open("foo", fn pid -> 101 | input = IO.gets(pid, ">") 102 | IO.write(pid, "The input was #{input}") 103 | StringIO.contents(pid) 104 | end) 105 | ``` 106 | 107 | ## Function open/3 108 | 109 | Creates an IO device. 110 | 111 | `string` will be the initial input of the newly created 112 | device. 113 | 114 | The device will be created and sent to the function given. 115 | When the function returns, the device will be closed. The final 116 | result will be a tuple with `:ok` and the result of the function. 117 | 118 | ## Options 119 | 120 | * `:capture_prompt` - if set to `true`, prompts (specified as 121 | arguments to `IO.get*` functions) are captured in the output. 122 | Defaults to `false`. 123 | 124 | * `:encoding` (since v1.10.0) - encoding of the IO device. Allowed 125 | values are `:unicode` (default) and `:latin1`. 126 | 127 | ## Examples 128 | ```elixir 129 | StringIO.open("foo", [], fn pid -> 130 | input = IO.gets(pid, ">") 131 | IO.write(pid, "The input was #{input}") 132 | StringIO.contents(pid) 133 | end) 134 | ``` 135 | ```elixir 136 | StringIO.open("foo", [capture_prompt: true], fn pid -> 137 | input = IO.gets(pid, ">") 138 | IO.write(pid, "The input was #{input}") 139 | StringIO.contents(pid) 140 | end) 141 | ``` 142 | 143 | -------------------------------------------------------------------------------- /elixir_livebooks/logger_backends_console.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Logger.Backends.Console 4 | 5 | A logger backend that logs messages by printing them to the console. 6 | 7 | ## Options 8 | 9 | * `:level` - the level to be logged by this backend. 10 | Note that messages are filtered by the general 11 | `:level` configuration for the `:logger` application first. 12 | 13 | * `:format` - the format message used to print logs. 14 | Defaults to: `"\n$time $metadata[$level] $levelpad$message\n"`. 15 | It may also be a `{module, function}` tuple that is invoked 16 | with the log level, the message, the current timestamp and 17 | the metadata. 18 | 19 | * `:metadata` - the metadata to be printed by `$metadata`. 20 | Defaults to an empty list (no metadata). 21 | Setting `:metadata` to `:all` prints all metadata. See 22 | the "Metadata" section for more information. 23 | 24 | * `:colors` - a keyword list of coloring options. 25 | 26 | * `:device` - the device to log error messages to. Defaults to 27 | `:user` but can be changed to something else such as `:standard_error`. 28 | 29 | * `:max_buffer` - maximum events to buffer while waiting 30 | for a confirmation from the IO device (default: 32). 31 | Once the buffer is full, the backend will block until 32 | a confirmation is received. 33 | 34 | The supported keys in the `:colors` keyword list are: 35 | * `:enabled` - boolean value that allows for switching the 36 | coloring on and off. Defaults to: `IO.ANSI.enabled?/0` 37 | 38 | * `:debug` - color for debug messages. Defaults to: `:cyan` 39 | 40 | * `:info` - color for info and notice messages. Defaults to: `:normal` 41 | 42 | * `:warn` - color for warning messages. Defaults to: `:yellow` 43 | 44 | * `:error` - color for error and higher messages. Defaults to: `:red` 45 | 46 | See the `IO.ANSI` module for a list of colors and attributes. 47 | Here is an example of how to configure the `:console` backend in a 48 | `config/config.exs` file: 49 | 50 | ```elixir 51 | config :logger, :console, 52 | format: "\n$time $metadata[$level] $levelpad$message\n", 53 | metadata: [:user_id] 54 | ``` 55 | ## Custom formatting 56 | 57 | The console backend allows you to customize the format of your 58 | log messages with the `:format` option. 59 | 60 | You may set `:format` to either a string or a `{module, function}` 61 | tuple if you wish to provide your own format function. Here is an 62 | example of how to configure the `:console` backend in a 63 | `config/config.exs` file: 64 | 65 | ```elixir 66 | config :logger, :console, format: {MyConsoleLogger, :format} 67 | ``` 68 | And here is an example of how you can define `MyConsoleLogger.format/4` 69 | from the above configuration: 70 | 71 | ```elixir 72 | defmodule MyConsoleLogger do 73 | def format(level, message, timestamp, metadata) do 74 | # Custom formatting logic... 75 | end 76 | end 77 | ``` 78 | It is extremely important that **the formatting function does 79 | not fail**, as it will bring that particular logger instance down, 80 | causing your system to temporarily lose messages. If necessary, 81 | wrap the function in a `rescue` and log a default message instead: 82 | 83 | ```elixir 84 | defmodule MyConsoleLogger do 85 | def format(level, message, timestamp, metadata) do 86 | # Custom formatting logic... 87 | rescue 88 | _ -> "could not format: #{inspect({level, message, metadata})}" 89 | end 90 | end 91 | ``` 92 | The `{module, function}` will be invoked with four arguments: 93 | 94 | * the log level: an atom 95 | * the message: this is usually chardata, but in some cases it 96 | may contain invalid data. Since the formatting function should 97 | *never* fail, you need to prepare for the message being anything 98 | * the current timestamp: a term of type `t:Logger.Formatter.time/0` 99 | * the metadata: a keyword list 100 | 101 | You can read more about formatting in `Logger.Formatter`, especiallyif you want to support custom formatting in a custom backend. 102 | 103 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_scm.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.SCM 4 | 5 | This module provides helper functions and defines the 6 | behaviour required by any source code manager (SCM) used by Mix. 7 | 8 | ## Function append/1 9 | 10 | Appends the given SCM module to the list of available SCMs. 11 | 12 | ## Function available/0 13 | 14 | Returns all available SCMs. Each SCM is tried in order 15 | until a matching one is found. 16 | 17 | ## Function prepend/1 18 | 19 | Prepends the given SCM module to the list of available SCMs. 20 | 21 | ## accepts_options/2 22 | 23 | This behaviour function receives a keyword list of `opts` 24 | and should return an updated list in case the SCM consumes 25 | the available options. For example, when a developer specifies 26 | a dependency: 27 | 28 | ```elixir 29 | {:foo, "0.1.0", github: "foo/bar"} 30 | ``` 31 | Each registered SCM will be asked if they consume this dependency, 32 | receiving `[github: "foo/bar"]` as argument. Since this option makes 33 | sense for the Git SCM, it will return an update list of options 34 | while other SCMs would simply return `nil`. 35 | 36 | ## checked_out?/1 37 | 38 | This behaviour function returns a boolean if the 39 | dependency is available. 40 | 41 | ## checkout/1 42 | 43 | This behaviour function checks out dependencies. 44 | 45 | If the dependency is locked, a lock is received in `opts` 46 | and the repository must be check out at the lock. Otherwise, 47 | no lock is given and the repository can be checked out 48 | to the latest version. 49 | 50 | It must return the current lock. 51 | 52 | ## equal?/2 53 | 54 | Receives two options and must return `true` if they refer to the 55 | same repository. The options are guaranteed to belong to the 56 | same SCM. 57 | 58 | ## fetchable?/0 59 | 60 | Returns a boolean if the dependency can be fetched 61 | or it is meant to be previously available in the 62 | file system. 63 | 64 | Local dependencies (i.e. non-fetchable ones) are automatically 65 | recompiled every time the parent project is compiled. 66 | 67 | ## format/1 68 | 69 | Returns a string representing the SCM. This is used 70 | when printing the dependency and not for inspection, 71 | so the amount of information should be concise and 72 | easy to spot. 73 | 74 | ## format_lock/1 75 | 76 | Returns a string representing the SCM. This is used 77 | when printing the dependency and not for inspection, 78 | so the amount of information should be concise and 79 | easy to spot. 80 | 81 | If nil is returned, it means no lock information is available. 82 | 83 | ## lock_status/1 84 | 85 | This behaviour function checks the status of the lock. In 86 | particular, it checks if the revision stored in the lock 87 | is the same as the repository it is currently in. 88 | 89 | It may return: 90 | 91 | * `:mismatch` - if the lock doesn't match and we need to 92 | simply move to the latest lock 93 | 94 | * `:outdated` - the repository options are outdated in the 95 | lock and we need to trigger a full update 96 | 97 | * `:ok` - everything is fine 98 | 99 | The lock is sent via `opts[:lock]` but it may not always beavailable. In such cases, if the SCM requires a lock, it must 100 | return `:mismatch`, otherwise simply `:ok`. 101 | 102 | Note the lock may also belong to another SCM and as such, an 103 | structural check is required. A structural mismatch should always 104 | return `:outdated`. 105 | 106 | ## managers/1 107 | 108 | Returns the usable managers for the dependency. This can be used 109 | if the SCM has extra knowledge of the dependency, otherwise it 110 | should return an empty list. 111 | 112 | ## update/1 113 | 114 | This behaviour function updates dependencies. It may be 115 | called by `deps.get` or `deps.update`. 116 | 117 | In the first scenario, a lock is received in `opts` and 118 | the repository must be updated to the lock. In the second, 119 | no lock is given and the repository can be updated freely. 120 | 121 | It must return the current lock. 122 | 123 | ## Type t 124 | 125 | A module implementing the `Mix.SCM` behaviour. 126 | 127 | -------------------------------------------------------------------------------- /elixir_livebooks/collectable.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Collectable 4 | 5 | A protocol to traverse data structures. 6 | 7 | The `Enum.into/2` function uses this protocol to insert an 8 | enumerable into a collection: 9 | 10 | ```elixir 11 | Enum.into([a: 1, b: 2], %{}) 12 | ``` 13 | ## Why Collectable? 14 | 15 | The `Enumerable` protocol is useful to take values out of a collection. 16 | In order to support a wide range of values, the functions provided by 17 | the `Enumerable` protocol do not keep shape. For example, passing a 18 | map to `Enum.map/2` always returns a list. 19 | 20 | This design is intentional. `Enumerable` was designed to support infinite 21 | collections, resources and other structures with fixed shape. For example, 22 | it doesn't make sense to insert values into a `Range`, as it has a 23 | fixed shape where only the range limits and step are stored. 24 | 25 | The `Collectable` module was designed to fill the gap left by the 26 | `Enumerable` protocol. `Collectable.into/1` can be seen as the opposite of 27 | `Enumerable.reduce/3`. If the functions in `Enumerable` are about taking values out, 28 | then `Collectable.into/1` is about collecting those values into a structure. 29 | 30 | ## Examples 31 | 32 | To show how to manually use the `Collectable` protocol, let's play with a 33 | simplified implementation for `MapSet`. 34 | 35 | ```elixir 36 | {initial_acc, collector_fun} = Collectable.into(MapSet.new()) 37 | 38 | updated_acc = 39 | Enum.reduce([1, 2, 3], initial_acc, fn elem, acc -> 40 | collector_fun.(acc, {:cont, elem}) 41 | end) 42 | 43 | collector_fun.(updated_acc, :done) 44 | ``` 45 | To show how the protocol can be implemented, we can again look at the 46 | simplified implementation for `MapSet`. In this implementation "collecting" elements 47 | simply means inserting them in the set through `MapSet.put/2`. 48 | 49 | ```elixir 50 | defimpl Collectable, for: MapSet do 51 | def into(map_set) do 52 | collector_fun = fn 53 | map_set_acc, {:cont, elem} -> 54 | MapSet.put(map_set_acc, elem) 55 | 56 | map_set_acc, :done -> 57 | map_set_acc 58 | 59 | _map_set_acc, :halt -> 60 | :ok 61 | end 62 | 63 | initial_acc = map_set 64 | 65 | {initial_acc, collector_fun} 66 | end 67 | end 68 | ``` 69 | So now we can call `Enum.into/2`: 70 | 71 | ```elixir 72 | Enum.into([1, 2, 3], MapSet.new()) 73 | ``` 74 | 75 | ## Function into/1 76 | 77 | Returns an initial accumulator and a "collector" function. 78 | 79 | Receives a `collectable` which can be used as the initial accumulator that will 80 | be passed to the function. 81 | 82 | The collector function receives a term and a command and injects the term into 83 | the collectable accumulator on every `{:cont, term}` command. 84 | 85 | `:done` is passed as a command when no further values will be injected. This 86 | is useful when there's a need to close resources or normalizing values. A 87 | collectable must be returned when the command is `:done`. 88 | 89 | If injection is suddenly interrupted, `:halt` is passed and the function 90 | can return any value as it won't be used. 91 | 92 | For examples on how to use the `Collectable` protocol and `into/1` see the 93 | module documentation. 94 | 95 | ## into/1 96 | 97 | Returns an initial accumulator and a "collector" function. 98 | 99 | Receives a `collectable` which can be used as the initial accumulator that will 100 | be passed to the function. 101 | 102 | The collector function receives a term and a command and injects the term into 103 | the collectable accumulator on every `{:cont, term}` command. 104 | 105 | `:done` is passed as a command when no further values will be injected. This 106 | is useful when there's a need to close resources or normalizing values. A 107 | collectable must be returned when the command is `:done`. 108 | 109 | If injection is suddenly interrupted, `:halt` is passed and the function 110 | can return any value as it won't be used. 111 | 112 | For examples on how to use the `Collectable` protocol and `into/1` see the 113 | module documentation. 114 | 115 | -------------------------------------------------------------------------------- /elixir_livebooks/tuple.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Tuple 4 | 5 | Functions for working with tuples. 6 | 7 | Please note the following functions for tuples are found in `Kernel`: 8 | 9 | * `elem/2` - accesses a tuple by index 10 | * `put_elem/3` - inserts a value into a tuple by index 11 | * `tuple_size/1` - gets the number of elements in a tuple 12 | 13 | Tuples are intended as fixed-size containers for multiple elements.To manipulate a collection of elements, use a list instead. `Enum` 14 | functions do not work on tuples. 15 | 16 | Tuples are denoted with curly braces: 17 | 18 | ```elixir 19 | {} 20 | ``` 21 | ```elixir 22 | {1, :two, "three"} 23 | ``` 24 | A tuple may contain elements of different types, which are stored 25 | contiguously in memory. Accessing any element takes constant time, 26 | but modifying a tuple, which produces a shallow copy, takes linear time. 27 | Tuples are good for reading data while lists are better for traversals. 28 | 29 | Tuples are typically used either when a function has multiple return values 30 | or for error handling. `File.read/1` returns `{:ok, contents}` if reading 31 | the given file is successful, or else `{:error, reason}` such as when 32 | the file does not exist. 33 | 34 | The functions in this module that add and remove elements from tuples are 35 | rarely used in practice, as they typically imply tuples are being used as 36 | collections. To append to a tuple, it is preferable to extract the elements 37 | from the old tuple with pattern matching, and then create a new tuple: 38 | 39 | ```elixir 40 | tuple = {:ok, :example} 41 | 42 | # Avoid 43 | result = Tuple.insert_at(tuple, 2, %{}) 44 | 45 | # Prefer 46 | {:ok, atom} = tuple 47 | result = {:ok, atom, %{}} 48 | ``` 49 | ## Function append/2 50 | 51 | Inserts an element at the end of a tuple. 52 | 53 | Returns a new tuple with the element appended at the end, and contains 54 | the elements in `tuple` followed by `value` as the last element. 55 | 56 | Inlined by the compiler. 57 | 58 | ## Examples 59 | 60 | ```elixir 61 | tuple = {:foo, :bar} 62 | Tuple.append(tuple, :baz) 63 | ``` 64 | 65 | ## Function delete_at/2 66 | 67 | Removes an element from a tuple. 68 | 69 | Deletes the element at the given `index` from `tuple`. 70 | Raises an `ArgumentError` if `index` is negative or greater than 71 | or equal to the length of `tuple`. Index is zero-based. 72 | 73 | Inlined by the compiler. 74 | 75 | ## Examples 76 | 77 | ```elixir 78 | tuple = {:foo, :bar, :baz} 79 | Tuple.delete_at(tuple, 0) 80 | ``` 81 | 82 | ## Function duplicate/2 83 | 84 | Creates a new tuple. 85 | 86 | Creates a tuple of `size` containing the 87 | given `data` at every position. 88 | 89 | Inlined by the compiler. 90 | 91 | ## Examples 92 | 93 | ```elixir 94 | Tuple.duplicate(:hello, 3) 95 | ``` 96 | 97 | ## Function insert_at/3 98 | 99 | Inserts an element into a tuple. 100 | 101 | Inserts `value` into `tuple` at the given `index`. 102 | Raises an `ArgumentError` if `index` is negative or greater than the 103 | length of `tuple`. Index is zero-based. 104 | 105 | Inlined by the compiler. 106 | 107 | ## Examples 108 | 109 | ```elixir 110 | tuple = {:bar, :baz} 111 | Tuple.insert_at(tuple, 0, :foo) 112 | ``` 113 | ```elixir 114 | Tuple.insert_at(tuple, 2, :bong) 115 | ``` 116 | 117 | ## Function product/1 118 | 119 | Computes a product of tuple elements. 120 | 121 | ## Examples 122 | 123 | ```elixir 124 | Tuple.product({255, 255}) 125 | ``` 126 | ```elixir 127 | Tuple.product({255, 1.0}) 128 | ``` 129 | ```elixir 130 | Tuple.product({}) 131 | ``` 132 | ## Function sum/1 133 | 134 | Computes a sum of tuple elements. 135 | 136 | ## Examples 137 | 138 | ```elixir 139 | Tuple.sum({255, 255}) 140 | ``` 141 | ```elixir 142 | Tuple.sum({255, 0.0}) 143 | ``` 144 | ```elixir 145 | Tuple.sum({}) 146 | ``` 147 | ## Function to_list/1 148 | 149 | Converts a tuple to a list. 150 | 151 | Returns a new list with all the tuple elements. 152 | 153 | Inlined by the compiler. 154 | 155 | ## Examples 156 | 157 | ```elixir 158 | tuple = {:foo, :bar, :baz} 159 | Tuple.to_list(tuple) 160 | ``` 161 | 162 | -------------------------------------------------------------------------------- /elixir_livebooks/bitwise.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Bitwise 4 | 5 | ## Section 6 | 7 | A set of functions that perform calculations on bits. 8 | 9 | All bitwise functions work only on integers; otherwise an 10 | `ArithmeticError` is raised. 11 | 12 | The functions in this module come in two flavors: named or 13 | operators. For example: 14 | 15 | ```elixir 16 | use Bitwise 17 | # named 18 | bnot(1) 19 | ``` 20 | 21 | ```elixir 22 | # operator 23 | 1 &&& 1 24 | ``` 25 | 26 | If you prefer to use only operators or skip them, you can 27 | pass the following options: 28 | 29 | * `:only_operators` - includes only operators 30 | * `:skip_operators` - skips operators 31 | 32 | For example: 33 | 34 | ```elixir 35 | use Bitwise, only_operators: true 36 | 1 &&& 1 37 | ``` 38 | 39 | When invoked with no options, `use Bitwise` is equivalent 40 | to `import Bitwise`. 41 | 42 | All bitwise functions can be used in guards: 43 | 44 | ```elixir 45 | odd? = fn 46 | int when Bitwise.band(int, 1) == 1 -> true 47 | _ -> false 48 | end 49 | 50 | odd?.(1) 51 | ``` 52 | 53 | All functions in this module are inlined by the compiler. 54 | 55 | ## Function &&&/2 56 | 57 | Bitwise AND operator. 58 | 59 | Calculates the bitwise AND of its arguments. 60 | 61 | Allowed in guard tests. Inlined by the compiler. 62 | 63 | ## Examples 64 | 65 | ```elixir 66 | 9 &&& 3 67 | ``` 68 | 69 | ## Function <<>>/2 96 | 97 | Arithmetic right bitshift operator. 98 | 99 | Calculates the result of an arithmetic right bitshift. 100 | 101 | Allowed in guard tests. Inlined by the compiler. 102 | 103 | ## Examples 104 | 105 | ```elixir 106 | 1 >>> 2 107 | ``` 108 | 109 | ```elixir 110 | 1 >>> -2 111 | ``` 112 | 113 | ```elixir 114 | -1 >>> 2 115 | ``` 116 | 117 | ```elixir 118 | -1 >>> -2 119 | ``` 120 | 121 | ## Function band/2 122 | 123 | Calculates the bitwise AND of its arguments. 124 | 125 | Allowed in guard tests. Inlined by the compiler. 126 | 127 | ## Examples 128 | 129 | ```elixir 130 | band(9, 3) 131 | ``` 132 | 133 | ## Function bnot/1 134 | 135 | Calculates the bitwise NOT of the argument. 136 | 137 | Allowed in guard tests. Inlined by the compiler. 138 | 139 | ## Examples 140 | 141 | ```elixir 142 | bnot(2) 143 | ``` 144 | 145 | ```elixir 146 | bnot(2) &&& 3 147 | ``` 148 | 149 | ## Function bor/2 150 | 151 | Calculates the bitwise OR of its arguments. 152 | 153 | Allowed in guard tests. Inlined by the compiler. 154 | 155 | ## Examples 156 | 157 | ```elixir 158 | bor(9, 3) 159 | ``` 160 | 161 | ## Function bsl/2 162 | 163 | Calculates the result of an arithmetic left bitshift. 164 | 165 | Allowed in guard tests. Inlined by the compiler. 166 | 167 | ## Examples 168 | 169 | ```elixir 170 | bsl(1, 2) 171 | ``` 172 | 173 | ```elixir 174 | bsl(1, -2) 175 | ``` 176 | 177 | ```elixir 178 | bsl(-1, 2) 179 | ``` 180 | 181 | ```elixir 182 | bsl(-1, -2) 183 | ``` 184 | 185 | ## Function bsr/2 186 | 187 | Calculates the result of an arithmetic right bitshift. 188 | 189 | Allowed in guard tests. Inlined by the compiler. 190 | 191 | ## Examples 192 | 193 | ```elixir 194 | bsr(1, 2) 195 | ``` 196 | 197 | ```elixir 198 | bsr(1, -2) 199 | ``` 200 | 201 | ```elixir 202 | bsr(-1, 2) 203 | ``` 204 | 205 | ```elixir 206 | bsr(-1, -2) 207 | ``` 208 | 209 | ## Function bxor/2 210 | 211 | Calculates the bitwise XOR of its arguments. 212 | 213 | Allowed in guard tests. Inlined by the compiler. 214 | 215 | ## Examples 216 | 217 | ```elixir 218 | bxor(9, 3) 219 | ``` 220 | 221 | ## Function |||/2 222 | 223 | Bitwise OR operator. 224 | 225 | Calculates the bitwise OR of its arguments. 226 | 227 | Allowed in guard tests. Inlined by the compiler. 228 | 229 | ## Examples 230 | 231 | ```elixir 232 | 9 ||| 3 233 | ``` 234 | 235 | ## Function ~~~/1 236 | 237 | Bitwise NOT unary operator. 238 | 239 | Calculates the bitwise NOT of the argument. 240 | 241 | Allowed in guard tests. Inlined by the compiler. 242 | 243 | ## Examples 244 | 245 | ```elixir 246 | ~~~2 247 | ``` 248 | 249 | ```elixir 250 | ~~~2 &&& 3 251 | ``` 252 | -------------------------------------------------------------------------------- /elixir_livebooks/mix_tasks_compile_app.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Mix.Tasks.Compile.App 4 | 5 | Writes an .app file. 6 | 7 | An `.app` file is a file containing Erlang terms that defines 8 | your application. Mix automatically generates this file based on 9 | your `mix.exs` configuration. 10 | 11 | In order to generate the `.app` file, Mix expects your project 12 | to have both `:app` and `:version` keys. Furthermore, you can 13 | configure the generated application by defining an `application/0` 14 | function in your `mix.exs` that returns a keyword list. 15 | 16 | The most commonly used keys are: 17 | 18 | * `:extra_applications` - a list of OTP applications 19 | your application depends on which are not included in `:deps` 20 | (usually defined in `deps/0` in your `mix.exs`). For example, 21 | here you can declare a dependency on applications that ship 22 | with Erlang/OTP or Elixir, like `:crypto` or `:logger`. 23 | Optional extra applications can be declared as a tuple, such 24 | as `{:ex_unit, :optional}`. Mix guarantees all non-optional 25 | applications are started before your application starts. 26 | 27 | * `:registered` - the name of all registered processes in the 28 | application. If your application defines a local GenServer 29 | with name `MyServer`, it is recommended to add `MyServer` 30 | to this list. It is most useful in detecting conflicts 31 | between applications that register the same names. 32 | 33 | * `:env` - the default values for the application environment. 34 | The application environment is one of the most common ways 35 | to configure applications. See the `Application` module for 36 | mechanisms to read and write to the application environment. 37 | 38 | For example: 39 | ```elixir 40 | def application do 41 | [ 42 | extra_applications: [:logger, :crypto, ex_unit: :optional], 43 | env: [key: :value], 44 | registered: [MyServer] 45 | ] 46 | end 47 | ``` 48 | Other options include: 49 | 50 | * `:applications` - all applications your application depends 51 | on at runtime. By default, this list is automatically inferred 52 | from your dependencies. Mix and other tools use the application 53 | list in order to start your dependencies before starting the 54 | application itself. 55 | 56 | * `:mod` - specifies a module to invoke when the application 57 | is started. It must be in the format `{Mod, args}` where 58 | args is often an empty list. The module specified must 59 | implement the callbacks defined by the `Application` 60 | module. 61 | 62 | * `:start_phases` - specifies a list of phases and their arguments 63 | to be called after the application is started. See the "Phases" 64 | section below. 65 | 66 | * `:included_applications` - specifies a list of applications 67 | that will be included in the application. It is the responsibility of 68 | the primary application to start the supervision tree of all included 69 | applications, as only the primary application will be started. A process 70 | in an included application considers itself belonging to the 71 | primary application. 72 | 73 | * `:maxT` - specifies the maximum time the application is allowed to run, in 74 | milliseconds. Applications are stopped if `:maxT` is reached, and their 75 | top-level supervisor terminated with reason `:normal`. This threshold is 76 | technically valid in any resource file, but it is only effective for 77 | applications with a callback module. Defaults to `:infinity`. 78 | 79 | Besides the options above, `.app` files also expect other options like`:modules` and `:vsn`, but these are automatically added by Mix. 80 | 81 | ## Command line options 82 | 83 | * `--force` - forces compilation regardless of modification times 84 | * `--compile-path` - where to find `.beam` files and write the 85 | resulting `.app` file, defaults to `Mix.Project.compile_path/0` 86 | 87 | ## Phases 88 | Applications provide a start phases mechanism which will be called, 89 | in order, for the application and all included applications. If a phase 90 | is not defined for an included application, that application is skipped. 91 | 92 | Let's see an example `MyApp.application/0` function: 93 | 94 | ```elixir 95 | def application do 96 | [ 97 | start_phases: [init: [], go: [], finish: []], 98 | included_applications: [:my_included_app] 99 | ] 100 | end 101 | ``` 102 | And an example `:my_included_app` defines on its `mix.exs` the function: 103 | 104 | ```elixir 105 | def application do 106 | [ 107 | mod: {MyIncludedApp, []}, 108 | start_phases: [go: []] 109 | ] 110 | end 111 | ``` 112 | In this example, the order that the application callbacks are called in is: 113 | 114 | ```elixir 115 | Application.start(MyApp) 116 | MyApp.start(:normal, []) 117 | MyApp.start_phase(:init, :normal, []) 118 | MyApp.start_phase(:go, :normal, []) 119 | MyIncludedApp.start_phase(:go, :normal, []) 120 | MyApp.start_phase(:finish, :normal, []) 121 | ``` 122 | -------------------------------------------------------------------------------- /elixir_livebooks/range.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Range 4 | 5 | Ranges represent a sequence of zero, one or many, ascending 6 | or descending integers with a common difference called step. 7 | 8 | Ranges are always inclusive and they may have custom steps. 9 | The most common form of creating and matching on ranges is 10 | via the [`first..last`](`../2`) and [`first..last//step`](`..///3`) 11 | notations, auto-imported from `Kernel`: 12 | 13 | ```elixir 14 | Enum.to_list(1..3) 15 | ``` 16 | ```elixir 17 | Enum.to_list(1..3//2) 18 | ``` 19 | ```elixir 20 | Enum.to_list(3..1//-1) 21 | ``` 22 | Ranges may also have a single element: 23 | 24 | ```elixir 25 | Enum.to_list(1..1) 26 | ``` 27 | ```elixir 28 | Enum.to_list(1..1//2) 29 | ``` 30 | Or even no elements at all: 31 | 32 | ```elixir 33 | Enum.to_list(10..0//1) 34 | ``` 35 | ```elixir 36 | Enum.to_list(0..10//-1) 37 | ``` 38 | When defining a range without a step, the step will be 39 | defined based on the first and last position of the 40 | range, If `first >= last`, it will be an increasing range 41 | with a step of 1. Otherwise, it is a decreasing range. 42 | Note however implicitly decreasing ranges are deprecated. 43 | Therefore, if you need a decreasing range from `3` to `1`, 44 | prefer to write `3..1//-1` instead. 45 | 46 | ## Definition 47 | 48 | An increasing range `first..last//step` is a range from 49 | `first` to `last` increasing by `step` where `step` must be a positive 50 | integer and all values `v` must be `first <= v and v <= last`. Therefore, a range 51 | `10..0//1` is an empty range because there is no value `v` 52 | that is `10 <= v and v <= 0`. 53 | 54 | Similarly, a decreasing range `first..last//step` is a range 55 | from `first` to `last` decreasing by `step` where `step` must be a negative 56 | integer and values `v` must be `first >= v and v >= last`. Therefore, a range 57 | `0..10//-1` is an empty range because there is no value `v` 58 | that is `0 >= v and v >= 10`. 59 | 60 | ## Representation 61 | 62 | Internally, ranges are represented as structs: 63 | 64 | ```elixir 65 | range = 1..9//2 66 | ``` 67 | ```elixir 68 | first..last//step = range 69 | first 70 | ``` 71 | ```elixir 72 | last 73 | ``` 74 | ```elixir 75 | step 76 | ``` 77 | ```elixir 78 | range.step 79 | ``` 80 | You can access the range fields (`first`, `last`, and `step`) 81 | directly but you should not modify nor create ranges by hand. 82 | Instead use the proper operators or `new/2` and `new/3`. 83 | 84 | A range implements the `Enumerable` protocol, which means 85 | functions in the `Enum` module can be used to work with 86 | ranges: 87 | 88 | ```elixir 89 | range = 1..10 90 | ``` 91 | ```elixir 92 | Enum.reduce(range, 0, fn i, acc -> i * i + acc end) 93 | ``` 94 | ```elixir 95 | Enum.count(range) 96 | ``` 97 | ```elixir 98 | Enum.member?(range, 11) 99 | ``` 100 | ```elixir 101 | Enum.member?(range, 8) 102 | ``` 103 | Such function calls are efficient memory-wise no matter the 104 | size of the range. The implementation of the `Enumerable` 105 | protocol uses logic based solely on the endpoints and does 106 | not materialize the whole list of integers. 107 | 108 | ## Function disjoint?/2 109 | 110 | Checks if two ranges are disjoint. 111 | 112 | ## Examples 113 | 114 | ```elixir 115 | Range.disjoint?(1..5, 6..9) 116 | ``` 117 | ```elixir 118 | Range.disjoint?(5..1, 6..9) 119 | ``` 120 | ```elixir 121 | Range.disjoint?(1..5, 5..9) 122 | ``` 123 | ```elixir 124 | Range.disjoint?(1..5, 2..7) 125 | ``` 126 | Steps are also considered when computing the ranges to be disjoint: 127 | 128 | ```elixir 129 | Range.disjoint?(1..10//2, 2..10//2) 130 | ``` 131 | ```elixir 132 | # First element in common in all below is 29 133 | ``` 134 | 135 | ```elixir 136 | Range.disjoint?(2..100//3, 9..100//5) 137 | ``` 138 | ```elixir 139 | Range.disjoint?(101..2//-3, 99..9//-5) 140 | ``` 141 | ```elixir 142 | Range.disjoint?(1..100//14, 8..100//21) 143 | ``` 144 | ```elixir 145 | Range.disjoint?(57..-1//-14, 8..100//21) 146 | ``` 147 | ```elixir 148 | Range.disjoint?(1..100//14, 51..8//-21) 149 | ``` 150 | ```elixir 151 | # If 29 is out of range 152 | ``` 153 | 154 | ```elixir 155 | Range.disjoint?(1..28//14, 8..28//21) 156 | ``` 157 | ```elixir 158 | Range.disjoint?(2..28//3, 9..28//5) 159 | ``` 160 | 161 | ## Function new/2 162 | 163 | Creates a new range. 164 | 165 | If `first` is less than `last`, the range will be increasing from 166 | `first` to `last`. If `first` is equal to `last`, the range will contain 167 | one element, which is the number itself. 168 | 169 | If `first` is greater than `last`, the range will be decreasing from `first` 170 | to `last`, albeit this behaviour is deprecated. Therefore, it is advised to 171 | explicitly list the step with `new/3`. 172 | 173 | ## Examples 174 | 175 | ```elixir 176 | Range.new(-100, 100) 177 | ``` 178 | 179 | ## Function new/3 180 | 181 | Creates a new range with `step`. 182 | 183 | ## Examples 184 | 185 | ```elixir 186 | Range.new(-100, 100, 2) 187 | ``` 188 | 189 | ## Function size/1 190 | 191 | Returns the size of `range`. 192 | 193 | ## Examples 194 | 195 | ```elixir 196 | Range.size(1..10) 197 | ``` 198 | ```elixir 199 | Range.size(1..10//2) 200 | ``` 201 | ```elixir 202 | Range.size(1..10//3) 203 | ``` 204 | ```elixir 205 | Range.size(1..10//-1) 206 | ``` 207 | ```elixir 208 | Range.size(10..1) 209 | ``` 210 | ```elixir 211 | Range.size(10..1//-1) 212 | ``` 213 | ```elixir 214 | Range.size(10..1//-2) 215 | ``` 216 | ```elixir 217 | Range.size(10..1//-3) 218 | ``` 219 | ```elixir 220 | Range.size(10..1//1) 221 | ``` 222 | 223 | -------------------------------------------------------------------------------- /elixir_livebooks/function.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Function 4 | 5 | A set of functions for working with functions. 6 | 7 | Anonymous functions are typically created by using `fn`: 8 | 9 | ```elixir 10 | add = fn a, b -> a + b end 11 | add.(1, 2) 12 | ``` 13 | Anonymous functions can also have multiple clauses. All clauses 14 | should expect the same number of arguments: 15 | 16 | ```elixir 17 | negate = fn 18 | true -> false 19 | false -> true 20 | end 21 | 22 | negate.(false) 23 | ``` 24 | ## The capture operator 25 | 26 | It is also possible to capture public module functions and pass them 27 | around as if they were anonymous functions by using the capture 28 | operator `Kernel.SpecialForms.&/1`: 29 | 30 | ```elixir 31 | add = &Kernel.+/2 32 | add.(1, 2) 33 | ``` 34 | ```elixir 35 | length = &String.length/1 36 | length.("hello") 37 | ``` 38 | To capture a definition within the current module, you can skip the 39 | module prefix, such as `&my_fun/2`. In those cases, the captured 40 | function can be public (`def`) or private (`defp`). 41 | 42 | The capture operator can also be used to create anonymous functions 43 | that expect at least one argument: 44 | 45 | ```elixir 46 | add = &(&1 + &2) 47 | add.(1, 2) 48 | ``` 49 | In such cases, using the capture operator is no different than using `fn`. 50 | 51 | ## Internal and external functions 52 | 53 | We say that functions that point to definitions residing in modules, such 54 | as `&String.length/1`, are **external** functions. All other functions are 55 | **local** and they are always bound to the file or module that defined them. 56 | 57 | Besides the functions in this module to work with functions, `Kernel` also 58 | has an `apply/2` function that invokes a function with a dynamic number of 59 | arguments, as well as `is_function/1` and `is_function/2`, to check 60 | respectively if a given value is a function or a function of a given arity. 61 | 62 | ## Function capture/3 63 | 64 | Captures the given function. 65 | 66 | Inlined by the compiler. 67 | 68 | ## Examples 69 | 70 | ```elixir 71 | Function.capture(String, :length, 1) 72 | ``` 73 | 74 | ## Function identity/1 75 | 76 | Returns its input `value`. This function can be passed as an anonymous function 77 | to transformation functions. 78 | 79 | ## Examples 80 | 81 | ```elixir 82 | Function.identity("Hello world!") 83 | ``` 84 | ```elixir 85 | 'abcdaabccc' |> Enum.sort() |> Enum.chunk_by(&Function.identity/1) 86 | ``` 87 | ```elixir 88 | Enum.group_by('abracadabra', &Function.identity/1) 89 | ``` 90 | ```elixir 91 | Enum.map([1, 2, 3, 4], &Function.identity/1) 92 | ``` 93 | 94 | ## Function info/1 95 | 96 | Returns a keyword list with information about a function. 97 | 98 | The returned keys (with the corresponding possible values) for 99 | all types of functions (local and external) are the following: 100 | 101 | * `:type` - `:local` (for anonymous functions) or `:external` (for 102 | named functions). 103 | 104 | * `:module` - an atom which is the module where the function is defined when 105 | anonymous or the module which the function refers to when it's a named function. 106 | * `:arity` - (integer) the number of arguments the function is to be called with. 107 | 108 | * `:name` - (atom) the name of the function. 109 | 110 | * `:env` - a list of the environment or free variables. For named 111 | functions, the returned list is always empty. 112 | 113 | When `fun` is an anonymous function (that is, the type is `:local`), the followingadditional keys are returned: 114 | 115 | * `:pid` - PID of the process that originally created the function. 116 | 117 | * `:index` - (integer) an index into the module function table. 118 | 119 | * `:new_index` - (integer) an index into the module function table. 120 | 121 | * `:new_uniq` - (binary) a unique value for this function. It's 122 | calculated from the compiled code for the entire module. 123 | 124 | * `:uniq` - (integer) a unique value for this function. This integer is 125 | calculated from the compiled code for the entire module. 126 | 127 | **Note**: this function must be used only for debugging purposes. 128 | Inlined by the compiler. 129 | 130 | ## Examples 131 | 132 | ```elixir 133 | fun = fn x -> x end 134 | info = Function.info(fun) 135 | Keyword.get(info, :arity) 136 | ``` 137 | ```elixir 138 | Keyword.get(info, :type) 139 | ``` 140 | ```elixir 141 | fun = &String.length/1 142 | info = Function.info(fun) 143 | Keyword.get(info, :type) 144 | ``` 145 | ```elixir 146 | Keyword.get(info, :name) 147 | ``` 148 | 149 | ## Function info/2 150 | 151 | Returns a specific information about the function. 152 | 153 | The returned information is a two-element tuple in the shape of 154 | `{info, value}`. 155 | 156 | For any function, the information asked for can be any of the atoms 157 | `:module`, `:name`, `:arity`, `:env`, or `:type`. 158 | 159 | For anonymous functions, there is also information about any of the 160 | atoms `:index`, `:new_index`, `:new_uniq`, `:uniq`, and `:pid`. 161 | For a named function, the value of any of these items is always the 162 | atom `:undefined`. 163 | 164 | For more information on each of the possible returned values, see 165 | `info/1`. 166 | 167 | Inlined by the compiler. 168 | 169 | ## Examples 170 | 171 | ```elixir 172 | f = fn x -> x end 173 | Function.info(f, :arity) 174 | ``` 175 | ```elixir 176 | Function.info(f, :type) 177 | ``` 178 | ```elixir 179 | fun = &String.length/1 180 | Function.info(fun, :name) 181 | ``` 182 | ```elixir 183 | Function.info(fun, :pid) 184 | ``` 185 | 186 | -------------------------------------------------------------------------------- /elixir_livebooks/map_set.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # MapSet 4 | 5 | Functions that work on sets. 6 | 7 | A set is a data structure that can contain unique elements of any kind, 8 | without any particular order. `MapSet` is the "go to" set data structure in Elixir. 9 | 10 | A set can be constructed using `MapSet.new/0`: 11 | 12 | ```elixir 13 | MapSet.new() 14 | ``` 15 | Elements in a set don't have to be of the same type and they can be 16 | populated from an [enumerable](`t:Enumerable.t/0`) using `MapSet.new/1`: 17 | 18 | ```elixir 19 | MapSet.new([1, :two, {"three"}]) 20 | ``` 21 | Elements can be inserted using `MapSet.put/2`: 22 | 23 | ```elixir 24 | MapSet.new([2]) |> MapSet.put(4) |> MapSet.put(0) 25 | ``` 26 | By definition, sets can't contain duplicate elements: when 27 | inserting an element in a set where it's already present, the insertion is 28 | simply a no-op. 29 | 30 | ```elixir 31 | map_set = MapSet.new() 32 | MapSet.put(map_set, "foo") 33 | ``` 34 | ```elixir 35 | map_set |> MapSet.put("foo") |> MapSet.put("foo") 36 | ``` 37 | A `MapSet` is represented internally using the `%MapSet{}` struct. This struct 38 | can be used whenever there's a need to pattern match on something being a `MapSet`: 39 | 40 | ```elixir 41 | match?(%MapSet{}, MapSet.new()) 42 | ``` 43 | Note that, however, the struct fields are private and must not be accessed 44 | directly; use the functions in this module to perform operations on sets. 45 | 46 | `MapSet`s can also be constructed starting from other collection-type data 47 | structures: for example, see `MapSet.new/1` or `Enum.into/2`. 48 | 49 | `MapSet` is built on top of `Map`, this means that they share many properties, 50 | including logarithmic time complexity. See the documentation for `Map` for more 51 | information on its execution time complexity. 52 | 53 | ## Function delete/2 54 | 55 | Deletes `value` from `map_set`. 56 | 57 | Returns a new set which is a copy of `map_set` but without `value`. 58 | 59 | ## Examples 60 | 61 | ```elixir 62 | map_set = MapSet.new([1, 2, 3]) 63 | MapSet.delete(map_set, 4) 64 | ``` 65 | ```elixir 66 | MapSet.delete(map_set, 2) 67 | ``` 68 | 69 | ## Function difference/2 70 | 71 | Returns a set that is `map_set1` without the members of `map_set2`. 72 | 73 | ## Examples 74 | 75 | ```elixir 76 | MapSet.difference(MapSet.new([1, 2]), MapSet.new([2, 3, 4])) 77 | ``` 78 | 79 | ## Function disjoint?/2 80 | 81 | Checks if `map_set1` and `map_set2` have no members in common. 82 | 83 | ## Examples 84 | 85 | ```elixir 86 | MapSet.disjoint?(MapSet.new([1, 2]), MapSet.new([3, 4])) 87 | ``` 88 | ```elixir 89 | MapSet.disjoint?(MapSet.new([1, 2]), MapSet.new([2, 3])) 90 | ``` 91 | 92 | ## Function equal?/2 93 | 94 | Checks if two sets are equal. 95 | 96 | The comparison between elements is done using `===/2`, 97 | which a set with `1` is not equivalent to a set with 98 | `1.0`. 99 | 100 | ## Examples 101 | 102 | ```elixir 103 | MapSet.equal?(MapSet.new([1, 2]), MapSet.new([2, 1, 1])) 104 | ``` 105 | ```elixir 106 | MapSet.equal?(MapSet.new([1, 2]), MapSet.new([3, 4])) 107 | ``` 108 | ```elixir 109 | MapSet.equal?(MapSet.new([1]), MapSet.new([1.0])) 110 | ``` 111 | 112 | ## Function intersection/2 113 | 114 | Returns a set containing only members that `map_set1` and `map_set2` have in common. 115 | 116 | ## Examples 117 | 118 | ```elixir 119 | MapSet.intersection(MapSet.new([1, 2]), MapSet.new([2, 3, 4])) 120 | ``` 121 | ```elixir 122 | MapSet.intersection(MapSet.new([1, 2]), MapSet.new([3, 4])) 123 | ``` 124 | 125 | ## Function member?/2 126 | 127 | Checks if `map_set` contains `value`. 128 | 129 | ## Examples 130 | 131 | ```elixir 132 | MapSet.member?(MapSet.new([1, 2, 3]), 2) 133 | ``` 134 | ```elixir 135 | MapSet.member?(MapSet.new([1, 2, 3]), 4) 136 | ``` 137 | 138 | ## Function new/0 139 | 140 | Returns a new set. 141 | 142 | ## Examples 143 | 144 | ```elixir 145 | MapSet.new() 146 | ``` 147 | 148 | ## Function new/1 149 | 150 | Creates a set from an enumerable. 151 | 152 | ## Examples 153 | 154 | ```elixir 155 | MapSet.new([:b, :a, 3]) 156 | ``` 157 | ```elixir 158 | MapSet.new([3, 3, 3, 2, 2, 1]) 159 | ``` 160 | 161 | ## Function new/2 162 | 163 | Creates a set from an enumerable via the transformation function. 164 | 165 | ## Examples 166 | 167 | ```elixir 168 | MapSet.new([1, 2, 1], fn x -> 2 * x end) 169 | ``` 170 | 171 | ## Function put/2 172 | 173 | Inserts `value` into `map_set` if `map_set` doesn't already contain it. 174 | 175 | ## Examples 176 | 177 | ```elixir 178 | MapSet.put(MapSet.new([1, 2, 3]), 3) 179 | ``` 180 | ```elixir 181 | MapSet.put(MapSet.new([1, 2, 3]), 4) 182 | ``` 183 | 184 | ## Function size/1 185 | 186 | Returns the number of elements in `map_set`. 187 | 188 | ## Examples 189 | 190 | ```elixir 191 | MapSet.size(MapSet.new([1, 2, 3])) 192 | ``` 193 | 194 | ## Function subset?/2 195 | 196 | Checks if `map_set1`'s members are all contained in `map_set2`. 197 | 198 | This function checks if `map_set1` is a subset of `map_set2`. 199 | 200 | ## Examples 201 | 202 | ```elixir 203 | MapSet.subset?(MapSet.new([1, 2]), MapSet.new([1, 2, 3])) 204 | ``` 205 | ```elixir 206 | MapSet.subset?(MapSet.new([1, 2, 3]), MapSet.new([1, 2])) 207 | ``` 208 | 209 | ## Function to_list/1 210 | 211 | Converts `map_set` to a list. 212 | 213 | ## Examples 214 | 215 | ```elixir 216 | MapSet.to_list(MapSet.new([1, 2, 3])) 217 | ``` 218 | 219 | ## Function union/2 220 | 221 | Returns a set containing all members of `map_set1` and `map_set2`. 222 | 223 | ## Examples 224 | 225 | ```elixir 226 | MapSet.union(MapSet.new([1, 2]), MapSet.new([2, 3, 4])) 227 | ``` 228 | 229 | -------------------------------------------------------------------------------- /elixir_livebooks/exception.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Exception 4 | 5 | Functions to format throw/catch/exit and exceptions. 6 | 7 | Note that stacktraces in Elixir are only available inside 8 | catch and rescue by using the `__STACKTRACE__/0` variable. 9 | 10 | Do not rely on the particular format returned by the `format*` 11 | functions in this module. They may be changed in future releases 12 | in order to better suit Elixir's tool chain. In other words, 13 | by using the functions in this module it is guaranteed you will 14 | format exceptions as in the current Elixir version being used. 15 | 16 | ## Function blame/3 17 | 18 | Attaches information to exceptions for extra debugging. 19 | 20 | This operation is potentially expensive, as it reads data 21 | from the file system, parses beam files, evaluates code and 22 | so on. 23 | 24 | If the exception module implements the optional `c:blame/2` 25 | callback, it will be invoked to perform the computation. 26 | 27 | ## Function blame_mfa/3 28 | 29 | Blames the invocation of the given module, function and arguments. 30 | 31 | This function will retrieve the available clauses from bytecode 32 | and evaluate them against the given arguments. The clauses are 33 | returned as a list of `{args, guards}` pairs where each argument 34 | and each top-level condition in a guard separated by `and`/`or` 35 | is wrapped in a tuple with blame metadata. 36 | 37 | This function returns either `{:ok, definition, clauses}` or `:error`. 38 | Where `definition` is `:def`, `:defp`, `:defmacro` or `:defmacrop`. 39 | 40 | ## Function exception?/1 41 | 42 | Returns `true` if the given `term` is an exception. 43 | 44 | ## Function format/3 45 | 46 | Normalizes and formats throw/errors/exits and stacktraces. 47 | 48 | It relies on `format_banner/3` and `format_stacktrace/1` 49 | to generate the final format. 50 | 51 | If `kind` is `{:EXIT, pid}`, it does not generate a stacktrace, 52 | as such exits are retrieved as messages without stacktraces. 53 | 54 | ## Function format_banner/3 55 | 56 | Normalizes and formats any throw/error/exit. 57 | 58 | The message is formatted and displayed in the same 59 | format as used by Elixir's CLI. 60 | 61 | The third argument is the stacktrace which is used to enrich 62 | a normalized error with more information. It is only used when 63 | the kind is an error. 64 | 65 | ## Function format_exit/1 66 | 67 | Formats an exit. It returns a string. 68 | 69 | Often there are errors/exceptions inside exits. Exits are often 70 | wrapped by the caller and provide stacktraces too. This function 71 | formats exits in a way to nicely show the exit reason, caller 72 | and stacktrace. 73 | 74 | ## Function format_fa/2 75 | 76 | Receives an anonymous function and arity and formats it as 77 | shown in stacktraces. The arity may also be a list of arguments. 78 | 79 | ## Examples 80 | 81 | ```elixir 82 | Exception.format_fa(fn -> nil end, 1) 83 | # => "#Function<...>/1" 84 | ``` 85 | ## Function format_file_line/3 86 | 87 | Formats the given `file` and `line` as shown in stacktraces. 88 | 89 | If any of the values are `nil`, they are omitted. 90 | 91 | ## Examples 92 | 93 | ```elixir 94 | Exception.format_file_line("foo", 1) 95 | ``` 96 | ```elixir 97 | Exception.format_file_line("foo", nil) 98 | ``` 99 | ```elixir 100 | Exception.format_file_line(nil, nil) 101 | ``` 102 | 103 | ## Function format_file_line_column/4 104 | 105 | Formats the given `file`, `line`, and `column` as shown in stacktraces. 106 | 107 | If any of the values are `nil`, they are omitted. 108 | 109 | ## Examples 110 | 111 | ```elixir 112 | Exception.format_file_line_column("foo", 1, 2) 113 | ``` 114 | ```elixir 115 | Exception.format_file_line_column("foo", 1, nil) 116 | ``` 117 | ```elixir 118 | Exception.format_file_line_column("foo", nil, nil) 119 | ``` 120 | ```elixir 121 | Exception.format_file_line_column("foo", nil, 2) 122 | ``` 123 | ```elixir 124 | Exception.format_file_line_column(nil, nil, nil) 125 | ``` 126 | 127 | ## Function format_mfa/3 128 | 129 | Receives a module, fun and arity and formats it 130 | as shown in stacktraces. The arity may also be a list 131 | of arguments. 132 | 133 | ## Examples 134 | 135 | ```elixir 136 | Exception.format_mfa(Foo, :bar, 1) 137 | ``` 138 | ```elixir 139 | Exception.format_mfa(Foo, :bar, []) 140 | ``` 141 | ```elixir 142 | Exception.format_mfa(nil, :bar, []) 143 | ``` 144 | Anonymous functions are reported as -func/arity-anonfn-count-, 145 | where func is the name of the enclosing function. Convert to 146 | "anonymous fn in func/arity" 147 | 148 | ## Function format_stacktrace/1 149 | 150 | Formats the stacktrace. 151 | 152 | A stacktrace must be given as an argument. If not, the stacktrace 153 | is retrieved from `Process.info/2`. 154 | 155 | ## Function format_stacktrace_entry/1 156 | 157 | Receives a stacktrace entry and formats it into a string. 158 | 159 | ## Function message/1 160 | 161 | Gets the message for an `exception`. 162 | 163 | ## Function normalize/3 164 | 165 | Normalizes an exception, converting Erlang exceptions 166 | to Elixir exceptions. 167 | 168 | It takes the `kind` spilled by `catch` as an argument and 169 | normalizes only `:error`, returning the untouched payload 170 | for others. 171 | 172 | The third argument is the stacktrace which is used to enrich 173 | a normalized error with more information. It is only used when 174 | the kind is an error. 175 | 176 | ## blame/2 177 | 178 | Called from `Exception.blame/3` to augment the exception struct. 179 | 180 | Can be used to collect additional information about the exception 181 | or do some additional expensive computation. 182 | 183 | ## Type t 184 | 185 | The exception type 186 | ## Type kind 187 | 188 | The kind handled by formatting functions 189 | -------------------------------------------------------------------------------- /elixir_livebooks/config.livemd: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Config 4 | 5 | A simple keyword-based configuration API. 6 | 7 | ## Example 8 | 9 | This module is most commonly used to define application configuration, 10 | typically in `config/config.exs`: 11 | 12 | ```elixir 13 | import Config 14 | 15 | config :some_app, 16 | key1: "value1", 17 | key2: "value2" 18 | 19 | import_config "#{config_env()}.exs" 20 | ``` 21 | `import Config` will import the functions `config/2`, `config/3` 22 | `config_env/0`, `config_target/0`, and `import_config/1` 23 | to help you manage your configuration. 24 | 25 | `config/2` and `config/3` are used to define key-value configuration 26 | for a given application. Once Mix starts, it will automatically 27 | evaluate the configuration file and persist the configuration above 28 | into `:some_app`'s application environment, which can be accessed in 29 | as follows: 30 | 31 | ```elixir 32 | "value1" = Application.fetch_env!(:some_app, :key1) 33 | ``` 34 | Finally, the line `import_config "#{config_env()}.exs"` will import 35 | other config files based on the current configuration environment, 36 | such as `config/dev.exs` and `config/test.exs`. 37 | 38 | `Config` also provides a low-level API for evaluating and reading 39 | configuration, under the `Config.Reader` module. 40 | 41 | **Important:** if you are writing a library to be used by other developers, 42 | it is generally recommended to avoid the application environment, as the 43 | application environment is effectively a global storage. Also note that 44 | the `config/config.exs` of a library is not evaluated when the library is 45 | used as a dependency, as configuration is always meant to configure the 46 | current project. For more information, read our [library guidelines](library-guidelines.md). 47 | 48 | ## Migrating from `use Mix.Config` 49 | 50 | The `Config` module in Elixir was introduced in v1.9 as a replacement to 51 | `Mix.Config`, which was specific to Mix and has been deprecated. 52 | 53 | You can leverage `Config` instead of `Mix.Config` in three steps. The first 54 | step is to replace `use Mix.Config` at the top of your config files by 55 | `import Config`. 56 | 57 | The second is to make sure your `import_config/1` calls do not have a 58 | wildcard character. If so, you need to perform the wildcard lookup 59 | manually. For example, if you did: 60 | 61 | ```elixir 62 | import_config "../apps/*/config/config.exs" 63 | ``` 64 | It has to be replaced by: 65 | 66 | ```elixir 67 | for config <- "../apps/*/config/config.exs" |> Path.expand(__DIR__) |> Path.wildcard() do 68 | import_config config 69 | end 70 | ``` 71 | The last step is to replace all `Mix.env()` calls by `config_env()`. 72 | 73 | ## config/runtime.exs 74 | 75 | For runtime configuration, you can use the `config/runtime.exs` file. 76 | It is executed right before applications start in both Mix and releases 77 | (assembled with `mix release`). 78 | 79 | ## Function config/2 80 | 81 | Configures the given `root_key`. 82 | 83 | Keyword lists are always deep-merged. 84 | 85 | ## Examples 86 | 87 | The given `opts` are merged into the existing configuration 88 | for the given `root_key`. Conflicting keys are overridden by the 89 | ones specified in `opts`, unless they are keywords, which are 90 | deep merged recursively. For example, the application configuration 91 | below 92 | 93 | ```elixir 94 | config :logger, 95 | level: :warn, 96 | backends: [:console] 97 | 98 | config :logger, 99 | level: :info, 100 | truncate: 1024 101 | ``` 102 | will have a final configuration for `:logger` of: 103 | 104 | ```elixir 105 | [level: :info, backends: [:console], truncate: 1024] 106 | ``` 107 | ## Function config/3 108 | 109 | Configures the given `key` for the given `root_key`. 110 | 111 | Keyword lists are always deep merged. 112 | 113 | ## Examples 114 | 115 | The given `opts` are merged into the existing values for `key` 116 | in the given `root_key`. Conflicting keys are overridden by the 117 | ones specified in `opts`, unless they are keywords, which are 118 | deep merged recursively. For example, the application configuration 119 | below 120 | 121 | ```elixir 122 | config :ecto, Repo, 123 | log_level: :warn, 124 | adapter: Ecto.Adapters.Postgres 125 | 126 | config :ecto, Repo, 127 | log_level: :info, 128 | pool_size: 10 129 | ``` 130 | will have a final value of the configuration for the `Repo` 131 | key in the `:ecto` application of: 132 | 133 | ```elixir 134 | [log_level: :info, pool_size: 10, adapter: Ecto.Adapters.Postgres] 135 | ``` 136 | ## Macro config_env/0 137 | 138 | Returns the environment this configuration file is executed on. 139 | 140 | In Mix projects this function returns the environment this configuration 141 | file is executed on. In releases, the environment when `mix release` ran. 142 | 143 | This is most often used to execute conditional code: 144 | 145 | ```elixir 146 | if config_env() == :prod do 147 | config :my_app, :debug, false 148 | end 149 | ``` 150 | ## Macro config_target/0 151 | 152 | Returns the target this configuration file is executed on. 153 | 154 | This is most often used to execute conditional code: 155 | 156 | ```elixir 157 | if config_target() == :host do 158 | config :my_app, :debug, false 159 | end 160 | ``` 161 | ## Macro import_config/1 162 | 163 | Imports configuration from the given file. 164 | 165 | In case the file doesn't exist, an error is raised. 166 | 167 | If file is a relative, it will be expanded relatively to the 168 | directory the current configuration file is in. 169 | 170 | ## Examples 171 | 172 | This is often used to emulate configuration across environments: 173 | 174 | ```elixir 175 | import_config "#{config_env()}.exs" 176 | ``` 177 | Note, however, some configuration files, such as `config/runtime.exs` 178 | does not support imports, as they are meant to be copied across 179 | systems. 180 | 181 | --------------------------------------------------------------------------------