├── .bazelrc ├── .github └── workflows │ └── codeql.yml ├── AUTHORS ├── LICENSE ├── Makefile.am ├── README ├── README.md ├── WORKSPACE ├── autogen.sh ├── configure.ac ├── diff_writer.py ├── fuzz.md ├── glog-0.4.0 ├── .bazelci │ └── presubmit.yml ├── .gitignore ├── .travis.ubuntu.sh ├── .travis.yml ├── AUTHORS ├── BUILD ├── CMakeLists.txt ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── COPYING ├── ChangeLog ├── Dockerfile.ubuntu.template ├── INSTALL ├── Makefile.am ├── README.md ├── README.windows ├── WORKSPACE ├── aclocal.m4 ├── appveyor.yml ├── autogen.sh ├── bazel │ ├── example │ │ ├── BUILD │ │ └── main.cc │ └── glog.bzl ├── cmake │ └── INSTALL.md ├── configure.ac ├── doc │ ├── designstyle.css │ └── glog.html ├── glog-config.cmake.in ├── libglog.pc.in ├── m4 │ ├── ac_have_attribute.m4 │ ├── ac_have_builtin_expect.m4 │ ├── ac_have_sync_val_compare_and_swap.m4 │ ├── ac_rwlock.m4 │ ├── acx_pthread.m4 │ ├── google_namespace.m4 │ ├── libtool.m4 │ ├── ltoptions.m4 │ ├── ltsugar.m4 │ ├── lt~obsolete.m4 │ ├── namespaces.m4 │ ├── pc_from_ucontext.m4 │ ├── stl_namespace.m4 │ └── using_operator.m4 ├── packages │ ├── deb.sh │ ├── deb │ │ ├── README │ │ ├── changelog │ │ ├── compat │ │ ├── control │ │ ├── copyright │ │ ├── docs │ │ ├── libgoogle-glog-dev.dirs │ │ ├── libgoogle-glog-dev.install │ │ ├── libgoogle-glog0.dirs │ │ ├── libgoogle-glog0.install │ │ └── rules │ ├── rpm.sh │ └── rpm │ │ └── rpm.spec ├── src │ ├── base │ │ ├── commandlineflags.h │ │ ├── googleinit.h │ │ └── mutex.h │ ├── config.h.cmake.in │ ├── config.h.in │ ├── config_for_unittests.h │ ├── demangle.cc │ ├── demangle.h │ ├── demangle_unittest.cc │ ├── demangle_unittest.sh │ ├── demangle_unittest.txt │ ├── glog │ │ ├── log_severity.h │ │ ├── logging.h.in │ │ ├── raw_logging.h.in │ │ ├── stl_logging.h.in │ │ └── vlog_is_on.h.in │ ├── googletest.h │ ├── logging.cc │ ├── logging_striplog_test.sh │ ├── logging_striptest10.cc │ ├── logging_striptest2.cc │ ├── logging_striptest_main.cc │ ├── logging_unittest.cc │ ├── logging_unittest.err │ ├── mock-log.h │ ├── mock-log_test.cc │ ├── raw_logging.cc │ ├── signalhandler.cc │ ├── signalhandler_unittest.cc │ ├── signalhandler_unittest.sh │ ├── stacktrace.h │ ├── stacktrace_generic-inl.h │ ├── stacktrace_libunwind-inl.h │ ├── stacktrace_powerpc-inl.h │ ├── stacktrace_unittest.cc │ ├── stacktrace_windows-inl.h │ ├── stacktrace_x86-inl.h │ ├── stacktrace_x86_64-inl.h │ ├── stl_logging_unittest.cc │ ├── symbolize.cc │ ├── symbolize.h │ ├── symbolize_unittest.cc │ ├── utilities.cc │ ├── utilities.h │ ├── utilities_unittest.cc │ ├── vlog_is_on.cc │ └── windows │ │ ├── glog │ │ ├── log_severity.h │ │ ├── logging.h │ │ ├── raw_logging.h │ │ ├── stl_logging.h │ │ └── vlog_is_on.h │ │ ├── port.cc │ │ ├── port.h │ │ └── preprocess.sh └── toolchains │ ├── .gitignore │ ├── clang-cxx17.cmake │ ├── gcc-cxx11.cmake │ ├── gcc-cxx17.cmake │ ├── gcc-cxx98.cmake │ ├── gcc-gnuxx11.cmake │ ├── linux-mingw-w64-cxx11.cmake │ ├── linux-mingw-w64-cxx17.cmake │ ├── linux-mingw-w64-gnuxx11.cmake │ ├── mingw-cxx11.cmake │ ├── mingw-cxx17.cmake │ ├── mingw-gnuxx11.cmake │ ├── vs-14-2015-sdk-8-1.cmake │ ├── vs-14-2015-win64.cmake │ ├── vs-15-2017-win64-cxx17.cmake │ └── vs-15-2017-win64.cmake ├── help.md ├── rc ├── commands │ └── grep │ │ └── environment ├── completion_models │ ├── format │ │ ├── cpp │ │ ├── py │ │ └── sql │ └── iso-639 │ │ └── en ├── editor_commands │ ├── camelcase.cc │ ├── compiler.cc │ ├── cpp │ ├── cpp-mode.cc │ ├── diff-with-disk │ ├── ellipsis │ ├── emdash │ ├── english │ ├── filter-all │ ├── filter-includes │ ├── filter-start │ ├── fold-next-line.cc │ ├── german │ ├── git.cc │ ├── guillemets │ ├── header.cc │ ├── include.cc │ ├── indent.cc │ ├── java │ ├── java-mode.cc │ ├── lib │ │ ├── can-remove-previous-prefix │ │ ├── clang-format.cc │ │ ├── csv.cc │ │ ├── dates.cc │ │ ├── languages │ │ │ └── es.cc │ │ ├── line_column.cc │ │ ├── markdown.cc │ │ ├── numbers.cc │ │ ├── paths.cc │ │ ├── sections.cc │ │ ├── strings.cc │ │ └── zk.cc │ ├── prompt-context.cc │ ├── reflow.cc │ ├── shapes.cc │ ├── smart-caps │ └── smart-quotes ├── hooks │ ├── buffer-first-enter.cc │ ├── buffer-reload.cc │ ├── buffer-save.cc │ ├── navigation-buffer-reload.cc │ └── start.cc └── tests │ └── BufferReloads │ └── hooks │ └── start.cc ├── screenshots └── shot.png ├── src ├── BUILD ├── README.md ├── args.cc ├── args.h ├── args_tests.cc ├── buffer.cc ├── buffer.h ├── buffer_contents_util.cc ├── buffer_contents_util.h ├── buffer_contents_view_layout.cc ├── buffer_contents_view_layout.h ├── buffer_display_data.cc ├── buffer_display_data.h ├── buffer_filter.cc ├── buffer_filter.h ├── buffer_flags.cc ├── buffer_flags.h ├── buffer_metadata_output_producer.cc ├── buffer_metadata_output_producer.h ├── buffer_name.cc ├── buffer_name.h ├── buffer_output_producer.cc ├── buffer_output_producer.h ├── buffer_registry.cc ├── buffer_registry.h ├── buffer_state.cc ├── buffer_state.h ├── buffer_subtypes.cc ├── buffer_subtypes.h ├── buffer_syntax_parser.cc ├── buffer_syntax_parser.h ├── buffer_tests.cc ├── buffer_transformation_adapter.cc ├── buffer_transformation_adapter.h ├── buffer_variables.cc ├── buffer_variables.h ├── buffer_vm.cc ├── buffer_vm.h ├── buffer_widget.cc ├── buffer_widget.h ├── buffers_list.cc ├── buffers_list.h ├── chatgpt-query.py ├── clozes.py ├── columns_vector.cc ├── columns_vector.h ├── command.cc ├── command.h ├── command_argument_mode.h ├── command_mode.cc ├── command_mode.h ├── completion_model.cc ├── completion_model.h ├── concurrent │ ├── BUILD │ ├── bag.cc │ ├── bag.h │ ├── operation.cc │ ├── operation.h │ ├── protected.cc │ ├── protected.h │ ├── thread_pool.cc │ ├── thread_pool.h │ ├── version_property_receiver.cc │ ├── version_property_receiver.h │ ├── work_queue.cc │ └── work_queue.h ├── cpp_command.cc ├── cpp_command.h ├── cpp_parse_tree.cc ├── cpp_parse_tree.h ├── delay_input_receiver.cc ├── delay_input_receiver.h ├── direction.cc ├── direction.h ├── directory_listing.cc ├── directory_listing.h ├── editor.cc ├── editor.h ├── editor_mode.cc ├── editor_mode.h ├── editor_variables.cc ├── editor_variables.h ├── editor_vm.cc ├── editor_vm.h ├── execution_context.cc ├── execution_context.h ├── file_link_mode.cc ├── file_link_mode.h ├── find_mode.cc ├── find_mode.h ├── fragments.cc ├── fragments.h ├── frame_output_producer.cc ├── frame_output_producer.h ├── futures │ ├── BUILD │ ├── delete_notification.cc │ ├── delete_notification.h │ ├── futures.cc │ ├── futures.h │ ├── listenable_value.h │ ├── serializer.cc │ └── serializer.h ├── fuzz_test.cc ├── goto_command.cc ├── goto_command.h ├── help_command.cc ├── help_command.h ├── horizontal_center_output_producer.cc ├── horizontal_center_output_producer.h ├── infrastructure │ ├── BUILD │ ├── audio.cc │ ├── audio.h │ ├── command_line.cc │ ├── command_line.h │ ├── dirname.cc │ ├── dirname.h │ ├── dirname_vm.cc │ ├── dirname_vm.h │ ├── execution.cc │ ├── execution.h │ ├── extended_char.cc │ ├── extended_char.h │ ├── extended_char_vm.cc │ ├── extended_char_vm.h │ ├── file_adapter.h │ ├── file_descriptor_reader.cc │ ├── file_descriptor_reader.h │ ├── file_system_driver.cc │ ├── file_system_driver.h │ ├── path_suffix_map.cc │ ├── path_suffix_map.h │ ├── regular_file_adapter.cc │ ├── regular_file_adapter.h │ ├── screen │ │ ├── BUILD │ │ ├── cursors.cc │ │ ├── cursors.h │ │ ├── line_modifier.cc │ │ ├── line_modifier.h │ │ ├── screen.h │ │ ├── visual_overlay.cc │ │ └── visual_overlay.h │ ├── terminal_adapter.cc │ ├── terminal_adapter.h │ ├── time.cc │ ├── time.h │ ├── time_human.cc │ ├── time_human.h │ ├── tracker.cc │ └── tracker.h ├── insert_history.cc ├── insert_history.h ├── insert_history_buffer.cc ├── insert_history_buffer.h ├── insert_mode.cc ├── insert_mode.h ├── key_commands_map.cc ├── key_commands_map.h ├── language │ ├── BUILD │ ├── cached_supplier.h │ ├── const_tree.cc │ ├── const_tree.h │ ├── container.h │ ├── error │ │ ├── BUILD │ │ ├── log.cc │ │ ├── log.h │ │ ├── value_or_error.cc │ │ ├── value_or_error.h │ │ └── view.h │ ├── function_traits.h │ ├── gc.cc │ ├── gc.h │ ├── gc_container.h │ ├── gc_tests.cc │ ├── gc_util.cc │ ├── gc_util.h │ ├── gc_view.h │ ├── ghost_type.cc │ ├── ghost_type.h │ ├── ghost_type_class.h │ ├── ghost_type_test.cc │ ├── hash.cc │ ├── hash.h │ ├── lazy_string │ │ ├── BUILD │ │ ├── append.h │ │ ├── char_buffer.cc │ │ ├── char_buffer.h │ │ ├── column_number.h │ │ ├── functional.cc │ │ ├── functional.h │ │ ├── lazy_string.cc │ │ ├── lazy_string.h │ │ ├── lowercase.cc │ │ ├── lowercase.h │ │ ├── single_line.cc │ │ ├── single_line.h │ │ ├── tokenize.cc │ │ ├── tokenize.h │ │ ├── tokenize_test.cc │ │ ├── trim.cc │ │ └── trim.h │ ├── lazy_value.cc │ ├── lazy_value.h │ ├── observers.cc │ ├── observers.h │ ├── observers_gc.h │ ├── once_only_function.h │ ├── overload.h │ ├── safe_types.h │ ├── text │ │ ├── BUILD │ │ ├── delegating_mutable_line_sequence_observer.cc │ │ ├── delegating_mutable_line_sequence_observer.h │ │ ├── line.cc │ │ ├── line.h │ │ ├── line_builder.cc │ │ ├── line_builder.h │ │ ├── line_column.cc │ │ ├── line_column.h │ │ ├── line_column_vm.cc │ │ ├── line_column_vm.h │ │ ├── line_processor_map.cc │ │ ├── line_processor_map.h │ │ ├── line_sequence.cc │ │ ├── line_sequence.h │ │ ├── line_sequence_functional.cc │ │ ├── line_sequence_functional.h │ │ ├── mutable_line_sequence.cc │ │ ├── mutable_line_sequence.h │ │ ├── mutable_line_sequence_observer.h │ │ ├── range.cc │ │ ├── range.h │ │ ├── sorted_line_sequence.cc │ │ └── sorted_line_sequence.h │ ├── wstring.cc │ └── wstring.h ├── line_marks.cc ├── line_marks.h ├── line_marks_buffer.cc ├── line_marks_buffer.h ├── line_marks_test.cc ├── line_number_output_producer.cc ├── line_number_output_producer.h ├── line_output.cc ├── line_output.h ├── line_prompt_mode.cc ├── line_prompt_mode.h ├── line_with_cursor.cc ├── line_with_cursor.h ├── log.cc ├── log.h ├── lru_cache.cc ├── lru_cache.h ├── main.cc ├── map_mode.cc ├── map_mode.h ├── math │ ├── BUILD │ ├── bigint.cc │ ├── bigint.h │ ├── checked_operation.cc │ ├── checked_operation.h │ ├── decaying_counter.cc │ ├── decaying_counter.h │ ├── naive_bayes.cc │ ├── naive_bayes.h │ ├── numbers.cc │ └── numbers.h ├── modifiers.cc ├── modifiers.h ├── navigate_command.cc ├── navigate_command.h ├── navigation_buffer.cc ├── navigation_buffer.h ├── open_directory_command.cc ├── open_directory_command.h ├── open_file_command.cc ├── open_file_command.h ├── operation.cc ├── operation.h ├── operation_scope.cc ├── operation_scope.h ├── operation_scope_buffer_information.h ├── parse_tools.cc ├── parse_tools.h ├── parse_tree.cc ├── parse_tree.h ├── parsers │ ├── csv.cc │ ├── csv.h │ ├── diff.cc │ ├── diff.h │ ├── markdown.cc │ ├── markdown.h │ ├── util.cc │ └── util.h ├── path_flags.cc ├── path_flags.h ├── predictor.cc ├── predictor.h ├── python │ └── mappings.py ├── quit_command.cc ├── quit_command.h ├── record_command.cc ├── record_command.h ├── repeat_mode.cc ├── repeat_mode.h ├── run_command_handler.cc ├── run_command_handler.h ├── run_cpp_command.cc ├── run_cpp_command.h ├── run_cpp_file.cc ├── run_cpp_file.h ├── screen_curses.cc ├── screen_curses.h ├── screen_union.h ├── screen_vm.cc ├── screen_vm.h ├── search_command.cc ├── search_command.h ├── search_handler.cc ├── search_handler.h ├── search_handler_vm.cc ├── search_handler_vm.h ├── section_brackets_producer.cc ├── section_brackets_producer.h ├── seek.cc ├── seek.h ├── server.cc ├── server.h ├── set_buffer_mode.cc ├── set_buffer_mode.h ├── set_mode_command.cc ├── set_mode_command.h ├── set_variable_command.cc ├── set_variable_command.h ├── shapes.cc ├── shapes.h ├── status.cc ├── status.h ├── status_output_producer.cc ├── status_output_producer.h ├── status_tests.cc ├── structure.cc ├── structure.h ├── structure_move.cc ├── structure_move.h ├── terminal.cc ├── terminal.h ├── test.cc ├── test │ ├── buffer_contents_test.cc │ ├── buffer_contents_test.h │ ├── fuzz │ │ ├── classes.cc │ │ ├── compiler.cc │ │ └── parser.cc │ ├── line_test.cc │ ├── line_test.h │ └── parser_fuzz.cc ├── tests │ ├── BUILD │ ├── benchmarks.cc │ ├── benchmarks.h │ ├── benchmarks_main.cc │ ├── concurrent.cc │ ├── concurrent.h │ ├── concurrent_interfaces.cc │ ├── concurrent_interfaces.h │ ├── fuzz.cc │ ├── fuzz.h │ ├── fuzz_testable.cc │ ├── fuzz_testable.h │ ├── tests.cc │ └── tests.h ├── token_predictor.cc ├── token_predictor.h ├── transformation.cc ├── transformation.h ├── transformation │ ├── BUILD │ ├── bisect.cc │ ├── bisect.h │ ├── composite.cc │ ├── composite.h │ ├── cursors.cc │ ├── cursors.h │ ├── delete.cc │ ├── delete.h │ ├── expand.cc │ ├── expand.h │ ├── input.h │ ├── insert.cc │ ├── insert.h │ ├── move.cc │ ├── move.h │ ├── noop.cc │ ├── noop.h │ ├── paste.cc │ ├── paste.h │ ├── reach_query.cc │ ├── reach_query.h │ ├── repetitions.cc │ ├── repetitions.h │ ├── result.h │ ├── set_position.cc │ ├── set_position.h │ ├── stack.cc │ ├── stack.h │ ├── switch_case.cc │ ├── switch_case.h │ ├── tree_navigate.cc │ ├── tree_navigate.h │ ├── type.cc │ ├── type.h │ ├── variant.h │ ├── visual_overlay.cc │ ├── visual_overlay.h │ ├── vm.cc │ └── vm.h ├── undo_state.cc ├── undo_state.h ├── url.cc ├── url.h ├── variables.h ├── vm │ ├── BUILD │ ├── append_expression.cc │ ├── append_expression.h │ ├── assign_expression.cc │ ├── assign_expression.h │ ├── binary_operator.cc │ ├── binary_operator.h │ ├── callbacks.cc │ ├── callbacks.h │ ├── class_expression.cc │ ├── class_expression.h │ ├── compilation.cc │ ├── compilation.h │ ├── constant_expression.cc │ ├── constant_expression.h │ ├── container.h │ ├── cpp.y │ ├── default_environment.cc │ ├── default_environment.h │ ├── environment.cc │ ├── environment.h │ ├── escape.cc │ ├── escape.h │ ├── expression.cc │ ├── expression.h │ ├── file_system.cc │ ├── file_system.h │ ├── filter_similar_names.cc │ ├── filter_similar_names.h │ ├── function_call.cc │ ├── function_call.h │ ├── fuzz.cc │ ├── if_expression.cc │ ├── if_expression.h │ ├── lambda.cc │ ├── lambda.h │ ├── lemon.c │ ├── lempar.c │ ├── logical_expression.cc │ ├── logical_expression.h │ ├── namespace_expression.cc │ ├── namespace_expression.h │ ├── natural.cc │ ├── natural.h │ ├── negate_expression.cc │ ├── negate_expression.h │ ├── numbers.cc │ ├── numbers.h │ ├── optional.h │ ├── return_expression.cc │ ├── return_expression.h │ ├── string.cc │ ├── string.h │ ├── time.cc │ ├── time.h │ ├── types.cc │ ├── types.h │ ├── types_promotion_tests.cc │ ├── value.cc │ ├── value.h │ ├── variable_lookup.cc │ ├── variable_lookup.h │ ├── vm.cc │ ├── vm.h │ ├── while_expression.cc │ └── while_expression.h ├── widget.h ├── widget_list.cc ├── widget_list.h └── zk-extract.py └── todo.md /.bazelrc: -------------------------------------------------------------------------------- 1 | # Set C++ standard to C++23. 2 | build --copt=-std=c++23 3 | # Enable debugging information 4 | build --copt=-g 5 | # Enable common warning flags 6 | build --copt=-Wall 7 | build --copt=-Wextra 8 | # Set preprocessor definition 9 | build --copt=-DDOCDIR='"$(docdir)"' 10 | # Enable specific error flags 11 | build --copt=-Werror=return-type 12 | build --copt=-Werror=switch 13 | build --copt=-Werror=unused-function 14 | build --copt=-Werror=missing-field-initializers 15 | build --copt=-Werror=unused-but-set-variable 16 | build --copt=-Werror=range-loop-construct 17 | build --copt=-Wunused-lambda-capture 18 | # Enable shadow warnings 19 | build --copt=-Wshadow -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [ "master" ] 9 | schedule: 10 | - cron: '30 7 * * 2' 11 | 12 | jobs: 13 | analyze: 14 | name: Analyze 15 | runs-on: ubuntu-latest 16 | permissions: 17 | actions: read 18 | contents: read 19 | security-events: write 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | language: [ 'cpp' ] 25 | 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v3 29 | 30 | - name: Initialize CodeQL 31 | uses: github/codeql-action/init@v3 32 | with: 33 | languages: ${{ matrix.language }} 34 | 35 | - name: Install dependencies 36 | run: sudo apt-get update && sudo apt-get install -y libtool libltdl-dev make g++ libncursesw6 libncurses-dev 37 | 38 | - run: | 39 | echo "Run, Build Application using script" 40 | ./autogen.sh && ./glog-*.*.*/autogen.sh && ./configure && make -j ${nproc:-2} -C glog-0.4.0 && make -j ${nproc:-2} edge && ln -s $(pwd)/rc ~/.edge 41 | 42 | - name: Tests 43 | run: ./edge --tests=run 44 | 45 | - name: Perform CodeQL Analysis 46 | uses: github/codeql-action/analyze@v3 47 | with: 48 | category: "/language:${{matrix.language}}" 49 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alejandro Forero Cuervo 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | See the README.md file. 2 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "com_github_gflags_gflags", 5 | sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf", 6 | strip_prefix = "gflags-2.2.2", 7 | urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"], 8 | ) 9 | 10 | http_archive( 11 | name = "com_github_google_glog", 12 | sha256 = "122fb6b712808ef43fbf80f75c52a21c9760683dae470154f02bddfc61135022", 13 | strip_prefix = "glog-0.6.0", 14 | urls = ["https://github.com/google/glog/archive/v0.6.0.zip"], 15 | ) 16 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | touch NEWS ChangeLog 3 | libtoolize --copy --ltdl --force 4 | aclocal 5 | autoconf 6 | autoheader 7 | automake --add-missing --copy 8 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.68]) 5 | AC_INIT([Edge], [0.0], [alefore@gmail.com]) 6 | LT_INIT 7 | AM_INIT_AUTOMAKE 8 | AC_CONFIG_SRCDIR([src/buffer.h]) 9 | AC_CONFIG_HEADERS([config.h]) 10 | 11 | # Checks for programs. 12 | AC_PROG_CXX 13 | AC_PROG_CC 14 | AC_PROG_MAKE_SET 15 | 16 | # Checks for libraries. 17 | AC_CHECK_LIB([ncursesw], [addwstr]) 18 | AC_CHECK_LIB([pthread], [pthread_create]) 19 | AC_CHECK_LIB([ao], [ao_play]) 20 | 21 | # Checks for header files. 22 | AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h ncursesw/curses.h]) 23 | 24 | # Checks for typedefs, structures, and compiler characteristics. 25 | AC_HEADER_STDBOOL 26 | AC_TYPE_PID_T 27 | AC_TYPE_SIZE_T 28 | AC_TYPE_SSIZE_T 29 | 30 | # Checks for library functions. 31 | AC_FUNC_FORK 32 | AC_FUNC_MALLOC 33 | AC_FUNC_MMAP 34 | AC_FUNC_REALLOC 35 | AC_FUNC_STRTOD 36 | AC_CHECK_FUNCS([dup2 floor memset mkfifo munmap realpath regcomp setenv strchr strdup strerror strrchr strtol]) 37 | 38 | AC_CONFIG_FILES([Makefile]) 39 | AC_CONFIG_SUBDIRS([glog-0.4.0]) 40 | AC_OUTPUT 41 | -------------------------------------------------------------------------------- /diff_writer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # TODO: Make this less brittle. If the second patch fails to apply, somehow 4 | # leave files in the original state. 5 | 6 | import os 7 | import sys 8 | 9 | def Run(cmd): 10 | status = os.system(cmd) 11 | if status: 12 | print "Error in command: %s" % cmd 13 | return status 14 | 15 | def RunOrDie(cmd): 16 | status = Run(cmd) 17 | if status: 18 | sys.exit(status) 19 | 20 | if len(sys.argv) != 3: 21 | print "Usage: %s PATH_OLD_DIFF PATH_NEW_DIFF" % (sys.argv[0],) 22 | sys.exit(1) 23 | 24 | patch_parameters = os.getenv("PATCH_PARAMETERS") or "-p1" 25 | 26 | RunOrDie("patch --dry-run --reverse %s <%s" % (patch_parameters, sys.argv[1])) 27 | RunOrDie("patch --reverse %s <%s" % (patch_parameters, sys.argv[1])) 28 | 29 | dry_run_status = Run("patch --dry-run %s <%s" % (patch_parameters, sys.argv[2])) 30 | if dry_run_status: 31 | print "Reverting to old state." 32 | RunOrDie("patch %s <%s" % (patch_parameters, sys.argv[1])) 33 | sys.exit(dry_run_status) 34 | 35 | RunOrDie("patch %s <%s" % (patch_parameters, sys.argv[2])) 36 | 37 | print "Done." 38 | -------------------------------------------------------------------------------- /fuzz.md: -------------------------------------------------------------------------------- 1 | # Fuzz testing 2 | 3 | ## Building 4 | 5 | CXXFLAGS=-fpermissive CXX=$(pwd)/afl-2.39b/afl-g++ ./configure 6 | 7 | ## Create input 8 | 9 | mkdir -p fuzz-data/{testcases,findings_dir} 10 | edge fuzz-data/testcases/start 11 | 12 | ## Running fuzzer 13 | 14 | GLOG_logtostderr=y EDGE_TEST_STDIN=yes afl-fuzz -i testcases -o findings_dir .libs/fuzz_test 15 | 16 | Master: 17 | 18 | GLOG_logtostderr=y afl-fuzz -i fuzz-data/testcases -o fuzz-data/findings_dir -M fuzz00 .libs/test_fuzz_vm 19 | 20 | Slaves: 21 | 22 | GLOG_logtostderr=y afl-fuzz -i fuzz-data/testcases -o fuzz-data/findings_dir -S fuzz01 .libs/test_fuzz_vm 23 | GLOG_logtostderr=y afl-fuzz -i fuzz-data/testcases -o fuzz-data/findings_dir -S fuzz02 .libs/test_fuzz_vm 24 | ... 25 | 26 | ## Minimize 27 | 28 | afl-tmin -i /tmp/crash -o /tmp/crash.min -- ./test_fuzz_vm 29 | -------------------------------------------------------------------------------- /glog-0.4.0/.bazelci/presubmit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platforms: 3 | ubuntu1404: 4 | build_targets: 5 | - "..." 6 | test_targets: 7 | - "..." 8 | ubuntu1604: 9 | build_targets: 10 | - "..." 11 | test_targets: 12 | - "..." 13 | macos: 14 | build_targets: 15 | - "..." 16 | test_targets: 17 | - "..." 18 | -------------------------------------------------------------------------------- /glog-0.4.0/.gitignore: -------------------------------------------------------------------------------- 1 | autom4te.cache 2 | glog-*.tar.gz 3 | packages/rpm-unknown 4 | packages/debian-* 5 | CMakeCache.txt 6 | CMakeFiles/ 7 | *.cmake 8 | config.h 9 | *.sln 10 | *.vcxproj 11 | *.filters 12 | bazel-* 13 | -------------------------------------------------------------------------------- /glog-0.4.0/.travis.ubuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -x 4 | 5 | uname -a 6 | 7 | cmake -H. -B_build_${TOOLCHAIN} -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/${TOOLCHAIN}.cmake" 8 | cmake --build _build_${TOOLCHAIN} -- -j4 9 | 10 | if [ "$RUN_TESTS" = true ]; then 11 | case "$TOOLCHAIN" in linux-mingw*) 12 | echo "copy runtime libraries needed for tests into build directory" 13 | cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll /usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/{libstdc++-6.dll,libgcc_s_seh-1.dll} _build_${TOOLCHAIN} 14 | esac 15 | CTEST_OUTPUT_ON_FAILURE=1 cmake --build _build_${TOOLCHAIN} --target test 16 | fi 17 | 18 | 19 | -------------------------------------------------------------------------------- /glog-0.4.0/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of glog authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS files. 3 | # See the latter for an explanation. 4 | # 5 | # Names should be added to this file as: 6 | # Name or Organization 7 | # The email address is not required for organizations. 8 | # 9 | # Please keep the list sorted. 10 | 11 | Abhishek Dasgupta 12 | Abhishek Parmar 13 | Andrew Schwartzmeyer 14 | Andy Ying 15 | Brian Silverman 16 | Google Inc. 17 | Guillaume Dumont 18 | Michael Tanner 19 | MiniLight 20 | romange 21 | Roman Perepelitsa 22 | Sergiu Deitsch 23 | tbennun 24 | Teddy Reed 25 | Zhongming Qu 26 | -------------------------------------------------------------------------------- /glog-0.4.0/BUILD: -------------------------------------------------------------------------------- 1 | licenses(['notice']) 2 | 3 | load(':bazel/glog.bzl', 'glog_library') 4 | 5 | glog_library() 6 | -------------------------------------------------------------------------------- /glog-0.4.0/Dockerfile.ubuntu.template: -------------------------------------------------------------------------------- 1 | # Build Ubuntu image 2 | FROM @BUILD_ARCH@/@BUILD_FLAVOR@:@BUILD_RELEASE@ 3 | 4 | # see https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#/run 5 | RUN apt-get update && \ 6 | apt-get install -y --no-install-recommends \ 7 | @BUILD_PACKAGES@ \ 8 | build-essential \ 9 | g++ 10 | 11 | RUN mkdir -p /usr/src/app 12 | WORKDIR /usr/src/app 13 | 14 | COPY . /usr/src/app 15 | -------------------------------------------------------------------------------- /glog-0.4.0/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://img.shields.io/travis/google/glog/master.svg?label=Travis)](https://travis-ci.org/google/glog/builds) 2 | [![Grunt status](https://img.shields.io/appveyor/ci/google-admin/glog/master.svg?label=Appveyor)](https://ci.appveyor.com/project/google-admin/glog/history) 3 | 4 | This repository contains a C++ implementation of the Google logging 5 | module. Documentation for the implementation is in doc/. 6 | 7 | See INSTALL for (generic) installation instructions for C++: basically 8 | ```sh 9 | ./autogen.sh && ./configure && make && make install 10 | ``` 11 | -------------------------------------------------------------------------------- /glog-0.4.0/README.windows: -------------------------------------------------------------------------------- 1 | This project has been ported to Windows, including stack tracing, signal 2 | handling, and unit tests. 3 | 4 | A Visual Studio solution file is explicitly not provided because it is not 5 | maintainable. Instead, a CMake build system exists to generate the correct 6 | solution for your version of Visual Studio. 7 | 8 | In short, 9 | (1) Install CMake from: https://cmake.org/download/ 10 | (2) With CMake on your PATH, run `cmake .` to generate the build files 11 | (3) Either use `cmake --build`, or open the generated solution 12 | 13 | CMake provides different generators, and by default will pick the most relevant 14 | one to your environment. If you need a specific version of Visual Studio, use 15 | `cmake . -G `, and see `cmake --help` for the available 16 | generators. Also see `-T `, which can used to request the native 17 | x64 toolchain with `-T host=x64`. -------------------------------------------------------------------------------- /glog-0.4.0/WORKSPACE: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | 3 | http_archive( 4 | name = "com_github_gflags_gflags", 5 | strip_prefix = "gflags-2.2.2", 6 | urls = [ 7 | "https://mirror.bazel.build/github.com/gflags/gflags/archive/v2.2.2.tar.gz", 8 | "https://github.com/gflags/gflags/archive/v2.2.2.tar.gz", 9 | ], 10 | ) 11 | -------------------------------------------------------------------------------- /glog-0.4.0/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | autoreconf -i 6 | -------------------------------------------------------------------------------- /glog-0.4.0/bazel/example/BUILD: -------------------------------------------------------------------------------- 1 | cc_test( 2 | name = "main", 3 | size = "small", 4 | srcs = ["main.cc"], 5 | deps = [ 6 | "//:glog", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /glog-0.4.0/bazel/example/main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char* argv[]) { 6 | // Initialize Google's logging library. 7 | google::InitGoogleLogging(argv[0]); 8 | 9 | // Optional: parse command line flags 10 | gflags::ParseCommandLineFlags(&argc, &argv, true); 11 | 12 | LOG(INFO) << "Hello, world!"; 13 | 14 | // glog/stl_logging.h allows logging STL containers. 15 | std::vector x; 16 | x.push_back(1); 17 | x.push_back(2); 18 | x.push_back(3); 19 | LOG(INFO) << "ABC, it's easy as " << x; 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /glog-0.4.0/glog-config.cmake.in: -------------------------------------------------------------------------------- 1 | if (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@) 2 | message (FATAL_ERROR "CMake >= @glog_CMake_VERSION@ required") 3 | endif (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@) 4 | 5 | @PACKAGE_INIT@ 6 | 7 | include (CMakeFindDependencyMacro) 8 | 9 | @gflags_DEPENDENCY@ 10 | 11 | include ("${CMAKE_CURRENT_LIST_DIR}/glog-targets.cmake") 12 | -------------------------------------------------------------------------------- /glog-0.4.0/libglog.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libglog 7 | Description: Google Log (glog) C++ logging framework 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lglog 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/ac_have_attribute.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([AX_C___ATTRIBUTE__], [ 2 | AC_MSG_CHECKING(for __attribute__) 3 | AC_CACHE_VAL(ac_cv___attribute__, [ 4 | AC_TRY_COMPILE( 5 | [#include 6 | static void foo(void) __attribute__ ((unused)); 7 | void foo(void) { exit(1); }], 8 | [], 9 | ac_cv___attribute__=yes, 10 | ac_cv___attribute__=no 11 | )]) 12 | if test "$ac_cv___attribute__" = "yes"; then 13 | AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__]) 14 | fi 15 | AC_MSG_RESULT($ac_cv___attribute__) 16 | ]) 17 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/ac_have_builtin_expect.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([AX_C___BUILTIN_EXPECT], [ 2 | AC_MSG_CHECKING(for __builtin_expect) 3 | AC_CACHE_VAL(ac_cv___builtin_expect, [ 4 | AC_TRY_COMPILE( 5 | [int foo(void) { if (__builtin_expect(0, 0)) return 1; return 0; }], 6 | [], 7 | ac_cv___builtin_expect=yes, 8 | ac_cv___builtin_expect=no 9 | )]) 10 | if test "$ac_cv___builtin_expect" = "yes"; then 11 | AC_DEFINE(HAVE___BUILTIN_EXPECT, 1, [define if your compiler has __builtin_expect]) 12 | fi 13 | AC_MSG_RESULT($ac_cv___builtin_expect) 14 | ]) 15 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/ac_have_sync_val_compare_and_swap.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([AX_C___SYNC_VAL_COMPARE_AND_SWAP], [ 2 | AC_MSG_CHECKING(for __sync_val_compare_and_swap) 3 | AC_CACHE_VAL(ac_cv___sync_val_compare_and_swap, [ 4 | AC_TRY_LINK( 5 | [], 6 | [int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0;], 7 | ac_cv___sync_val_compare_and_swap=yes, 8 | ac_cv___sync_val_compare_and_swap=no 9 | )]) 10 | if test "$ac_cv___sync_val_compare_and_swap" = "yes"; then 11 | AC_DEFINE(HAVE___SYNC_VAL_COMPARE_AND_SWAP, 1, [define if your compiler has __sync_val_compare_and_swap]) 12 | fi 13 | AC_MSG_RESULT($ac_cv___sync_val_compare_and_swap) 14 | ]) 15 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/ac_rwlock.m4: -------------------------------------------------------------------------------- 1 | # TODO(csilvers): it would be better to actually try to link against 2 | # -pthreads, to make sure it defines these methods, but that may be 3 | # too hard, since pthread support is really tricky. 4 | 5 | # Check for support for pthread_rwlock_init() etc. 6 | # These aren't posix, but are widely supported. To get them on linux, 7 | # you need to define _XOPEN_SOURCE first, so this check assumes your 8 | # application does that. 9 | # 10 | # Note: OS X (as of 6/1/06) seems to support pthread_rwlock, but 11 | # doesn't define PTHREAD_RWLOCK_INITIALIZER. Therefore, we don't test 12 | # that particularly macro. It's probably best if you don't use that 13 | # macro in your code either. 14 | 15 | AC_DEFUN([AC_RWLOCK], 16 | [AC_CACHE_CHECK(support for pthread_rwlock_* functions, 17 | ac_cv_rwlock, 18 | [AC_LANG_SAVE 19 | AC_LANG_C 20 | AC_TRY_COMPILE([#define _XOPEN_SOURCE 500 21 | #include ], 22 | [pthread_rwlock_t l; pthread_rwlock_init(&l, NULL); 23 | pthread_rwlock_rdlock(&l); 24 | return 0;], 25 | ac_cv_rwlock=yes, ac_cv_rwlock=no) 26 | AC_LANG_RESTORE 27 | ]) 28 | if test "$ac_cv_rwlock" = yes; then 29 | AC_DEFINE(HAVE_RWLOCK,1,[define if the compiler implements pthread_rwlock_*]) 30 | fi 31 | ]) 32 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/namespaces.m4: -------------------------------------------------------------------------------- 1 | # Checks whether the compiler implements namespaces 2 | AC_DEFUN([AC_CXX_NAMESPACES], 3 | [AC_CACHE_CHECK(whether the compiler implements namespaces, 4 | ac_cv_cxx_namespaces, 5 | [AC_LANG_SAVE 6 | AC_LANG_CPLUSPLUS 7 | AC_TRY_COMPILE([namespace Outer { 8 | namespace Inner { int i = 0; }}], 9 | [using namespace Outer::Inner; return i;], 10 | ac_cv_cxx_namespaces=yes, 11 | ac_cv_cxx_namespaces=no) 12 | AC_LANG_RESTORE]) 13 | if test "$ac_cv_cxx_namespaces" = yes; then 14 | AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces]) 15 | fi]) 16 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/stl_namespace.m4: -------------------------------------------------------------------------------- 1 | # We check what namespace stl code like vector expects to be executed in 2 | 3 | AC_DEFUN([AC_CXX_STL_NAMESPACE], 4 | [AC_CACHE_CHECK( 5 | what namespace STL code is in, 6 | ac_cv_cxx_stl_namespace, 7 | [AC_REQUIRE([AC_CXX_NAMESPACES]) 8 | AC_LANG_SAVE 9 | AC_LANG_CPLUSPLUS 10 | AC_TRY_COMPILE([#include ], 11 | [vector t; return 0;], 12 | ac_cv_cxx_stl_namespace=none) 13 | AC_TRY_COMPILE([#include ], 14 | [std::vector t; return 0;], 15 | ac_cv_cxx_stl_namespace=std) 16 | AC_LANG_RESTORE]) 17 | if test "$ac_cv_cxx_stl_namespace" = none; then 18 | AC_DEFINE(STL_NAMESPACE,, 19 | [the namespace where STL code like vector<> is defined]) 20 | fi 21 | if test "$ac_cv_cxx_stl_namespace" = std; then 22 | AC_DEFINE(STL_NAMESPACE,std, 23 | [the namespace where STL code like vector<> is defined]) 24 | fi 25 | ]) 26 | -------------------------------------------------------------------------------- /glog-0.4.0/m4/using_operator.m4: -------------------------------------------------------------------------------- 1 | AC_DEFUN([AC_CXX_USING_OPERATOR], 2 | [AC_CACHE_CHECK( 3 | whether compiler supports using ::operator<<, 4 | ac_cv_cxx_using_operator, 5 | [AC_LANG_SAVE 6 | AC_LANG_CPLUSPLUS 7 | AC_TRY_COMPILE([#include 8 | std::ostream& operator<<(std::ostream&, struct s);], 9 | [using ::operator<<; return 0;], 10 | ac_cv_cxx_using_operator=1, 11 | ac_cv_cxx_using_operator=0) 12 | AC_LANG_RESTORE]) 13 | if test "$ac_cv_cxx_using_operator" = 1; then 14 | AC_DEFINE(HAVE_USING_OPERATOR, 1, [define if the compiler supports using expression for operator]) 15 | fi]) 16 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/README: -------------------------------------------------------------------------------- 1 | The list of files here isn't complete. For a step-by-step guide on 2 | how to set this package up correctly, check out 3 | http://www.debian.org/doc/maint-guide/ 4 | 5 | Most of the files that are in this directory are boilerplate. 6 | However, you may need to change the list of binary-arch dependencies 7 | in 'rules'. 8 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/compat: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/control: -------------------------------------------------------------------------------- 1 | Source: google-glog 2 | Priority: optional 3 | Maintainer: Google Inc. 4 | Build-Depends: debhelper (>= 4.0.0), binutils 5 | Standards-Version: 3.6.1 6 | 7 | Package: libgoogle-glog-dev 8 | Section: libdevel 9 | Architecture: any 10 | Depends: libgoogle-glog0 (= ${Source-Version}) 11 | Description: a library that implements application-level logging. 12 | This library provides logging APIs based on C++-style streams and 13 | various helper macros. The devel package contains static and debug 14 | libraries and header files for developing applications that use the 15 | google-glog package. 16 | 17 | Package: libgoogle-glog0 18 | Section: libs 19 | Architecture: any 20 | Depends: ${shlibs:Depends} 21 | Description: a library that implements application-level logging. 22 | This library provides logging APIs based on C++-style streams and 23 | various helper macros. 24 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/docs: -------------------------------------------------------------------------------- 1 | AUTHORS 2 | COPYING 3 | ChangeLog 4 | INSTALL 5 | README.md 6 | doc/designstyle.css 7 | doc/glog.html 8 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/libgoogle-glog-dev.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | usr/lib/pkgconfig 3 | usr/include 4 | usr/include/glog 5 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/libgoogle-glog-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/glog/* 2 | usr/lib/lib*.so 3 | usr/lib/lib*.a 4 | usr/lib/*.la 5 | usr/lib/pkgconfig/* 6 | debian/tmp/usr/include/glog/* 7 | debian/tmp/usr/lib/lib*.so 8 | debian/tmp/usr/lib/lib*.a 9 | debian/tmp/usr/lib/*.la 10 | debian/tmp/usr/lib/pkgconfig/* 11 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/libgoogle-glog0.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | -------------------------------------------------------------------------------- /glog-0.4.0/packages/deb/libgoogle-glog0.install: -------------------------------------------------------------------------------- 1 | usr/lib/lib*.so.* 2 | debian/tmp/usr/lib/lib*.so.* 3 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/.gitignore: -------------------------------------------------------------------------------- 1 | # allow toolchain files to be tracked by git 2 | !*.cmake 3 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/clang-cxx17.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER clang) 8 | set(CMAKE_CXX_COMPILER clang++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 17) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/gcc-cxx11.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/gcc-cxx17.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 17) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/gcc-cxx98.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 98) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/gcc-gnuxx11.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS ON) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/linux-mingw-w64-cxx11.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building for Windows from an Ubuntu Linux system. 2 | # 3 | # Typical usage: 4 | # *) install cross compiler: `sudo apt-get install mingw-w64` 5 | # *) cmake -H. -B_build_mingw -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/linux-mingw-w64.cmake" 6 | 7 | set(CMAKE_SYSTEM_NAME Windows) 8 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 9 | set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 10 | 11 | # set compiler 12 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) 13 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) 14 | set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) 15 | 16 | # target environment on the build host system 17 | # set 1st to dir with the cross compiler's C/C++ headers/libs 18 | set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) 19 | 20 | # modify default behavior of FIND_XXX() commands to 21 | # search for headers/libs in the target environment and 22 | # search for programs in the build host environment 23 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 25 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 26 | 27 | # use emulator for `try_run` calls 28 | set(CMAKE_CROSSCOMPILING_EMULATOR wine64) 29 | 30 | # set c++ standard 31 | set(CMAKE_CXX_STANDARD 11) 32 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 33 | set(CMAKE_CXX_EXTENSIONS OFF) 34 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/linux-mingw-w64-cxx17.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building for Windows from an Ubuntu Linux system. 2 | # 3 | # Typical usage: 4 | # *) install cross compiler: `sudo apt-get install mingw-w64` 5 | # *) cmake -H. -B_build_mingw -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/linux-mingw-w64.cmake" 6 | 7 | set(CMAKE_SYSTEM_NAME Windows) 8 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 9 | set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 10 | 11 | # set compiler 12 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) 13 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) 14 | set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) 15 | 16 | # target environment on the build host system 17 | # set 1st to dir with the cross compiler's C/C++ headers/libs 18 | set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) 19 | 20 | # modify default behavior of FIND_XXX() commands to 21 | # search for headers/libs in the target environment and 22 | # search for programs in the build host environment 23 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 25 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 26 | 27 | # use emulator for `try_run` calls 28 | set(CMAKE_CROSSCOMPILING_EMULATOR wine64) 29 | 30 | # set c++ standard 31 | set(CMAKE_CXX_STANDARD 17) 32 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 33 | set(CMAKE_CXX_EXTENSIONS OFF) 34 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/linux-mingw-w64-gnuxx11.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building for Windows from an Ubuntu Linux system. 2 | # 3 | # Typical usage: 4 | # *) install cross compiler: `sudo apt-get install mingw-w64` 5 | # *) cmake -H. -B_build_mingw -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/linux-mingw-w64.cmake" 6 | 7 | set(CMAKE_SYSTEM_NAME Windows) 8 | set(CMAKE_SYSTEM_PROCESSOR x86_64) 9 | set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 10 | 11 | # set compiler 12 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) 13 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) 14 | set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) 15 | 16 | # target environment on the build host system 17 | # set 1st to dir with the cross compiler's C/C++ headers/libs 18 | set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) 19 | 20 | # modify default behavior of FIND_XXX() commands to 21 | # search for headers/libs in the target environment and 22 | # search for programs in the build host environment 23 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 25 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 26 | 27 | # use emulator for `try_run` calls 28 | set(CMAKE_CROSSCOMPILING_EMULATOR wine64) 29 | 30 | # set c++ standard 31 | set(CMAKE_CXX_STANDARD 11) 32 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 33 | set(CMAKE_CXX_EXTENSIONS ON) 34 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/mingw-cxx11.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\mingw.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/mingw-cxx17.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\mingw.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 17) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS OFF) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/mingw-gnuxx11.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building with gcc compiler 2 | # 3 | # Typical usage: 4 | # *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\mingw.cmake" 5 | 6 | # set compiler 7 | set(CMAKE_C_COMPILER gcc) 8 | set(CMAKE_CXX_COMPILER g++) 9 | 10 | # set c++ standard 11 | set(CMAKE_CXX_STANDARD 11) 12 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set(CMAKE_CXX_EXTENSIONS YES) 14 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/vs-14-2015-sdk-8-1.cmake: -------------------------------------------------------------------------------- 1 | # set c++ standard 2 | set(CMAKE_SYSTEM_VERSION 8.1) 3 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/vs-14-2015-win64.cmake: -------------------------------------------------------------------------------- 1 | # dummy, nothing extra to set 2 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/vs-15-2017-win64-cxx17.cmake: -------------------------------------------------------------------------------- 1 | # set c++ standard 2 | set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /std:c++17") 3 | -------------------------------------------------------------------------------- /glog-0.4.0/toolchains/vs-15-2017-win64.cmake: -------------------------------------------------------------------------------- 1 | # dummy, nothing extra to set 2 | -------------------------------------------------------------------------------- /rc/commands/grep/environment: -------------------------------------------------------------------------------- 1 | GREP_OPTIONS=-n 2 | -------------------------------------------------------------------------------- /rc/completion_models/format/cpp: -------------------------------------------------------------------------------- 1 | wl while 2 | sm std::move 3 | ct const 4 | lg language 5 | mnns MakeNonNullShared< 6 | mnnu MakeNonNullUnique< 7 | nnu NonNull 38 | -------------------------------------------------------------------------------- /rc/completion_models/format/py: -------------------------------------------------------------------------------- 1 | p3 python3 2 | df def 3 | la lambda 4 | im import 5 | sf self 6 | rn return 7 | _i_ __init__ 8 | ast assert 9 | -------------------------------------------------------------------------------- /rc/completion_models/format/sql: -------------------------------------------------------------------------------- 1 | fm FROM 2 | gb GROUP BY 3 | l LIMIT 4 | lj LEFT JOIN 5 | ob ORDER BY 6 | st SELECT -------------------------------------------------------------------------------- /rc/completion_models/iso-639/en: -------------------------------------------------------------------------------- 1 | a a 2 | ab about 3 | ac abstraction 4 | ad and 5 | an an 6 | as as 7 | at at 8 | b be 9 | c can 10 | cs cities 11 | d decision 12 | df different 13 | ds distributed systems 14 | dse distributed systems efficiency 15 | e efficiency 16 | ep expectation 17 | eps expectations 18 | ex example 19 | f for 20 | fk feedback 21 | fr from 22 | fw following 23 | g good 24 | gc google.com 25 | gg Google 26 | h have 27 | i i 28 | ic impact 29 | ih in the 30 | in in 31 | infty ∞ 32 | ir important 33 | it it 34 | j just 35 | jr journal 36 | l large 37 | le leadership 38 | m md 39 | mr more 40 | n next 41 | o of 42 | ot of the 43 | p performance 44 | ps points 45 | ps ps 46 | pt point 47 | pu pueblos 48 | q question 49 | qs questions 50 | r are 51 | re related 52 | rsa richer semantic abstractions 53 | s should 54 | sw software 55 | t the 56 | te they 57 | th that 58 | ti this 59 | tl technical 60 | u you 61 | v very 62 | w with 63 | wk week 64 | zk zettelkasten -------------------------------------------------------------------------------- /rc/editor_commands/compiler.cc: -------------------------------------------------------------------------------- 1 | // Marks the current buffer as a “compiler”: a buffer that goes over the text 2 | // being edited and produces a report of errors as its output. 3 | 4 | void SetAsCompiler(Buffer buffer) { 5 | // Avoid giving it a pts. 6 | buffer.set_pts(false); 7 | 8 | // Scroll down to the end of output automatically. 9 | buffer.set_follow_end_of_file(true); 10 | 11 | // If another buffer is saved, reload this buffer automatically. 12 | buffer.set_reload_on_buffer_write(true); 13 | 14 | // Track PATH:LINE references to other files in the compiler output. 15 | buffer.set_contains_line_marks(true); 16 | 17 | // Show the last lines of this buffer in the list of buffers. 18 | buffer.set_buffer_list_context_lines(5); 19 | } 20 | 21 | void SetAsCompiler() { 22 | SetAsCompiler(buffer); 23 | } 24 | -------------------------------------------------------------------------------- /rc/editor_commands/cpp: -------------------------------------------------------------------------------- 1 | // Convenience wrapper, making it easy to activate directly from the editor. 2 | #include "cpp-mode" 3 | CppMode(); 4 | -------------------------------------------------------------------------------- /rc/editor_commands/diff-with-disk: -------------------------------------------------------------------------------- 1 | #include "lib/paths" 2 | 3 | string original_path = buffer.path(); 4 | 5 | if (original_path.empty()) { 6 | editor.SetStatus("Buffer doesn't have a path: " + buffer.name()); 7 | } else { 8 | // TODO: Get this from mkstemp. 9 | string tmp_path = "/tmp/edge-file-diff"; 10 | 11 | buffer.set_path(tmp_path); 12 | buffer.Save(); 13 | buffer.set_path(original_path); 14 | 15 | ForkCommandOptions options = ForkCommandOptions(); 16 | options.set_command("diff -Naur " + original_path.shell_escape() + " " + 17 | tmp_path.shell_escape()); 18 | options.set_name("🔀" + Basename(buffer.name())); 19 | options.set_insertion_type("visit"); 20 | 21 | Buffer diff_buffer = editor.ForkCommand(options); 22 | diff_buffer.set_allow_dirty_delete(true); 23 | } 24 | -------------------------------------------------------------------------------- /rc/editor_commands/ellipsis: -------------------------------------------------------------------------------- 1 | // Turns three consecutive dots ("...") into a single ellipsis character (“…”). 2 | 3 | #include "lib/can-remove-previous-prefix" 4 | 5 | string HandleEllipsis(string input) { 6 | if (input != "." || !CanRemovePreviousPrefix("..")) { 7 | return input; 8 | } 9 | return "…"; 10 | } 11 | 12 | buffer.AddKeyboardTextTransformer(HandleEllipsis); 13 | -------------------------------------------------------------------------------- /rc/editor_commands/emdash: -------------------------------------------------------------------------------- 1 | // Turns two consecutive dashes (“--”) into an emdash (“—”). 2 | 3 | #include "lib/can-remove-previous-prefix" 4 | 5 | string HandleDash(string input) { 6 | if (input != "-" || !CanRemovePreviousPrefix("-")) { 7 | return input; 8 | } 9 | return "—"; 10 | } 11 | 12 | buffer.AddKeyboardTextTransformer(HandleDash); 13 | -------------------------------------------------------------------------------- /rc/editor_commands/english: -------------------------------------------------------------------------------- 1 | #include "ellipsis" 2 | #include "emdash" 3 | #include "smart-caps" 4 | #include "smart-quotes" 5 | -------------------------------------------------------------------------------- /rc/editor_commands/filter-all: -------------------------------------------------------------------------------- 1 | bool ShowAllStrings(string x) { return true; } 2 | buffer.Filter(ShowAllStrings); 3 | -------------------------------------------------------------------------------- /rc/editor_commands/filter-includes: -------------------------------------------------------------------------------- 1 | bool HasInclude(string x) { 2 | return x.find("#include", 0) != -1; 3 | } 4 | 5 | buffer.Filter(HasInclude); 6 | -------------------------------------------------------------------------------- /rc/editor_commands/filter-start: -------------------------------------------------------------------------------- 1 | bool StartNonWhite(string x) { 2 | return x.size() > 0 && x.substr(0, 1) != " "; 3 | } 4 | buffer.Filter(StartNonWhite); 5 | -------------------------------------------------------------------------------- /rc/editor_commands/german: -------------------------------------------------------------------------------- 1 | #include "ellipsis" 2 | #include "emdash" 3 | #include "smart-caps" 4 | #include "smart-quotes" 5 | #include "guillemets" 6 | -------------------------------------------------------------------------------- /rc/editor_commands/git.cc: -------------------------------------------------------------------------------- 1 | void GitCommitAll(string message) { 2 | ForkCommandOptions options; 3 | options.set_command("git commit -a" + 4 | (message.empty() ? "" : " -m " + message.shell_escape())); 5 | options.set_insertion_type("visit"); 6 | editor.ForkCommand(options); 7 | } 8 | -------------------------------------------------------------------------------- /rc/editor_commands/guillemets: -------------------------------------------------------------------------------- 1 | #include "lib/can-remove-previous-prefix" 2 | 3 | string HandleGuillemet(string input) { 4 | if (input == "<") { 5 | return CanRemovePreviousPrefix("<") ? "«" : "<"; 6 | } else if (input == ">") { 7 | return CanRemovePreviousPrefix(">") ? "»" : ">"; 8 | } 9 | return input; 10 | } 11 | 12 | buffer.AddKeyboardTextTransformer(HandleGuillemet); 13 | -------------------------------------------------------------------------------- /rc/editor_commands/include.cc: -------------------------------------------------------------------------------- 1 | // TODO(easy): Switch this to the FunctionTransformation interface. 2 | void AddIncludeLine(Buffer buffer) { 3 | LineColumn position = buffer.position(); 4 | string line = buffer.line(position.line()); 5 | editor.SetStatus(line); 6 | 7 | if (line == "#include <>") { 8 | buffer.ApplyTransformation( 9 | SetPositionTransformation(LineColumn(position.line(), 9))); 10 | buffer.ApplyTransformation( 11 | DeleteTransformationBuilder() 12 | .set_modifiers(Modifiers().set_repetitions(2)) 13 | .build()); 14 | buffer.ApplyTransformation( 15 | InsertTransformationBuilder().set_text("\"\"").build()); 16 | buffer.ApplyTransformation( 17 | SetPositionTransformation(LineColumn(position.line(), 10))); 18 | } else if (line == "#include \"\"") { 19 | buffer.ApplyTransformation( 20 | SetPositionTransformation(LineColumn(position.line(), 9))); 21 | buffer.ApplyTransformation( 22 | DeleteTransformationBuilder() 23 | .set_modifiers(Modifiers().set_repetitions(2)) 24 | .build()); 25 | buffer.ApplyTransformation( 26 | InsertTransformationBuilder().set_text("<>").build()); 27 | buffer.ApplyTransformation( 28 | SetPositionTransformation(LineColumn(position.line(), 10))); 29 | } else { 30 | buffer.ApplyTransformation( 31 | SetPositionTransformation(LineColumn(position.line(), 0))); 32 | buffer.ApplyTransformation( 33 | InsertTransformationBuilder().set_text("#include <>\n").build()); 34 | buffer.ApplyTransformation( 35 | SetPositionTransformation(LineColumn(position.line(), 10))); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /rc/editor_commands/java: -------------------------------------------------------------------------------- 1 | // Convenience wrapper, making it easy to activate directly from the editor. 2 | #include "java-mode" 3 | JavaMode(); 4 | -------------------------------------------------------------------------------- /rc/editor_commands/java-mode.cc: -------------------------------------------------------------------------------- 1 | void JavaMode(Buffer buffer) { 2 | buffer.set_paragraph_line_prefix_characters(" /*"); 3 | buffer.set_line_prefix_characters(" /*"); 4 | buffer.set_line_width(100); 5 | buffer.set_language_keywords( 6 | "class interface extends implements this new " 7 | "public private protected static " 8 | "final " 9 | "void " 10 | // Flow control. 11 | "switch case default " 12 | "if else " 13 | "for while do " 14 | "break continue " 15 | "return " 16 | // Types 17 | "double long int String Object Integer Boolean Double " 18 | // Values 19 | "true false null"); 20 | buffer.set_tree_parser("cpp"); 21 | } -------------------------------------------------------------------------------- /rc/editor_commands/lib/can-remove-previous-prefix: -------------------------------------------------------------------------------- 1 | // Attempts to remove the string prefix right before the current cursor. 2 | // 3 | // Does not skip line boundaries. 4 | // 5 | // Returns a boolean indicating if the prefix was successfully removed. 6 | bool CanRemovePreviousPrefix(string prefix) { 7 | int column = buffer.position().column(); 8 | if (column < prefix.size()) { 9 | return false; 10 | } 11 | string line = buffer.line(buffer.position().line()); 12 | if (line.substr(column - prefix.size(), prefix.size()) != prefix) { 13 | return false; 14 | } 15 | buffer.ApplyTransformation(SetPositionTransformation( 16 | LineColumn(buffer.position().line(), column - prefix.size()))); 17 | buffer.ApplyTransformation( 18 | DeleteTransformationBuilder() 19 | .set_modifiers(Modifiers().set_repetitions(prefix.size())) 20 | .build()); 21 | return true; 22 | } 23 | -------------------------------------------------------------------------------- /rc/editor_commands/lib/dates.cc: -------------------------------------------------------------------------------- 1 | // Useful functions for :-style completion. 2 | string FormatDay(Time time) { return time.format("%Y-%m-%d"); } 3 | string Yesterday() { return FormatDay(Now().AddDays(-1)); } 4 | string Today() { return FormatDay(Now()); } 5 | string Tomorrow() { return FormatDay(Now().AddDays(1)); } 6 | string now() { return Now().format("%Y-%m-%d %H:%M"); } 7 | 8 | // Receives the dates as ISO yyyy-mm-dd strings and returns an approximation of 9 | // the number of days between them. 10 | number Days(string date_a, string date_b) { 11 | return DurationBetween(ParseTime(date_a, "%F"), ParseTime(date_b, "%F")) 12 | .days(); 13 | } 14 | -------------------------------------------------------------------------------- /rc/editor_commands/lib/line_column.cc: -------------------------------------------------------------------------------- 1 | // TODO(2023-09-18): Allow operator< to be defined so that we can just compare 2 | // them directly? Define it close to LineColumn? 3 | bool LessThan(LineColumn a, LineColumn b) { 4 | return a.line() < b.line() || 5 | (a.line() == b.line() && a.column() < b.column()); 6 | } 7 | -------------------------------------------------------------------------------- /rc/editor_commands/lib/paths.cc: -------------------------------------------------------------------------------- 1 | string Basename(string path) { 2 | number last_slash = path.find_last_of("/", path.size()); 3 | if (last_slash == -1) { 4 | return path; 5 | } 6 | return path.substr(last_slash + 1, path.size() - (last_slash + 1)); 7 | } 8 | 9 | string Dirname(string path) { 10 | number last_slash = path.find_last_of("/", path.size()); 11 | if (last_slash == -1) { 12 | return path; 13 | } 14 | return path.substr(0, last_slash); 15 | } 16 | 17 | string Extension(string path) { 18 | number last_dot = path.find_last_of(".", path.size()); 19 | if (last_dot == -1) { 20 | return ""; 21 | } 22 | return path.substr(last_dot + 1, path.size() - (last_dot + 1)); 23 | } 24 | -------------------------------------------------------------------------------- /rc/editor_commands/lib/sections.cc: -------------------------------------------------------------------------------- 1 | LineColumn FindSymbolBegin(Buffer buffer, LineColumn position) { 2 | auto line = buffer.line(position.line()); 3 | number column = position.column(); 4 | while (column > 0) { 5 | if (buffer.symbol_characters().find(line.substr(column - 1, 1), 0) == -1) 6 | return LineColumn(position.line(), column); 7 | column--; 8 | } 9 | return LineColumn(position.line(), column); 10 | } 11 | 12 | LineColumn FindSymbolEnd(Buffer buffer, LineColumn position) { 13 | auto line = buffer.line(position.line()); 14 | number column = position.column(); 15 | while (column + 1 < line.size()) { 16 | if (buffer.symbol_characters().find(line.substr(column + 1, 1), 0) == -1) 17 | return LineColumn(position.line(), column + 1); 18 | column++; 19 | } 20 | editor.SetStatus("Moved from " + position.column().tostring() + " to " + 21 | column.tostring()); 22 | return LineColumn(position.line(), column + 1); 23 | } 24 | -------------------------------------------------------------------------------- /rc/editor_commands/smart-quotes: -------------------------------------------------------------------------------- 1 | // Transforms plain quotes and apostrophes (“"” and “’”) into curvy ones (““”, 2 | // “””, “‘”, and “’”). 3 | 4 | #include "lib/can-remove-previous-prefix" 5 | 6 | // Returns true if the quote that we’re inserting should be an opening quote. 7 | // This is checked just by looking at whether the preceding character is a 8 | // space. 9 | bool IsOpeningQuote() { 10 | int column = buffer.position().column(); 11 | if (column == 0) { 12 | return true; 13 | } 14 | string line = buffer.line(buffer.position().line()); 15 | return line.substr(column - 1, 1) == " "; 16 | } 17 | 18 | string TransformQuotes(string input) { 19 | if (input == "\"") { 20 | return IsOpeningQuote() ? "“" : "”"; 21 | } else if (input == "'") { 22 | if (CanRemovePreviousPrefix("'") || CanRemovePreviousPrefix("’")) { 23 | return "“"; 24 | } 25 | return IsOpeningQuote() ? "‘" : "’"; 26 | } else if (input == ",") { 27 | return CanRemovePreviousPrefix(",") ? "„" : ","; 28 | } 29 | return input; 30 | } 31 | 32 | buffer.AddKeyboardTextTransformer(TransformQuotes); 33 | -------------------------------------------------------------------------------- /rc/hooks/buffer-reload.cc: -------------------------------------------------------------------------------- 1 | #include "../editor_commands/lib/strings.cc" 2 | 3 | if (buffer.path() == "") { 4 | string command = BaseCommand(SkipInitialSpaces(buffer.command())); 5 | // Interactive commands that get a full pts. This must happen here (rather 6 | // than in buffer-first-enter.cc) so that the pts information is set before 7 | // the command is actually spawned. 8 | if (command == "bash" || command == "python" || command == "python3" || 9 | command == "watch" || command == "sh" || command == "gdb" || 10 | command == "fish") 11 | buffer.set_pts(true); 12 | } 13 | -------------------------------------------------------------------------------- /rc/hooks/navigation-buffer-reload.cc: -------------------------------------------------------------------------------- 1 | buffer.SetStatus("Enjoy your navigation."); 2 | 3 | void SetDepthToZero() { 4 | if (navigation_buffer_depth == 0) { 5 | buffer.SetStatus("We're already at the surface."); 6 | return; 7 | } 8 | navigation_buffer_depth = 0; 9 | buffer.Reload(); 10 | buffer.SetStatus("Thought is the wind, and knowledge the sail."); 11 | } 12 | 13 | void IncrementDepth() { 14 | navigation_buffer_depth = navigation_buffer_depth + 1; 15 | buffer.Reload(); 16 | buffer.SetStatus("We must go deeper (" + navigation_buffer_depth.tostring() + 17 | ")"); 18 | } 19 | 20 | void DecrementDepth() { 21 | if (navigation_buffer_depth == 0) { 22 | buffer.SetStatus("We're already at the surface."); 23 | return; 24 | } 25 | navigation_buffer_depth = navigation_buffer_depth - 1; 26 | buffer.Reload(); 27 | buffer.SetStatus("Simplifying view (" + navigation_buffer_depth.tostring() + 28 | ")"); 29 | } 30 | 31 | buffer.AddBinding("sk", "navigation_depth := 0", SetDepthToZero); 32 | buffer.AddBinding("sh", "navigation_depth--", DecrementDepth); 33 | buffer.AddBinding("sl", "navigation_depth++", IncrementDepth); 34 | -------------------------------------------------------------------------------- /rc/tests/BufferReloads/hooks/start.cc: -------------------------------------------------------------------------------- 1 | number x = 0; 2 | 3 | void OnReload(Buffer buffer) { 4 | // Just burn some cycles. 5 | for (number i = 0; i < 1000; i++) buffer.line_count(); 6 | 7 | x = 5678; 8 | } 9 | -------------------------------------------------------------------------------- /screenshots/shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alefore/edge/adc4022485fe4f4ecc752159c2944f540eb53819/screenshots/shot.png -------------------------------------------------------------------------------- /src/buffer_contents_util.cc: -------------------------------------------------------------------------------- 1 | #include "src/buffer_contents_util.h" 2 | 3 | #include "src/language/lazy_string/functional.h" 4 | 5 | using afc::language::lazy_string::ColumnNumber; 6 | using afc::language::lazy_string::FindFirstOf; 7 | using afc::language::lazy_string::FindLastNotOf; 8 | using afc::language::lazy_string::LazyString; 9 | 10 | namespace afc::editor { 11 | LazyString GetCurrentToken(CurrentTokenOptions options) { 12 | LazyString line = 13 | options.contents.at(options.line_column.line).contents().read(); 14 | // Scroll back to the first character outside of the token. If we're in not 15 | // inside a token, this is a no-op. 16 | line = line.Substring( 17 | FindLastNotOf( 18 | line.Substring(ColumnNumber{}, options.line_column.column.ToDelta()), 19 | options.token_characters) 20 | .value_or(ColumnNumber{})); 21 | 22 | // Scroll past any non-token characters. Typically this will just skip the 23 | // character we landed at in the block above. However, if we started in a 24 | // sequence of non-token characters, we skip them all. 25 | if (std::optional start = 26 | FindFirstOf(line, options.token_characters); 27 | start.has_value()) 28 | line = line.Substring(*start); 29 | 30 | if (std::optional end = 31 | FindFirstNotOf(line, options.token_characters); 32 | end.has_value()) 33 | line = line.Substring(ColumnNumber{}, end->ToDelta()); 34 | 35 | return line; 36 | } 37 | } // namespace afc::editor 38 | -------------------------------------------------------------------------------- /src/buffer_contents_util.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_CONTENTS_UTIL_H__ 2 | #define __AFC_EDITOR_BUFFER_CONTENTS_UTIL_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/language/lazy_string/lazy_string.h" 9 | #include "src/language/text/line_column.h" 10 | #include "src/language/text/line_sequence.h" 11 | 12 | namespace afc::editor { 13 | struct CurrentTokenOptions { 14 | const language::text::LineSequence& contents; 15 | language::text::LineColumn line_column; 16 | std::unordered_set token_characters; 17 | }; 18 | language::lazy_string::LazyString GetCurrentToken(CurrentTokenOptions options); 19 | } // namespace afc::editor 20 | #endif // __AFC_EDITOR_BUFFER_CONTENTS_UTIL_H__ 21 | -------------------------------------------------------------------------------- /src/buffer_display_data.cc: -------------------------------------------------------------------------------- 1 | #include "src/buffer_display_data.h" 2 | 3 | #include "src/language/text/line_column.h" 4 | 5 | namespace afc::editor { 6 | using language::ObservableValue; 7 | using language::lazy_string::ColumnNumberDelta; 8 | using language::text::LineColumnDelta; 9 | using language::text::LineNumberDelta; 10 | 11 | ObservableValue& BufferDisplayData::view_size() { 12 | return view_size_; 13 | } 14 | 15 | const ObservableValue& BufferDisplayData::view_size() const { 16 | return view_size_; 17 | } 18 | 19 | void BufferDisplayData::AddDisplayWidth(ColumnNumberDelta display_width) { 20 | max_display_width_ = std::max(max_display_width_, display_width); 21 | } 22 | 23 | ColumnNumberDelta BufferDisplayData::max_display_width() const { 24 | return max_display_width_; 25 | } 26 | 27 | void BufferDisplayData::AddVerticalPrefixSize( 28 | LineNumberDelta vertical_prefix_size) { 29 | min_vertical_prefix_size_ = 30 | std::min(vertical_prefix_size, 31 | min_vertical_prefix_size_.value_or(vertical_prefix_size)); 32 | } 33 | 34 | std::optional BufferDisplayData::min_vertical_prefix_size() 35 | const { 36 | return min_vertical_prefix_size_; 37 | } 38 | 39 | language::text::LineNumberDelta BufferDisplayData::content_lines() const { 40 | return content_lines_; 41 | } 42 | 43 | void BufferDisplayData::set_content_lines( 44 | language::text::LineNumberDelta input) { 45 | content_lines_ = input; 46 | } 47 | } // namespace afc::editor 48 | -------------------------------------------------------------------------------- /src/buffer_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_FLAGS_H__ 2 | #define __AFC_EDITOR_BUFFER_FLAGS_H__ 3 | 4 | #include 5 | 6 | #include "src/buffer.h" 7 | #include "src/infrastructure/screen/line_modifier.h" 8 | 9 | namespace afc::editor { 10 | std::vector GetBufferFlag( 11 | const OpenBuffer& buffer); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_BUFFER_FLAGS_H__ 15 | -------------------------------------------------------------------------------- /src/buffer_metadata_output_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_METADATA_OUTPUT_PRODUCER_H__ 2 | #define __AFC_EDITOR_BUFFER_METADATA_OUTPUT_PRODUCER_H__ 3 | 4 | #include "src/buffer_contents_view_layout.h" 5 | #include "src/columns_vector.h" 6 | #include "src/line_with_cursor.h" 7 | #include "src/parse_tree.h" 8 | 9 | namespace afc::editor { 10 | class OpenBuffer; 11 | 12 | // It is OK for all referenced objects to be deleted after BufferMetadataOutput 13 | // has returned. 14 | struct BufferMetadataOutputOptions { 15 | const OpenBuffer& buffer; 16 | const std::vector& screen_lines; 17 | const ParseTree& zoomed_out_tree; 18 | }; 19 | 20 | // OutputProducer that prints the metadata that is usually shown right after the 21 | // contents of the buffer (at the right side). This includes information from 22 | // LineMarks and the syntax tree. 23 | // 24 | // Generates one element for each value in screen_lines. 25 | ColumnsVector::Column BufferMetadataOutput(BufferMetadataOutputOptions options); 26 | 27 | } // namespace afc::editor 28 | #endif // __AFC_EDITOR_BUFFER_METADATA_OUTPUT_PRODUCER_H__ 29 | -------------------------------------------------------------------------------- /src/buffer_output_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_OUTPUT_PRODUCER_H__ 2 | #define __AFC_EDITOR_BUFFER_OUTPUT_PRODUCER_H__ 3 | 4 | #include "src/buffer.h" 5 | #include "src/buffer_contents_view_layout.h" 6 | #include "src/language/text/line_column.h" 7 | #include "src/line_with_cursor.h" 8 | 9 | namespace afc { 10 | namespace editor { 11 | 12 | // Unlike `CreateBufferOutputProducer`, doesn't do much beyond just displaying 13 | // the contents of the buffer (with syntax highlighting). 14 | // 15 | // The output produced can be shorter than output_producer_options.size.line 16 | // lines long. 17 | LineWithCursor::Generator::Vector ProduceBufferView( 18 | const OpenBuffer& buffer, 19 | const std::vector& lines, 20 | const Widget::OutputProducerOptions& output_producer_options); 21 | 22 | } // namespace editor 23 | } // namespace afc 24 | 25 | #endif // __AFC_EDITOR_BUFFER_OUTPUT_PRODUCER_H__ 26 | -------------------------------------------------------------------------------- /src/buffer_state.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_STATE_H__ 2 | #define __AFC_EDITOR_BUFFER_STATE_H__ 3 | 4 | #include "src/buffer_variables.h" 5 | #include "src/infrastructure/dirname.h" 6 | #include "src/language/text/line_column.h" 7 | #include "src/language/text/line_sequence.h" 8 | #include "src/variables.h" 9 | 10 | namespace afc::editor { 11 | struct BufferVariablesInstance { 12 | EdgeStructInstance bool_variables = 13 | buffer_variables::BoolStruct()->NewInstance(); 14 | EdgeStructInstance string_variables = 15 | buffer_variables::StringStruct()->NewInstance(); 16 | EdgeStructInstance int_variables = 17 | buffer_variables::IntStruct()->NewInstance(); 18 | EdgeStructInstance double_variables = 19 | buffer_variables::DoubleStruct()->NewInstance(); 20 | EdgeStructInstance line_column_variables = 21 | buffer_variables::LineColumnStruct()->NewInstance(); 22 | }; 23 | 24 | language::text::LineSequence SerializeState( 25 | language::text::LineColumn input, 26 | const BufferVariablesInstance& buffer_variables_instance); 27 | } // namespace afc::editor 28 | 29 | #endif // __AFC_EDITOR_BUFFER_STATE_H__ -------------------------------------------------------------------------------- /src/buffer_subtypes.cc: -------------------------------------------------------------------------------- 1 | #include "src/buffer_subtypes.h" 2 | 3 | #include "src/buffer.h" 4 | #include "src/buffer_variables.h" 5 | 6 | namespace afc::editor { 7 | std::variant GetPasteModeVariant( 8 | OpenBuffer& buffer) { 9 | if (buffer.Read(buffer_variables::paste_mode)) 10 | return OpenBufferPasteMode{buffer}; 11 | else 12 | return OpenBufferNoPasteMode{buffer}; 13 | } 14 | 15 | OpenBufferPasteMode::OpenBufferPasteMode(OpenBuffer& buffer) : value(buffer) {} 16 | 17 | OpenBufferNoPasteMode::OpenBufferNoPasteMode(OpenBuffer& buffer) 18 | : value(buffer) {} 19 | 20 | } // namespace afc::editor 21 | -------------------------------------------------------------------------------- /src/buffer_subtypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_SUBTYPES__ 2 | #define __AFC_EDITOR_BUFFER_SUBTYPES__ 3 | 4 | #include 5 | 6 | namespace afc::editor { 7 | class OpenBuffer; 8 | 9 | class OpenBufferPasteMode; 10 | class OpenBufferNoPasteMode; 11 | 12 | std::variant GetPasteModeVariant( 13 | OpenBuffer& buffer); 14 | 15 | struct OpenBufferPasteMode { 16 | OpenBuffer& value; 17 | 18 | private: 19 | OpenBufferPasteMode(OpenBuffer&); 20 | 21 | friend std::variant 22 | GetPasteModeVariant(OpenBuffer& buffer); 23 | }; 24 | 25 | struct OpenBufferNoPasteMode { 26 | OpenBuffer& value; 27 | 28 | private: 29 | OpenBufferNoPasteMode(OpenBuffer&); 30 | 31 | friend std::variant 32 | GetPasteModeVariant(OpenBuffer& buffer); 33 | }; 34 | 35 | } // namespace afc::editor 36 | 37 | #endif // __AFC_EDITOR_BUFFER_SUBTYPES__ 38 | -------------------------------------------------------------------------------- /src/buffer_transformation_adapter.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_BUFFER_TRANSFORMATION_ADAPTER 2 | #define __AFC_EDITOR_BUFFER_TRANSFORMATION_ADAPTER 3 | 4 | #include 5 | 6 | #include "src/infrastructure/screen/line_modifier.h" 7 | #include "src/language/text/line.h" 8 | #include "src/transformation/input.h" 9 | 10 | namespace afc::editor { 11 | class OpenBuffer; 12 | class EditorState; 13 | class TransformationInputAdapterImpl : public transformation::Input::Adapter { 14 | OpenBuffer& buffer_; 15 | 16 | public: 17 | TransformationInputAdapterImpl(OpenBuffer& buffer) : buffer_(buffer) {} 18 | 19 | const language::text::LineSequence contents() const override; 20 | 21 | void SetActiveCursors( 22 | std::vector positions) override; 23 | 24 | language::text::LineColumn InsertInPosition( 25 | const language::text::LineSequence& contents_to_insert, 26 | const language::text::LineColumn& input_position, 27 | const std::optional& modifiers) 28 | override; 29 | 30 | void AddError(language::Error error) override; 31 | 32 | void AddFragment(language::text::LineSequence fragment) override; 33 | }; 34 | } // namespace afc::editor 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_COMMAND_H__ 2 | #define __AFC_EDITOR_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/editor_mode.h" 7 | #include "src/language/ghost_type_class.h" 8 | #include "src/language/lazy_string/single_line.h" 9 | 10 | namespace afc::editor { 11 | struct CommandCategory 12 | : public language::GhostType { 14 | using GhostType::GhostType; 15 | 16 | static const CommandCategory& kBuffers(); 17 | static const CommandCategory& kCppFunctions(); 18 | static const CommandCategory& kEdit(); 19 | static const CommandCategory& kEditor(); 20 | static const CommandCategory& kExtensions(); 21 | static const CommandCategory& kModifiers(); 22 | static const CommandCategory& kNavigate(); 23 | static const CommandCategory& kPrompt(); 24 | static const CommandCategory& kView(); 25 | }; 26 | 27 | class Command : public EditorMode { 28 | public: 29 | virtual ~Command() {} 30 | virtual CommandCategory Category() const = 0; 31 | virtual language::lazy_string::LazyString Description() const = 0; 32 | CursorMode cursor_mode() const override; 33 | }; 34 | } // namespace afc::editor 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/command_mode.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_COMMAND_MODE_H__ 2 | #define __AFC_EDITOR_COMMAND_MODE_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | #include "src/map_mode.h" 8 | 9 | namespace afc::editor { 10 | class EditorState; 11 | language::gc::Root NewCommandMode(EditorState& editor_state); 12 | } // namespace afc::editor 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/concurrent/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "bag", 3 | srcs = ["bag.cc"], 4 | hdrs = ["bag.h"], 5 | visibility = ["//visibility:public"], 6 | deps = [ 7 | ":operation", 8 | "//src/infrastructure:tracker", 9 | ], 10 | ) 11 | 12 | cc_library( 13 | name = "operation", 14 | srcs = ["operation.cc"], 15 | hdrs = ["operation.h"], 16 | visibility = ["//visibility:public"], 17 | deps = [ 18 | ":protected", 19 | ":thread_pool", 20 | ], 21 | ) 22 | 23 | cc_library( 24 | name = "protected", 25 | srcs = ["protected.cc"], 26 | hdrs = ["protected.h"], 27 | visibility = ["//visibility:public"], 28 | deps = [ 29 | "//src/tests", 30 | "//src/tests:concurrent_interfaces", 31 | ], 32 | ) 33 | 34 | cc_library( 35 | name = "thread_pool", 36 | srcs = ["thread_pool.cc"], 37 | hdrs = ["thread_pool.h"], 38 | visibility = ["//visibility:public"], 39 | deps = [":work_queue"], 40 | ) 41 | 42 | cc_library( 43 | name = "work_queue", 44 | srcs = ["work_queue.cc"], 45 | hdrs = ["work_queue.h"], 46 | visibility = ["//visibility:public"], 47 | deps = [ 48 | ":protected", 49 | "//src/futures:delete_notification", 50 | "//src/infrastructure:time", 51 | "//src/language:observers", 52 | "//src/math:decaying_counter", 53 | ], 54 | ) 55 | -------------------------------------------------------------------------------- /src/concurrent/operation.cc: -------------------------------------------------------------------------------- 1 | #include "src/concurrent/operation.h" 2 | 3 | #include "src/concurrent/thread_pool.h" 4 | #include "src/language/safe_types.h" 5 | #include "src/tests/tests.h" 6 | 7 | using afc::language::MakeNonNullUnique; 8 | using afc::language::NonNull; 9 | 10 | namespace afc::concurrent { 11 | namespace { 12 | const bool tests_registration = tests::Register( 13 | L"Concurrent::Operation", 14 | {{.name = L"Empty", 15 | .callback = 16 | [] { 17 | ThreadPool thread_pool(5); 18 | Operation op(thread_pool); 19 | }}, 20 | {.name = L"Sleeps", .callback = [] { 21 | ThreadPool thread_pool(4); 22 | Protected executions(0); 23 | auto op = std::make_unique(thread_pool); 24 | for (size_t i = 0; i < 8; i++) 25 | op->Add([&] { 26 | std::this_thread::sleep_for(std::chrono::milliseconds(500)); 27 | (*executions.lock())++; 28 | }); 29 | op = nullptr; 30 | CHECK_EQ(*executions.lock(), 8); 31 | }}}); 32 | } 33 | 34 | OperationFactory ::OperationFactory( 35 | NonNull> thread_pool) 36 | : thread_pool_(std::move(thread_pool)) {} 37 | 38 | language::NonNull> OperationFactory::New( 39 | std::unique_ptr> tracker_call) { 40 | return MakeNonNullUnique( 41 | thread_pool_.value(), thread_pool_->size() * 2, std::move(tracker_call)); 42 | } 43 | 44 | } // namespace afc::concurrent 45 | -------------------------------------------------------------------------------- /src/concurrent/protected.cc: -------------------------------------------------------------------------------- 1 | #include "src/concurrent/protected.h" 2 | 3 | #include 4 | 5 | #include "src/tests/tests.h" 6 | 7 | namespace afc::concurrent { 8 | namespace { 9 | const bool tests_registration = tests::Register( 10 | L"concurrent::Protected", {{.name = L"MoveWorks", .callback = [] { 11 | Protected foo(5); 12 | Protected bar(50); 13 | Protected quux(100); 14 | foo = std::move(bar); 15 | bar = std::move(quux); 16 | auto foo_lock = foo.lock(); 17 | auto bar_lock = bar.lock(); 18 | CHECK_EQ(*foo_lock, 50); 19 | }}}); 20 | } 21 | } // namespace afc::concurrent 22 | -------------------------------------------------------------------------------- /src/cpp_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_CPP_COMMAND_H__ 2 | #define __AFC_EDITOR_CPP_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/execution_context.h" 7 | #include "src/language/error/value_or_error.h" 8 | #include "src/language/gc.h" 9 | #include "src/language/lazy_string/lazy_string.h" 10 | #include "src/vm/vm.h" 11 | 12 | namespace afc::editor { 13 | class Command; 14 | 15 | language::ValueOrError> NewCppCommand( 16 | ExecutionContext& execution_context, 17 | const language::lazy_string::LazyString& code); 18 | } // namespace afc::editor 19 | 20 | #endif // __AFC_EDITOR_CPP_COMMAND_H__ 21 | -------------------------------------------------------------------------------- /src/cpp_parse_tree.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_CPP_PARSE_TREE_H__ 2 | #define __AFC_EDITOR_CPP_PARSE_TREE_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/language/lazy_string/single_line.h" 8 | #include "src/language/safe_types.h" 9 | #include "src/parse_tree.h" 10 | 11 | namespace afc::editor { 12 | language::NonNull> NewCppTreeParser( 13 | std::unordered_set keywords, 14 | std::unordered_set typos, 15 | IdentifierBehavior identifier_behavior); 16 | } // namespace afc::editor 17 | #endif // __AFC_EDITOR_CPP_PARSE_TREE_H__ 18 | -------------------------------------------------------------------------------- /src/delay_input_receiver.cc: -------------------------------------------------------------------------------- 1 | #include "src/delay_input_receiver.h" 2 | 3 | using afc::infrastructure::ExtendedChar; 4 | 5 | namespace afc::editor { 6 | DelayInputReceiver::DelayInputReceiver(CursorMode cursor_mode) 7 | : cursor_mode_(cursor_mode) {} 8 | 9 | void DelayInputReceiver::ProcessInput(ExtendedChar c) { input_.push_back(c); } 10 | 11 | EditorMode::CursorMode DelayInputReceiver::cursor_mode() const { 12 | return cursor_mode_; 13 | } 14 | 15 | const std::vector& DelayInputReceiver::input() const { 16 | return input_; 17 | } 18 | } // namespace afc::editor 19 | -------------------------------------------------------------------------------- /src/delay_input_receiver.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_DELAY_INPUT_RECEIVER_H__ 2 | #define __AFC_EDITOR_DELAY_INPUT_RECEIVER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/editor_mode.h" 8 | #include "src/infrastructure/extended_char.h" 9 | 10 | namespace afc::editor { 11 | class DelayInputReceiver : public EditorMode { 12 | const CursorMode cursor_mode_; 13 | std::vector input_; 14 | 15 | public: 16 | DelayInputReceiver(CursorMode cursor_mode); 17 | 18 | void ProcessInput(infrastructure::ExtendedChar c) override; 19 | 20 | CursorMode cursor_mode() const override; 21 | 22 | std::vector>> 23 | Expand() const override { 24 | return {}; 25 | }; 26 | 27 | const std::vector& input() const; 28 | }; 29 | } // namespace afc::editor 30 | 31 | #endif // __AFC_EDITOR_DELAY_INPUT_RECEIVER_H__ 32 | -------------------------------------------------------------------------------- /src/direction.cc: -------------------------------------------------------------------------------- 1 | #include "src/direction.h" 2 | 3 | #include 4 | 5 | namespace afc { 6 | namespace editor { 7 | 8 | Direction ReverseDirection(Direction direction) { 9 | switch (direction) { 10 | case Direction::kForwards: 11 | return Direction::kBackwards; 12 | case Direction::kBackwards: 13 | return Direction::kForwards; 14 | } 15 | LOG(FATAL) << "Invalid direction value."; 16 | return Direction::kForwards; 17 | } 18 | 19 | std::wstring ToString(Direction direction) { 20 | switch (direction) { 21 | case Direction::kForwards: 22 | return L"Forwards"; 23 | case Direction::kBackwards: 24 | return L"Backwards"; 25 | } 26 | LOG(FATAL) << "Invalid direction."; 27 | return L"Invalid direction."; 28 | } 29 | 30 | } // namespace editor 31 | } // namespace afc 32 | -------------------------------------------------------------------------------- /src/direction.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_DIRECTION_H__ 2 | #define __AFC_EDITOR_DIRECTION_H__ 3 | 4 | #include 5 | 6 | namespace afc { 7 | namespace editor { 8 | 9 | enum class Direction { kBackwards, kForwards }; 10 | 11 | Direction ReverseDirection(Direction direction); 12 | std::wstring ToString(Direction direction); 13 | 14 | } // namespace editor 15 | } // namespace afc 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/directory_listing.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_DIRECTORY_LISTING_H__ 2 | #define __AFC_EDITOR_DIRECTORY_LISTING_H__ 3 | 4 | #include "src/futures/futures.h" 5 | #include "src/infrastructure/dirname.h" 6 | #include "src/language/error/value_or_error.h" 7 | 8 | namespace afc::editor { 9 | class OpenBuffer; 10 | futures::Value GenerateDirectoryListing( 11 | infrastructure::Path path, OpenBuffer& output); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_DIRECTORY_LISTING_H__ 15 | -------------------------------------------------------------------------------- /src/editor_mode.cc: -------------------------------------------------------------------------------- 1 | #include "src/editor_mode.h" 2 | 3 | namespace afc::editor { 4 | size_t EditorMode::Receive( 5 | const std::vector& input, 6 | size_t start_index) { 7 | CHECK_LT(start_index, input.size()); 8 | ProcessInput(input.at(start_index)); 9 | return 1; 10 | } 11 | } // namespace afc::editor 12 | -------------------------------------------------------------------------------- /src/editor_mode.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_EDITOR_MODE_H__ 2 | #define __AFC_EDITOR_EDITOR_MODE_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/infrastructure/extended_char.h" 8 | #include "src/language/gc.h" 9 | 10 | namespace afc::editor { 11 | 12 | // Rename to something like 'KeyboardHandler'. 13 | class InputReceiver { 14 | public: 15 | virtual ~InputReceiver() = default; 16 | 17 | // Starts processing characters from `input` starting at the index 18 | // `start_index`. Returns the number of characters processed. 19 | // 20 | // Precondition: `start_index` must be less than `input.size()`. 21 | // Postcondition: The returned value must be greater than 0. 22 | // Postcondition: The returned value must be less than `input.size() - 23 | // start_index`. 24 | virtual size_t Receive(const std::vector& input, 25 | size_t start_index) = 0; 26 | 27 | enum class CursorMode { kDefault, kInserting, kOverwriting }; 28 | virtual CursorMode cursor_mode() const = 0; 29 | 30 | virtual std::vector< 31 | language::NonNull>> 32 | Expand() const = 0; 33 | }; 34 | 35 | // TODO(2023-11-29, trivial): Rename this class to `SimpleInputReceiver`. 36 | class EditorMode : public InputReceiver { 37 | public: 38 | size_t Receive(const std::vector& input, 39 | size_t start_index) override; 40 | virtual void ProcessInput(infrastructure::ExtendedChar c) = 0; 41 | }; 42 | } // namespace afc::editor 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/editor_variables.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_EDITOR_VARIABLES_H__ 2 | #define __AFC_EDITOR_EDITOR_VARIABLES_H__ 3 | 4 | #include "src/language/lazy_string/lazy_string.h" 5 | #include "src/variables.h" 6 | #include "src/vm/value.h" 7 | 8 | namespace afc::editor::editor_variables { 9 | 10 | EdgeStruct* StringStruct(); 11 | extern EdgeVariable* const buffer_sort_order; 12 | 13 | EdgeStruct* BoolStruct(); 14 | extern EdgeVariable* const multiple_buffers; 15 | 16 | EdgeStruct* IntStruct(); 17 | extern EdgeVariable* const buffers_to_retain; 18 | extern EdgeVariable* const buffers_to_show; 19 | extern EdgeVariable* const numbers_column_padding; 20 | 21 | EdgeStruct* DoubleStruct(); 22 | extern EdgeVariable* const volume; 23 | 24 | } // namespace afc::editor::editor_variables 25 | 26 | #endif // __AFC_EDITOR_EDITOR_VARIABLES_H__ 27 | -------------------------------------------------------------------------------- /src/editor_vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_EDITOR_VM_H__ 2 | #define __AFC_EDITOR_EDITOR_VM_H__ 3 | 4 | #include "src/infrastructure/file_system_driver.h" 5 | #include "src/language/gc.h" 6 | #include "src/language/safe_types.h" 7 | #include "src/vm/callbacks.h" 8 | 9 | namespace afc::vm { 10 | class Environment; 11 | } // namespace afc::vm 12 | namespace afc::editor { 13 | class EditorState; 14 | // Builds the environment for a given editor. 15 | language::gc::Root BuildEditorEnvironment( 16 | language::gc::Pool& pool, 17 | language::NonNull>); 18 | } // namespace afc::editor 19 | namespace afc::vm { 20 | template <> 21 | struct VMTypeMapper { 22 | static editor::EditorState& get(Value& value); 23 | static const types::ObjectName object_type_name; 24 | }; 25 | } // namespace afc::vm 26 | #endif // __AFC_EDITOR_EDITOR_VM_H__ 27 | -------------------------------------------------------------------------------- /src/find_mode.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_FIND_MODE_H__ 2 | #define __AFC_EDITOR_FIND_MODE_H__ 3 | 4 | #include 5 | 6 | #include "src/transformation/composite.h" 7 | 8 | namespace afc::editor { 9 | class FindTransformation : public CompositeTransformation { 10 | public: 11 | FindTransformation(wchar_t c); 12 | std::wstring Serialize() const override; 13 | futures::Value Apply(Input input) const override; 14 | 15 | private: 16 | std::optional SeekOnce( 17 | const language::text::Line& line, 18 | language::lazy_string::ColumnNumber column, 19 | const Modifiers& modifiers) const; 20 | 21 | const wchar_t c_; 22 | }; 23 | } // namespace afc::editor 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/fragments.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_FRAGMENTS_H__ 2 | #define __AFC_EDITOR_FRAGMENTS_H__ 3 | 4 | #include "src/buffer_filter.h" 5 | #include "src/futures/futures.h" 6 | #include "src/language/gc.h" 7 | #include "src/language/lazy_string/single_line.h" 8 | #include "src/language/text/line_sequence.h" 9 | 10 | namespace afc::editor { 11 | class EditorState; 12 | class OpenBuffer; 13 | 14 | void AddFragment(EditorState& editor, language::text::LineSequence fragment); 15 | 16 | struct FindFragmentQuery { 17 | language::lazy_string::SingleLine filter; 18 | size_t results_limit = 50; 19 | }; 20 | 21 | // Returns up to query.results_limit entries. The output is sorted from the most 22 | // to the least relevant entry. 23 | futures::Value> FindFragment( 24 | EditorState& editor, FindFragmentQuery query); 25 | 26 | } // namespace afc::editor 27 | #endif 28 | -------------------------------------------------------------------------------- /src/frame_output_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_FRAME_OUTPUT_PRODUCER_H__ 2 | #define __AFC_EDITOR_FRAME_OUTPUT_PRODUCER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/language/lazy_string/lazy_string.h" 8 | #include "src/language/safe_types.h" 9 | #include "src/language/text/line.h" 10 | #include "src/language/text/line_column.h" 11 | 12 | namespace afc::editor { 13 | 14 | struct FrameOutputProducerOptions { 15 | language::lazy_string::ColumnNumberDelta width = 16 | language::lazy_string::ColumnNumberDelta(); 17 | language::lazy_string::SingleLine title; 18 | std::optional position_in_parent = std::nullopt; 19 | enum class ActiveState { kActive, kInactive }; 20 | ActiveState active_state = ActiveState::kInactive; 21 | language::lazy_string::SingleLine extra_information = 22 | language::lazy_string::SingleLine(); 23 | language::lazy_string::SingleLine prefix = 24 | language::lazy_string::SingleLine{}; 25 | }; 26 | 27 | language::text::Line FrameLine(FrameOutputProducerOptions options); 28 | } // namespace afc::editor 29 | 30 | #endif // __AFC_EDITOR_FRAME_OUTPUT_PRODUCER_H__ 31 | -------------------------------------------------------------------------------- /src/futures/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "delete_notification", 3 | srcs = ["delete_notification.cc"], 4 | hdrs = ["delete_notification.h"], 5 | visibility = ["//visibility:public"], 6 | deps = [ 7 | ":futures", 8 | ":listenable_value", 9 | ], 10 | ) 11 | 12 | cc_library( 13 | name = "futures", 14 | srcs = ["futures.cc"], 15 | hdrs = ["futures.h"], 16 | visibility = ["//visibility:public"], 17 | deps = [ 18 | "//src/concurrent:protected", 19 | "//src/language:function_traits", 20 | "//src/language:once_only_function", 21 | "//src/language/error:value_or_error", 22 | ], 23 | ) 24 | 25 | cc_library( 26 | name = "listenable_value", 27 | hdrs = ["listenable_value.h"], 28 | visibility = ["//visibility:public"], 29 | ) 30 | 31 | cc_library( 32 | name = "serializer", 33 | srcs = ["serializer.cc"], 34 | hdrs = ["serializer.h"], 35 | deps = [ 36 | ":futures", 37 | ], 38 | ) 39 | -------------------------------------------------------------------------------- /src/futures/delete_notification.cc: -------------------------------------------------------------------------------- 1 | #include "src/futures/delete_notification.h" 2 | 3 | #include "src/language/safe_types.h" 4 | 5 | namespace afc::futures { 6 | using language::EmptyValue; 7 | using language::MakeNonNullShared; 8 | using language::NonNull; 9 | 10 | /* static */ DeleteNotification::Value DeleteNotification::Never() { 11 | return futures::Future().value; 12 | } 13 | 14 | DeleteNotification::DeleteNotification() 15 | : DeleteNotification(futures::Future()) {} 16 | 17 | DeleteNotification::~DeleteNotification() { 18 | std::move(consumer_)(EmptyValue()); 19 | } 20 | 21 | DeleteNotification::Value DeleteNotification::listenable_value() const { 22 | return listenable_value_; 23 | } 24 | 25 | DeleteNotification::DeleteNotification(futures::Future future) 26 | : consumer_(std::move(future.consumer)), 27 | listenable_value_(std::move(future.value)) {} 28 | } // namespace afc::futures 29 | -------------------------------------------------------------------------------- /src/futures/serializer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_FUTURES_SERIALIZER_H__ 2 | #define __AFC_EDITOR_FUTURES_SERIALIZER_H__ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "src/futures/futures.h" 12 | #include "src/language/error/value_or_error.h" 13 | #include "src/language/once_only_function.h" 14 | 15 | namespace afc::futures { 16 | // Receives multiple callbacks concurrently, each returning a future. Ensures 17 | // that they are only executed serially. 18 | // 19 | // The serializer may be deleted before all callbacks have executed; they will 20 | // still execute. 21 | // 22 | // This class is thread-safe. If the futures schedule asynchronous work, they 23 | // must make sure that the notification happens in the same thread that calls 24 | // Push. 25 | class Serializer { 26 | public: 27 | using Callback = 28 | language::OnceOnlyFunction()>; 29 | void Push(Callback callback); 30 | 31 | private: 32 | futures::Value last_execution_ = 33 | futures::Past(language::EmptyValue()); 34 | }; 35 | } // namespace afc::futures 36 | 37 | #endif // __AFC_EDITOR_FUTURES_SERIALIZER_H__ 38 | -------------------------------------------------------------------------------- /src/goto_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_GOTO_COMMAND_H__ 2 | #define __AFC_EDITOR_GOTO_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | #include "src/transformation/composite.h" 8 | 9 | namespace afc::editor { 10 | class Command; 11 | class GotoTransformation : public CompositeTransformation { 12 | public: 13 | GotoTransformation(int calls); 14 | 15 | std::wstring Serialize() const override; 16 | 17 | futures::Value Apply(Input input) const override; 18 | 19 | private: 20 | const int calls_; 21 | }; 22 | 23 | language::gc::Root NewGotoCommand(EditorState& editor_state); 24 | 25 | } // namespace afc::editor 26 | 27 | #endif // __AFC_EDITOR_GOTO_COMMAND_H__ 28 | -------------------------------------------------------------------------------- /src/help_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_HELP_COMMAND_H__ 2 | #define __AFC_EDITOR_HELP_COMMAND_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "command.h" 10 | #include "map_mode.h" 11 | #include "src/language/safe_types.h" 12 | #include "src/language/text/line.h" 13 | 14 | namespace afc::editor { 15 | language::text::LineBuilder DescribeSequence( 16 | const std::vector& input); 17 | language::text::LineBuilder DescribeSequenceWithQuotes( 18 | const std::vector& input); 19 | 20 | language::gc::Root NewHelpCommand( 21 | EditorState& editor_state, const MapModeCommands& commands, 22 | const std::wstring& mode_description); 23 | 24 | } // namespace afc::editor 25 | 26 | #endif // __AFC_EDITOR_HELP_COMMAND_H__ 27 | -------------------------------------------------------------------------------- /src/horizontal_center_output_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_HORIZONTAL_CENTER_OUTPUT_PRODUCER_H__ 2 | #define __AFC_EDITOR_HORIZONTAL_CENTER_OUTPUT_PRODUCER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/infrastructure/screen/line_modifier.h" 8 | #include "src/language/text/line_column.h" 9 | #include "src/line_with_cursor.h" 10 | 11 | namespace afc::editor { 12 | // padding_lines can be shorter than lines (or empty), in which case it will be 13 | // extended to match. 14 | LineWithCursor::Generator::Vector CenterOutput( 15 | LineWithCursor::Generator::Vector lines, 16 | language::lazy_string::ColumnNumberDelta width, 17 | std::vector padding_modifiers); 18 | } // namespace afc::editor 19 | 20 | #endif // __AFC_EDITOR_HORIZONTAL_CENTER_OUTPUT_PRODUCER_H__ 21 | -------------------------------------------------------------------------------- /src/infrastructure/audio.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_INFRASTRUCTURE_AUDIO_H__ 2 | #define __AFC_EDITOR_INFRASTRUCTURE_AUDIO_H__ 3 | 4 | // clang-format off 5 | #include "config.h" 6 | // clang-format on 7 | 8 | #if HAVE_LIBAO 9 | #include 10 | #endif 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "src/language/ghost_type.h" 23 | #include "src/language/safe_types.h" 24 | 25 | namespace afc::infrastructure::audio { 26 | GHOST_TYPE_DOUBLE(Frequency); 27 | GHOST_TYPE(SpeakerValue, int); 28 | GHOST_TYPE_DOUBLE(Volume); 29 | 30 | struct Generator; 31 | 32 | class Player { 33 | public: 34 | using Time = double; 35 | using Duration = double; 36 | 37 | class Lock { 38 | public: 39 | virtual ~Lock() {} 40 | virtual Time time() const = 0; 41 | virtual void Add(Generator) = 0; 42 | }; 43 | 44 | virtual ~Player() {} 45 | virtual language::NonNull> lock() = 0; 46 | virtual void SetVolume(Volume) = 0; 47 | }; 48 | 49 | language::NonNull> NewPlayer(); 50 | language::NonNull> NewNullPlayer(); 51 | 52 | void GenerateBeep(Player& player, Frequency frequency); 53 | void BeepFrequencies(Player& player, Player::Duration duration, 54 | const std::vector& frequencies); 55 | void GenerateAlert(Player& player); 56 | } // namespace afc::infrastructure::audio 57 | 58 | GHOST_TYPE_HASH(afc::infrastructure::audio::Frequency); 59 | 60 | #endif // __AFC_EDITOR_INFRASTRUCTURE_AUDIO_H__ 61 | -------------------------------------------------------------------------------- /src/infrastructure/dirname_vm.cc: -------------------------------------------------------------------------------- 1 | #include "src/infrastructure/dirname_vm.h" 2 | 3 | #include "src/language/error/value_or_error.h" 4 | #include "src/language/gc.h" 5 | #include "src/language/lazy_string/lazy_string.h" 6 | 7 | namespace gc = afc::language::gc; 8 | using afc::infrastructure::Path; 9 | using afc::language::ValueOrError; 10 | using afc::language::lazy_string::LazyString; 11 | 12 | namespace afc::vm { 13 | const Type VMTypeMapper::vmtype = types::String{}; 14 | 15 | ValueOrError vm::VMTypeMapper::get(Value& value) { 16 | return Path::New(value.get_string()); 17 | } 18 | 19 | /* static */ gc::Root VMTypeMapper::New(gc::Pool& pool, 20 | Path value) { 21 | return vm::Value::NewString(pool, value.read()); 22 | } 23 | 24 | } // namespace afc::vm 25 | -------------------------------------------------------------------------------- /src/infrastructure/dirname_vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_INFRASTRUCTURE_DIRNAME_VM_H__ 2 | #define __AFC_INFRASTRUCTURE_DIRNAME_VM_H__ 3 | 4 | #include 5 | 6 | #include "src/infrastructure/dirname.h" 7 | #include "src/language/gc.h" 8 | #include "src/language/safe_types.h" 9 | #include "src/vm/callbacks.h" 10 | #include "src/vm/value.h" 11 | 12 | namespace afc::vm { 13 | template <> 14 | struct VMTypeMapper { 15 | static language::ValueOrError get(Value& value); 16 | static language::gc::Root New(language::gc::Pool& pool, 17 | infrastructure::Path value); 18 | static const Type vmtype; 19 | }; 20 | } // namespace afc::vm 21 | #endif // __AFC_INFRASTRUCTURE_DIRNAME_VM_H__ 22 | -------------------------------------------------------------------------------- /src/infrastructure/execution.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_INFRASTRUCTURE_EXECUTION__ 2 | #define __AFC_EDITOR_INFRASTRUCTURE_EXECUTION__ 3 | 4 | #include 5 | #include 6 | 7 | #include "poll.h" 8 | #include "src/infrastructure/file_system_driver.h" 9 | #include "src/infrastructure/time.h" 10 | 11 | namespace afc::infrastructure::execution { 12 | class IterationHandler { 13 | public: 14 | virtual ~IterationHandler() = default; 15 | 16 | virtual void AddHandler(FileDescriptor, int requested_events, 17 | std::function handler) = 0; 18 | }; 19 | 20 | struct ExecutionEnvironmentOptions { 21 | std::function stop_check; 22 | std::function()> get_next_alarm; 23 | std::function on_signals; 24 | std::function on_iteration; 25 | }; 26 | 27 | class ExecutionEnvironment { 28 | const ExecutionEnvironmentOptions options_; 29 | 30 | public: 31 | ExecutionEnvironment(ExecutionEnvironmentOptions options); 32 | 33 | void Run(); 34 | }; 35 | } // namespace afc::infrastructure::execution 36 | 37 | #endif -------------------------------------------------------------------------------- /src/infrastructure/extended_char.cc: -------------------------------------------------------------------------------- 1 | #include "src/infrastructure/extended_char.h" 2 | 3 | #include "src/language/container.h" 4 | 5 | using afc::language::lazy_string::LazyString; 6 | 7 | namespace afc::infrastructure { 8 | std::vector VectorExtendedChar(const LazyString& input) { 9 | // Why spell the vector type explicitly? To trigger conversion from 10 | // NonNull> to NonNull>. 11 | return language::container::Materialize>(input); 12 | } 13 | 14 | } // namespace afc::infrastructure 15 | -------------------------------------------------------------------------------- /src/infrastructure/extended_char.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_INFRASTRUCTURE_CONTROL_CHARACTER__ 2 | #define __AFC_INFRASTRUCTURE_CONTROL_CHARACTER__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/language/lazy_string/lazy_string.h" 9 | 10 | namespace afc::infrastructure { 11 | enum class ControlChar { 12 | kEscape, 13 | kDownArrow, 14 | kUpArrow, 15 | kLeftArrow, 16 | kRightArrow, 17 | kBackspace, 18 | kPageDown, 19 | kPageUp, 20 | kCtrlL, 21 | kCtrlV, 22 | kCtrlU, 23 | kCtrlK, 24 | kCtrlD, 25 | kCtrlA, 26 | kCtrlE, 27 | kDelete, 28 | kHome, 29 | kEnd 30 | }; 31 | 32 | // Represents either a regular wchar_t, or a special control character. 33 | using ExtendedChar = std::variant; 34 | 35 | std::vector VectorExtendedChar( 36 | const language::lazy_string::LazyString&); 37 | 38 | } // namespace afc::infrastructure 39 | #endif 40 | -------------------------------------------------------------------------------- /src/infrastructure/extended_char_vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_INFRASTRUCTURE_EXTENDED_CHAR_VM_H__ 2 | #define __AFC_INFRASTRUCTURE_EXTENDED_CHAR_VM_H__ 3 | 4 | #include "src/concurrent/protected.h" 5 | #include "src/infrastructure/extended_char.h" 6 | #include "src/language/gc.h" 7 | #include "src/language/safe_types.h" 8 | #include "src/vm/callbacks.h" 9 | #include "src/vm/environment.h" 10 | 11 | using afc::concurrent::Protected; 12 | 13 | namespace afc::infrastructure { 14 | void RegisterVectorExtendedChar(language::gc::Pool&, vm::Environment&); 15 | } 16 | namespace afc::vm { 17 | template <> 18 | struct VMTypeMapper { 19 | static language::gc::Root New(language::gc::Pool& pool, 20 | afc::infrastructure::ExtendedChar value); 21 | static afc::infrastructure::ExtendedChar get(Value& value); 22 | static const types::ObjectName object_type_name; 23 | }; 24 | 25 | template <> 26 | const types::ObjectName VMTypeMapper>>>>::object_type_name; 28 | } // namespace afc::vm 29 | #endif // __AFC_INFRASTRUCTURE_EXTENDED_CHAR_VM_H__ 30 | -------------------------------------------------------------------------------- /src/infrastructure/regular_file_adapter.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_INFRASTRUCTURE_REGULAR_FILE_ADAPTER_H__ 2 | #define __AFC_INFRASTRUCTURE_REGULAR_FILE_ADAPTER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "src/futures/futures.h" 10 | #include "src/infrastructure/file_adapter.h" 11 | #include "src/infrastructure/file_system_driver.h" 12 | #include "src/infrastructure/screen/line_modifier.h" 13 | #include "src/language/error/value_or_error.h" 14 | #include "src/language/lazy_string/lazy_string.h" 15 | #include "src/language/safe_types.h" 16 | #include "src/language/text/line.h" 17 | #include "src/language/text/line_column.h" 18 | 19 | namespace afc::infrastructure { 20 | class RegularFileAdapter : public FileAdapter { 21 | public: 22 | struct Options { 23 | concurrent::ThreadPoolWithWorkQueue& thread_pool; 24 | std::function)> insert_lines; 25 | }; 26 | 27 | private: 28 | const Options options_; 29 | 30 | public: 31 | RegularFileAdapter(Options options); 32 | void UpdateSize() override; 33 | 34 | std::optional position() const override; 35 | void SetPositionToZero() override; 36 | 37 | futures::Value ReceiveInput( 38 | language::lazy_string::LazyString str, 39 | const infrastructure::screen::LineModifierSet& modifiers) override; 40 | 41 | bool WriteSignal(infrastructure::UnixSignal signal) override; 42 | }; 43 | } // namespace afc::infrastructure 44 | #endif // __AFC_INFRASTRUCTURE_REGULAR_FILE_ADAPTER_H__ 45 | -------------------------------------------------------------------------------- /src/infrastructure/screen/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "cursors", 3 | srcs = ["cursors.cc"], 4 | hdrs = ["cursors.h"], 5 | visibility = ["//src/transformation:__pkg__"], 6 | deps = [ 7 | "//src/futures", 8 | "//src/language/lazy_string:append", 9 | "//src/language/lazy_string:char_buffer", 10 | "//src/language/lazy_string:substring", 11 | "//src/language/text:line_column", 12 | ], 13 | ) 14 | 15 | cc_library( 16 | name = "line_modifier", 17 | srcs = ["line_modifier.cc"], 18 | hdrs = ["line_modifier.h"], 19 | visibility = ["//visibility:public"], 20 | deps = [ 21 | "//src/language:hash", 22 | ], 23 | ) 24 | 25 | cc_library( 26 | name = "screen", 27 | hdrs = ["screen.h"], 28 | visibility = ["//visibility:public"], 29 | ) 30 | 31 | cc_library( 32 | name = "visual_overlay", 33 | srcs = ["visual_overlay.cc"], 34 | hdrs = ["visual_overlay.h"], 35 | visibility = ["//visibility:public"], 36 | deps = [ 37 | ":line_modifier", 38 | "//src/language:ghost_type", 39 | "//src/language/lazy_string", 40 | "//src/language/text:line", 41 | ], 42 | ) 43 | -------------------------------------------------------------------------------- /src/infrastructure/screen/line_modifier.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_INFRASTRUCTURE_LINE_MODIFIER_H__ 2 | #define __AFC_EDITOR_INFRASTRUCTURE_LINE_MODIFIER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/language/hash.h" 9 | #include "src/language/lazy_string/lazy_string.h" 10 | 11 | namespace afc::infrastructure::screen { 12 | enum class LineModifier { 13 | kReset, 14 | kBold, 15 | kItalic, 16 | kDim, 17 | kUnderline, 18 | kReverse, 19 | kBlack, 20 | kRed, 21 | kGreen, 22 | kBlue, 23 | kCyan, 24 | kYellow, 25 | kMagenta, 26 | kWhite, 27 | kBgRed, 28 | }; 29 | 30 | using LineModifierSet = 31 | std::unordered_set; 32 | 33 | language::lazy_string::LazyString ModifierToString(LineModifier modifier); 34 | LineModifier ModifierFromString(std::string modifier); 35 | 36 | void ToggleModifier(LineModifier m, LineModifierSet& output); 37 | 38 | std::ostream& operator<<(std::ostream& os, const LineModifierSet& s); 39 | 40 | } // namespace afc::infrastructure::screen 41 | 42 | #endif // __AFC_EDITOR_INFRASTRUCTURE_LINE_MODIFIER_H__ 43 | -------------------------------------------------------------------------------- /src/infrastructure/time_human.cc: -------------------------------------------------------------------------------- 1 | #include "src/infrastructure/time_human.h" 2 | 3 | #include "src/language/lazy_string/lazy_string.h" 4 | #include "src/language/lazy_string/single_line.h" 5 | 6 | using afc::language::Error; 7 | using afc::language::Success; 8 | using afc::language::lazy_string::LazyString; 9 | using afc::language::lazy_string::NonEmptySingleLine; 10 | using afc::language::lazy_string::SingleLine; 11 | 12 | namespace afc::infrastructure { 13 | language::ValueOrError HumanReadableTime( 14 | const struct timespec& time) { 15 | struct tm tm_value; 16 | if (localtime_r(&time.tv_sec, &tm_value) == nullptr) 17 | return Error{LazyString{L"localtime_r failed"}}; 18 | char buffer[1024]; 19 | size_t len = strftime(buffer, sizeof(buffer), "%Y-%m-%e %T %z", &tm_value); 20 | if (len == 0) return Error{LazyString{L"strftime failed"}}; 21 | snprintf(buffer + len, sizeof(buffer) - len, ".%09ld", time.tv_nsec); 22 | return NonEmptySingleLine::New(SingleLine::New(LazyString{ 23 | language::FromByteString(std::string(buffer, strlen(buffer)))})); 24 | } 25 | } // namespace afc::infrastructure 26 | -------------------------------------------------------------------------------- /src/infrastructure/time_human.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SRC_INFRASTRUCTURE_TIME_HUMAN_H__ 2 | #define __AFC_EDITOR_SRC_INFRASTRUCTURE_TIME_HUMAN_H__ 3 | 4 | #include "src/infrastructure/time.h" 5 | #include "src/language/error/value_or_error.h" 6 | #include "src/language/lazy_string/lazy_string.h" 7 | #include "src/language/lazy_string/single_line.h" 8 | 9 | namespace afc::infrastructure { 10 | language::ValueOrError 11 | HumanReadableTime(const Time& time); 12 | } 13 | 14 | #endif // __AFC_EDITOR_SRC_INFRASTRUCTURE_TIME_HUMAN_H__ 15 | -------------------------------------------------------------------------------- /src/insert_history.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_INSERT_HISTORY_H__ 2 | #define __AFC_EDITOR_INSERT_HISTORY_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/language/safe_types.h" 9 | #include "src/language/text/line_sequence.h" 10 | 11 | namespace afc::editor { 12 | class EditorState; 13 | 14 | class InsertHistory { 15 | public: 16 | InsertHistory() = default; 17 | 18 | void Append(const language::text::LineSequence& insertion); 19 | 20 | const std::vector& get() const; 21 | 22 | struct SearchOptions { 23 | language::lazy_string::SingleLine query; 24 | }; 25 | 26 | // Return the entry from the history that best fits `search_options`. For now, 27 | // that's just the most recent entry. 28 | std::optional Search( 29 | EditorState& editor, SearchOptions search_options); 30 | 31 | private: 32 | std::vector history_; 33 | }; 34 | } // namespace afc::editor 35 | 36 | #endif // __AFC_EDITOR_INSERT_HISTORY_H__ 37 | -------------------------------------------------------------------------------- /src/insert_history_buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_INSERT_HISTORY_BUFFER_H__ 2 | #define __AFC_EDITOR_INSERT_HISTORY_BUFFER_H__ 3 | 4 | namespace afc::editor { 5 | class EditorState; 6 | 7 | void ShowInsertHistoryBuffer(EditorState& editor); 8 | } // namespace afc::editor 9 | 10 | #endif // __AFC_EDITOR_INSERT_HISTORY_BUFFER_H__ 11 | -------------------------------------------------------------------------------- /src/language/error/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "value_or_error", 3 | srcs = ["value_or_error.cc"], 4 | hdrs = ["value_or_error.h"], 5 | visibility = ["//visibility:public"], 6 | deps = [ 7 | "//src/language:ghost_type", 8 | "//src/language:overload", 9 | "//src/language:safe_types", 10 | "//src/language:wstring", 11 | "//src/language/lazy_string", 12 | "//src/language/lazy_string:append", 13 | "//src/language/lazy_string:char_buffer", 14 | "//src/tests", 15 | ], 16 | ) 17 | 18 | cc_library( 19 | name = "view", 20 | hdrs = ["view.h"], 21 | visibility = ["//visibility:public"], 22 | ) 23 | -------------------------------------------------------------------------------- /src/language/error/log.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_LANGUAGE_ERROR_LOG_H__ 2 | #define __AFC_EDITOR_LANGUAGE_ERROR_LOG_H__ 3 | 4 | #include "src/concurrent/protected.h" 5 | #include "src/infrastructure/time.h" 6 | #include "src/language/error/value_or_error.h" 7 | 8 | namespace afc::language::error { 9 | 10 | // This class is thread-safe. 11 | class Log { 12 | public: 13 | enum class InsertResult { kInserted, kAlreadyFound }; 14 | InsertResult Insert(language::Error error, infrastructure::Duration duration); 15 | 16 | private: 17 | struct ErrorAndExpiration { 18 | language::Error error; 19 | infrastructure::Time expiration; 20 | }; 21 | 22 | concurrent::Protected> entries_; 23 | }; 24 | } // namespace afc::language::error 25 | 26 | #endif // __AFC_EDITOR_LANGUAGE_ERROR_LOG_H__ 27 | -------------------------------------------------------------------------------- /src/language/error/value_or_error.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/error/value_or_error.h" 2 | 3 | #include "glog/logging.h" 4 | #include "src/language/lazy_string/append.h" 5 | #include "src/language/lazy_string/char_buffer.h" 6 | #include "src/language/wstring.h" 7 | #include "src/tests/tests.h" 8 | 9 | using afc::language::lazy_string::LazyString; 10 | 11 | namespace afc::language { 12 | Error AugmentError(language::lazy_string::LazyString prefix, Error error) { 13 | return Error{prefix + LazyString{L": "} + error.read()}; 14 | } 15 | 16 | // Precondition: `errors` must be non-empty. 17 | Error MergeErrors(const std::vector& errors, 18 | const std::wstring& separator) { 19 | CHECK(!errors.empty()); 20 | return Error(Concatenate( 21 | errors | std::views::transform([](const Error& e) { return e.read(); }) | 22 | Intersperse(LazyString{separator}))); 23 | } 24 | 25 | ValueOrError Success() { 26 | return ValueOrError(EmptyValue()); 27 | } 28 | 29 | void IgnoreErrors::operator()(Error) {} 30 | 31 | namespace { 32 | bool tests_register = tests::Register( 33 | L"ValueOrError", {{.name = L"EmptyConstructor", .callback = [] { 34 | ValueOrError foo; 35 | CHECK(!IsError(foo)); 36 | CHECK_EQ(std::get(foo), int()); 37 | }}}); 38 | } // namespace 39 | } // namespace afc::language 40 | -------------------------------------------------------------------------------- /src/language/error/view.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_ERROR_VIEW_H__ 2 | #define __AFC_LANGUAGE_ERROR_VIEW_H__ 3 | 4 | #include "src/language/container.h" 5 | #include "src/language/error/value_or_error.h" 6 | 7 | namespace afc::language::view { 8 | 9 | // View that removes errors from a range of `ValueOrError` instances and 10 | // unwraps the values (into just `T`). 11 | inline constexpr auto SkipErrors = 12 | std::views::filter([](const auto& v) { return !IsError(v); }) | 13 | std::views::transform([](auto v) { return ValueOrDie(std::move(v)); }); 14 | 15 | inline constexpr auto GetErrors = 16 | std::views::filter([](const auto& v) { return IsError(v); }) | 17 | std::views::transform([](auto& v) { return std::get(v); }); 18 | 19 | template 20 | ValueOrError> ExtractErrors(std::vector> input) { 21 | if (std::vector errors = 22 | container::MaterializeVector(input | GetErrors); 23 | !errors.empty()) 24 | return MergeErrors(errors, L", "); 25 | return container::MaterializeVector(input | SkipErrors); 26 | } 27 | 28 | } // namespace afc::language::view 29 | 30 | #endif // __AFC_LANGUAGE_ERROR_VIEW_H__ 31 | -------------------------------------------------------------------------------- /src/language/function_traits.h: -------------------------------------------------------------------------------- 1 | // Defines a `function_traits` templated type with a few specializations. 2 | // 3 | // Given a type of a callable, defines these symbols: 4 | // 5 | // `ReturnType`: The type that the callable returns. 6 | // `ArgType`: A typle with the types of all the arguments. 7 | // `arity`: A constexpr with the number of arguments expected. 8 | #ifndef __AFC_EDITOR_FUNCTION_TRAITS_H__ 9 | #define __AFC_EDITOR_FUNCTION_TRAITS_H__ 10 | 11 | namespace afc::language { 12 | template 13 | struct function_traits : public function_traits {}; 14 | 15 | template 16 | struct function_traits { 17 | using ReturnType = R; 18 | using ArgTuple = std::tuple; 19 | static constexpr auto arity = sizeof...(Args); 20 | }; 21 | 22 | template 23 | struct function_traits { 24 | using ReturnType = R; 25 | using ArgTuple = std::tuple; 26 | static constexpr auto arity = sizeof...(Args); 27 | }; 28 | 29 | template 30 | struct function_traits { 31 | using ReturnType = R; 32 | using ArgTuple = std::tuple; 33 | static constexpr auto arity = sizeof...(Args); 34 | }; 35 | 36 | template 37 | struct function_traits { 38 | using ReturnType = R; 39 | using ArgTuple = std::tuple; 40 | static constexpr auto arity = sizeof...(Args); 41 | }; 42 | } // namespace afc::language 43 | 44 | #endif // __AFC_EDITOR_FUNCTION_TRAITS_H__ 45 | -------------------------------------------------------------------------------- /src/language/gc_container.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_GC_CONTAINER_H__ 2 | #define __AFC_LANGUAGE_GC_CONTAINER_H__ 3 | 4 | #include 5 | 6 | #include "src/language/container.h" 7 | #include "src/language/gc.h" 8 | #include "src/language/gc_view.h" 9 | 10 | namespace afc::language::gc { 11 | template 12 | struct ExpandHelper>> { 13 | std::vector>> operator()( 14 | const std::vector>& input) { 15 | return container::MaterializeVector(input | gc::view::ObjectMetadata); 16 | } 17 | }; 18 | 19 | } // namespace afc::language::gc 20 | #endif // __AFC_LANGUAGE_GC_CONTAINER_H__ 21 | -------------------------------------------------------------------------------- /src/language/ghost_type.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/ghost_type.h" 2 | 3 | #include 4 | 5 | namespace afc::language { 6 | std::wstring to_wstring(std::wstring s) { return s; } 7 | } // namespace afc::language 8 | -------------------------------------------------------------------------------- /src/language/hash.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/hash.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "src/tests/tests.h" 8 | 9 | namespace afc::language { 10 | namespace { 11 | const bool line_tests_registration = tests::Register( 12 | L"Hash", {{.name = L"HashableContainerFromVector", 13 | .callback = 14 | [] { 15 | HashableContainer> elements( 16 | {L"alejo", L"selina", L"tintín"}); 17 | size_t initial_hash = compute_hash(elements); 18 | elements.container.push_back(L"gael"); 19 | CHECK(compute_hash(elements) != initial_hash); 20 | elements.container.pop_back(); 21 | CHECK(compute_hash(elements) == initial_hash); 22 | }}, 23 | {.name = L"WithHash", .callback = [] { 24 | auto value = std::make_shared(0); 25 | size_t initial_hash = 26 | compute_hash(MakeWithHash(value, compute_hash(*value))); 27 | *value = 4; 28 | CHECK(compute_hash(MakeWithHash( 29 | value, compute_hash(*value))) != initial_hash); 30 | }}}); 31 | } // namespace 32 | } // namespace afc::language 33 | -------------------------------------------------------------------------------- /src/language/lazy_string/char_buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_CHAR_BUFFER_H__ 2 | #define __AFC_EDITOR_CHAR_BUFFER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/language/lazy_string/lazy_string.h" 8 | #include "src/language/safe_types.h" 9 | 10 | namespace afc::language::lazy_string { 11 | LazyString NewMoveableCharBuffer(const wchar_t* const* buffer, size_t size); 12 | LazyString NewCharBuffer(const wchar_t* buffer, size_t size); 13 | LazyString NewCharBufferWithOwnership(const wchar_t* buffer, size_t size); 14 | LazyString NewCopyCharBuffer(const wchar_t* buffer); 15 | LazyString NewLazyString(std::vector input); 16 | } // namespace afc::language::lazy_string 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/language/lazy_string/lowercase.h: -------------------------------------------------------------------------------- 1 | // TODO(trivial, 2024-08-28): Move to `case.h`, since this can also conver to 2 | // upper case. 3 | #ifndef __AFC_LANGUAGE_LAZY_STRING_LOWERCASE_H__ 4 | #define __AFC_LANGUAGE_LAZY_STRING_LOWERCASE_H__ 5 | 6 | #include 7 | 8 | #include "src/language/lazy_string/lazy_string.h" 9 | #include "src/language/lazy_string/single_line.h" 10 | #include "src/language/safe_types.h" 11 | 12 | namespace afc::language::lazy_string { 13 | LazyString LowerCase(LazyString input); 14 | LazyString UpperCase(LazyString input); 15 | 16 | SingleLine LowerCase(SingleLine input); 17 | SingleLine UpperCase(SingleLine input); 18 | 19 | NonEmptySingleLine LowerCase(NonEmptySingleLine input); 20 | NonEmptySingleLine UpperCase(NonEmptySingleLine input); 21 | } // namespace afc::language::lazy_string 22 | 23 | #endif // __AFC_LANGUAGE_LAZY_STRING_LOWERCASE_H__ 24 | -------------------------------------------------------------------------------- /src/language/lazy_string/trim.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_LAZY_STRING_TRIM_H__ 2 | #define __AFC_LANGUAGE_LAZY_STRING_TRIM_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/infrastructure/tracker.h" 8 | #include "src/language/lazy_string/lazy_string.h" 9 | #include "src/language/lazy_string/single_line.h" 10 | #include "src/language/safe_types.h" 11 | 12 | namespace afc::language::lazy_string { 13 | // Returns a copy with all left space characters removed. 14 | template 15 | StringType TrimLeft(StringType source, 16 | const std::unordered_set& space_characters) { 17 | TRACK_OPERATION(LazyString_StringTrimLeft); 18 | return source.Substring(FindFirstNotOf(source, space_characters) 19 | .value_or(ColumnNumber(0) + source.size())); 20 | } 21 | 22 | // StringType is expected to be either LazyString or SingleLine. 23 | template 24 | StringType Trim(StringType in, 25 | const std::unordered_set& space_characters) { 26 | if (std::optional begin = FindFirstNotOf(in, space_characters); 27 | begin.has_value()) { 28 | if (std::optional end = FindLastNotOf(in, space_characters); 29 | end.has_value()) 30 | return in.Substring(*begin, *end - *begin + ColumnNumberDelta{1}); 31 | } 32 | return StringType{}; 33 | } 34 | } // namespace afc::language::lazy_string 35 | 36 | #endif // __AFC_LANGUAGE_LAZY_STRING_TRIM_H__ 37 | -------------------------------------------------------------------------------- /src/language/lazy_value.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/lazy_value.h" 2 | 3 | #include 4 | 5 | #include "src/tests/tests.h" 6 | 7 | namespace afc::language { 8 | namespace { 9 | const bool filter_to_range_tests_registration = tests::Register( 10 | L"LazyValue", {{.name = L"NeverRuns", 11 | .callback = 12 | [] { 13 | bool run = false; 14 | LazyValue([&run] { 15 | CHECK(!run); 16 | run = true; 17 | return 5; 18 | }); 19 | CHECK(!run); 20 | }}, 21 | {.name = L"RunsAndReturnsValid", .callback = [] { 22 | bool run = false; 23 | LazyValue lazy_value([&run] { 24 | CHECK(!run); 25 | run = true; 26 | return 549; 27 | }); 28 | for (size_t i = 0; i < 10; i++) { 29 | CHECK_EQ(lazy_value.get(), 549); 30 | CHECK(run); 31 | } 32 | }}}); 33 | } // namespace 34 | } // namespace afc::language 35 | -------------------------------------------------------------------------------- /src/language/observers_gc.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_OBSERVERS_GC_H__ 2 | #define __AFC_EDITOR_OBSERVERS_GC_H__ 3 | 4 | #include "src/concurrent/protected.h" 5 | #include "src/language/gc.h" 6 | #include "src/language/observers.h" 7 | 8 | namespace afc::language { 9 | template 10 | static Observers::Observer WeakPtrLockingObserver( 11 | Callable callable, language::gc::WeakPtr

