diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..6acf686
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,568 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+max_line_length = 120
+tab_width = 2
+ij_continuation_indent_size = 2
+ij_formatter_off_tag = @fmt:off
+ij_formatter_on_tag = @fmt:on
+ij_formatter_tags_enabled = false
+ij_smart_tabs = true
+ij_visual_guides = none
+ij_wrap_on_typing = false
+
+[*.java]
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = true
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 0
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 1
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 0
+ij_java_blank_lines_before_class_end = 0
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 0
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = end_of_line
+ij_java_block_comment_at_first_column = true
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = off
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = false
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = end_of_line
+ij_java_class_count_to_use_import_on_demand = 5
+ij_java_class_names_in_javadoc = 1
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_while_brace_force = never
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = false
+ij_java_doc_add_blank_line_after_return = false
+ij_java_doc_add_p_tag_on_empty_lines = true
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = true
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = false
+ij_java_enum_constants_wrap = off
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_finally_on_new_line = false
+ij_java_for_brace_force = never
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_if_brace_force = never
+ij_java_imports_layout = *,|,javax.**,java.**,|,$*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_control_statement_in_one_line = true
+ij_java_keep_first_column_comment = true
+ij_java_keep_indents_on_empty_lines = false
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = false
+ij_java_keep_simple_classes_in_one_line = false
+ij_java_keep_simple_lambdas_in_one_line = true
+ij_java_keep_simple_methods_in_one_line = false
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = end_of_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = true
+ij_java_line_comment_at_first_column = false
+ij_java_method_annotation_wrap = normal
+ij_java_method_brace_style = end_of_line
+ij_java_method_call_chain_wrap = off
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = off
+ij_java_modifier_list_wrap = false
+ij_java_names_count_to_use_import_on_demand = 3
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = off
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_space_after_closing_angle_bracket_in_type_argument = false
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = false
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = true
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = true
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = true
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = true
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = true
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = true
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = true
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = false
+ij_java_spaces_within_angle_brackets = false
+ij_java_spaces_within_annotation_parentheses = false
+ij_java_spaces_within_array_initializer_braces = false
+ij_java_spaces_within_braces = false
+ij_java_spaces_within_brackets = false
+ij_java_spaces_within_cast_parentheses = false
+ij_java_spaces_within_catch_parentheses = false
+ij_java_spaces_within_for_parentheses = false
+ij_java_spaces_within_if_parentheses = false
+ij_java_spaces_within_method_call_parentheses = false
+ij_java_spaces_within_method_parentheses = false
+ij_java_spaces_within_parentheses = false
+ij_java_spaces_within_record_header = false
+ij_java_spaces_within_switch_parentheses = false
+ij_java_spaces_within_synchronized_parentheses = false
+ij_java_spaces_within_try_parentheses = false
+ij_java_spaces_within_while_parentheses = false
+ij_java_special_else_if_treatment = true
+ij_java_subclass_name_suffix = Impl
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = never
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = false
+
+[*.properties]
+ij_properties_align_group_field_declarations = false
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = false
+
+[*.proto]
+ij_proto_keep_indents_on_empty_lines = false
+
+[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.jspx,*.pom,*.rng,*.tagx,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 1
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+
+[{*.gant,*.gradle,*.groovy,*.gy}]
+ij_groovy_align_group_field_declarations = false
+ij_groovy_align_multiline_array_initializer_expression = false
+ij_groovy_align_multiline_assignment = false
+ij_groovy_align_multiline_binary_operation = false
+ij_groovy_align_multiline_chained_methods = false
+ij_groovy_align_multiline_extends_list = false
+ij_groovy_align_multiline_for = true
+ij_groovy_align_multiline_list_or_map = true
+ij_groovy_align_multiline_method_parentheses = false
+ij_groovy_align_multiline_parameters = true
+ij_groovy_align_multiline_parameters_in_calls = false
+ij_groovy_align_multiline_resources = true
+ij_groovy_align_multiline_ternary_operation = false
+ij_groovy_align_multiline_throws_list = false
+ij_groovy_align_named_args_in_map = true
+ij_groovy_align_throws_keyword = false
+ij_groovy_array_initializer_new_line_after_left_brace = false
+ij_groovy_array_initializer_right_brace_on_new_line = false
+ij_groovy_array_initializer_wrap = off
+ij_groovy_assert_statement_wrap = off
+ij_groovy_assignment_wrap = off
+ij_groovy_binary_operation_wrap = off
+ij_groovy_blank_lines_after_class_header = 0
+ij_groovy_blank_lines_after_imports = 1
+ij_groovy_blank_lines_after_package = 1
+ij_groovy_blank_lines_around_class = 1
+ij_groovy_blank_lines_around_field = 0
+ij_groovy_blank_lines_around_field_in_interface = 0
+ij_groovy_blank_lines_around_method = 1
+ij_groovy_blank_lines_around_method_in_interface = 1
+ij_groovy_blank_lines_before_imports = 1
+ij_groovy_blank_lines_before_method_body = 0
+ij_groovy_blank_lines_before_package = 0
+ij_groovy_block_brace_style = end_of_line
+ij_groovy_block_comment_at_first_column = true
+ij_groovy_call_parameters_new_line_after_left_paren = false
+ij_groovy_call_parameters_right_paren_on_new_line = false
+ij_groovy_call_parameters_wrap = off
+ij_groovy_catch_on_new_line = false
+ij_groovy_class_annotation_wrap = split_into_lines
+ij_groovy_class_brace_style = end_of_line
+ij_groovy_class_count_to_use_import_on_demand = 5
+ij_groovy_do_while_brace_force = never
+ij_groovy_else_on_new_line = false
+ij_groovy_enum_constants_wrap = off
+ij_groovy_extends_keyword_wrap = off
+ij_groovy_extends_list_wrap = off
+ij_groovy_field_annotation_wrap = off
+ij_groovy_finally_on_new_line = false
+ij_groovy_for_brace_force = never
+ij_groovy_for_statement_new_line_after_left_paren = false
+ij_groovy_for_statement_right_paren_on_new_line = false
+ij_groovy_for_statement_wrap = off
+ij_groovy_if_brace_force = never
+ij_groovy_import_annotation_wrap = 2
+ij_groovy_imports_layout = *,|,javax.**,java.**,|,$*
+ij_groovy_indent_case_from_switch = true
+ij_groovy_indent_label_blocks = true
+ij_groovy_insert_inner_class_imports = false
+ij_groovy_keep_blank_lines_before_right_brace = 2
+ij_groovy_keep_blank_lines_in_code = 2
+ij_groovy_keep_blank_lines_in_declarations = 2
+ij_groovy_keep_control_statement_in_one_line = true
+ij_groovy_keep_first_column_comment = true
+ij_groovy_keep_indents_on_empty_lines = false
+ij_groovy_keep_line_breaks = true
+ij_groovy_keep_multiple_expressions_in_one_line = false
+ij_groovy_keep_simple_blocks_in_one_line = false
+ij_groovy_keep_simple_classes_in_one_line = true
+ij_groovy_keep_simple_lambdas_in_one_line = true
+ij_groovy_keep_simple_methods_in_one_line = true
+ij_groovy_label_indent_absolute = false
+ij_groovy_label_indent_size = 0
+ij_groovy_lambda_brace_style = end_of_line
+ij_groovy_layout_static_imports_separately = true
+ij_groovy_line_comment_add_space = false
+ij_groovy_line_comment_at_first_column = true
+ij_groovy_method_annotation_wrap = off
+ij_groovy_method_brace_style = end_of_line
+ij_groovy_method_call_chain_wrap = off
+ij_groovy_method_parameters_new_line_after_left_paren = false
+ij_groovy_method_parameters_right_paren_on_new_line = false
+ij_groovy_method_parameters_wrap = off
+ij_groovy_modifier_list_wrap = false
+ij_groovy_names_count_to_use_import_on_demand = 3
+ij_groovy_parameter_annotation_wrap = off
+ij_groovy_parentheses_expression_new_line_after_left_paren = false
+ij_groovy_parentheses_expression_right_paren_on_new_line = false
+ij_groovy_prefer_parameters_wrap = false
+ij_groovy_resource_list_new_line_after_left_paren = false
+ij_groovy_resource_list_right_paren_on_new_line = false
+ij_groovy_resource_list_wrap = off
+ij_groovy_space_after_assert_separator = true
+ij_groovy_space_after_colon = true
+ij_groovy_space_after_comma = true
+ij_groovy_space_after_comma_in_type_arguments = true
+ij_groovy_space_after_for_semicolon = true
+ij_groovy_space_after_quest = true
+ij_groovy_space_after_type_cast = true
+ij_groovy_space_before_annotation_parameter_list = false
+ij_groovy_space_before_array_initializer_left_brace = false
+ij_groovy_space_before_assert_separator = false
+ij_groovy_space_before_catch_keyword = true
+ij_groovy_space_before_catch_left_brace = true
+ij_groovy_space_before_catch_parentheses = true
+ij_groovy_space_before_class_left_brace = true
+ij_groovy_space_before_closure_left_brace = true
+ij_groovy_space_before_colon = true
+ij_groovy_space_before_comma = false
+ij_groovy_space_before_do_left_brace = true
+ij_groovy_space_before_else_keyword = true
+ij_groovy_space_before_else_left_brace = true
+ij_groovy_space_before_finally_keyword = true
+ij_groovy_space_before_finally_left_brace = true
+ij_groovy_space_before_for_left_brace = true
+ij_groovy_space_before_for_parentheses = true
+ij_groovy_space_before_for_semicolon = false
+ij_groovy_space_before_if_left_brace = true
+ij_groovy_space_before_if_parentheses = true
+ij_groovy_space_before_method_call_parentheses = false
+ij_groovy_space_before_method_left_brace = true
+ij_groovy_space_before_method_parentheses = false
+ij_groovy_space_before_quest = true
+ij_groovy_space_before_switch_left_brace = true
+ij_groovy_space_before_switch_parentheses = true
+ij_groovy_space_before_synchronized_left_brace = true
+ij_groovy_space_before_synchronized_parentheses = true
+ij_groovy_space_before_try_left_brace = true
+ij_groovy_space_before_try_parentheses = true
+ij_groovy_space_before_while_keyword = true
+ij_groovy_space_before_while_left_brace = true
+ij_groovy_space_before_while_parentheses = true
+ij_groovy_space_in_named_argument = true
+ij_groovy_space_in_named_argument_before_colon = false
+ij_groovy_space_within_empty_array_initializer_braces = false
+ij_groovy_space_within_empty_method_call_parentheses = false
+ij_groovy_spaces_around_additive_operators = true
+ij_groovy_spaces_around_assignment_operators = true
+ij_groovy_spaces_around_bitwise_operators = true
+ij_groovy_spaces_around_equality_operators = true
+ij_groovy_spaces_around_lambda_arrow = true
+ij_groovy_spaces_around_logical_operators = true
+ij_groovy_spaces_around_multiplicative_operators = true
+ij_groovy_spaces_around_regex_operators = true
+ij_groovy_spaces_around_relational_operators = true
+ij_groovy_spaces_around_shift_operators = true
+ij_groovy_spaces_within_annotation_parentheses = false
+ij_groovy_spaces_within_array_initializer_braces = false
+ij_groovy_spaces_within_braces = true
+ij_groovy_spaces_within_brackets = false
+ij_groovy_spaces_within_cast_parentheses = false
+ij_groovy_spaces_within_catch_parentheses = false
+ij_groovy_spaces_within_for_parentheses = false
+ij_groovy_spaces_within_gstring_injection_braces = false
+ij_groovy_spaces_within_if_parentheses = false
+ij_groovy_spaces_within_list_or_map = false
+ij_groovy_spaces_within_method_call_parentheses = false
+ij_groovy_spaces_within_method_parentheses = false
+ij_groovy_spaces_within_parentheses = false
+ij_groovy_spaces_within_switch_parentheses = false
+ij_groovy_spaces_within_synchronized_parentheses = false
+ij_groovy_spaces_within_try_parentheses = false
+ij_groovy_spaces_within_tuple_expression = false
+ij_groovy_spaces_within_while_parentheses = false
+ij_groovy_special_else_if_treatment = true
+ij_groovy_ternary_operation_wrap = off
+ij_groovy_throws_keyword_wrap = off
+ij_groovy_throws_list_wrap = off
+ij_groovy_use_flying_geese_braces = false
+ij_groovy_use_fq_class_names = false
+ij_groovy_use_fq_class_names_in_javadoc = true
+ij_groovy_use_relative_indents = false
+ij_groovy_use_single_class_imports = true
+ij_groovy_variable_annotation_wrap = off
+ij_groovy_while_brace_force = never
+ij_groovy_while_on_new_line = false
+ij_groovy_wrap_long_lines = false
+
+[{*.kt,*.kts}]
+ij_kotlin_align_in_columns_case_branch = false
+ij_kotlin_align_multiline_binary_operation = false
+ij_kotlin_align_multiline_extends_list = false
+ij_kotlin_align_multiline_method_parentheses = false
+ij_kotlin_align_multiline_parameters = true
+ij_kotlin_align_multiline_parameters_in_calls = false
+ij_kotlin_allow_trailing_comma = true
+ij_kotlin_allow_trailing_comma_on_call_site = true
+ij_kotlin_assignment_wrap = off
+ij_kotlin_blank_lines_after_class_header = 0
+ij_kotlin_blank_lines_around_block_when_branches = 0
+ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
+ij_kotlin_block_comment_at_first_column = true
+ij_kotlin_call_parameters_new_line_after_left_paren = false
+ij_kotlin_call_parameters_right_paren_on_new_line = false
+ij_kotlin_call_parameters_wrap = off
+ij_kotlin_catch_on_new_line = false
+ij_kotlin_class_annotation_wrap = split_into_lines
+ij_kotlin_continuation_indent_for_chained_calls = true
+ij_kotlin_continuation_indent_for_expression_bodies = true
+ij_kotlin_continuation_indent_in_argument_lists = true
+ij_kotlin_continuation_indent_in_elvis = true
+ij_kotlin_continuation_indent_in_if_conditions = true
+ij_kotlin_continuation_indent_in_parameter_lists = true
+ij_kotlin_continuation_indent_in_supertype_lists = true
+ij_kotlin_else_on_new_line = false
+ij_kotlin_enum_constants_wrap = off
+ij_kotlin_extends_list_wrap = off
+ij_kotlin_field_annotation_wrap = on_every_item
+ij_kotlin_finally_on_new_line = false
+ij_kotlin_if_rparen_on_new_line = false
+ij_kotlin_import_nested_classes = false
+ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
+ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
+ij_kotlin_keep_blank_lines_before_right_brace = 2
+ij_kotlin_keep_blank_lines_in_code = 2
+ij_kotlin_keep_blank_lines_in_declarations = 2
+ij_kotlin_keep_first_column_comment = true
+ij_kotlin_keep_indents_on_empty_lines = false
+ij_kotlin_keep_line_breaks = true
+ij_kotlin_lbrace_on_next_line = false
+ij_kotlin_line_comment_add_space = false
+ij_kotlin_line_comment_at_first_column = true
+ij_kotlin_method_annotation_wrap = normal
+ij_kotlin_method_call_chain_wrap = off
+ij_kotlin_method_parameters_new_line_after_left_paren = false
+ij_kotlin_method_parameters_right_paren_on_new_line = false
+ij_kotlin_method_parameters_wrap = off
+ij_kotlin_name_count_to_use_star_import = 5
+ij_kotlin_name_count_to_use_star_import_for_members = 3
+ij_kotlin_packages_to_use_import_on_demand = java.util.*,io.ktor.**,java.awt.*,javax.swing.*
+ij_kotlin_parameter_annotation_wrap = off
+ij_kotlin_space_after_comma = true
+ij_kotlin_space_after_extend_colon = true
+ij_kotlin_space_after_type_colon = true
+ij_kotlin_space_before_catch_parentheses = true
+ij_kotlin_space_before_comma = false
+ij_kotlin_space_before_extend_colon = true
+ij_kotlin_space_before_for_parentheses = true
+ij_kotlin_space_before_if_parentheses = true
+ij_kotlin_space_before_lambda_arrow = true
+ij_kotlin_space_before_type_colon = false
+ij_kotlin_space_before_when_parentheses = true
+ij_kotlin_space_before_while_parentheses = true
+ij_kotlin_spaces_around_additive_operators = true
+ij_kotlin_spaces_around_assignment_operators = true
+ij_kotlin_spaces_around_equality_operators = true
+ij_kotlin_spaces_around_function_type_arrow = true
+ij_kotlin_spaces_around_logical_operators = true
+ij_kotlin_spaces_around_multiplicative_operators = true
+ij_kotlin_spaces_around_range = false
+ij_kotlin_spaces_around_relational_operators = true
+ij_kotlin_spaces_around_unary_operator = false
+ij_kotlin_spaces_around_when_arrow = true
+ij_kotlin_variable_annotation_wrap = off
+ij_kotlin_while_on_new_line = false
+ij_kotlin_wrap_elvis_expressions = 1
+ij_kotlin_wrap_expression_body_functions = 0
+ij_kotlin_wrap_first_method_in_call_chain = false
+
+[{*.har,*.json}]
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = true
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+
+[{*.markdown,*.md}]
+ij_markdown_force_one_space_after_blockquote_symbol = true
+ij_markdown_force_one_space_after_header_symbol = true
+ij_markdown_force_one_space_after_list_bullet = true
+ij_markdown_force_one_space_between_words = true
+ij_markdown_keep_indents_on_empty_lines = false
+ij_markdown_max_lines_around_block_elements = 1
+ij_markdown_max_lines_around_header = 1
+ij_markdown_max_lines_between_paragraphs = 1
+ij_markdown_min_lines_around_block_elements = 1
+ij_markdown_min_lines_around_header = 1
+ij_markdown_min_lines_between_paragraphs = 1
+
+[{*.yaml,*.yml}]
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
+ij_yaml_space_before_colon = true
+ij_yaml_spaces_within_braces = true
+ij_yaml_spaces_within_brackets = true
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aa35c5a..93a20c0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -125,22 +125,22 @@
@@ -159,12 +159,6 @@
android:exported="false"
android:label="@string/pref_customization_color_scheme"
android:theme="@style/AppTheme.NoActionBar.Dark"/>
-
-
-
\ No newline at end of file
+
diff --git a/app/src/main/java/io/neoterm/App.kt b/app/src/main/java/io/neoterm/App.kt
index 08612af..9b39d38 100644
--- a/app/src/main/java/io/neoterm/App.kt
+++ b/app/src/main/java/io/neoterm/App.kt
@@ -9,8 +9,8 @@ import android.view.Gravity
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import io.neoterm.component.NeoInitializer
-import io.neoterm.frontend.config.NeoPreference
-import io.neoterm.ui.bonus.BonusActivity
+import io.neoterm.component.config.NeoPreference
+import io.neoterm.ui.other.BonusActivity
import io.neoterm.utils.CrashHandler
/**
@@ -73,4 +73,4 @@ class App : Application() {
return app!!
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/component/NeoInitializer.kt b/app/src/main/java/io/neoterm/component/NeoInitializer.kt
index 1a7d867..e30678a 100644
--- a/app/src/main/java/io/neoterm/component/NeoInitializer.kt
+++ b/app/src/main/java/io/neoterm/component/NeoInitializer.kt
@@ -10,10 +10,9 @@ import io.neoterm.component.font.FontComponent
import io.neoterm.component.pm.PackageComponent
import io.neoterm.component.profile.ProfileComponent
import io.neoterm.component.session.SessionComponent
+import io.neoterm.component.session.ShellProfile
import io.neoterm.component.userscript.UserScriptComponent
-import io.neoterm.frontend.component.ComponentManager
-import io.neoterm.frontend.logging.NLog
-import io.neoterm.frontend.session.shell.ShellProfile
+import io.neoterm.utils.NLog
/**
* @author kiva
@@ -39,4 +38,4 @@ object NeoInitializer {
val profileComp = ComponentManager.getComponent()
profileComp.registerProfile(ShellProfile.PROFILE_META_NAME, ShellProfile::class.java)
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/component/codegen/CodeGenParameter.kt b/app/src/main/java/io/neoterm/component/codegen/CodeGenParameter.kt
deleted file mode 100644
index 0d0170a..0000000
--- a/app/src/main/java/io/neoterm/component/codegen/CodeGenParameter.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package io.neoterm.component.codegen
-
-/**
- * @author kiva
- */
-class CodeGenParameter
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/codegen/CodeGenComponent.kt b/app/src/main/java/io/neoterm/component/codegen/comp.kt
similarity index 64%
rename from app/src/main/java/io/neoterm/component/codegen/CodeGenComponent.kt
rename to app/src/main/java/io/neoterm/component/codegen/comp.kt
index ec78f3d..4ffcb47 100644
--- a/app/src/main/java/io/neoterm/component/codegen/CodeGenComponent.kt
+++ b/app/src/main/java/io/neoterm/component/codegen/comp.kt
@@ -1,12 +1,8 @@
package io.neoterm.component.codegen
-import io.neoterm.component.codegen.interfaces.CodeGenObject
-import io.neoterm.component.codegen.interfaces.CodeGenerator
-import io.neoterm.frontend.component.NeoComponent
+import io.neoterm.component.NeoComponent
+
-/**
- * @author kiva
- */
class CodeGenComponent : NeoComponent {
override fun onServiceInit() {
}
@@ -23,3 +19,4 @@ class CodeGenComponent : NeoComponent {
}
}
+class CodeGenParameter
diff --git a/app/src/main/java/io/neoterm/component/codegen/generators/NeoColorGenerator.kt b/app/src/main/java/io/neoterm/component/codegen/generators.kt
similarity index 84%
rename from app/src/main/java/io/neoterm/component/codegen/generators/NeoColorGenerator.kt
rename to app/src/main/java/io/neoterm/component/codegen/generators.kt
index a0ef650..3ceb7f2 100644
--- a/app/src/main/java/io/neoterm/component/codegen/generators/NeoColorGenerator.kt
+++ b/app/src/main/java/io/neoterm/component/codegen/generators.kt
@@ -1,15 +1,9 @@
-package io.neoterm.component.codegen.generators
+package io.neoterm.component.codegen
-import io.neoterm.component.codegen.CodeGenParameter
-import io.neoterm.component.codegen.interfaces.CodeGenObject
-import io.neoterm.component.codegen.interfaces.CodeGenerator
+import io.neoterm.component.ComponentManager
import io.neoterm.component.colorscheme.NeoColorScheme
import io.neoterm.component.config.ConfigureComponent
-import io.neoterm.frontend.component.ComponentManager
-/**
- * @author kiva
- */
class NeoColorGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter) {
override fun getGeneratorName(): String {
return "NeoColorScheme-Generator"
@@ -44,7 +38,7 @@ class NeoColorGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter)
" ${NeoColorScheme.COLOR_META_VERSION}: ${
colorScheme.colorVersion
?: component.getLoaderVersion()
- }\n"
+ }\n",
)
builder.append("\n")
}
@@ -61,4 +55,14 @@ class NeoColorGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter)
builder.append(" }\n")
}
-}
\ No newline at end of file
+}
+
+class NeoProfileGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter) {
+ override fun getGeneratorName(): String {
+ return "NeoProfile-Generator"
+ }
+
+ override fun generateCode(codeGenObject: CodeGenObject): String {
+ return ""
+ }
+}
diff --git a/app/src/main/java/io/neoterm/component/codegen/generators/NeoProfileGenerator.kt b/app/src/main/java/io/neoterm/component/codegen/generators/NeoProfileGenerator.kt
deleted file mode 100644
index 3fb2209..0000000
--- a/app/src/main/java/io/neoterm/component/codegen/generators/NeoProfileGenerator.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.neoterm.component.codegen.generators
-
-import io.neoterm.component.codegen.CodeGenParameter
-import io.neoterm.component.codegen.interfaces.CodeGenObject
-import io.neoterm.component.codegen.interfaces.CodeGenerator
-
-/**
- * @author kiva
- */
-class NeoProfileGenerator(parameter: CodeGenParameter) : CodeGenerator(parameter) {
- override fun getGeneratorName(): String {
- return "NeoProfile-Generator"
- }
-
- override fun generateCode(codeGenObject: CodeGenObject): String {
- return ""
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/codegen/interfaces/CodeGenerator.kt b/app/src/main/java/io/neoterm/component/codegen/interfaces.kt
similarity index 56%
rename from app/src/main/java/io/neoterm/component/codegen/interfaces/CodeGenerator.kt
rename to app/src/main/java/io/neoterm/component/codegen/interfaces.kt
index b4a25c3..30441cd 100644
--- a/app/src/main/java/io/neoterm/component/codegen/interfaces/CodeGenerator.kt
+++ b/app/src/main/java/io/neoterm/component/codegen/interfaces.kt
@@ -1,12 +1,10 @@
-package io.neoterm.component.codegen.interfaces
+package io.neoterm.component.codegen
-import io.neoterm.component.codegen.CodeGenParameter
-
-/**
- * @author kiva
- */
abstract class CodeGenerator(parameter: CodeGenParameter) {
abstract fun getGeneratorName(): String
-
abstract fun generateCode(codeGenObject: CodeGenObject): String
}
+
+interface CodeGenObject {
+ fun getCodeGenerator(parameter: CodeGenParameter): CodeGenerator
+}
diff --git a/app/src/main/java/io/neoterm/component/codegen/interfaces/CodeGenObject.kt b/app/src/main/java/io/neoterm/component/codegen/interfaces/CodeGenObject.kt
deleted file mode 100644
index abf69ca..0000000
--- a/app/src/main/java/io/neoterm/component/codegen/interfaces/CodeGenObject.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.neoterm.component.codegen.interfaces
-
-import io.neoterm.component.codegen.CodeGenParameter
-
-/**
- * @author kiva
- */
-interface CodeGenObject {
- fun getCodeGenerator(parameter: CodeGenParameter): CodeGenerator
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/colorscheme/DefaultColorScheme.kt b/app/src/main/java/io/neoterm/component/colorscheme/DefaultColorScheme.kt
deleted file mode 100644
index 694a7ec..0000000
--- a/app/src/main/java/io/neoterm/component/colorscheme/DefaultColorScheme.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.neoterm.component.colorscheme
-
-/**
- * @author kiva
- */
-object DefaultColorScheme : NeoColorScheme() {
- init {
- /* NOTE: Keep in sync with assets/colors/Default.nl */
- colorName = "Default"
-
- foregroundColor = "#ffffff"
- backgroundColor = "#14181c"
- cursorColor = "#a9aaa9"
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/colorscheme/ColorSchemeComponent.kt b/app/src/main/java/io/neoterm/component/colorscheme/comp.kt
similarity index 91%
rename from app/src/main/java/io/neoterm/component/colorscheme/ColorSchemeComponent.kt
rename to app/src/main/java/io/neoterm/component/colorscheme/comp.kt
index f855c5f..cb6563b 100644
--- a/app/src/main/java/io/neoterm/component/colorscheme/ColorSchemeComponent.kt
+++ b/app/src/main/java/io/neoterm/component/colorscheme/comp.kt
@@ -4,20 +4,17 @@ import android.content.Context
import io.neolang.visitor.ConfigVisitor
import io.neoterm.App
import io.neoterm.R
+import io.neoterm.component.ComponentManager
+import io.neoterm.component.ConfigFileBasedComponent
import io.neoterm.component.codegen.CodeGenComponent
-import io.neoterm.frontend.component.ComponentManager
-import io.neoterm.frontend.component.helper.ConfigFileBasedComponent
-import io.neoterm.frontend.config.NeoPreference
-import io.neoterm.frontend.config.NeoTermPath
-import io.neoterm.frontend.terminal.TerminalView
-import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
+import io.neoterm.component.config.NeoPreference
+import io.neoterm.component.config.NeoTermPath
+import io.neoterm.frontend.session.view.TerminalView
+import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
import io.neoterm.utils.extractAssetsDir
import java.io.File
import java.nio.file.Files
-/**
- * @author kiva
- */
class ColorSchemeComponent : ConfigFileBasedComponent(NeoTermPath.COLORS_PATH) {
companion object {
fun colorFile(colorName: String): File {
@@ -120,4 +117,5 @@ class ColorSchemeComponent : ConfigFileBasedComponent(NeoTermPat
throw RuntimeException("Failed to save file ${colorFile.absolutePath}")
}
}
-}
\ No newline at end of file
+}
+
diff --git a/app/src/main/java/io/neoterm/component/colorscheme/NeoColorScheme.kt b/app/src/main/java/io/neoterm/component/colorscheme/data.kt
similarity index 80%
rename from app/src/main/java/io/neoterm/component/colorscheme/NeoColorScheme.kt
rename to app/src/main/java/io/neoterm/component/colorscheme/data.kt
index 4373009..04ec525 100644
--- a/app/src/main/java/io/neoterm/component/colorscheme/NeoColorScheme.kt
+++ b/app/src/main/java/io/neoterm/component/colorscheme/data.kt
@@ -3,23 +3,15 @@ package io.neoterm.component.colorscheme
import io.neolang.visitor.ConfigVisitor
import io.neoterm.backend.TerminalColorScheme
import io.neoterm.backend.TerminalColors
+import io.neoterm.component.ConfigFileBasedObject
+import io.neoterm.component.codegen.CodeGenObject
import io.neoterm.component.codegen.CodeGenParameter
-import io.neoterm.component.codegen.generators.NeoColorGenerator
-import io.neoterm.component.codegen.interfaces.CodeGenObject
-import io.neoterm.component.codegen.interfaces.CodeGenerator
-import io.neoterm.component.config.ConfigureComponent
-import io.neoterm.frontend.component.ComponentManager
-import io.neoterm.frontend.component.helper.ConfigFileBasedObject
-import io.neoterm.frontend.config.NeoConfigureFile
-import io.neoterm.frontend.logging.NLog
-import io.neoterm.frontend.terminal.TerminalView
-import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
-import org.jetbrains.annotations.TestOnly
-import java.io.File
+import io.neoterm.component.codegen.CodeGenerator
+import io.neoterm.component.codegen.NeoColorGenerator
+import io.neoterm.frontend.session.view.TerminalView
+import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
+import io.neoterm.utils.NLog
-/**
- * @author kiva
- */
open class NeoColorScheme : CodeGenObject, ConfigFileBasedObject {
companion object {
const val COLOR_PREFIX = "color"
@@ -173,24 +165,15 @@ open class NeoColorScheme : CodeGenObject, ConfigFileBasedObject {
private fun getColorByVisitor(visitor: ConfigVisitor, colorName: String): String? {
return visitor.getStringValue(COLOR_PATH, colorName)
}
+}
- @TestOnly
- fun testLoadConfigure(file: File): Boolean {
- val loaderService = ComponentManager.getComponent()
+object DefaultColorScheme : NeoColorScheme() {
+ init {
+ /* NOTE: Keep in sync with assets/colors/Default.nl */
+ colorName = "Default"
- val configure: NeoConfigureFile?
- try {
- configure = loaderService.newLoader(file).loadConfigure()
- if (configure == null) {
- throw RuntimeException("Parse configuration failed.")
- }
- } catch (e: Exception) {
- NLog.e("ExtraKey", "Failed to load extra key config: ${file.absolutePath}: ${e.localizedMessage}")
- return false
- }
-
- val visitor = configure.getVisitor()
- onConfigLoaded(visitor)
- return true
+ foregroundColor = "#ffffff"
+ backgroundColor = "#14181c"
+ cursorColor = "#a9aaa9"
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/frontend/component/ComponentManager.kt b/app/src/main/java/io/neoterm/component/comp.kt
similarity index 79%
rename from app/src/main/java/io/neoterm/frontend/component/ComponentManager.kt
rename to app/src/main/java/io/neoterm/component/comp.kt
index b4b5f25..da0e529 100644
--- a/app/src/main/java/io/neoterm/frontend/component/ComponentManager.kt
+++ b/app/src/main/java/io/neoterm/component/comp.kt
@@ -1,10 +1,13 @@
-package io.neoterm.frontend.component
+package io.neoterm.component
import java.util.concurrent.ConcurrentHashMap
-/**
- * @author kiva
- */
+interface NeoComponent {
+ fun onServiceInit()
+ fun onServiceDestroy()
+ fun onServiceObtained()
+}
+
object ComponentManager {
private val COMPONENTS = ConcurrentHashMap, NeoComponent>()
@@ -43,3 +46,7 @@ object ComponentManager {
return componentInterface.newInstance()
}
}
+
+class ComponentDuplicateException(serviceName: String) : RuntimeException("Service $serviceName duplicate")
+class ComponentNotFoundException(serviceName: String) : RuntimeException("Component `$serviceName' not found")
+
diff --git a/app/src/main/java/io/neoterm/component/completion/CompletionComponent.kt b/app/src/main/java/io/neoterm/component/completion/CompletionComponent.kt
deleted file mode 100644
index 428960f..0000000
--- a/app/src/main/java/io/neoterm/component/completion/CompletionComponent.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.neoterm.component.completion
-
-import io.neoterm.component.completion.provider.FileCompletionProvider
-import io.neoterm.component.completion.provider.ProgramCompletionProvider
-import io.neoterm.frontend.completion.CompletionManager
-import io.neoterm.frontend.component.NeoComponent
-
-/**
- * @author kiva
- */
-class CompletionComponent : NeoComponent {
- override fun onServiceInit() {
- CompletionManager.registerProvider(FileCompletionProvider())
- CompletionManager.registerProvider(ProgramCompletionProvider())
- }
-
- override fun onServiceDestroy() {
- }
-
- override fun onServiceObtained() {
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/frontend/completion/CompletionManager.kt b/app/src/main/java/io/neoterm/component/completion/comp.kt
similarity index 55%
rename from app/src/main/java/io/neoterm/frontend/completion/CompletionManager.kt
rename to app/src/main/java/io/neoterm/component/completion/comp.kt
index a7d69ca..e6bad82 100644
--- a/app/src/main/java/io/neoterm/frontend/completion/CompletionManager.kt
+++ b/app/src/main/java/io/neoterm/component/completion/comp.kt
@@ -1,11 +1,20 @@
-package io.neoterm.frontend.completion
+package io.neoterm.component.completion
-import io.neoterm.frontend.completion.model.CompletionResult
-import io.neoterm.frontend.completion.provider.ICandidateProvider
+import io.neoterm.component.NeoComponent
+
+class CompletionComponent : NeoComponent {
+ override fun onServiceInit() {
+ CompletionManager.registerProvider(FileCompletionProvider())
+ CompletionManager.registerProvider(ProgramCompletionProvider())
+ }
+
+ override fun onServiceDestroy() {
+ }
+
+ override fun onServiceObtained() {
+ }
+}
-/**
- * @author kiva
- */
object CompletionManager {
private val candidateProviders = mutableMapOf()
@@ -37,4 +46,23 @@ object CompletionManager {
return ProviderDetector(candidateProviders.values
.takeWhile { it.canComplete(text) })
}
-}
\ No newline at end of file
+}
+
+class ProviderDetector(val providers: List) : MarkScoreListener {
+ private var detectedProvider: ICandidateProvider? = null
+
+ override fun onMarkScore(score: Int) {
+ // TODO: Save provider score
+ }
+
+ fun detectBest(): ICandidateProvider? {
+ // TODO: detect best
+ detectedProvider = if (providers.isEmpty())
+ null
+ else
+ providers[0]
+
+ return detectedProvider
+ }
+}
+
diff --git a/app/src/main/java/io/neoterm/frontend/completion/model/CompletionResult.kt b/app/src/main/java/io/neoterm/component/completion/data.kt
similarity index 58%
rename from app/src/main/java/io/neoterm/frontend/completion/model/CompletionResult.kt
rename to app/src/main/java/io/neoterm/component/completion/data.kt
index 6069191..5b7acaf 100644
--- a/app/src/main/java/io/neoterm/frontend/completion/model/CompletionResult.kt
+++ b/app/src/main/java/io/neoterm/component/completion/data.kt
@@ -1,10 +1,10 @@
-package io.neoterm.frontend.completion.model
+package io.neoterm.component.completion
-import io.neoterm.frontend.completion.listener.MarkScoreListener
+class CompletionCandidate(val completeString: String) {
+ var displayName: String = completeString
+ var description: String? = null
+}
-/**
- * @author kiva
- */
class CompletionResult(val candidates: List, var scoreMarker: MarkScoreListener) {
fun markScore(score: Int) {
scoreMarker.onMarkScore(score)
@@ -13,4 +13,5 @@ class CompletionResult(val candidates: List, var scoreMarke
fun hasResult(): Boolean {
return candidates.isNotEmpty()
}
-}
\ No newline at end of file
+}
+
diff --git a/app/src/main/java/io/neoterm/component/completion/listeners.kt b/app/src/main/java/io/neoterm/component/completion/listeners.kt
new file mode 100644
index 0000000..944388e
--- /dev/null
+++ b/app/src/main/java/io/neoterm/component/completion/listeners.kt
@@ -0,0 +1,16 @@
+package io.neoterm.component.completion
+
+interface MarkScoreListener {
+ fun onMarkScore(score: Int)
+}
+
+interface OnAutoCompleteListener {
+ fun onCompletionRequired(newText: String?)
+ fun onKeyCode(keyCode: Int, keyMod: Int)
+ fun onCleanUp()
+ fun onFinishCompletion(): Boolean
+}
+
+interface OnCandidateSelectedListener {
+ fun onCandidateSelected(candidate: CompletionCandidate)
+}
diff --git a/app/src/main/java/io/neoterm/component/completion/provider/ProgramCompletionProvider.kt b/app/src/main/java/io/neoterm/component/completion/provider/ProgramCompletionProvider.kt
deleted file mode 100644
index 79aa12c..0000000
--- a/app/src/main/java/io/neoterm/component/completion/provider/ProgramCompletionProvider.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.neoterm.component.completion.provider
-
-import java.io.File
-
-/**
- * @author kiva
- */
-class ProgramCompletionProvider : FileCompletionProvider() {
- override val providerName: String
- get() = "NeoTermProvider.ProgramCompletionProvider"
-
-
- override fun generateDesc(file: File): String? {
- return if (file.canExecute()) "" else super.generateDesc(file)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/completion/provider/FileCompletionProvider.kt b/app/src/main/java/io/neoterm/component/completion/providers.kt
similarity index 58%
rename from app/src/main/java/io/neoterm/component/completion/provider/FileCompletionProvider.kt
rename to app/src/main/java/io/neoterm/component/completion/providers.kt
index f6bcdb8..c86a0e0 100644
--- a/app/src/main/java/io/neoterm/component/completion/provider/FileCompletionProvider.kt
+++ b/app/src/main/java/io/neoterm/component/completion/providers.kt
@@ -1,18 +1,18 @@
-package io.neoterm.component.completion.provider
+package io.neoterm.component.completion
-import io.neoterm.frontend.completion.model.CompletionCandidate
-import io.neoterm.frontend.completion.provider.ICandidateProvider
import java.io.File
-/**
- * @author kiva
- */
+interface ICandidateProvider {
+ val providerName: String
+ fun provideCandidates(text: String): List
+ fun canComplete(text: String): Boolean
+}
open class FileCompletionProvider : ICandidateProvider {
override val providerName: String
get() = "NeoTermProvider.FileCompletionProvider"
- override fun provideCandidates(text: String): List? {
+ override fun provideCandidates(text: String): List {
var file = File(text)
var filter: ((File) -> Boolean)? = null
@@ -33,20 +33,14 @@ open class FileCompletionProvider : ICandidateProvider {
return if (filter != null) path.listFiles(filter) else path.listFiles()
}
- private fun generateCandidateList(file: File, filter: ((File) -> Boolean)?): List? {
- if (file.canRead()) {
- val candidates = mutableListOf()
- listDirectory(file, filter)
- .mapTo(candidates, {
- val candidate = CompletionCandidate(it.name)
- candidate.description = generateDesc(it)
- candidate.displayName = generateDisplayName(it)
- candidate
- })
- return candidates
- }
- return null
- }
+ private fun generateCandidateList(file: File, filter: ((File) -> Boolean)?) =
+ if (file.canRead()) listDirectory(file, filter).map {
+ val candidate = CompletionCandidate(it.name)
+ candidate.description = generateDesc(it)
+ candidate.displayName = generateDisplayName(it)
+ candidate
+ }.toList()
+ else listOf()
open fun generateDisplayName(file: File): String {
return if (file.isDirectory) "${file.name}/" else file.name
@@ -56,3 +50,13 @@ open class FileCompletionProvider : ICandidateProvider {
return null
}
}
+
+class ProgramCompletionProvider : FileCompletionProvider() {
+ override val providerName: String
+ get() = "NeoTermProvider.ProgramCompletionProvider"
+
+
+ override fun generateDesc(file: File): String? {
+ return if (file.canExecute()) "" else super.generateDesc(file)
+ }
+}
diff --git a/app/src/main/java/io/neoterm/component/config/ConfigureComponent.kt b/app/src/main/java/io/neoterm/component/config/ConfigureComponent.kt
deleted file mode 100644
index 02c8d09..0000000
--- a/app/src/main/java/io/neoterm/component/config/ConfigureComponent.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package io.neoterm.component.config
-
-import io.neoterm.component.config.loaders.NeoLangConfigureLoader
-import io.neoterm.component.config.loaders.OldConfigureLoader
-import io.neoterm.frontend.component.NeoComponent
-import java.io.File
-
-/**
- * @author kiva
- */
-class ConfigureComponent : NeoComponent {
- val CONFIG_LOADER_VERSION = 20
-
- override fun onServiceInit() {
- }
-
- override fun onServiceDestroy() {
- }
-
- override fun onServiceObtained() {
- }
-
- fun getLoaderVersion(): Int {
- return CONFIG_LOADER_VERSION
- }
-
- fun newLoader(configFile: File): IConfigureLoader {
- return when (configFile.extension) {
- "nl" -> NeoLangConfigureLoader(configFile)
- else -> OldConfigureLoader(configFile)
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/config/IConfigureLoader.kt b/app/src/main/java/io/neoterm/component/config/IConfigureLoader.kt
deleted file mode 100644
index 78cae91..0000000
--- a/app/src/main/java/io/neoterm/component/config/IConfigureLoader.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package io.neoterm.component.config
-
-import io.neoterm.frontend.config.NeoConfigureFile
-
-/**
- * @author kiva
- */
-interface IConfigureLoader {
- fun loadConfigure(): NeoConfigureFile?
-}
diff --git a/app/src/main/java/io/neoterm/frontend/config/NeoPreference.kt b/app/src/main/java/io/neoterm/component/config/comp.kt
similarity index 84%
rename from app/src/main/java/io/neoterm/frontend/config/NeoPreference.kt
rename to app/src/main/java/io/neoterm/component/config/comp.kt
index dbf7437..d44c728 100644
--- a/app/src/main/java/io/neoterm/frontend/config/NeoPreference.kt
+++ b/app/src/main/java/io/neoterm/component/config/comp.kt
@@ -1,4 +1,4 @@
-package io.neoterm.frontend.config
+package io.neoterm.component.config
import android.content.Context
import android.content.SharedPreferences
@@ -6,18 +6,59 @@ import android.preference.PreferenceManager
import android.system.ErrnoException
import android.system.Os
import android.util.TypedValue
+import io.neolang.parser.NeoLangParser
+import io.neolang.visitor.ConfigVisitor
import io.neoterm.App
import io.neoterm.R
import io.neoterm.backend.TerminalSession
-import io.neoterm.frontend.logging.NLog
+import io.neoterm.component.NeoComponent
import io.neoterm.services.NeoTermService
+import io.neoterm.utils.NLog
import java.io.File
import java.nio.file.Files
+class ConfigureComponent : NeoComponent {
+ override fun onServiceInit() {
+ }
-/**
- * @author kiva
- */
+ override fun onServiceDestroy() {
+ }
+
+ override fun onServiceObtained() {
+ }
+
+ fun getLoaderVersion(): Int {
+ return CONFIG_LOADER_VERSION
+ }
+
+ fun newLoader(configFile: File): IConfigureLoader {
+ return when (configFile.extension) {
+ "nl" -> NeoLangConfigureLoader(configFile)
+ else -> OldConfigureLoader(configFile)
+ }
+ }
+
+ companion object {
+ private const val CONFIG_LOADER_VERSION = 20
+ }
+}
+
+open class NeoConfigureFile(val configureFile: File) {
+ private val configParser = NeoLangParser()
+ protected open var configVisitor: ConfigVisitor? = null
+
+ fun getVisitor() = configVisitor ?: throw IllegalStateException("Configure file not loaded or parse failed.")
+
+ open fun parseConfigure() = kotlin.runCatching {
+ val programCode = String(Files.readAllBytes(configureFile.toPath()))
+ configParser.setInputSource(programCode)
+
+ val ast = configParser.parse()
+ val astVisitor = ast.visit().getVisitor(ConfigVisitor::class.java) ?: return false
+ astVisitor.start()
+ configVisitor = astVisitor.getCallback()
+ }.isSuccess
+}
object NeoPreference {
const val KEY_HAPPY_EGG = "neoterm_fun_happy"
diff --git a/app/src/main/java/io/neoterm/frontend/config/NeoTermPath.kt b/app/src/main/java/io/neoterm/component/config/defaults.kt
similarity index 59%
rename from app/src/main/java/io/neoterm/frontend/config/NeoTermPath.kt
rename to app/src/main/java/io/neoterm/component/config/defaults.kt
index ad211d4..eaf2d34 100644
--- a/app/src/main/java/io/neoterm/frontend/config/NeoTermPath.kt
+++ b/app/src/main/java/io/neoterm/component/config/defaults.kt
@@ -1,10 +1,28 @@
-package io.neoterm.frontend.config
+package io.neoterm.component.config
import android.annotation.SuppressLint
-/**
- * @author kiva
- */
+object DefaultValues {
+ const val fontSize = 30
+
+ const val enableBell = false
+ const val enableVibrate = false
+ const val enableExecveWrapper = true
+ const val enableAutoCompletion = false
+ const val enableFullScreen = false
+ const val enableAutoHideToolbar = false
+ const val enableSwitchNextTab = false
+ const val enableExtraKeys = true
+ const val enableExplicitExtraKeysWeight = false
+ const val enableBackButtonBeMappedToEscape = false
+ const val enableSpecialVolumeKeys = false
+ const val enableWordBasedIme = false
+
+ const val loginShell = "bash"
+ const val initialCommand = ""
+ const val defaultFont = "SourceCodePro"
+}
+
object NeoTermPath {
@SuppressLint("SdCardPath")
const val ROOT_PATH = "/data/data/io.neoterm/files"
@@ -32,4 +50,4 @@ object NeoTermPath {
init {
DEFAULT_MAIN_PACKAGE_SOURCE = SOURCE
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/component/config/loaders.kt b/app/src/main/java/io/neoterm/component/config/loaders.kt
new file mode 100644
index 0000000..39c610a
--- /dev/null
+++ b/app/src/main/java/io/neoterm/component/config/loaders.kt
@@ -0,0 +1,194 @@
+package io.neoterm.component.config
+
+import io.neolang.runtime.type.NeoLangValue
+import io.neolang.visitor.ConfigVisitor
+import io.neoterm.component.colorscheme.NeoColorScheme
+import io.neoterm.component.extrakey.NeoExtraKey
+import io.neoterm.frontend.session.view.extrakey.TextButton
+import io.neoterm.utils.NLog
+import java.io.BufferedReader
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileReader
+import java.util.*
+
+interface IConfigureLoader {
+ fun loadConfigure(): NeoConfigureFile?
+}
+
+class NeoLangConfigureLoader(private val configFile: File) : IConfigureLoader {
+ override fun loadConfigure(): NeoConfigureFile? {
+ val configureFile = NeoConfigureFile(configFile)
+ return if (configureFile.parseConfigure()) configureFile else null
+ }
+}
+
+class OldConfigureLoader(private val configFile: File) : IConfigureLoader {
+ override fun loadConfigure(): NeoConfigureFile? {
+ return when (configFile.extension) {
+ "eks" -> returnConfigure(OldExtraKeysConfigureFile(configFile))
+ "color" -> returnConfigure(OldColorSchemeConfigureFile(configFile))
+ else -> null
+ }
+ }
+
+ private fun returnConfigure(configureFile: NeoConfigureFile): NeoConfigureFile? {
+ return if (configureFile.parseConfigure()) configureFile else null
+ }
+
+ companion object {
+ class OldColorSchemeConfigureFile(configureFile: File) : NeoConfigureFile(configureFile) {
+ override var configVisitor: ConfigVisitor? = null
+
+ override fun parseConfigure(): Boolean {
+ try {
+ val visitor = ConfigVisitor()
+ visitor.onStart()
+ visitor.onEnterContext(NeoColorScheme.CONTEXT_META_NAME)
+
+ visitor.getCurrentContext()
+ .defineAttribute(NeoColorScheme.COLOR_META_NAME, NeoLangValue(configureFile.nameWithoutExtension))
+ .defineAttribute(NeoColorScheme.COLOR_META_VERSION, NeoLangValue("1.0"))
+
+ visitor.onEnterContext(NeoColorScheme.CONTEXT_COLOR_NAME)
+
+ return FileInputStream(configureFile).use {
+ val prop = Properties()
+ prop.load(it)
+ prop.forEach {
+ visitor.getCurrentContext().defineAttribute(it.key as String, NeoLangValue(it.value as String))
+ }
+ visitor.onFinish()
+ this.configVisitor = visitor
+ true
+ }
+
+ } catch (e: Exception) {
+ this.configVisitor = null
+ NLog.e("ConfigureLoader", "Error while loading old config", e)
+ return false
+ }
+ }
+ }
+ class OldExtraKeysConfigureFile(configureFile: File) : NeoConfigureFile(configureFile) {
+ override var configVisitor: ConfigVisitor? = null
+
+ override fun parseConfigure(): Boolean {
+ try {
+ val config = parseOldConfig(BufferedReader(FileReader(configureFile)))
+ return generateVisitor(config)
+ } catch (e: Exception) {
+ NLog.e("ConfigureLoader", "Failed to load old extra keys config: ${e.localizedMessage}")
+ return false
+ }
+ }
+
+ private fun generateVisitor(config: NeoExtraKey): Boolean {
+ configVisitor = ConfigVisitor()
+ val visitor = configVisitor!!
+ visitor.onStart()
+ visitor.onEnterContext(NeoExtraKey.EKS_META_CONTEXT_NAME)
+ visitor.getCurrentContext()
+ .defineAttribute(NeoExtraKey.EKS_META_VERSION, NeoLangValue(config.version))
+ .defineAttribute(NeoExtraKey.EKS_META_WITH_DEFAULT, NeoLangValue(config.withDefaultKeys))
+
+ // program
+ visitor.onEnterContext(NeoExtraKey.EKS_META_PROGRAM)
+ config.programNames.forEachIndexed { index, program ->
+ visitor.getCurrentContext().defineAttribute(index.toString(), NeoLangValue(program))
+ }
+ visitor.onExitContext()
+
+ // key
+ visitor.onEnterContext(NeoExtraKey.EKS_META_KEY)
+ config.shortcutKeys.forEachIndexed { index, button ->
+ if (button is TextButton) {
+ visitor.onEnterContext(index.toString())
+ visitor.getCurrentContext()
+ .defineAttribute(NeoExtraKey.EKS_META_WITH_ENTER, NeoLangValue(button.withEnter))
+ .defineAttribute(NeoExtraKey.EKS_META_DISPLAY, NeoLangValue(button.buttonKeys!!))
+ .defineAttribute(NeoExtraKey.EKS_META_CODE, NeoLangValue(button.buttonKeys!!))
+ visitor.onExitContext()
+ }
+ }
+ visitor.onExitContext()
+
+ visitor.onFinish()
+ return true
+ }
+
+ private fun parseOldConfig(source: BufferedReader): NeoExtraKey {
+ val config = NeoExtraKey()
+ var line: String? = source.readLine()
+
+ while (line != null) {
+ line = line.trim().trimEnd()
+ if (line.isEmpty() || line.startsWith("#")) {
+ line = source.readLine()
+ continue
+ }
+
+ if (line.startsWith(NeoExtraKey.EKS_META_VERSION)) {
+ parseHeader(line, config)
+ } else if (line.startsWith(NeoExtraKey.EKS_META_PROGRAM)) {
+ parseProgram(line, config)
+ } else if (line.startsWith("define")) {
+ parseKeyDefine(line, config)
+ } else if (line.startsWith(NeoExtraKey.EKS_META_WITH_DEFAULT)) {
+ parseWithDefault(line, config)
+ }
+ line = source.readLine()
+ }
+
+ if (config.version < 0) {
+ throw RuntimeException("Not a valid shortcut config file")
+ }
+ if (config.programNames.size == 0) {
+ throw RuntimeException("At least one program name should be given")
+ }
+ return config
+ }
+
+ private fun parseWithDefault(line: String, config: NeoExtraKey) {
+ val value = line.substring(NeoExtraKey.EKS_META_WITH_DEFAULT.length).trim().trimEnd()
+ config.withDefaultKeys = value == "true"
+ }
+
+ private fun parseKeyDefine(line: String, config: NeoExtraKey) {
+ val keyDefine = line.substring("define".length).trim().trimEnd()
+ val keyValues = keyDefine.split(" ")
+ if (keyValues.size < 2) {
+ throw RuntimeException("Bad define")
+ }
+
+ val buttonText = keyValues[0]
+ val withEnter = keyValues[1] == "true"
+
+ config.shortcutKeys.add(TextButton(buttonText, withEnter))
+ }
+
+ private fun parseProgram(line: String, config: NeoExtraKey) {
+ val programNames = line.substring(NeoExtraKey.EKS_META_PROGRAM.length).trim().trimEnd()
+ if (programNames.isEmpty()) {
+ return
+ }
+
+ for (name in programNames.split(" ")) {
+ config.programNames.add(name)
+ }
+ }
+
+ private fun parseHeader(line: String, config: NeoExtraKey) {
+ val version: Int
+ val versionString = line.substring(NeoExtraKey.EKS_META_VERSION.length).trim().trimEnd()
+ try {
+ version = Integer.parseInt(versionString)
+ } catch (e: NumberFormatException) {
+ throw RuntimeException("Bad version '$versionString'")
+ }
+
+ config.version = version
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/io/neoterm/component/config/loaders/NeoLangConfigureLoader.kt b/app/src/main/java/io/neoterm/component/config/loaders/NeoLangConfigureLoader.kt
deleted file mode 100644
index 95391d4..0000000
--- a/app/src/main/java/io/neoterm/component/config/loaders/NeoLangConfigureLoader.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.neoterm.component.config.loaders
-
-import io.neoterm.component.config.IConfigureLoader
-import io.neoterm.frontend.config.NeoConfigureFile
-import java.io.File
-
-/**
- * @author kiva
- */
-class NeoLangConfigureLoader(private val configFile: File) : IConfigureLoader {
- override fun loadConfigure(): NeoConfigureFile? {
- val configureFile = NeoConfigureFile(configFile)
- return if (configureFile.parseConfigure()) configureFile else null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/config/loaders/OldColorSchemeConfigureFile.kt b/app/src/main/java/io/neoterm/component/config/loaders/OldColorSchemeConfigureFile.kt
deleted file mode 100644
index f4d2a50..0000000
--- a/app/src/main/java/io/neoterm/component/config/loaders/OldColorSchemeConfigureFile.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package io.neoterm.component.config.loaders
-
-import io.neolang.runtime.type.NeoLangValue
-import io.neolang.visitor.ConfigVisitor
-import io.neoterm.component.colorscheme.NeoColorScheme
-import io.neoterm.frontend.config.NeoConfigureFile
-import io.neoterm.frontend.logging.NLog
-import java.io.File
-import java.io.FileInputStream
-import java.util.*
-
-/**
- * @author kiva
- */
-class OldColorSchemeConfigureFile(configureFile: File) : NeoConfigureFile(configureFile) {
- override var configVisitor: ConfigVisitor? = null
-
- override fun parseConfigure(): Boolean {
- try {
- val visitor = ConfigVisitor()
- visitor.onStart()
- visitor.onEnterContext(NeoColorScheme.CONTEXT_META_NAME)
-
- visitor.getCurrentContext()
- .defineAttribute(NeoColorScheme.COLOR_META_NAME, NeoLangValue(configureFile.nameWithoutExtension))
- .defineAttribute(NeoColorScheme.COLOR_META_VERSION, NeoLangValue("1.0"))
-
- visitor.onEnterContext(NeoColorScheme.CONTEXT_COLOR_NAME)
-
- return FileInputStream(configureFile).use {
- val prop = Properties()
- prop.load(it)
- prop.forEach {
- visitor.getCurrentContext().defineAttribute(it.key as String, NeoLangValue(it.value as String))
- }
- visitor.onFinish()
- this.configVisitor = visitor
- true
- }
-
- } catch (e: Exception) {
- this.configVisitor = null
- NLog.e("ConfigureLoader", "Error while loading old config", e)
- return false
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/config/loaders/OldConfigureLoader.kt b/app/src/main/java/io/neoterm/component/config/loaders/OldConfigureLoader.kt
deleted file mode 100644
index ff73d55..0000000
--- a/app/src/main/java/io/neoterm/component/config/loaders/OldConfigureLoader.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package io.neoterm.component.config.loaders
-
-import io.neoterm.component.config.IConfigureLoader
-import io.neoterm.frontend.config.NeoConfigureFile
-import java.io.File
-
-/**
- * @author kiva
- */
-class OldConfigureLoader(private val configFile: File) : IConfigureLoader {
- override fun loadConfigure(): NeoConfigureFile? {
- return when (configFile.extension) {
- "eks" -> returnConfigure(OldExtraKeysConfigureFile(configFile))
- "color" -> returnConfigure(OldColorSchemeConfigureFile(configFile))
- else -> null
- }
- }
-
- private fun returnConfigure(configureFile: NeoConfigureFile): NeoConfigureFile? {
- return if (configureFile.parseConfigure()) configureFile else null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/component/config/loaders/OldExtraKeysConfigureFile.kt b/app/src/main/java/io/neoterm/component/config/loaders/OldExtraKeysConfigureFile.kt
deleted file mode 100644
index e2a1a28..0000000
--- a/app/src/main/java/io/neoterm/component/config/loaders/OldExtraKeysConfigureFile.kt
+++ /dev/null
@@ -1,135 +0,0 @@
-package io.neoterm.component.config.loaders
-
-import io.neolang.runtime.type.NeoLangValue
-import io.neolang.visitor.ConfigVisitor
-import io.neoterm.component.extrakey.NeoExtraKey
-import io.neoterm.frontend.config.NeoConfigureFile
-import io.neoterm.frontend.logging.NLog
-import io.neoterm.frontend.terminal.extrakey.button.TextButton
-import java.io.BufferedReader
-import java.io.File
-import java.io.FileReader
-
-/**
- * @author kiva
- */
-class OldExtraKeysConfigureFile(configureFile: File) : NeoConfigureFile(configureFile) {
- override var configVisitor: ConfigVisitor? = null
-
- override fun parseConfigure(): Boolean {
- try {
- val config = parseOldConfig(BufferedReader(FileReader(configureFile)))
- return generateVisitor(config)
- } catch (e: Exception) {
- NLog.e("ConfigureLoader", "Failed to load old extra keys config: ${e.localizedMessage}")
- return false
- }
- }
-
- private fun generateVisitor(config: NeoExtraKey): Boolean {
- configVisitor = ConfigVisitor()
- val visitor = configVisitor!!
- visitor.onStart()
- visitor.onEnterContext(NeoExtraKey.EKS_META_CONTEXT_NAME)
- visitor.getCurrentContext()
- .defineAttribute(NeoExtraKey.EKS_META_VERSION, NeoLangValue(config.version))
- .defineAttribute(NeoExtraKey.EKS_META_WITH_DEFAULT, NeoLangValue(config.withDefaultKeys))
-
- // program
- visitor.onEnterContext(NeoExtraKey.EKS_META_PROGRAM)
- config.programNames.forEachIndexed { index, program ->
- visitor.getCurrentContext().defineAttribute(index.toString(), NeoLangValue(program))
- }
- visitor.onExitContext()
-
- // key
- visitor.onEnterContext(NeoExtraKey.EKS_META_KEY)
- config.shortcutKeys.forEachIndexed { index, button ->
- if (button is TextButton) {
- visitor.onEnterContext(index.toString())
- visitor.getCurrentContext()
- .defineAttribute(NeoExtraKey.EKS_META_WITH_ENTER, NeoLangValue(button.withEnter))
- .defineAttribute(NeoExtraKey.EKS_META_DISPLAY, NeoLangValue(button.buttonKeys!!))
- .defineAttribute(NeoExtraKey.EKS_META_CODE, NeoLangValue(button.buttonKeys!!))
- visitor.onExitContext()
- }
- }
- visitor.onExitContext()
-
- visitor.onFinish()
- return true
- }
-
- private fun parseOldConfig(source: BufferedReader): NeoExtraKey {
- val config = NeoExtraKey()
- var line: String? = source.readLine()
-
- while (line != null) {
- line = line.trim().trimEnd()
- if (line.isEmpty() || line.startsWith("#")) {
- line = source.readLine()
- continue
- }
-
- if (line.startsWith(NeoExtraKey.EKS_META_VERSION)) {
- parseHeader(line, config)
- } else if (line.startsWith(NeoExtraKey.EKS_META_PROGRAM)) {
- parseProgram(line, config)
- } else if (line.startsWith("define")) {
- parseKeyDefine(line, config)
- } else if (line.startsWith(NeoExtraKey.EKS_META_WITH_DEFAULT)) {
- parseWithDefault(line, config)
- }
- line = source.readLine()
- }
-
- if (config.version < 0) {
- throw RuntimeException("Not a valid shortcut config file")
- }
- if (config.programNames.size == 0) {
- throw RuntimeException("At least one program name should be given")
- }
- return config
- }
-
- private fun parseWithDefault(line: String, config: NeoExtraKey) {
- val value = line.substring(NeoExtraKey.EKS_META_WITH_DEFAULT.length).trim().trimEnd()
- config.withDefaultKeys = value == "true"
- }
-
- private fun parseKeyDefine(line: String, config: NeoExtraKey) {
- val keyDefine = line.substring("define".length).trim().trimEnd()
- val keyValues = keyDefine.split(" ")
- if (keyValues.size < 2) {
- throw RuntimeException("Bad define")
- }
-
- val buttonText = keyValues[0]
- val withEnter = keyValues[1] == "true"
-
- config.shortcutKeys.add(TextButton(buttonText, withEnter))
- }
-
- private fun parseProgram(line: String, config: NeoExtraKey) {
- val programNames = line.substring(NeoExtraKey.EKS_META_PROGRAM.length).trim().trimEnd()
- if (programNames.isEmpty()) {
- return
- }
-
- for (name in programNames.split(" ")) {
- config.programNames.add(name)
- }
- }
-
- private fun parseHeader(line: String, config: NeoExtraKey) {
- val version: Int
- val versionString = line.substring(NeoExtraKey.EKS_META_VERSION.length).trim().trimEnd()
- try {
- version = Integer.parseInt(versionString)
- } catch (e: NumberFormatException) {
- throw RuntimeException("Bad version '$versionString'")
- }
-
- config.version = version
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/io/neoterm/frontend/component/helper/ConfigFileBasedComponent.kt b/app/src/main/java/io/neoterm/component/data.kt
similarity index 88%
rename from app/src/main/java/io/neoterm/frontend/component/helper/ConfigFileBasedComponent.kt
rename to app/src/main/java/io/neoterm/component/data.kt
index 2bf248f..3dc2441 100644
--- a/app/src/main/java/io/neoterm/frontend/component/helper/ConfigFileBasedComponent.kt
+++ b/app/src/main/java/io/neoterm/component/data.kt
@@ -1,16 +1,16 @@
-package io.neoterm.frontend.component.helper
+package io.neoterm.component
import io.neolang.visitor.ConfigVisitor
import io.neoterm.component.config.ConfigureComponent
-import io.neoterm.frontend.component.ComponentManager
-import io.neoterm.frontend.component.NeoComponent
-import io.neoterm.frontend.logging.NLog
+import io.neoterm.utils.NLog
import java.io.File
import java.io.FileFilter
-/**
- * @author kiva
- */
+interface ConfigFileBasedObject {
+ @Throws(RuntimeException::class)
+ fun onConfigLoaded(configVisitor: ConfigVisitor)
+}
+
abstract class ConfigFileBasedComponent(protected val baseDir: String) : NeoComponent {
companion object {
private val TAG = ConfigFileBasedComponent::class.java.simpleName
@@ -60,4 +60,5 @@ abstract class ConfigFileBasedComponent(protected
abstract fun onCheckComponentFiles()
abstract fun onCreateComponentObject(configVisitor: ConfigVisitor): T
-}
\ No newline at end of file
+}
+
diff --git a/app/src/main/java/io/neoterm/component/extrakey/ExtraKeyComponent.kt b/app/src/main/java/io/neoterm/component/extrakey/comp.kt
similarity index 87%
rename from app/src/main/java/io/neoterm/component/extrakey/ExtraKeyComponent.kt
rename to app/src/main/java/io/neoterm/component/extrakey/comp.kt
index 36ed3a7..93478d7 100644
--- a/app/src/main/java/io/neoterm/component/extrakey/ExtraKeyComponent.kt
+++ b/app/src/main/java/io/neoterm/component/extrakey/comp.kt
@@ -3,16 +3,13 @@ package io.neoterm.component.extrakey
import android.content.Context
import io.neolang.visitor.ConfigVisitor
import io.neoterm.App
-import io.neoterm.frontend.component.helper.ConfigFileBasedComponent
-import io.neoterm.frontend.config.NeoTermPath
-import io.neoterm.frontend.logging.NLog
-import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
+import io.neoterm.component.ConfigFileBasedComponent
+import io.neoterm.component.config.NeoTermPath
+import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
+import io.neoterm.utils.NLog
import io.neoterm.utils.extractAssetsDir
import java.io.File
-/**
- * @author kiva
- */
class ExtraKeyComponent : ConfigFileBasedComponent(NeoTermPath.EKS_PATH) {
override val checkComponentFileWhenObtained
get() = true
@@ -68,4 +65,4 @@ class ExtraKeyComponent : ConfigFileBasedComponent(NeoTermPath.EKS_
registerShortcutKeys(it)
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/component/extrakey/NeoExtraKey.kt b/app/src/main/java/io/neoterm/component/extrakey/data.kt
similarity index 69%
rename from app/src/main/java/io/neoterm/component/extrakey/NeoExtraKey.kt
rename to app/src/main/java/io/neoterm/component/extrakey/data.kt
index 9eee948..df09a6f 100644
--- a/app/src/main/java/io/neoterm/component/extrakey/NeoExtraKey.kt
+++ b/app/src/main/java/io/neoterm/component/extrakey/data.kt
@@ -1,16 +1,10 @@
package io.neoterm.component.extrakey
import io.neolang.visitor.ConfigVisitor
-import io.neoterm.component.config.ConfigureComponent
-import io.neoterm.frontend.component.ComponentManager
-import io.neoterm.frontend.component.helper.ConfigFileBasedObject
-import io.neoterm.frontend.config.NeoConfigureFile
-import io.neoterm.frontend.logging.NLog
-import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
-import io.neoterm.frontend.terminal.extrakey.button.IExtraButton
-import io.neoterm.frontend.terminal.extrakey.button.TextButton
-import org.jetbrains.annotations.TestOnly
-import java.io.File
+import io.neoterm.component.ConfigFileBasedObject
+import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
+import io.neoterm.frontend.session.view.extrakey.IExtraButton
+import io.neoterm.frontend.session.view.extrakey.TextButton
/**
* @author kiva
@@ -86,24 +80,4 @@ class NeoExtraKey : ConfigFileBasedObject {
private fun getMetaByVisitor(visitor: ConfigVisitor, metaName: String): String? {
return visitor.getStringValue(EKS_META_CONTEXT_PATH, metaName)
}
-
- @TestOnly
- fun testLoadConfigure(file: File): Boolean {
- val loaderService = ComponentManager.getComponent()
-
- val configure: NeoConfigureFile?
- try {
- configure = loaderService.newLoader(file).loadConfigure()
- if (configure == null) {
- throw RuntimeException("Parse configuration failed.")
- }
- } catch (e: Exception) {
- NLog.e("ExtraKey", "Failed to load extra key config: ${file.absolutePath}: ${e.localizedMessage}")
- return false
- }
-
- val visitor = configure.getVisitor()
- onConfigLoaded(visitor)
- return true
- }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/component/font/FontComponent.kt b/app/src/main/java/io/neoterm/component/font/comp.kt
similarity index 91%
rename from app/src/main/java/io/neoterm/component/font/FontComponent.kt
rename to app/src/main/java/io/neoterm/component/font/comp.kt
index 3c9d337..c22cf9c 100644
--- a/app/src/main/java/io/neoterm/component/font/FontComponent.kt
+++ b/app/src/main/java/io/neoterm/component/font/comp.kt
@@ -4,18 +4,15 @@ import android.content.Context
import android.graphics.Typeface
import io.neoterm.App
import io.neoterm.R
-import io.neoterm.frontend.component.NeoComponent
-import io.neoterm.frontend.config.DefaultValues
-import io.neoterm.frontend.config.NeoPreference
-import io.neoterm.frontend.config.NeoTermPath
-import io.neoterm.frontend.terminal.TerminalView
-import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
+import io.neoterm.component.NeoComponent
+import io.neoterm.component.config.DefaultValues
+import io.neoterm.component.config.NeoPreference
+import io.neoterm.component.config.NeoTermPath
+import io.neoterm.frontend.session.view.TerminalView
+import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
import io.neoterm.utils.extractAssetsDir
import java.io.File
-/**
- * @author kiva
- */
class FontComponent : NeoComponent {
private lateinit var DEFAULT_FONT: NeoFont
private lateinit var fonts: MutableMap
@@ -126,4 +123,5 @@ class FontComponent : NeoComponent {
fonts.put(defaultFont, DEFAULT_FONT)
}
}
-}
\ No newline at end of file
+}
+
diff --git a/app/src/main/java/io/neoterm/component/font/NeoFont.kt b/app/src/main/java/io/neoterm/component/font/data.kt
similarity index 84%
rename from app/src/main/java/io/neoterm/component/font/NeoFont.kt
rename to app/src/main/java/io/neoterm/component/font/data.kt
index d4ac7fe..54f9815 100644
--- a/app/src/main/java/io/neoterm/component/font/NeoFont.kt
+++ b/app/src/main/java/io/neoterm/component/font/data.kt
@@ -1,13 +1,10 @@
package io.neoterm.component.font
import android.graphics.Typeface
-import io.neoterm.frontend.terminal.TerminalView
-import io.neoterm.frontend.terminal.extrakey.ExtraKeysView
+import io.neoterm.frontend.session.view.TerminalView
+import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
import java.io.File
-/**
- * @author kiva
- */
class NeoFont {
private var fontFile: File? = null
private var typeface: Typeface? = null
@@ -36,4 +33,4 @@ class NeoFont {
}
return typeface
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/io/neoterm/component/pm/Architecture.kt b/app/src/main/java/io/neoterm/component/pm/Architecture.kt
deleted file mode 100644
index b9ae753..0000000
--- a/app/src/main/java/io/neoterm/component/pm/Architecture.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.neoterm.component.pm
-
-/**
- * @author kiva
- */
-
-enum class Architecture {
- ALL, ARM, AARCH64, X86, X86_64;
-
- companion object {
- fun parse(arch: String): Architecture {
- return when (arch) {
- "arm" -> ARM
- "aarch64" -> AARCH64
- "x86" -> X86
- "x86_64" -> X86_64
- else -> ALL
- }
- }
- }
-}
diff --git a/app/src/main/java/io/neoterm/component/pm/PackageComponent.java b/app/src/main/java/io/neoterm/component/pm/PackageComponent.java
index 0d10fc6..56099bd 100644
--- a/app/src/main/java/io/neoterm/component/pm/PackageComponent.java
+++ b/app/src/main/java/io/neoterm/component/pm/PackageComponent.java
@@ -1,6 +1,6 @@
package io.neoterm.component.pm;
-import io.neoterm.frontend.component.NeoComponent;
+import io.neoterm.component.NeoComponent;
import java.io.File;
import java.io.FileInputStream;
diff --git a/app/src/main/java/io/neoterm/component/pm/SourceManager.kt b/app/src/main/java/io/neoterm/component/pm/SourceManager.kt
deleted file mode 100644
index 1c398cc..0000000
--- a/app/src/main/java/io/neoterm/component/pm/SourceManager.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package io.neoterm.component.pm
-
-import io.neoterm.App
-import io.neoterm.R
-import io.neoterm.framework.NeoTermDatabase
-import io.neoterm.frontend.config.NeoTermPath
-
-/**
- * @author kiva
- */
-class SourceManager internal constructor() {
- private val database = NeoTermDatabase.instance("sources")
-
- init {
- if (database.findAll