data) { 12 | return [data, callable] { 13 | return VisitPointer( 14 | data.Lock(), 15 | [callable](language::gc::Root

root) { 16 | callable(root.ptr().value()); 17 | return Observers::State::kAlive; 18 | }, 19 | [] { return Observers::State::kExpired; }); 20 | }; 21 | } 22 | } // namespace afc::language 23 | #endif // __AFC_EDITOR_OBSERVERS_GC_H__ 24 | -------------------------------------------------------------------------------- /src/language/once_only_function.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_ONCE_ONLY_FUNCTION_H__ 2 | #define __AFC_LANGUAGE_ONCE_ONLY_FUNCTION_H__ 3 | 4 | #include 5 | 6 | #include // For std::move_only_function 7 | #include 8 | #include 9 | 10 | namespace afc::language { 11 | template 12 | class OnceOnlyFunction; 13 | 14 | template 15 | class OnceOnlyFunction { 16 | std::move_only_function func_; 17 | 18 | template 19 | friend class OnceOnlyFunction; 20 | 21 | public: 22 | template 23 | OnceOnlyFunction(Callable&& callable) 24 | : func_(std::forward(callable)) { 25 | CHECK(func_ != nullptr); 26 | } 27 | 28 | template 29 | OnceOnlyFunction(OnceOnlyFunction&& other) 30 | : OnceOnlyFunction(std::move(other.func_)) {} 31 | 32 | OnceOnlyFunction(OnceOnlyFunction&&) = default; 33 | OnceOnlyFunction(const OnceOnlyFunction&) = delete; 34 | OnceOnlyFunction& operator=(const OnceOnlyFunction&) = delete; 35 | OnceOnlyFunction& operator=(OnceOnlyFunction&& other) noexcept = default; 36 | 37 | Ret operator()(Args... args) && { return func_(std::forward(args)...); } 38 | }; 39 | } // namespace afc::language 40 | #endif // __AFC_LANGUAGE_ONCE_ONLY_FUNCTION_H__ 41 | -------------------------------------------------------------------------------- /src/language/overload.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_OVERLOAD_H__ 2 | #define __AFC_LANGUAGE_OVERLOAD_H__ 3 | 4 | namespace afc::language { 5 | template 6 | struct overload : Ts... { 7 | using Ts::operator()...; 8 | }; 9 | template 10 | overload(Ts...) -> overload; 11 | } // namespace afc::language 12 | #endif 13 | -------------------------------------------------------------------------------- /src/language/text/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "line", 3 | srcs = [ 4 | "line.cc", 5 | ], 6 | hdrs = [ 7 | "line.h", 8 | ], 9 | visibility = ["//visibility:public"], 10 | deps = [ 11 | ":line_column", 12 | "//src/concurrent:protected", 13 | "//src/futures", 14 | "//src/futures:listenable_value", 15 | "//src/infrastructure/screen:line_modifier", 16 | "//src/language:observers", 17 | "//src/language:safe_types", 18 | "//src/language/lazy_string", 19 | "//src/language/lazy_string:append", 20 | "//src/language/lazy_string:substring", 21 | ], 22 | ) 23 | 24 | cc_library( 25 | name = "line_column", 26 | srcs = ["line_column.cc"], 27 | hdrs = ["line_column.h"], 28 | visibility = ["//visibility:public"], 29 | deps = [ 30 | "//src/language:hash", 31 | "//src/language:safe_types", 32 | "//src/language:wstring", 33 | "//src/language/error:value_or_error", 34 | "//src/language/lazy_string", 35 | "//src/language/lazy_string:char_buffer", 36 | "//src/tests:fuzz", 37 | "//src/vm:environment", 38 | ], 39 | ) 40 | 41 | cc_library( 42 | name = "line_column_vm", 43 | srcs = ["line_column_vm.cc"], 44 | hdrs = ["line_column_vm.h"], 45 | visibility = ["//visibility:public"], 46 | deps = [ 47 | "//src/language:safe_types", 48 | "//src/language/text:line_column", 49 | "//src/vm:callbacks", 50 | "//src/vm:container", 51 | ], 52 | ) 53 | -------------------------------------------------------------------------------- /src/language/text/delegating_mutable_line_sequence_observer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_TEXT_DELEGATING_MUTABLE_LINE_SEQUENCE_OBSERVER_H__ 2 | #define __AFC_LANGUAGE_TEXT_DELEGATING_MUTABLE_LINE_SEQUENCE_OBSERVER_H__ 3 | 4 | #include "src/language/text/mutable_line_sequence.h" 5 | 6 | namespace afc::language::text { 7 | class DelegatingMutableLineSequenceObserver 8 | : public MutableLineSequenceObserver { 9 | public: 10 | using Delegate = 11 | language::NonNull>; 12 | DelegatingMutableLineSequenceObserver(std::vector delegates); 13 | 14 | void LinesInserted(language::text::LineNumber position, 15 | language::text::LineNumberDelta size) override; 16 | void LinesErased(language::text::LineNumber position, 17 | language::text::LineNumberDelta size) override; 18 | void SplitLine(language::text::LineColumn position) override; 19 | void FoldedLine(language::text::LineColumn position) override; 20 | void Sorted() override; 21 | void AppendedToLine(language::text::LineColumn position) override; 22 | void DeletedCharacters( 23 | language::text::LineColumn position, 24 | language::lazy_string::ColumnNumberDelta amount) override; 25 | void SetCharacter(language::text::LineColumn position) override; 26 | void InsertedCharacter(language::text::LineColumn position) override; 27 | 28 | private: 29 | const std::vector delegates_; 30 | }; 31 | } // namespace afc::language::text 32 | 33 | #endif // __AFC_LANGUAGE_TEXT_DELEGATING_MUTABLE_LINE_SEQUENCE_OBSERVER_H__ 34 | -------------------------------------------------------------------------------- /src/language/text/line_processor_map.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/text/line_processor_map.h" 2 | 3 | #include "src/infrastructure/tracker.h" 4 | #include "src/language/container.h" 5 | #include "src/language/overload.h" 6 | 7 | namespace afc::language::text { 8 | void LineProcessorMap::Add(LineProcessorKey key, Callback callback) { 9 | callbacks_.lock( 10 | [&key, &callback](std::map& data) { 11 | InsertOrDie(data, {key, std::move(callback)}); 12 | }); 13 | } 14 | 15 | std::map LineProcessorMap::Process( 16 | LineProcessorInput input) const { 17 | TRACK_OPERATION(LineProcessorMap_Process); 18 | return callbacks_.lock([&input]( 19 | const std::map& data) { 20 | std::map output; 21 | std::ranges::for_each( 22 | data, 23 | [&output, &input](const std::pair& p) { 24 | std::visit(overload{[&output, &p](LineProcessorOutputFuture value) { 25 | output.insert({p.first, value}); 26 | }, 27 | IgnoreErrors{}}, 28 | p.second(input)); 29 | }); 30 | return output; 31 | }); 32 | } 33 | 34 | } // namespace afc::language::text 35 | -------------------------------------------------------------------------------- /src/language/text/line_sequence_functional.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/text/line_sequence_functional.h" 2 | 3 | #include "src/language/container.h" 4 | #include "src/language/text/mutable_line_sequence.h" 5 | 6 | namespace afc::language::text { 7 | using ::operator<<; 8 | 9 | LineSequence FilterLines( 10 | LineSequence input, 11 | const std::function& 12 | predicate) { 13 | MutableLineSequence builder; 14 | builder.append_back(container::MaterializeVector( 15 | input | std::views::filter([&](const Line& line) { 16 | return predicate(line) == FilterPredicateResult::kKeep; 17 | }))); 18 | if (builder.size() > LineNumberDelta(1)) 19 | builder.EraseLines(LineNumber(), LineNumber(1)); 20 | LOG(INFO) << "Output: [" << builder.snapshot().ToLazyString() << "]"; 21 | return builder.snapshot(); 22 | } 23 | } // namespace afc::language::text 24 | -------------------------------------------------------------------------------- /src/language/text/line_sequence_functional.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_TEXT_LINE_SEQUENCE_FUNCTIONAL_H__ 2 | #define __AFC_LANGUAGE_TEXT_LINE_SEQUENCE_FUNCTIONAL_H__ 3 | 4 | #include 5 | 6 | #include "src/language/text/line.h" 7 | #include "src/language/text/line_sequence.h" 8 | 9 | namespace afc::language::text { 10 | enum class FilterPredicateResult { kKeep, kErase }; 11 | 12 | LineSequence FilterLines( 13 | LineSequence input, 14 | const std::function& predicate); 15 | } // namespace afc::language::text 16 | #endif 17 | -------------------------------------------------------------------------------- /src/language/text/mutable_line_sequence_observer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_LANGUAGE_TEXT_MUTABLE_LINE_SEQUENCE_OBSERVER_H__ 2 | #define __AFC_LANGUAGE_TEXT_MUTABLE_LINE_SEQUENCE_OBSERVER_H__ 3 | 4 | #include "src/language/text/line_column.h" 5 | 6 | namespace afc::language::text { 7 | class MutableLineSequenceObserver { 8 | public: 9 | virtual ~MutableLineSequenceObserver() = default; 10 | virtual void LinesInserted(language::text::LineNumber position, 11 | language::text::LineNumberDelta size) = 0; 12 | virtual void LinesErased(language::text::LineNumber position, 13 | language::text::LineNumberDelta size) = 0; 14 | virtual void SplitLine(language::text::LineColumn position) = 0; 15 | virtual void FoldedLine(language::text::LineColumn position) = 0; 16 | virtual void Sorted() = 0; 17 | virtual void AppendedToLine(language::text::LineColumn position) = 0; 18 | virtual void DeletedCharacters( 19 | language::text::LineColumn position, 20 | language::lazy_string::ColumnNumberDelta amount) = 0; 21 | virtual void SetCharacter(language::text::LineColumn position) = 0; 22 | virtual void InsertedCharacter(language::text::LineColumn position) = 0; 23 | }; 24 | 25 | } // namespace afc::language::text 26 | #endif // __AFC_LANGUAGE_TEXT_MUTABLE_LINE_SEQUENCE_OBSERVER_H__ 27 | -------------------------------------------------------------------------------- /src/language/wstring.cc: -------------------------------------------------------------------------------- 1 | #include "src/language/wstring.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace afc::language { 9 | 10 | typedef std::codecvt Converter; 11 | 12 | std::string ToByteString(std::wstring input) { 13 | VLOG(5) << "ToByteString: " << input; 14 | 15 | static std::locale loc("en_US.utf-8"); 16 | 17 | const wchar_t* src = input.data(); 18 | int length = wcsnrtombs(nullptr, &src, input.length(), 0, nullptr); 19 | VLOG(6) << "Output length: " << length; 20 | if (length == -1) { 21 | return ""; 22 | } 23 | std::vector output(length); 24 | 25 | src = input.data(); 26 | wcsnrtombs(&output[0], &src, input.length(), output.size(), nullptr); 27 | 28 | std::string output_string(&output[0], output.size()); 29 | VLOG(6) << "Conversion result: [" << output_string << "]"; 30 | return output_string; 31 | } 32 | 33 | std::wstring FromByteString(std::string input) { 34 | const char* src = input.data(); 35 | int length = mbsnrtowcs(nullptr, &src, input.length(), 0, nullptr); 36 | if (length == -1) { 37 | return L""; 38 | } 39 | std::vector output(length); 40 | 41 | src = input.data(); 42 | mbsnrtowcs(&output[0], &src, input.length(), output.size(), nullptr); 43 | 44 | std::wstring output_string(&output[0], output.size()); 45 | return output_string; 46 | } 47 | } // namespace afc::language 48 | -------------------------------------------------------------------------------- /src/language/wstring.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_WSTRING_H__ 2 | #define __AFC_EDITOR_WSTRING_H__ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | inline std::ostream& operator<<(std::ostream& out, const wchar_t* str) { 11 | size_t len = 1 + std::wcsrtombs(nullptr, &str, 0, nullptr); 12 | std::vector mbstr(len); 13 | std::wcsrtombs(&mbstr[0], &str, mbstr.size(), nullptr); 14 | out << &mbstr[0]; 15 | return out; 16 | } 17 | 18 | inline std::ostream& operator<<(std::ostream& out, const std::wstring& str) { 19 | return operator<<(out, str.c_str()); 20 | } 21 | 22 | namespace afc::language { 23 | using ::operator<<; 24 | std::string ToByteString(std::wstring input); 25 | std::wstring FromByteString(std::string input); 26 | } // namespace afc::language 27 | 28 | #endif // __AFC_EDITOR_WSTRING_H__ 29 | -------------------------------------------------------------------------------- /src/line_marks_buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_LINE_MARKS_BUFFER_H__ 2 | #define __AFC_EDITOR_LINE_MARKS_BUFFER_H__ 3 | 4 | #include "src/command.h" 5 | #include "src/editor.h" 6 | #include "src/futures/futures.h" 7 | #include "src/language/error/value_or_error.h" 8 | #include "src/language/gc.h" 9 | 10 | namespace afc::editor { 11 | language::gc::Root NewLineMarksBufferCommand( 12 | EditorState& editor_state); 13 | } // namespace afc::editor 14 | 15 | #endif // __AFC_EDITOR_LINE_MARKS_BUFFER_H__ 16 | -------------------------------------------------------------------------------- /src/line_number_output_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_LINE_NUMBER_OUTPUT_PRODUCER_H__ 2 | #define __AFC_EDITOR_LINE_NUMBER_OUTPUT_PRODUCER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/buffer.h" 8 | #include "src/buffer_contents_view_layout.h" 9 | #include "src/language/text/line_column.h" 10 | #include "src/line_with_cursor.h" 11 | 12 | namespace afc::editor { 13 | 14 | language::lazy_string::ColumnNumberDelta LineNumberOutputWidth( 15 | language::text::LineNumberDelta lines_size); 16 | 17 | LineWithCursor::Generator::Vector LineNumberOutput( 18 | const OpenBuffer& buffer, 19 | const std::vector& screen_lines); 20 | 21 | } // namespace afc::editor 22 | 23 | #endif // __AFC_EDITOR_LINE_NUMBER_OUTPUT_PRODUCER_H__ 24 | -------------------------------------------------------------------------------- /src/line_output.h: -------------------------------------------------------------------------------- 1 | // Helper functions for Line class. 2 | 3 | #ifndef __AFC_EDITOR_LINE_OUTPUT_H__ 4 | #define __AFC_EDITOR_LINE_OUTPUT_H__ 5 | 6 | #include 7 | 8 | #include "src/language/text/line.h" 9 | 10 | namespace afc::editor { 11 | enum class LineWrapStyle { kBreakWords, kContentBased }; 12 | struct ColumnRange { 13 | language::lazy_string::ColumnNumber begin; 14 | language::lazy_string::ColumnNumber end; 15 | 16 | bool operator==(const ColumnRange& other) const { 17 | return begin == other.begin && end == other.end; 18 | } 19 | }; 20 | 21 | // Breaks `line` into separate ranges to be printed without overflowing a 22 | // desired screein width, taking into account double-width characters. 23 | std::list BreakLineForOutput( 24 | const language::text::Line& line, 25 | language::lazy_string::ColumnNumberDelta screen_positions, 26 | LineWrapStyle line_wrap_style, 27 | std::unordered_set symbol_characters); 28 | 29 | } // namespace afc::editor 30 | 31 | #endif // __AFC_EDITOR_LINE_OUTPUT_H__ 32 | -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_LOG_H__ 2 | #define __AFC_EDITOR_LOG_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/futures/futures.h" 8 | #include "src/infrastructure/file_system_driver.h" 9 | #include "src/language/error/value_or_error.h" 10 | #include "src/language/lazy_string/lazy_string.h" 11 | #include "src/language/safe_types.h" 12 | 13 | namespace afc::editor { 14 | class Log { 15 | public: 16 | virtual ~Log() {} 17 | virtual void Append(language::lazy_string::LazyString statement) = 0; 18 | virtual language::NonNull> NewChild( 19 | language::lazy_string::LazyString name) = 0; 20 | }; 21 | 22 | // file_system may be deleted as soon as this function returns (i.e., before the 23 | // future has a value). 24 | futures::ValueOrError>> NewFileLog( 25 | infrastructure::FileSystemDriver& file_system, infrastructure::Path path); 26 | 27 | language::NonNull> NewNullLog(); 28 | 29 | template 30 | auto RunAndLog(Log* log, language::lazy_string::LazyString name, 31 | Callable callable) { 32 | auto sub_log = log->NewChild(name); 33 | return callable(); 34 | } 35 | 36 | } // namespace afc::editor 37 | 38 | #endif // __AFC_EDITOR_LOG_H__ 39 | -------------------------------------------------------------------------------- /src/math/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "bigint", 3 | srcs = ["bigint.cc"], 4 | hdrs = ["bigint.h"], 5 | visibility = ["//visibility:public"], 6 | deps = [ 7 | ":checked_operation", 8 | "//src/language/error:value_or_error", 9 | ], 10 | ) 11 | 12 | cc_library( 13 | name = "checked_operation", 14 | hdrs = ["checked_operation.h"], 15 | visibility = ["//visibility:public"], 16 | ) 17 | 18 | cc_library( 19 | name = "decaying_counter", 20 | srcs = ["decaying_counter.cc"], 21 | hdrs = ["decaying_counter.h"], 22 | visibility = ["//visibility:public"], 23 | deps = [ 24 | "//src/infrastructure:time", 25 | ], 26 | ) 27 | 28 | cc_library( 29 | name = "naive_bayes", 30 | srcs = ["naive_bayes.cc"], 31 | hdrs = ["naive_bayes.h"], 32 | visibility = ["//visibility:public"], 33 | deps = [ 34 | "//src/infrastructure:tracker", 35 | "//src/language:ghost_type", 36 | "//src/language:wstring", 37 | ], 38 | ) 39 | 40 | cc_library( 41 | name = "numbers", 42 | srcs = ["numbers.cc"], 43 | hdrs = ["numbers.h"], 44 | visibility = ["//visibility:public"], 45 | deps = [ 46 | ":bigint", 47 | ":checked_operation", 48 | "//src/language:overload", 49 | "//src/language:safe_types", 50 | "//src/language:wstring", 51 | "//src/language/error:value_or_error", 52 | "//src/tests", 53 | ], 54 | ) 55 | -------------------------------------------------------------------------------- /src/math/decaying_counter.cc: -------------------------------------------------------------------------------- 1 | #include "src/math/decaying_counter.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "src/infrastructure/time.h" 9 | 10 | namespace afc::math { 11 | 12 | double SecondsToMicroseconds(double seconds) { return seconds * 1e6; } 13 | 14 | DecayingCounter::DecayingCounter(double half_life_seconds) 15 | : half_life_seconds_(half_life_seconds), 16 | rate_scale_factor_(half_life_seconds_ * sqrt(2)) {} 17 | 18 | double DecayingCounter::GetEventsPerSecond() const { 19 | return const_cast(this)->IncrementAndGetEventsPerSecond( 20 | 0.0); 21 | } 22 | 23 | double DecayingCounter::IncrementAndGetEventsPerSecond(double events) { 24 | const double elapsed_half_lifes = 25 | infrastructure::GetElapsedSecondsAndUpdate(&last_decay_) / 26 | half_life_seconds_; 27 | if (elapsed_half_lifes > 0) { 28 | const double decay_factor = std::exp2(-elapsed_half_lifes); 29 | VLOG(5) << "Decaying. Factor: " << decay_factor 30 | << ", previous: " << scaled_rate_ << ", events: " << events 31 | << ", elapsed half lifes: " << elapsed_half_lifes; 32 | CHECK_GE(decay_factor, 0.0); 33 | CHECK_LE(decay_factor, 1.0); 34 | scaled_rate_ = scaled_rate_ * decay_factor; 35 | } 36 | scaled_rate_ += events; 37 | return scaled_rate_ / rate_scale_factor_; 38 | } 39 | 40 | } // namespace afc::math 41 | -------------------------------------------------------------------------------- /src/math/decaying_counter.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_MATH_DECAYING_COUNTER_H__ 2 | #define __AFC_MATH_DECAYING_COUNTER_H__ 3 | 4 | #include "src/infrastructure/time.h" 5 | 6 | namespace afc::math { 7 | 8 | class DecayingCounter { 9 | public: 10 | DecayingCounter(double half_life_seconds); 11 | 12 | double GetEventsPerSecond() const; 13 | double IncrementAndGetEventsPerSecond(double events); 14 | 15 | private: 16 | const double half_life_seconds_; 17 | const double rate_scale_factor_; 18 | 19 | mutable struct timespec last_decay_ = {0, 0}; 20 | mutable double scaled_rate_ = 0; 21 | }; 22 | 23 | } // namespace afc::math 24 | 25 | #endif // __AFC_MATH_DECAYING_COUNTER_H__ 26 | -------------------------------------------------------------------------------- /src/navigate_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_NAVIGATE_COMMAND_H__ 2 | #define __AFC_EDITOR_NAVIGATE_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | 8 | namespace afc::editor { 9 | class EditorState; 10 | class Command; 11 | language::gc::Root NewNavigateCommand(EditorState& editor_state); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_NAVIGATE_COMMAND_H__ 15 | -------------------------------------------------------------------------------- /src/navigation_buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_NAVIGATION_BUFFER_H__ 2 | #define __AFC_EDITOR_NAVIGATION_BUFFER_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | 8 | namespace afc::editor { 9 | class Command; 10 | class EditorState; 11 | language::gc::Root NewNavigationBufferCommand( 12 | EditorState& editor_state); 13 | } // namespace afc::editor 14 | 15 | #endif // __AFC_EDITOR_NAVIGATION_BUFFER_H__ 16 | -------------------------------------------------------------------------------- /src/open_directory_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_OPEN_DIRECTORY_COMMAND_H__ 2 | #define __AFC_EDITOR_OPEN_DIRECTORY_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | 8 | namespace afc::editor { 9 | class Command; 10 | class EditorState; 11 | language::gc::Root NewOpenDirectoryCommand(EditorState& editor_state); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_OPEN_DIRECTORY_COMMAND_H__ 15 | -------------------------------------------------------------------------------- /src/open_file_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_OPEN_FILE_COMMAND_H__ 2 | #define __AFC_EDITOR_OPEN_FILE_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | 8 | namespace afc::editor { 9 | class EditorState; 10 | class Command; 11 | language::gc::Root NewOpenFileCommand(EditorState& editor); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_OPEN_FILE_COMMAND_H__ 15 | -------------------------------------------------------------------------------- /src/operation_scope.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_OPERATION_SCOPE_H__ 2 | #define __AFC_EDITOR_OPERATION_SCOPE_H__ 3 | 4 | #include 5 | 6 | #include "src/concurrent/protected.h" 7 | #include "src/language/text/line_column.h" 8 | #include "src/operation_scope_buffer_information.h" 9 | 10 | namespace afc::editor { 11 | class OpenBuffer; 12 | 13 | class OperationScope { 14 | public: 15 | OperationScope() = default; 16 | OperationScope(OperationScope&&) = default; 17 | OperationScope(const OperationScope&) = delete; 18 | 19 | OperationScopeBufferInformation get(const OpenBuffer& buffer) const; 20 | 21 | private: 22 | using Map = std::map; 23 | mutable concurrent::Protected data_; 24 | }; 25 | } // namespace afc::editor 26 | 27 | #endif // __AFC_EDITOR_OPERATION_SCOPE_H__ 28 | -------------------------------------------------------------------------------- /src/operation_scope_buffer_information.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_OPERATION_SCOPE_BUFFER_INFORMATION_H__ 2 | #define __AFC_EDITOR_OPERATION_SCOPE_BUFFER_INFORMATION_H__ 3 | 4 | #include "src/language/text/line_column.h" 5 | #include "src/line_marks.h" 6 | 7 | namespace afc::editor { 8 | // Freezes information about buffers in the scope of an operation. This makes 9 | // the operation repeatable: if the information changes in the buffers, those 10 | // changes won't affect repeated applications of the operation. 11 | // 12 | // This is used for PageUp/PageDown. If the screen sizes, we still scroll by the 13 | // original screen size. 14 | struct OperationScopeBufferInformation { 15 | language::text::LineNumberDelta screen_lines; 16 | 17 | std::multimap line_marks; 18 | 19 | // From buffer_variables::margin_lines_ratio. 20 | double margin_lines_ratio; 21 | }; 22 | } // namespace afc::editor 23 | #endif //__AFC_EDITOR_OPERATION_SCOPE_BUFFER_INFORMATION_H__ 24 | -------------------------------------------------------------------------------- /src/parsers/csv.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_PARSERS_CSV_H__ 2 | #define __AFC_EDITOR_PARSERS_CSV_H__ 3 | 4 | #include 5 | 6 | #include "src/language/safe_types.h" 7 | #include "src/parse_tree.h" 8 | 9 | namespace afc::editor::parsers { 10 | language::NonNull> NewCsvTreeParser(); 11 | } // namespace afc::editor::parsers 12 | 13 | #endif // __AFC_EDITOR_PARSERS_CSV_H__ 14 | -------------------------------------------------------------------------------- /src/parsers/diff.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_PARSERS_DIFF_H__ 2 | #define __AFC_EDITOR_PARSERS_DIFF_H__ 3 | 4 | #include 5 | 6 | #include "src/language/safe_types.h" 7 | #include "src/parse_tree.h" 8 | 9 | namespace afc { 10 | namespace editor { 11 | namespace parsers { 12 | language::NonNull> NewDiffTreeParser(); 13 | } // namespace parsers 14 | } // namespace editor 15 | } // namespace afc 16 | 17 | #endif // __AFC_EDITOR_PARSERS_DIFF_H__ 18 | -------------------------------------------------------------------------------- /src/parsers/markdown.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_PARSERS_MARKDOWN_H__ 2 | #define __AFC_EDITOR_PARSERS_MARKDOWN_H__ 3 | 4 | #include 5 | 6 | #include "src/language/lazy_string/lazy_string.h" 7 | #include "src/language/safe_types.h" 8 | #include "src/language/text/sorted_line_sequence.h" 9 | #include "src/parse_tree.h" 10 | 11 | namespace afc::editor::parsers { 12 | language::NonNull> NewMarkdownTreeParser( 13 | language::lazy_string::LazyString symbol_characters, 14 | language::text::SortedLineSequence dictionary); 15 | } // namespace afc::editor::parsers 16 | 17 | #endif // __AFC_EDITOR_PARSERS_MARKDOWN_H__ 18 | -------------------------------------------------------------------------------- /src/parsers/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_PARSERS_UTIL_H__ 2 | #define __AFC_EDITOR_PARSERS_UTIL_H__ 3 | 4 | #include "src/lru_cache.h" 5 | #include "src/parse_tools.h" 6 | 7 | namespace afc::editor::parsers { 8 | // `result` should be after the initial double-quoted string. 9 | void ParseDoubleQuotedString( 10 | ParseData* result, infrastructure::screen::LineModifierSet string_modifiers, 11 | std::unordered_set properties); 12 | 13 | // `result` should be after the initial digit. 14 | void ParseNumber(ParseData* result, 15 | infrastructure::screen::LineModifierSet number_modifiers, 16 | std::unordered_set properties); 17 | 18 | class LineOrientedTreeParser : public TreeParser { 19 | public: 20 | ParseTree FindChildren(const language::text::LineSequence& buffer, 21 | language::text::Range range); 22 | 23 | protected: 24 | static constexpr size_t kDefaultState = 0; 25 | virtual void ParseLine(ParseData* result) = 0; 26 | 27 | // Allows us to avoid reparsing previously parsed lines. The key is the hash 28 | // of: 29 | // 30 | // - The contents of a line. 31 | // - The stack of states available when parsing of the line starts. 32 | // 33 | // The values are the results of parsing the line. 34 | // 35 | // Why set the size to 1? Because `FindChildren` will adjust it to be based on 36 | // the size of the file. 37 | LRUCache cache_ = LRUCache(1); 38 | }; 39 | } // namespace afc::editor::parsers 40 | #endif // __AFC_EDITOR_PARSERS_UTIL_H__ 41 | -------------------------------------------------------------------------------- /src/path_flags.cc: -------------------------------------------------------------------------------- 1 | #include "src/path_flags.h" 2 | 3 | #include 4 | 5 | #include "src/language/hash.h" 6 | 7 | namespace afc::editor::flags { 8 | using afc::language::compute_hash; 9 | 10 | std::vector GenerateFlags(const std::vector& spec, 11 | const std::vector& colors, 12 | std::map inputs) { 13 | CHECK(!spec.empty()); 14 | CHECK(!colors.empty()); 15 | 16 | std::vector output; 17 | output.reserve(spec.size()); 18 | 19 | std::map previous_count_map; 20 | 21 | for (const InputKey& key : spec) { 22 | auto& previous_count = previous_count_map[key]; 23 | auto it_value = inputs.find(key); 24 | output.push_back( 25 | colors[compute_hash(previous_count, 26 | (it_value == inputs.end() ? InputValue() 27 | : it_value->second)) % 28 | colors.size()]); 29 | previous_count++; 30 | } 31 | return output; 32 | } 33 | 34 | } // namespace afc::editor::flags 35 | -------------------------------------------------------------------------------- /src/path_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_PATH_FLAGS_H__ 2 | #define __AFC_EDITOR_PATH_FLAGS_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/language/ghost_type_class.h" 8 | #include "src/language/lazy_string/lazy_string.h" 9 | #include "src/language/lazy_string/single_line.h" 10 | #include "src/language/wstring.h" 11 | 12 | namespace afc::editor::flags { 13 | 14 | struct InputKey 15 | : public language::GhostType { 17 | using GhostType::GhostType; 18 | }; 19 | struct InputValue 20 | : public language::GhostType { 22 | using GhostType::GhostType; 23 | }; 24 | struct Color 25 | : public language::GhostType { 27 | using GhostType::GhostType; 28 | }; 29 | 30 | std::vector GenerateFlags(const std::vector& spec, 31 | const std::vector& colors, 32 | std::map inputs); 33 | 34 | } // namespace afc::editor::flags 35 | 36 | #endif // __AFC_EDITOR_PATH_FLAGS_H__ 37 | -------------------------------------------------------------------------------- /src/quit_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_QUIT_COMMAND_H__ 2 | #define __AFC_EDITOR_QUIT_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | 8 | namespace afc::editor { 9 | class Command; 10 | class EditorState; 11 | language::gc::Root NewQuitCommand(EditorState& editor_state, 12 | int exit_value); 13 | } // namespace afc::editor 14 | 15 | #endif // __AFC_EDITOR_QUIT_COMMAND_H__ 16 | -------------------------------------------------------------------------------- /src/record_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_RECORD_COMMAND_H__ 2 | #define __AFC_EDITOR_RECORD_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | namespace afc::editor { 8 | class Command; 9 | class EditorState; 10 | language::gc::Root NewRecordCommand(EditorState& editor_state); 11 | } // namespace afc::editor 12 | 13 | #endif // __AFC_EDITOR_RECORD_COMMAND_H__ 14 | -------------------------------------------------------------------------------- /src/repeat_mode.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_REPEAT_MODE_H__ 2 | #define __AFC_EDITOR_REPEAT_MODE_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | 8 | namespace afc::editor { 9 | class InputReceiver; 10 | class EditorState; 11 | language::gc::Root NewRepeatMode( 12 | EditorState& editor_state, std::function consumer); 13 | } // namespace afc::editor 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/run_cpp_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_RUN_CPP_COMMAND_H__ 2 | #define __AFC_EDITOR_RUN_CPP_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/futures/futures.h" 7 | #include "src/language/gc.h" 8 | #include "src/language/lazy_string/single_line.h" 9 | #include "src/language/safe_types.h" 10 | 11 | namespace afc { 12 | namespace vm { 13 | class Value; 14 | } 15 | namespace editor { 16 | 17 | enum class CppCommandMode { 18 | // Compiles the string and runs it. 19 | kLiteral, 20 | 21 | // Splits the string into a vector of strings (respecting quotes). Looks up a 22 | // C++ (VM) function named after the first token that receives strings and 23 | // runs it, providing the tokens given. 24 | // 25 | // This has nothing to do with the system shell (i.e., system(3)). 26 | kShell 27 | }; 28 | 29 | class EditorState; 30 | class Command; 31 | 32 | // A command looks like this: build foo "bar hey". 33 | // 34 | // In this case, that'd run something like: build("foo", "bar hey"); 35 | futures::ValueOrError> RunCppCommandShell( 36 | const language::lazy_string::SingleLine& command, 37 | EditorState& editor_state); 38 | 39 | language::gc::Root NewRunCppCommand(EditorState& editor_state, 40 | CppCommandMode mode); 41 | 42 | } // namespace editor 43 | } // namespace afc 44 | 45 | #endif // __AFC_EDITOR_RUN_CPP_COMMAND_H__ 46 | -------------------------------------------------------------------------------- /src/run_cpp_file.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_RUN_CPP_FILE_H__ 2 | #define __AFC_EDITOR_RUN_CPP_FILE_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | #include "src/language/lazy_string/lazy_string.h" 8 | 9 | namespace afc::editor { 10 | class EditorState; 11 | class Command; 12 | language::gc::Root NewRunCppFileCommand(EditorState& editor_state); 13 | } // namespace afc::editor 14 | 15 | #endif // __AFC_EDITOR_RUN_CPP_FILE_H__ 16 | -------------------------------------------------------------------------------- /src/screen_curses.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SCREEN_CURSES_H__ 2 | #define __AFC_EDITOR_SCREEN_CURSES_H__ 3 | 4 | #include 5 | 6 | #include "src/infrastructure/extended_char.h" 7 | #include "src/infrastructure/screen/screen.h" 8 | #include "src/language/safe_types.h" 9 | 10 | namespace afc::editor { 11 | 12 | std::optional ReadChar(std::mbstate_t* mbstate); 13 | 14 | language::NonNull> 15 | NewScreenCurses(); 16 | 17 | } // namespace afc::editor 18 | 19 | #endif // __AFC_EDITOR_SCREEN_CURSES_H__ 20 | -------------------------------------------------------------------------------- /src/screen_union.h: -------------------------------------------------------------------------------- 1 | class ScreenUnion : public Screen { 2 | public: 3 | void AddScreen(std::unique_ptr screen) { 4 | screens_.push_back(std::move(screen)); 5 | } 6 | 7 | bool Empty() const { return screens_.empty(); }; 8 | 9 | private: 10 | std::list> screens_; 11 | }; 12 | -------------------------------------------------------------------------------- /src/screen_vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SCREEN_VM_H__ 2 | #define __AFC_EDITOR_SCREEN_VM_H__ 3 | 4 | #include 5 | 6 | #include "src/infrastructure/screen/screen.h" 7 | #include "src/vm/callbacks.h" 8 | #include "src/vm/escape.h" 9 | 10 | namespace afc::infrastructure { 11 | class FileDescriptor; 12 | } 13 | namespace afc::vm { 14 | struct VMType; 15 | class Environment; 16 | } // namespace afc::vm 17 | namespace afc::editor { 18 | class EditorState; 19 | void RegisterScreenType(EditorState& editor, vm::Environment& environment); 20 | std::unique_ptr NewScreenVm( 21 | infrastructure::FileDescriptor fd); 22 | const vm::types::ObjectName& GetScreenVmType(); 23 | } // namespace afc::editor 24 | 25 | #endif // __AFC_EDITOR_SCREEN_VM_H__ 26 | -------------------------------------------------------------------------------- /src/search_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SEARCH_COMMAND_H__ 2 | #define __AFC_EDITOR_SEARCH_COMMAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | namespace afc::editor { 8 | class Command; 9 | class EditorState; 10 | language::gc::Root NewSearchCommand(EditorState& editor_state); 11 | } // namespace afc::editor 12 | 13 | #endif // __AFC_EDITOR_SEARCH_COMMAND_H__ 14 | -------------------------------------------------------------------------------- /src/search_handler_vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SEARCH_HANDLER_VM_H__ 2 | #define __AFC_EDITOR_SEARCH_HANDLER_VM_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | #include "src/vm/environment.h" 8 | 9 | namespace afc::editor { 10 | void RegisterSearchOptionsVm(language::gc::Pool& pool, 11 | vm::Environment& environment); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_SEARCH_HANDLER_VM_H__ 15 | -------------------------------------------------------------------------------- /src/section_brackets_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SECTION_BRACKETS_PRODUCER_H__ 2 | #define __AFC_EDITOR_SECTION_BRACKETS_PRODUCER_H__ 3 | 4 | #include "src/language/text/line_column.h" 5 | #include "src/line_with_cursor.h" 6 | 7 | namespace afc::editor { 8 | enum class SectionBracketsSide { kLeft, kRight }; 9 | LineWithCursor::Generator::Vector SectionBrackets( 10 | language::text::LineNumberDelta lines, 11 | SectionBracketsSide section_brackets_side); 12 | } // namespace afc::editor 13 | 14 | #endif // __AFC_EDITOR_SECTION_BRACKETS_PRODUCER_H__ 15 | -------------------------------------------------------------------------------- /src/server.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SERVER_H__ 2 | #define __AFC_EDITOR_SERVER_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/infrastructure/dirname.h" 8 | #include "src/infrastructure/file_system_driver.h" 9 | #include "src/language/error/value_or_error.h" 10 | #include "src/language/gc.h" 11 | #include "src/language/safe_types.h" 12 | 13 | namespace afc::editor { 14 | 15 | void Daemonize( 16 | const std::unordered_set& surviving_fd); 17 | 18 | // These methods block. You may want to call them in a background thread. 19 | language::PossibleError SyncSendCommandsToServer( 20 | infrastructure::FileDescriptor server_fd, 21 | language::lazy_string::LazyString commands_to_run); 22 | language::ValueOrError SyncConnectToServer( 23 | const infrastructure::Path& address); 24 | language::ValueOrError 25 | SyncConnectToParentServer(); 26 | 27 | class EditorState; 28 | class OpenBuffer; 29 | 30 | // address can be empty, in which case it'll use a temporary file in /tmp. The 31 | // actual address used is returned. 32 | language::ValueOrError StartServer( 33 | EditorState& editor_state, std::optional address); 34 | 35 | void OpenServerBuffer(EditorState& editor_state, 36 | const infrastructure::Path& address); 37 | 38 | } // namespace afc::editor 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/set_buffer_mode.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SET_BUFFER_MODE_H__ 2 | #define __AFC_EDITOR_SET_BUFFER_MODE_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/command_argument_mode.h" 8 | #include "src/editor_mode.h" 9 | 10 | namespace afc::editor { 11 | std::optional> NewSetBufferMode( 12 | EditorState& editor); 13 | } // namespace afc::editor 14 | 15 | #endif // __AFC_EDITOR_SET_BUFFER_MODE_H__ 16 | -------------------------------------------------------------------------------- /src/set_mode_command.cc: -------------------------------------------------------------------------------- 1 | #include "src/set_mode_command.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include "src/editor.h" 9 | #include "src/editor_mode.h" 10 | 11 | namespace gc = afc::language::gc; 12 | 13 | using afc::infrastructure::ExtendedChar; 14 | using afc::language::MakeNonNullUnique; 15 | using afc::language::NonNull; 16 | using afc::language::lazy_string::LazyString; 17 | 18 | namespace afc::editor { 19 | namespace { 20 | class SetModeCommand : public Command { 21 | public: 22 | SetModeCommand(SetModeCommandOptions options) 23 | : options_(std::move(options)) {} 24 | 25 | CommandCategory Category() const override { return options_.category; } 26 | LazyString Description() const override { return options_.description; } 27 | void ProcessInput(ExtendedChar) override { 28 | options_.editor_state.set_keyboard_redirect(options_.factory()); 29 | } 30 | 31 | std::vector>> 32 | Expand() const override { 33 | return {}; 34 | } 35 | 36 | private: 37 | const SetModeCommandOptions options_; 38 | }; 39 | } // namespace 40 | 41 | gc::Root NewSetModeCommand(SetModeCommandOptions options) { 42 | return options.editor_state.gc_pool().NewRoot( 43 | MakeNonNullUnique(std::move(options))); 44 | } 45 | 46 | } // namespace afc::editor 47 | -------------------------------------------------------------------------------- /src/set_mode_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SET_MODE_COMMAND_H__ 2 | #define __AFC_EDITOR_SET_MODE_COMMAND_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/command.h" 9 | #include "src/language/gc.h" 10 | #include "src/language/lazy_string/lazy_string.h" 11 | 12 | namespace afc::editor { 13 | class EditorState; 14 | class InputReceiver; 15 | class Command; 16 | struct SetModeCommandOptions { 17 | EditorState& editor_state; 18 | language::lazy_string::LazyString description; 19 | CommandCategory category; 20 | std::function()> factory; 21 | }; 22 | 23 | language::gc::Root NewSetModeCommand(SetModeCommandOptions options); 24 | } // namespace afc::editor 25 | 26 | #endif // __AFC_EDITOR_SET_MODE_COMMAND_H__ 27 | -------------------------------------------------------------------------------- /src/set_variable_command.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SET_VARIABLE_COMMAND_H__ 2 | #define __AFC_EDITOR_SET_VARIABLE_COMMAND_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/futures/futures.h" 8 | #include "src/language/error/value_or_error.h" 9 | #include "src/language/gc.h" 10 | #include "src/language/lazy_string/single_line.h" 11 | #include "src/language/safe_types.h" 12 | 13 | namespace afc::editor { 14 | class Command; 15 | class EditorState; 16 | 17 | // Shows a prompt that reads a value for a given variable. 18 | futures::Value SetVariableCommandHandler( 19 | EditorState& editor_state, language::lazy_string::SingleLine input_name); 20 | 21 | language::gc::Root NewSetVariableCommand(EditorState& editor_state); 22 | } // namespace afc::editor 23 | 24 | #endif // __AFC_EDITOR_SET_VARIABLE_COMMAND_H__ 25 | -------------------------------------------------------------------------------- /src/shapes.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_SHAPES_H__ 2 | #define __AFC_EDITOR_SHAPES_H__ 3 | 4 | #include "src/vm/environment.h" 5 | 6 | namespace afc::language::gc { 7 | class Pool; 8 | } 9 | namespace afc::editor { 10 | void InitShapes(language::gc::Pool& pool, vm::Environment& environment); 11 | } // namespace afc::editor 12 | 13 | #endif // __AFC_EDITOR_SHAPES_H__ 14 | -------------------------------------------------------------------------------- /src/status_output_producer.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_STATUS_OUTPUT_PRODUCER_H__ 2 | #define __AFC_EDITOR_STATUS_OUTPUT_PRODUCER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "src/line_with_cursor.h" 10 | #include "src/modifiers.h" 11 | 12 | namespace afc { 13 | namespace editor { 14 | 15 | class Status; 16 | class OpenBuffer; 17 | 18 | struct StatusOutputOptions { 19 | const Status& status; 20 | 21 | // `buffer` will be null if this status isn't associated with a specific 22 | // buffer (i.e., if it's the editor's status). 23 | const OpenBuffer* buffer; 24 | Modifiers modifiers; 25 | 26 | // Size is the maximum size to generate; we may generate fewer lines (e.g., if 27 | // the status is empty). 28 | language::text::LineColumnDelta size; 29 | }; 30 | 31 | LineWithCursor::Generator::Vector StatusOutput(StatusOutputOptions options); 32 | } // namespace editor 33 | } // namespace afc 34 | 35 | #endif // __AFC_EDITOR_STATUS_OUTPUT_PRODUCER_H__ 36 | -------------------------------------------------------------------------------- /src/structure_move.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_STRUCTURE_MOVE_H__ 2 | #define __AFC_VM_STRUCTURE_MOVE_H__ 3 | 4 | #include 5 | 6 | #include "src/language/text/line_column.h" 7 | #include "src/language/text/line_sequence.h" 8 | #include "src/structure.h" 9 | 10 | namespace afc::editor { 11 | 12 | struct OperationScopeBufferInformation; 13 | struct Modifiers; 14 | 15 | std::optional Move( 16 | const OperationScopeBufferInformation& scope, Structure structure, 17 | const language::text::LineSequence& contents, 18 | language::text::LineColumn position, language::text::Range range, 19 | const Modifiers& modifiers); 20 | 21 | } // namespace afc::editor 22 | 23 | #endif // __AFC_VM_STRUCTURE_MOVE_H__ 24 | -------------------------------------------------------------------------------- /src/test/buffer_contents_test.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TEST_LINE_SEQUENCE_TEST_H__ 2 | #define __AFC_EDITOR_TEST_LINE_SEQUENCE_TEST_H__ 3 | 4 | namespace afc { 5 | namespace editor { 6 | namespace testing { 7 | void MutableLineSequenceTests(); 8 | } // namespace testing 9 | } // namespace editor 10 | } // namespace afc 11 | 12 | #endif // __AFC_EDITOR_TEST_LINE_SEQUENCE_TEST_H__ 13 | -------------------------------------------------------------------------------- /src/test/fuzz/compiler.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern "C" { 10 | #include 11 | #include 12 | #include 13 | } 14 | 15 | #include "src/concurrent/thread_pool.h" 16 | #include "src/cpp_parse_tree.h" 17 | #include "src/infrastructure/dirname.h" 18 | #include "src/language/error/value_or_error.h" 19 | #include "src/language/gc.h" 20 | #include "src/language/lazy_string/char_buffer.h" 21 | #include "src/language/lazy_string/lazy_string.h" 22 | #include "src/language/wstring.h" 23 | #include "src/vm/default_environment.h" 24 | #include "src/vm/environment.h" 25 | #include "src/vm/vm.h" 26 | 27 | using namespace afc::editor; 28 | 29 | using afc::concurrent::OperationFactory; 30 | using afc::concurrent::ThreadPool; 31 | using afc::infrastructure::Path; 32 | using afc::language::FromByteString; 33 | using afc::language::MakeNonNullShared; 34 | using afc::language::ValueOrDie; 35 | using afc::language::lazy_string::LazyString; 36 | 37 | int main(int, char** argv) { 38 | google::InitGoogleLogging(argv[0]); 39 | std::wifstream input(argv[1]); 40 | afc::language::gc::Pool pool(afc::language::gc::Pool::Options{ 41 | .collect_duration_threshold = std::nullopt, 42 | .operation_factory = std::make_shared( 43 | MakeNonNullShared(6))}); 44 | 45 | afc::vm::CompileFile( 46 | ValueOrDie(Path::New(LazyString{FromByteString(argv[1])})), pool, 47 | afc::vm::NewDefaultEnvironment(pool)); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/test/line_test.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TEST_LINE_TEST_H__ 2 | #define __AFC_EDITOR_TEST_LINE_TEST_H__ 3 | 4 | namespace afc { 5 | namespace editor { 6 | namespace testing { 7 | void LineTests(); 8 | } // namespace testing 9 | } // namespace editor 10 | } // namespace afc 11 | 12 | #endif // __AFC_EDITOR_TEST_LINE_TEST_H__ 13 | -------------------------------------------------------------------------------- /src/test/parser_fuzz.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "src/cpp_parse_tree.h" 8 | #include "src/editor.h" 9 | #include "src/terminal.h" 10 | #include "src/tree.h" 11 | 12 | using namespace afc::editor; 13 | using language::text::MutableLineSequence; 14 | 15 | int main(int argc, char** argv) { 16 | google::InitGoogleLogging(argv[0]); 17 | auto parser = NewCppTreeParser( 18 | {L"auto", L"int", L"char", L"if", L"while", L"const", L"for"}, 19 | {L"optoins"}); 20 | 21 | CHECK_EQ(argc, 2); 22 | int fd = open(argv[1], O_RDONLY); 23 | CHECK_GT(fd, 0); 24 | 25 | char BUFFER[64000]; 26 | int len = read(fd, &buffer, sizeof(buffer)); 27 | CHECK_GE(0, len); 28 | 29 | std::wstringstream ss(wstring(buffer, len)); 30 | std::wstring line; 31 | 32 | MutableLineSequence contents; 33 | while (std::getline(ss, line, '\n')) { 34 | Line::Options options; 35 | options.contents = LazyString{line}; 36 | contents.AppendToLastLine(Line(std::move(options))); 37 | contents.push_back(std::make_shared()); 38 | } 39 | 40 | parser->FindChildren(const MutableLineSequence& lines, ParseTree* root) = 0; 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/tests/BUILD: -------------------------------------------------------------------------------- 1 | cc_library( 2 | name = "benchmarks", 3 | srcs = ["benchmarks.cc"], 4 | hdrs = ["benchmarks.h"], 5 | visibility = ["//visibility:public"], 6 | deps = [ 7 | "//src/infrastructure:time", 8 | "//src/language:container", 9 | "//src/language:wstring", 10 | ], 11 | ) 12 | 13 | cc_binary( 14 | name = "benchmarks_main", 15 | srcs = ["benchmarks_main.cc"], 16 | deps = [ 17 | ":benchmarks", 18 | "@com_github_google_glog//:glog", 19 | ], 20 | ) 21 | 22 | cc_library( 23 | name = "concurrent_interfaces", 24 | srcs = ["concurrent_interfaces.cc"], 25 | hdrs = ["concurrent_interfaces.h"], 26 | visibility = ["//visibility:public"], 27 | deps = [ 28 | ], 29 | ) 30 | 31 | cc_library( 32 | name = "fuzz", 33 | srcs = ["fuzz.cc"], 34 | hdrs = ["fuzz.h"], 35 | visibility = ["//visibility:public"], 36 | deps = [ 37 | ":fuzz_testable", 38 | "//src/language/lazy_string", 39 | ], 40 | ) 41 | 42 | cc_library( 43 | name = "fuzz_testable", 44 | srcs = ["fuzz_testable.cc"], 45 | hdrs = ["fuzz_testable.h"], 46 | visibility = ["//visibility:public"], 47 | deps = [ 48 | "//src/language:wstring", 49 | "@com_github_google_glog//:glog", 50 | ], 51 | ) 52 | 53 | cc_library( 54 | name = "tests", 55 | srcs = ["tests.cc"], 56 | hdrs = ["tests.h"], 57 | visibility = ["//visibility:public"], 58 | deps = [ 59 | "//src/language:container", 60 | "//src/language:wstring", 61 | ], 62 | ) 63 | -------------------------------------------------------------------------------- /src/tests/benchmarks.cc: -------------------------------------------------------------------------------- 1 | #include "src/tests/benchmarks.h" 2 | 3 | #include 4 | 5 | #include "src/infrastructure/time.h" 6 | #include "src/language/container.h" 7 | 8 | namespace container = afc::language::container; 9 | 10 | using afc::language::InsertOrDie; 11 | 12 | namespace afc::tests { 13 | namespace { 14 | std::unordered_map& benchmarks_map() { 15 | static std::unordered_map* const output = 16 | new std::unordered_map(); 17 | return *output; 18 | } 19 | } // namespace 20 | 21 | bool RegisterBenchmark(BenchmarkName name, BenchmarkFunction benchmark) { 22 | CHECK(benchmark != nullptr); 23 | InsertOrDie(benchmarks_map(), {name, std::move(benchmark)}); 24 | return true; 25 | } 26 | 27 | void RunBenchmark(BenchmarkName name) { 28 | auto benchmark = benchmarks_map().find(name); 29 | if (benchmark == benchmarks_map().end()) { 30 | std::cerr << "Unknown Benchmark: " << name << std::endl; 31 | exit(1); 32 | } 33 | 34 | int input_size = 1; 35 | static const int kRuns = 5; 36 | while (true) { 37 | double total_seconds = 0; 38 | for (int i = 0; i < kRuns; i++) { 39 | total_seconds += benchmark->second(input_size); 40 | } 41 | std::cerr << input_size << " " << total_seconds / kRuns << std::endl; 42 | if (input_size * 2 < input_size) return; 43 | input_size *= 2; 44 | } 45 | } 46 | 47 | std::vector BenchmarkNames() { 48 | return container::MaterializeVector(benchmarks_map() | std::views::keys); 49 | } 50 | } // namespace afc::tests 51 | -------------------------------------------------------------------------------- /src/tests/benchmarks.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TESTS_BENCHMARKS_H__ 2 | #define __AFC_EDITOR_TESTS_BENCHMARKS_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "src/language/ghost_type_class.h" 10 | #include "src/language/lazy_string/single_line.h" 11 | 12 | namespace afc::tests { 13 | struct BenchmarkName 14 | : public language::GhostType { 16 | using GhostType::GhostType; 17 | }; 18 | 19 | using BenchmarkSize = size_t; 20 | using BenchmarkFunction = std::function; 21 | 22 | bool RegisterBenchmark(BenchmarkName name, BenchmarkFunction benchmark); 23 | 24 | void RunBenchmark(BenchmarkName name); 25 | 26 | std::vector BenchmarkNames(); 27 | 28 | } // namespace afc::tests 29 | 30 | #endif // __AFC_EDITOR_TESTS_BENCHMARKS_H__ 31 | -------------------------------------------------------------------------------- /src/tests/benchmarks_main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "src/language/lazy_string/single_line.h" 4 | #include "src/language/wstring.h" 5 | #include "src/tests/benchmarks.h" 6 | 7 | using afc::language::FromByteString; 8 | using afc::language::lazy_string::LazyString; 9 | using afc::language::lazy_string::NonEmptySingleLine; 10 | using afc::language::lazy_string::SingleLine; 11 | 12 | int main(int argc, const char** argv) { 13 | using std::cerr; 14 | 15 | google::InitGoogleLogging(argv[0]); 16 | google::InstallFailureSignalHandler(); 17 | 18 | srand(time(NULL)); 19 | 20 | if (argc == 2) { 21 | afc::tests::RunBenchmark(afc::tests::BenchmarkName( 22 | NonEmptySingleLine(SingleLine(LazyString{FromByteString(argv[1])})))); 23 | exit(0); 24 | } 25 | 26 | std::cerr << "Usage: " << argv[0] << " BENCHMARK" << std::endl; 27 | std::cerr << "BENCHMARK must be one of: " << std::endl; 28 | for (auto& name : afc::tests::BenchmarkNames()) { 29 | std::cerr << name << std::endl; 30 | } 31 | exit(1); 32 | } 33 | -------------------------------------------------------------------------------- /src/tests/concurrent.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_TESTS_CONCURRENT_H__ 2 | #define __AFC_TESTS_CONCURRENT_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/concurrent/thread_pool.h" 8 | #include "src/infrastructure/time.h" 9 | #include "src/language/safe_types.h" 10 | 11 | namespace afc::tests::concurrent { 12 | struct Options { 13 | language::NonNull> thread_pool; 14 | afc::infrastructure::Duration timeout = 0.050; 15 | std::function start; 16 | }; 17 | 18 | void TestFlows(Options options); 19 | }; // namespace afc::tests::concurrent 20 | #endif 21 | -------------------------------------------------------------------------------- /src/tests/concurrent_interfaces.cc: -------------------------------------------------------------------------------- 1 | #include "src/tests/concurrent_interfaces.h" 2 | 3 | #include 4 | 5 | namespace afc::tests::concurrent { 6 | namespace { 7 | Handler* global_handler = nullptr; 8 | } 9 | 10 | Handler* GetGlobalHandler() { return global_handler; } 11 | 12 | void SetGlobalHandler(Handler* handler) { 13 | CHECK((global_handler == nullptr) != (handler == nullptr)); 14 | global_handler = handler; 15 | } 16 | 17 | } // namespace afc::tests::concurrent 18 | -------------------------------------------------------------------------------- /src/tests/concurrent_interfaces.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_TESTS_CONCURRENT_INTERFACES_H__ 2 | #define __AFC_TESTS_CONCURRENT_INTERFACES_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace afc::tests::concurrent { 9 | class Handler { 10 | public: 11 | virtual ~Handler() = default; 12 | 13 | virtual void Lock(const std::mutex& lock) = 0; 14 | virtual void Unlock(const std::mutex& lock) = 0; 15 | 16 | virtual std::function Wrap(std::function work) = 0; 17 | }; 18 | 19 | // May return nullptr. 20 | Handler* GetGlobalHandler(); 21 | void SetGlobalHandler(Handler* handler); 22 | } // namespace afc::tests::concurrent 23 | #endif 24 | -------------------------------------------------------------------------------- /src/tests/fuzz_testable.cc: -------------------------------------------------------------------------------- 1 | #include "src/tests/fuzz_testable.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "glog/logging.h" 9 | #include "src/language/wstring.h" 10 | 11 | namespace afc::tests::fuzz { 12 | 13 | /* static */ 14 | void FuzzTestable::Test(Stream& input, FuzzTestable* fuzz_testable) { 15 | auto handlers = fuzz_testable->FuzzHandlers(); 16 | CHECK_LT(handlers.size(), 256ul); 17 | while (true) { 18 | unsigned char choice; 19 | if (!(input >> choice)) { 20 | VLOG(4) << "Done fuzzing."; 21 | return; 22 | } 23 | choice %= handlers.size(); 24 | VLOG(5) << "Next handler choice: " << static_cast(choice); 25 | handlers[choice](input); 26 | } 27 | } 28 | 29 | } // namespace afc::tests::fuzz 30 | -------------------------------------------------------------------------------- /src/tests/fuzz_testable.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TESTS_FUZZ_TESTABLE_H__ 2 | #define __AFC_EDITOR_TESTS_FUZZ_TESTABLE_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace afc::tests::fuzz { 10 | 11 | using Stream = std::ifstream; 12 | using Handler = std::function; 13 | 14 | class FuzzTestable { 15 | public: 16 | virtual ~FuzzTestable() = default; 17 | 18 | static void Test(Stream& input, FuzzTestable* testable); 19 | 20 | virtual std::vector FuzzHandlers() = 0; 21 | }; 22 | 23 | } // namespace afc::tests::fuzz 24 | 25 | #endif // __AFC_EDITOR_TESTS_FUZZ_TESTABLE_H__ 26 | -------------------------------------------------------------------------------- /src/token_predictor.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TOKEN_PREDICTOR__ 2 | #define __AFC_EDITOR_TOKEN_PREDICTOR__ 3 | #include "src/predictor.h" 4 | namespace afc::editor { 5 | Predictor TokenPredictor(Predictor); 6 | } 7 | #endif // __AFC_EDITOR_TOKEN_PREDICTOR__ 8 | -------------------------------------------------------------------------------- /src/transformation.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_H__ 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include "src/direction.h" 9 | #include "src/futures/futures.h" 10 | #include "src/language/text/line.h" 11 | #include "src/language/text/line_column.h" 12 | #include "src/modifiers.h" 13 | #include "src/structure.h" 14 | #include "src/transformation/type.h" 15 | 16 | namespace afc::editor { 17 | class OpenBuffer; 18 | 19 | // Goes to a given position and applies a transformation. 20 | transformation::Variant TransformationAtPosition( 21 | const language::text::LineColumn& position, 22 | transformation::Variant transformation); 23 | 24 | // Returns a transformation that deletes superfluous characters (based on 25 | // OpenBuffer::variable_line_suffix_superfluous_characters) from the current 26 | // line. 27 | transformation::Variant NewDeleteSuffixSuperfluousCharacters(); 28 | } // namespace afc::editor 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/transformation/bisect.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_BISECT_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_BISECT_H__ 3 | 4 | #include 5 | 6 | #include "src/transformation/composite.h" 7 | 8 | namespace afc::editor::transformation { 9 | class Bisect : public CompositeTransformation { 10 | public: 11 | Bisect(Structure structure, std::vector directions); 12 | std::wstring Serialize() const override; 13 | futures::Value Apply(Input input) const override; 14 | 15 | private: 16 | const Structure structure_; 17 | const std::vector directions_; 18 | }; 19 | } // namespace afc::editor::transformation 20 | 21 | #endif // __AFC_EDITOR_TRANSFORMATION_BISECT_H__ 22 | -------------------------------------------------------------------------------- /src/transformation/cursors.cc: -------------------------------------------------------------------------------- 1 | #include "src/transformation/cursors.h" 2 | 3 | #include 4 | 5 | #include "src/futures/futures.h" 6 | #include "src/language/lazy_string/append.h" 7 | 8 | namespace afc::editor::transformation { 9 | using language::text::LineColumn; 10 | 11 | futures::Value ApplyBase(const Cursors& parameters, Input input) { 12 | std::vector positions = {parameters.active}; 13 | bool skipped = false; 14 | for (const auto& cursor : parameters.cursors) { 15 | if (!skipped && cursor == parameters.active) { 16 | skipped = true; 17 | } else { 18 | positions.push_back(cursor); 19 | } 20 | } 21 | input.adapter.SetActiveCursors(positions); 22 | return futures::Past(Result(parameters.active)); 23 | } 24 | 25 | std::wstring ToStringBase(const Cursors& v) { 26 | return L"Cursors{.size = " + std::to_wstring(v.cursors.size()) + L"};"; 27 | } 28 | 29 | Cursors OptimizeBase(Cursors cursors) { return cursors; } 30 | 31 | } // namespace afc::editor::transformation 32 | -------------------------------------------------------------------------------- /src/transformation/cursors.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_CURSORS_TRANSFORMATION_H__ 2 | #define __AFC_EDITOR_CURSORS_TRANSFORMATION_H__ 3 | 4 | #include "src/futures/futures.h" 5 | #include "src/infrastructure/screen/cursors.h" 6 | #include "src/language/text/line_column.h" 7 | #include "src/transformation/input.h" 8 | #include "src/transformation/result.h" 9 | 10 | namespace afc::editor::transformation { 11 | struct Cursors { 12 | infrastructure::screen::CursorsSet cursors; 13 | language::text::LineColumn active; 14 | }; 15 | 16 | futures::Value ApplyBase(const Cursors& parameters, Input input); 17 | std::wstring ToStringBase(const Cursors& v); 18 | Cursors OptimizeBase(Cursors cursors); 19 | } // namespace afc::editor::transformation 20 | 21 | #endif // __AFC_EDITOR_CURSORS_TRANSFORMATION_H__ 22 | -------------------------------------------------------------------------------- /src/transformation/expand.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_EXPAND_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_EXPAND_H__ 3 | 4 | #include 5 | 6 | #include "src/language/safe_types.h" 7 | #include "src/transformation.h" 8 | #include "src/transformation/composite.h" 9 | 10 | namespace afc::editor { 11 | language::NonNull> 12 | NewExpandTransformation(); 13 | } // namespace afc::editor 14 | 15 | #endif // __AFC_EDITOR_TRANSFORMATION_EXPAND_H__ 16 | -------------------------------------------------------------------------------- /src/transformation/move.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_MOVE_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_MOVE_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/language/safe_types.h" 8 | #include "src/modifiers.h" 9 | #include "src/transformation/input.h" 10 | #include "src/transformation/result.h" 11 | 12 | namespace afc::editor { 13 | namespace transformation { 14 | // Transformation that swaps the current cursor with the next active cursor. 15 | struct SwapActiveCursor { 16 | // Honors `direction` and `repetitions`. May honor more modifiers in the 17 | // future. 18 | Modifiers modifiers; 19 | }; 20 | 21 | futures::Value ApplyBase(const SwapActiveCursor& parameters, 22 | Input input); 23 | std::wstring ToStringBase(const SwapActiveCursor& v); 24 | SwapActiveCursor OptimizeBase(SwapActiveCursor transformation); 25 | } // namespace transformation 26 | 27 | class OperationScope; 28 | class CompositeTransformation; 29 | language::NonNull> 30 | NewMoveTransformation(); 31 | language::NonNull> 32 | NewMoveTransformation( 33 | language::NonNull> operation_scope); 34 | } // namespace afc::editor 35 | 36 | #endif // __AFC_EDITOR_TRANSFORMATION_MOVE_H__ 37 | -------------------------------------------------------------------------------- /src/transformation/noop.cc: -------------------------------------------------------------------------------- 1 | #include "src/transformation/noop.h" 2 | 3 | #include "src/futures/futures.h" 4 | #include "src/transformation/composite.h" 5 | #include "src/transformation/vm.h" 6 | #include "src/vm/types.h" 7 | 8 | namespace gc = afc::language::gc; 9 | 10 | using afc::language::MakeNonNullUnique; 11 | using afc::language::NonNull; 12 | using afc::language::lazy_string::LazyString; 13 | using afc::language::lazy_string::NonEmptySingleLine; 14 | using afc::language::lazy_string::SingleLine; 15 | 16 | namespace afc::editor { 17 | namespace transformation { 18 | namespace { 19 | class Noop : public CompositeTransformation { 20 | public: 21 | static void Register(language::gc::Pool& pool, vm::Environment& environment) { 22 | environment.Define( 23 | vm::Identifier{ 24 | NonEmptySingleLine{SingleLine{LazyString{L"NoopTransformation"}}}}, 25 | vm::NewCallback(pool, vm::kPurityTypePure, []() { 26 | return MakeNonNullShared(NewNoopTransformation()); 27 | })); 28 | } 29 | 30 | std::wstring Serialize() const override { return L"NoopTransformation();"; } 31 | futures::Value Apply(Input) const override { 32 | return futures::Past(Output()); 33 | } 34 | }; 35 | } // namespace 36 | } // namespace transformation 37 | 38 | NonNull> NewNoopTransformation() { 39 | return NonNull>(); 40 | } 41 | 42 | void RegisterNoopTransformation(gc::Pool& pool, vm::Environment& environment) { 43 | transformation::Noop::Register(pool, environment); 44 | } 45 | } // namespace afc::editor 46 | -------------------------------------------------------------------------------- /src/transformation/noop.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_NOOP_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_NOOP_H__ 3 | 4 | #include 5 | 6 | #include "src/transformation/composite.h" 7 | #include "src/vm/environment.h" 8 | 9 | namespace afc::language::gc { 10 | class Pool; 11 | } 12 | namespace afc::editor { 13 | language::NonNull> 14 | NewNoopTransformation(); 15 | void RegisterNoopTransformation(language::gc::Pool& pool, 16 | vm::Environment& environment); 17 | } // namespace afc::editor 18 | 19 | #endif // __AFC_EDITOR_TRANSFORMATION_NOOP_H__ 20 | -------------------------------------------------------------------------------- /src/transformation/paste.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_PASTE_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_PASTE_H__ 3 | 4 | #include 5 | 6 | #include "src/fragments.h" 7 | #include "src/transformation/composite.h" 8 | 9 | namespace afc::editor::transformation { 10 | class Paste : public CompositeTransformation { 11 | const FindFragmentQuery query_; 12 | 13 | public: 14 | Paste() = default; 15 | Paste(FindFragmentQuery query); 16 | std::wstring Serialize() const override; 17 | futures::Value Apply(Input input) const override; 18 | }; 19 | } // namespace afc::editor::transformation 20 | 21 | #endif // __AFC_EDITOR_TRANSFORMATION_PASTE_H__ 22 | -------------------------------------------------------------------------------- /src/transformation/reach_query.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_REACH_QUERY_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_REACH_QUERY_H__ 3 | 4 | #include 5 | 6 | #include "src/language/lazy_string/lazy_string.h" 7 | #include "src/transformation/composite.h" 8 | 9 | namespace afc::editor::transformation { 10 | class ReachQueryTransformation : public CompositeTransformation { 11 | const language::lazy_string::SingleLine query_; 12 | 13 | public: 14 | ReachQueryTransformation(language::lazy_string::SingleLine query); 15 | std::wstring Serialize() const override; 16 | futures::Value Apply(Input input) const override; 17 | }; 18 | } // namespace afc::editor::transformation 19 | 20 | #endif // __AFC_EDITOR_TRANSFORMATION_REACH_QUERY_H__ 21 | -------------------------------------------------------------------------------- /src/transformation/repetitions.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_REPETITIONS_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_REPETITIONS_H__ 3 | 4 | #include 5 | 6 | #include "src/transformation/input.h" 7 | #include "src/transformation/result.h" 8 | #include "src/transformation/type.h" 9 | #include "src/vm/environment.h" 10 | 11 | namespace afc::editor::transformation { 12 | // Repeats a transformation a given number of times. 13 | struct Repetitions { 14 | size_t repetitions; 15 | std::shared_ptr transformation; 16 | }; 17 | 18 | futures::Value ApplyBase(const Repetitions& parameters, Input input); 19 | std::wstring ToStringBase(const Repetitions& v); 20 | Variant OptimizeBase(Repetitions transformation); 21 | } // namespace afc::editor::transformation 22 | #endif // __AFC_EDITOR_TRANSFORMATION_REPETITIONS_H__ 23 | -------------------------------------------------------------------------------- /src/transformation/result.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_RESULT_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_RESULT_H__ 3 | 4 | #include 5 | 6 | #include "src/language/text/line_column.h" 7 | 8 | namespace afc::editor { 9 | class OpenBuffer; 10 | namespace transformation { 11 | struct Stack; 12 | struct Result { 13 | Result(language::text::LineColumn input_position); 14 | Result(Result&&); 15 | ~Result(); 16 | 17 | void MergeFrom(Result result); 18 | 19 | // Did the transformation run to completion? If it only run partially, this 20 | // should be false. 21 | bool success = true; 22 | 23 | // Did the transformation actually make any progress? Some transformations 24 | // succeed without actually having any effect; we use this to stop iterating 25 | // them needlessly. 26 | bool made_progress = false; 27 | 28 | // This the transformation made any actual changes to the contents of the 29 | // buffer? 30 | bool modified_buffer = false; 31 | 32 | // Transformation that will undo any changes done by this one. 33 | language::NonNull> undo_stack; 34 | 35 | bool added_to_paste_buffer = false; 36 | 37 | // Where should the cursor move to after the transformation? 38 | language::text::LineColumn position; 39 | }; 40 | } // namespace transformation 41 | } // namespace afc::editor 42 | #endif //__AFC_EDITOR_TRANSFORMATION_RESULT_H__ 43 | -------------------------------------------------------------------------------- /src/transformation/set_position.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_SET_POSITION_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_SET_POSITION_H__ 3 | 4 | #include 5 | 6 | #include "src/futures/futures.h" 7 | #include "src/language/text/line_column.h" 8 | #include "src/transformation/input.h" 9 | #include "src/transformation/result.h" 10 | #include "src/vm/environment.h" 11 | 12 | namespace afc::editor::transformation { 13 | struct SetPosition { 14 | explicit SetPosition(language::text::LineColumn position) 15 | : line(position.line), column(position.column) {} 16 | explicit SetPosition(language::lazy_string::ColumnNumber input_column) 17 | : column(input_column) {} 18 | 19 | std::optional line; 20 | // If column is greater than the length of the line, goes to the end of the 21 | // line. 22 | language::lazy_string::ColumnNumber column; 23 | }; 24 | 25 | void RegisterSetPosition(language::gc::Pool& pool, 26 | vm::Environment& environment); 27 | 28 | futures::Value ApplyBase(const SetPosition& parameters, Input input); 29 | std::wstring ToStringBase(const SetPosition& parameters); 30 | SetPosition OptimizeBase(SetPosition transformation); 31 | } // namespace afc::editor::transformation 32 | 33 | #endif // __AFC_EDITOR_TRANSFORMATION_SET_POSITION_H__ 34 | -------------------------------------------------------------------------------- /src/transformation/switch_case.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_SWITCH_CASE_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_SWITCH_CASE_H__ 3 | 4 | #include 5 | 6 | #include "src/modifiers.h" 7 | #include "src/transformation.h" 8 | 9 | namespace afc::editor { 10 | class SwitchCaseTransformation : public CompositeTransformation { 11 | public: 12 | std::wstring Serialize() const override; 13 | futures::Value Apply(Input input) const override; 14 | }; 15 | } // namespace afc::editor 16 | 17 | #endif // __AFC_EDITOR_TRANSFORMATION_SWITCH_CASE_H__ 18 | -------------------------------------------------------------------------------- /src/transformation/tree_navigate.h: -------------------------------------------------------------------------------- 1 | // TODO(trivial, 2023-09-29): Delete this dead code. But probably want to 2 | // improve the tree-scroll behavior first. 3 | 4 | #ifndef __AFC_EDITOR_TRANSFORMATION_TREE_NAVIGATE_H__ 5 | #define __AFC_EDITOR_TRANSFORMATION_TREE_NAVIGATE_H__ 6 | 7 | #include 8 | 9 | #include "src/transformation.h" 10 | #include "src/vm/environment.h" 11 | 12 | namespace afc::editor { 13 | class TreeNavigate : public CompositeTransformation { 14 | std::wstring Serialize() const override; 15 | futures::Value Apply(Input input) const override; 16 | }; 17 | } // namespace afc::editor 18 | 19 | #endif // __AFC_EDITOR_TRANSFORMATION_TREE_NAVIGATE_H__ 20 | -------------------------------------------------------------------------------- /src/transformation/type.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_TYPE_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_TYPE_H__ 3 | 4 | #include "src/transformation/composite.h" 5 | #include "src/transformation/repetitions.h" 6 | #include "src/transformation/stack.h" 7 | #include "src/transformation/variant.h" 8 | #include "src/transformation/visual_overlay.h" 9 | 10 | namespace afc::editor::transformation { 11 | void Register(vm::Environment* environment); 12 | 13 | void BaseTransformationRegister(vm::Environment* environment); 14 | 15 | struct Result; 16 | struct Input; 17 | futures::Value Apply(Variant base_transformation, const Input& input); 18 | 19 | std::wstring ToString(const Variant& transformation); 20 | 21 | Variant Optimize(Variant transformation); 22 | 23 | } // namespace afc::editor::transformation 24 | #endif 25 | -------------------------------------------------------------------------------- /src/transformation/variant.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_VARIANT_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_VARIANT_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/transformation/cursors.h" 8 | #include "src/transformation/delete.h" 9 | #include "src/transformation/insert.h" 10 | #include "src/transformation/move.h" 11 | #include "src/transformation/set_position.h" 12 | #include "src/vm/environment.h" 13 | 14 | namespace afc::editor { 15 | class CompositeTransformation; 16 | namespace transformation { 17 | using CompositePtr = 18 | language::NonNull>; 19 | 20 | struct ModifiersAndComposite; 21 | struct Repetitions; 22 | struct Stack; 23 | struct SwapActiveCursor; 24 | struct VisualOverlay; 25 | 26 | using Variant = std::variant; 29 | } // namespace transformation 30 | } // namespace afc::editor 31 | #endif 32 | -------------------------------------------------------------------------------- /src/transformation/visual_overlay.cc: -------------------------------------------------------------------------------- 1 | #include "src/transformation/visual_overlay.h" 2 | 3 | #include "src/buffer.h" 4 | #include "src/futures/futures.h" 5 | 6 | namespace afc::editor::transformation { 7 | using infrastructure::screen::VisualOverlayMap; 8 | 9 | futures::Value ApplyBase(const VisualOverlay& parameters, Input input) { 10 | VisualOverlayMap previous_value = 11 | input.buffer.SetVisualOverlayMap(parameters.visual_overlay_map); 12 | Result result(input.position); 13 | result.undo_stack->push_back( 14 | VisualOverlay{.visual_overlay_map = previous_value}); 15 | return futures::Past(std::move(result)); 16 | } 17 | 18 | std::wstring ToStringBase(const VisualOverlay&) { return L"VisualOverlay"; } 19 | 20 | VisualOverlay OptimizeBase(VisualOverlay transformation) { 21 | return transformation; 22 | } 23 | 24 | } // namespace afc::editor::transformation 25 | -------------------------------------------------------------------------------- /src/transformation/visual_overlay.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_VISUAL_OVERLAY_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_VISUAL_OVERLAY_H__ 3 | 4 | #include 5 | 6 | #include "src/futures/futures.h" 7 | #include "src/infrastructure/screen/visual_overlay.h" 8 | #include "src/language/text/line_column.h" 9 | #include "src/transformation/input.h" 10 | #include "src/transformation/result.h" 11 | #include "src/vm/environment.h" 12 | 13 | namespace afc::editor::transformation { 14 | struct VisualOverlay { 15 | infrastructure::screen::VisualOverlayMap visual_overlay_map; 16 | }; 17 | 18 | futures::Value ApplyBase(const VisualOverlay& parameters, Input input); 19 | std::wstring ToStringBase(const VisualOverlay& parameters); 20 | VisualOverlay OptimizeBase(VisualOverlay transformation); 21 | } // namespace afc::editor::transformation 22 | 23 | #endif // __AFC_EDITOR_TRANSFORMATION_VISUAL_OVERLAY_H__ 24 | -------------------------------------------------------------------------------- /src/transformation/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_TRANSFORMATION_VM_H__ 2 | #define __AFC_EDITOR_TRANSFORMATION_VM_H__ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "src/language/safe_types.h" 10 | #include "src/transformation/type.h" 11 | #include "src/vm/callbacks.h" 12 | 13 | namespace afc::language::gc { 14 | class Pool; 15 | } 16 | namespace afc::vm { 17 | class Environment; 18 | template <> 19 | const types::ObjectName VMTypeMapper>>::object_type_name; 21 | } // namespace afc::vm 22 | namespace afc::editor { 23 | void RegisterTransformations(language::gc::Pool& pool, 24 | vm::Environment& environment); 25 | } // namespace afc::editor 26 | 27 | #endif // __AFC_EDITOR_TRANSFORMATION_VM_H__ 28 | -------------------------------------------------------------------------------- /src/url.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_URL_H__ 2 | #define __AFC_EDITOR_URL_H__ 3 | 4 | #include "src/infrastructure/dirname.h" 5 | #include "src/language/error/value_or_error.h" 6 | #include "src/language/ghost_type_class.h" 7 | #include "src/language/lazy_string/lazy_string.h" 8 | #include "src/language/lazy_string/single_line.h" 9 | #include "src/language/safe_types.h" 10 | 11 | namespace afc::editor { 12 | 13 | class URL 14 | : public language::GhostType { 16 | public: 17 | using GhostType::GhostType; 18 | 19 | static URL FromPath(infrastructure::Path path); 20 | 21 | enum class Schema { kFile, kHttp, kHttps }; 22 | std::optional schema() const; 23 | 24 | language::ValueOrError GetLocalFilePath() const; 25 | }; 26 | 27 | // If `url` is a local file, returns a vector with variations adding all the 28 | // extensions from a list of extensions (given as a space-separated list). 29 | std::vector GetLocalFileURLsWithExtensions( 30 | const language::lazy_string::SingleLine& file_context_extensions, 31 | const URL& url); 32 | 33 | } // namespace afc::editor 34 | 35 | #endif // __AFC_EDITOR_URL_H__ 36 | -------------------------------------------------------------------------------- /src/vm/append_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_APPEND_EXPRESSION_H__ 2 | #define __AFC_VM_APPEND_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/language/error/value_or_error.h" 7 | #include "src/language/safe_types.h" 8 | 9 | namespace afc::vm { 10 | class Expression; 11 | struct Compilation; 12 | 13 | language::ValueOrError>> 14 | NewAppendExpression(Compilation& compilation, std::unique_ptr a, 15 | std::unique_ptr b); 16 | 17 | language::ValueOrError>> 18 | NewAppendExpression(language::NonNull> a, 19 | language::NonNull> b); 20 | 21 | } // namespace afc::vm 22 | 23 | #endif // __AFC_VM_APPEND_EXPRESSION_H__ 24 | -------------------------------------------------------------------------------- /src/vm/assign_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_ASSIGN_EXPRESSION_H__ 2 | #define __AFC_VM_ASSIGN_EXPRESSION_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/vm/types.h" 9 | 10 | namespace afc::vm { 11 | 12 | struct Compilation; 13 | class Expression; 14 | 15 | // Declares a new variable of a given type. 16 | std::optional NewDefineTypeExpression(Compilation& compilation, 17 | Identifier type, Identifier symbol, 18 | std::optional default_type); 19 | 20 | // Declares a new variable of a given type and gives it an initial value. 21 | std::unique_ptr NewDefineExpression( 22 | Compilation& compilation, Identifier type, Identifier symbol, 23 | std::unique_ptr value); 24 | 25 | // Returns an expression that assigns a given value to an existing variable. 26 | std::unique_ptr NewAssignExpression( 27 | Compilation& compilation, Identifier symbol, 28 | std::unique_ptr value); 29 | 30 | } // namespace afc::vm 31 | 32 | #endif // __AFC_VM_ASSIGN_EXPRESSION_H__ 33 | -------------------------------------------------------------------------------- /src/vm/class_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_INTERNAL_CLASS_EXPRESSION_H__ 2 | #define __AFC_VM_INTERNAL_CLASS_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/language/error/value_or_error.h" 7 | #include "src/language/safe_types.h" 8 | #include "src/vm/compilation.h" 9 | #include "src/vm/expression.h" 10 | 11 | namespace afc::vm { 12 | struct Compilation; 13 | namespace types { 14 | class ObjectName; 15 | } 16 | void StartClassDeclaration(Compilation& compilation, 17 | const types::ObjectName& name); 18 | language::PossibleError FinishClassDeclaration( 19 | Compilation& compilation, 20 | language::NonNull> body); 21 | } // namespace afc::vm 22 | 23 | #endif // __AFC_VM_INTERNAL_CLASS_EXPRESSION_H__ 24 | -------------------------------------------------------------------------------- /src/vm/constant_expression.cc: -------------------------------------------------------------------------------- 1 | #include "src/vm/constant_expression.h" 2 | 3 | #include 4 | 5 | #include "src/vm/expression.h" 6 | #include "src/vm/value.h" 7 | 8 | namespace afc::language::gc { 9 | class Pool; 10 | } 11 | namespace afc::vm { 12 | namespace { 13 | using language::MakeNonNullUnique; 14 | using language::NonNull; 15 | using language::Success; 16 | 17 | namespace gc = language::gc; 18 | 19 | class ConstantExpression : public Expression { 20 | public: 21 | ConstantExpression(gc::Root value) : value_(std::move(value)) {} 22 | 23 | std::vector Types() override { return {value_.ptr()->type()}; } 24 | std::unordered_set ReturnTypes() const override { return {}; } 25 | 26 | PurityType purity() override { return PurityType{}; } 27 | 28 | futures::ValueOrError Evaluate(Trampoline&, 29 | const Type& type) override { 30 | CHECK(type == value_.ptr()->type()); 31 | DVLOG(5) << "Evaluating constant value: " << value_.ptr().value(); 32 | return futures::Past(EvaluationOutput::New(value_)); 33 | } 34 | 35 | private: 36 | const gc::Root value_; 37 | }; 38 | 39 | } // namespace 40 | 41 | NonNull> NewVoidExpression(gc::Pool& pool) { 42 | return NewConstantExpression(Value::NewVoid(pool)); 43 | } 44 | 45 | NonNull> NewConstantExpression( 46 | gc::Root value) { 47 | return MakeNonNullUnique(std::move(value)); 48 | } 49 | } // namespace afc::vm 50 | -------------------------------------------------------------------------------- /src/vm/constant_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_CONSTANT_EXPRESSION_H__ 2 | #define __AFC_VM_CONSTANT_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | #include "src/language/safe_types.h" 8 | 9 | namespace afc::vm { 10 | class Expression; 11 | class Value; 12 | 13 | language::NonNull> NewVoidExpression( 14 | language::gc::Pool& pool); 15 | language::NonNull> NewConstantExpression( 16 | language::gc::Root value); 17 | } // namespace afc::vm 18 | 19 | #endif // __AFC_VM_CONSTANT_EXPRESSION_H__ 20 | -------------------------------------------------------------------------------- /src/vm/default_environment.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_DEFAULT_ENVIRONMENT__ 2 | #define __AFC_VM_DEFAULT_ENVIRONMENT__ 3 | 4 | #include "src/language/gc.h" 5 | #include "src/vm/environment.h" 6 | 7 | namespace afc::vm { 8 | language::gc::Root NewDefaultEnvironment(language::gc::Pool& pool); 9 | } 10 | #endif 11 | -------------------------------------------------------------------------------- /src/vm/file_system.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_FILE_SYSTEM_H__ 2 | #define __AFC_VM_FILE_SYSTEM_H__ 3 | 4 | #include "src/infrastructure/file_system_driver.h" 5 | #include "src/language/gc.h" 6 | #include "src/language/safe_types.h" 7 | #include "src/vm/environment.h" 8 | 9 | namespace afc::vm { 10 | class Environment; 11 | void RegisterFileSystemFunctions( 12 | language::gc::Pool& pool, 13 | language::NonNull> 14 | file_system_driver, 15 | Environment& environment); 16 | } // namespace afc::vm 17 | 18 | #endif // __AFC_VM_FILE_SYSTEM_H__ 19 | -------------------------------------------------------------------------------- /src/vm/filter_similar_names.cc: -------------------------------------------------------------------------------- 1 | #include "src/vm/filter_similar_names.h" 2 | 3 | #include 4 | 5 | namespace afc::vm { 6 | std::vector FilterSimilarNames(Identifier name, 7 | std::vector candidates) { 8 | // TODO(easy, 2022-11-26): This can be significantly more flexible. 9 | std::wstring name_str = to_wstring(name); 10 | candidates.erase(std::remove_if(candidates.begin(), candidates.end(), 11 | [&name_str](Identifier candidate) { 12 | return !std::equal( 13 | name_str.begin(), name_str.end(), 14 | to_wstring(candidate).begin(), 15 | [](wchar_t a, wchar_t b) { 16 | return tolower(a) == tolower(b); 17 | }); 18 | }), 19 | candidates.end()); 20 | return candidates; 21 | } 22 | } // namespace afc::vm 23 | -------------------------------------------------------------------------------- /src/vm/filter_similar_names.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_FILTER_SIMILAR_NAMES_H__ 2 | #define __AFC_VM_FILTER_SIMILAR_NAMES_H__ 3 | 4 | #include 5 | 6 | #include "src/vm/types.h" 7 | 8 | namespace afc::vm { 9 | std::vector FilterSimilarNames(Identifier name, 10 | std::vector candidates); 11 | } 12 | 13 | #endif // __AFC_VM_FILTER_SIMILAR_NAMES_H__ 14 | -------------------------------------------------------------------------------- /src/vm/function_call.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_FUNCTION_CALL_H__ 2 | #define __AFC_VM_FUNCTION_CALL_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/futures/futures.h" 8 | #include "src/language/gc.h" 9 | #include "src/language/once_only_function.h" 10 | #include "src/language/safe_types.h" 11 | #include "value.h" 12 | 13 | namespace afc { 14 | namespace vm { 15 | 16 | class Expression; 17 | struct Compilation; 18 | 19 | language::NonNull> NewFunctionCall( 20 | language::NonNull> func, 21 | std::vector>> args); 22 | 23 | std::unique_ptr NewFunctionCall( 24 | Compilation& compilation, 25 | language::NonNull> func, 26 | std::vector>> args); 27 | 28 | futures::ValueOrError> Call( 29 | language::gc::Pool& pool, const Value& func, 30 | std::vector> args, 31 | std::function)> yield_callback); 32 | 33 | std::unique_ptr NewMethodLookup(Compilation& compilation, 34 | std::unique_ptr object, 35 | Identifier method_name); 36 | 37 | } // namespace vm 38 | } // namespace afc 39 | 40 | #endif // __AFC_VM_FUNCTION_CALL_H__ 41 | -------------------------------------------------------------------------------- /src/vm/if_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_INTERNAL_IF_EXPRESSION_H__ 2 | #define __AFC_VM_INTERNAL_IF_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/language/error/value_or_error.h" 7 | #include "src/language/safe_types.h" 8 | #include "src/vm/expression.h" 9 | 10 | namespace afc::vm { 11 | struct Compilation; 12 | language::ValueOrError>> 13 | NewIfExpression(Compilation& compilation, std::unique_ptr condition, 14 | std::unique_ptr true_case, 15 | std::unique_ptr false_case); 16 | } // namespace afc::vm 17 | 18 | #endif // __AFC_VM_INTERNAL_IF_EXPRESSION_H__ 19 | -------------------------------------------------------------------------------- /src/vm/lambda.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_LAMBDA_H__ 2 | #define __AFC_VM_LAMBDA_H__ 3 | 4 | #include 5 | 6 | #include "src/language/gc.h" 7 | #include "src/language/safe_types.h" 8 | #include "src/vm/compilation.h" 9 | #include "src/vm/expression.h" 10 | 11 | namespace afc::vm { 12 | 13 | // Temporary type used during compilation of a function expression. On `New`, 14 | // receives parameters from the function's declaration. These are used on 15 | // `Build` once the body of the expression becomes known. 16 | struct UserFunction { 17 | static std::unique_ptr New( 18 | Compilation& compilation, Identifier return_type, 19 | std::optional name, 20 | std::unique_ptr>> args); 21 | 22 | language::ValueOrError>> 23 | BuildExpression(Compilation& compilation, 24 | language::NonNull> body); 25 | 26 | // It is the caller's responsibility to register errors. 27 | language::ValueOrError> BuildValue( 28 | Compilation& compilation, 29 | language::NonNull> body); 30 | void Abort(Compilation& compilation); 31 | void Done(Compilation& compilation); 32 | 33 | std::optional name; 34 | Type type; 35 | language::NonNull>> argument_names; 36 | }; 37 | } // namespace afc::vm 38 | 39 | #endif // __AFC_VM_LAMBDA_H__ 40 | -------------------------------------------------------------------------------- /src/vm/logical_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_LOGICAL_EXPRESSION_H__ 2 | #define __AFC_VM_LOGICAL_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/language/error/value_or_error.h" 7 | #include "src/language/safe_types.h" 8 | 9 | namespace afc::vm { 10 | 11 | class Expression; 12 | struct Compilation; 13 | 14 | language::ValueOrError>> 15 | NewLogicalExpression(Compilation& compilation, bool identity, 16 | std::unique_ptr a, 17 | std::unique_ptr b); 18 | 19 | } // namespace afc::vm 20 | 21 | #endif // __AFC_VM_LOGICAL_EXPRESSION_H__ 22 | -------------------------------------------------------------------------------- /src/vm/namespace_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_INTERNAL_NAMESPACE_EXPRESSION_H__ 2 | #define __AFC_VM_INTERNAL_NAMESPACE_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/vm/expression.h" 7 | 8 | namespace afc::vm { 9 | struct Compilation; 10 | void StartNamespaceDeclaration(Compilation& compilation, 11 | const Identifier& name); 12 | 13 | std::unique_ptr NewNamespaceExpression( 14 | Compilation& compilation, std::unique_ptr body); 15 | } // namespace afc::vm 16 | 17 | #endif // __AFC_VM_INTERNAL_NAMESPACE_EXPRESSION_H__ 18 | -------------------------------------------------------------------------------- /src/vm/natural.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_NATURAL_H__ 2 | #define __AFC_VM_NATURAL_H__ 3 | 4 | #include 5 | 6 | #include "src/language/error/value_or_error.h" 7 | #include "src/language/lazy_string/lazy_string.h" 8 | #include "src/language/safe_types.h" 9 | #include "src/vm/environment.h" 10 | #include "src/vm/expression.h" 11 | 12 | namespace afc::vm::natural { 13 | // function_name_prefix will be prepended to the name of the top-level function. 14 | // This can be used to select a `preview` function: the environment can define 15 | // function `PreviewFoo` and `Foo` and we can select which one should be used. 16 | language::ValueOrError>> Compile( 17 | const language::lazy_string::SingleLine& input, 18 | const language::lazy_string::SingleLine& function_name_prefix, 19 | const Environment& environment, 20 | const std::vector& search_namespaces, language::gc::Pool& pool); 21 | } // namespace afc::vm::natural 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/vm/negate_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_NEGATE_EXPRESSION_H__ 2 | #define __AFC_VM_NEGATE_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | namespace afc::vm { 7 | struct Compilation; 8 | class Expression; 9 | 10 | std::unique_ptr NewNegateExpressionBool( 11 | Compilation& compilation, std::unique_ptr expr); 12 | std::unique_ptr NewNegateExpressionNumber( 13 | Compilation& compilation, std::unique_ptr expr); 14 | } // namespace afc::vm 15 | 16 | #endif // __AFC_VM_NEGATE_EXPRESSION_H__ 17 | -------------------------------------------------------------------------------- /src/vm/numbers.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_INTERNAL_NUMBERS_H__ 2 | #define __AFC_VM_INTERNAL_NUMBERS_H__ 3 | 4 | namespace afc::language::gc { 5 | class Pool; 6 | } 7 | namespace afc::vm { 8 | class Environment; 9 | void RegisterNumberFunctions(language::gc::Pool& pool, 10 | Environment& environment); 11 | } // namespace afc::vm 12 | 13 | #endif // __AFC_VM_INTERNAL_NUMBERS_H__ 14 | -------------------------------------------------------------------------------- /src/vm/return_expression.cc: -------------------------------------------------------------------------------- 1 | #include "return_expression.h" 2 | 3 | #include 4 | 5 | using afc::language::MakeNonNullUnique; 6 | using afc::language::NonNull; 7 | using afc::language::Success; 8 | using afc::language::VisitPointer; 9 | 10 | namespace afc::vm { 11 | namespace { 12 | class ReturnExpression : public Expression { 13 | public: 14 | ReturnExpression(NonNull> expr) 15 | : expr_(std::move(expr)) {} 16 | 17 | std::vector Types() override { return expr_->Types(); } 18 | 19 | std::unordered_set ReturnTypes() const override { 20 | auto types = expr_->Types(); 21 | return {types.cbegin(), types.cend()}; 22 | } 23 | 24 | PurityType purity() override { return expr_->purity(); } 25 | 26 | futures::ValueOrError Evaluate(Trampoline& trampoline, 27 | const Type&) override { 28 | return trampoline.Bounce(expr_, expr_->Types()[0]) 29 | .Transform([](EvaluationOutput expr_output) { 30 | return Success( 31 | EvaluationOutput::Return(std::move(expr_output.value))); 32 | }); 33 | } 34 | 35 | private: 36 | const NonNull> expr_; 37 | }; 38 | 39 | } // namespace 40 | 41 | std::unique_ptr NewReturnExpression( 42 | std::unique_ptr expr_input) { 43 | return VisitPointer( 44 | std::move(expr_input), 45 | [](NonNull> expr) { 46 | return std::make_unique(std::move(expr)); 47 | }, 48 | [] { return nullptr; }); 49 | } 50 | 51 | } // namespace afc::vm 52 | -------------------------------------------------------------------------------- /src/vm/return_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_RETURN_EXPRESSION_H__ 2 | #define __AFC_VM_RETURN_EXPRESSION_H__ 3 | 4 | #include "src/vm/compilation.h" 5 | #include "src/vm/expression.h" 6 | 7 | namespace afc::vm { 8 | std::unique_ptr NewReturnExpression( 9 | std::unique_ptr expr); 10 | } // namespace afc::vm 11 | 12 | #endif // __AFC_VM_RETURN_EXPRESSION_H__ 13 | -------------------------------------------------------------------------------- /src/vm/string.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_INTERNAL_STRING_H__ 2 | #define __AFC_VM_INTERNAL_STRING_H__ 3 | 4 | #include 5 | 6 | #include "src/concurrent/protected.h" 7 | #include "src/language/lazy_string/lazy_string.h" 8 | #include "src/language/safe_types.h" 9 | #include "src/vm/callbacks.h" 10 | 11 | namespace afc::language::gc { 12 | class Pool; 13 | } 14 | namespace afc::vm { 15 | class Environment; 16 | void RegisterStringType(language::gc::Pool& pool, Environment& environment); 17 | 18 | template <> 19 | const types::ObjectName 20 | VMTypeMapper>>>>::object_type_name; 22 | 23 | } // namespace afc::vm 24 | 25 | #endif // __AFC_VM_INTERNAL_STRING_H__ 26 | -------------------------------------------------------------------------------- /src/vm/time.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_INTERNAL_TIME_H__ 2 | #define __AFC_VM_INTERNAL_TIME_H__ 3 | 4 | namespace afc::language::gc { 5 | class Pool; 6 | } 7 | namespace afc::vm { 8 | class Environment; 9 | void RegisterTimeType(language::gc::Pool& pool, Environment& environment); 10 | } // namespace afc::vm 11 | 12 | #endif // __AFC_VM_INTERNAL_TIME_H__ 13 | -------------------------------------------------------------------------------- /src/vm/variable_lookup.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_VARIABLE_LOOKUP_H__ 2 | #define __AFC_VM_VARIABLE_LOOKUP_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/vm/types.h" 9 | 10 | namespace afc::vm { 11 | struct Compilation; 12 | class Expression; 13 | 14 | // Symbols is a list of tokens, including namespace or class prefixes. The last 15 | // item will be the final symbol to look up. 16 | std::unique_ptr NewVariableLookup(Compilation& compilation, 17 | std::list symbols); 18 | 19 | } // namespace afc::vm 20 | 21 | #endif // __AFC_VM_VARIABLE_LOOKUP_H__ 22 | -------------------------------------------------------------------------------- /src/vm/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_PUBLIC_VM_H__ 2 | #define __AFC_VM_PUBLIC_VM_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/infrastructure/dirname.h" 8 | #include "src/language/error/value_or_error.h" 9 | #include "src/language/gc.h" 10 | #include "src/language/lazy_string/lazy_string.h" 11 | #include "src/language/safe_types.h" 12 | #include "src/vm/environment.h" 13 | #include "src/vm/expression.h" 14 | #include "src/vm/types.h" 15 | 16 | namespace afc::vm { 17 | language::ValueOrError>> 18 | CompileFile(infrastructure::Path path, language::gc::Pool& pool, 19 | language::gc::Root environment); 20 | 21 | language::ValueOrError>> 22 | CompileString(const language::lazy_string::LazyString& str, 23 | language::gc::Pool& pool, 24 | language::gc::Root environment); 25 | } // namespace afc::vm 26 | 27 | #endif // __AFC_VM_VM_H__ 28 | -------------------------------------------------------------------------------- /src/vm/while_expression.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_VM_WHILE_EXPRESSION_H__ 2 | #define __AFC_VM_WHILE_EXPRESSION_H__ 3 | 4 | #include 5 | 6 | #include "src/language/error/value_or_error.h" 7 | #include "src/language/safe_types.h" 8 | 9 | namespace afc { 10 | namespace vm { 11 | 12 | using std::unique_ptr; 13 | 14 | struct Compilation; 15 | class Expression; 16 | 17 | language::ValueOrError>> 18 | NewWhileExpression(Compilation& compilation, unique_ptr cond, 19 | unique_ptr body); 20 | 21 | language::ValueOrError>> 22 | NewForExpression(Compilation& compilation, std::unique_ptr init, 23 | std::unique_ptr condition, 24 | std::unique_ptr update, 25 | std::unique_ptr body); 26 | 27 | } // namespace vm 28 | } // namespace afc 29 | 30 | #endif // __AFC_VM_WHILE_EXPRESSION_H__ 31 | -------------------------------------------------------------------------------- /src/widget.h: -------------------------------------------------------------------------------- 1 | #ifndef __AFC_EDITOR_WIDGET_H__ 2 | #define __AFC_EDITOR_WIDGET_H__ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/language/text/line_column.h" 8 | #include "src/line_with_cursor.h" 9 | #include "src/vm/environment.h" 10 | 11 | namespace afc::editor { 12 | class Widget { 13 | public: 14 | virtual ~Widget() = default; 15 | 16 | struct OutputProducerOptions { 17 | language::text::LineColumnDelta size; 18 | enum class MainCursorDisplay { 19 | kActive, 20 | // The main cursor should be shown as inactive. 21 | kInactive 22 | }; 23 | MainCursorDisplay main_cursor_display = MainCursorDisplay::kActive; 24 | }; 25 | virtual LineWithCursor::Generator::Vector CreateOutput( 26 | OutputProducerOptions options) const = 0; 27 | 28 | virtual language::text::LineNumberDelta MinimumLines() const = 0; 29 | virtual language::text::LineNumberDelta DesiredLines() const = 0; 30 | }; 31 | } // namespace afc::editor 32 | 33 | #endif // __AFC_EDITOR_WIDGET_H__ 34 | --------------------------------------------------------------------------------