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(Source::class.java).isEmpty()) { - App.get().resources.getStringArray(R.array.pref_package_source_values) - .forEach { - database.saveBean(Source(it, "stable main", true)) - } - } - } - - fun addSource(sourceUrl: String, repo: String, enabled: Boolean) { - database.saveBean(Source(sourceUrl, repo, enabled)) - } - - fun removeSource(sourceUrl: String) { - database.deleteBeanByWhere(Source::class.java, "url == '$sourceUrl'") - } - - fun updateAll(sources: List) { - database.dropAllTable() - database.saveBeans(sources) - } - - fun getAllSources(): List { - return database.findAll(Source::class.java) - } - - fun getEnabledSources(): List { - return getAllSources().filter { it.enabled } - } - - fun getMainPackageSource(): String { - return getEnabledSources() - .map { it.repo } - .singleOrNull { it.trim() == "stable main" } - ?: NeoTermPath.DEFAULT_MAIN_PACKAGE_SOURCE - } - - fun applyChanges() { - database.vacuum() - } -} diff --git a/app/src/main/java/io/neoterm/component/pm/NeoPackageInfo.kt b/app/src/main/java/io/neoterm/component/pm/data.kt similarity index 66% rename from app/src/main/java/io/neoterm/component/pm/NeoPackageInfo.kt rename to app/src/main/java/io/neoterm/component/pm/data.kt index fa304a4..c7029c8 100644 --- a/app/src/main/java/io/neoterm/component/pm/NeoPackageInfo.kt +++ b/app/src/main/java/io/neoterm/component/pm/data.kt @@ -1,8 +1,20 @@ 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 + } + } + } +} class NeoPackageInfo { var packageName: String? = null @@ -21,4 +33,3 @@ class NeoPackageInfo { var homePage: String? = null var description: String? = null } - diff --git a/app/src/main/java/io/neoterm/component/pm/SourceHelper.kt b/app/src/main/java/io/neoterm/component/pm/helper.kt similarity index 59% rename from app/src/main/java/io/neoterm/component/pm/SourceHelper.kt rename to app/src/main/java/io/neoterm/component/pm/helper.kt index bf9b429..2b7ed9a 100644 --- a/app/src/main/java/io/neoterm/component/pm/SourceHelper.kt +++ b/app/src/main/java/io/neoterm/component/pm/helper.kt @@ -1,16 +1,16 @@ package io.neoterm.component.pm -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.logging.NLog +import io.neoterm.App +import io.neoterm.R +import io.neoterm.component.ComponentManager +import io.neoterm.component.config.NeoTermPath +import io.neoterm.framework.NeoTermDatabase +import io.neoterm.utils.NLog import java.io.File import java.net.URL import java.nio.file.Files import java.nio.file.Paths -/** - * @author kiva - */ object SourceHelper { fun syncSource() { val sourceManager = ComponentManager.getComponent().sourceManager @@ -71,4 +71,50 @@ object SourceHelper { return "" } } -} \ No newline at end of file +} + +class SourceManager internal constructor() { + private val database = NeoTermDatabase.instance("sources") + + init { + if (database.findAll(Source::class.java).isEmpty()) { + App.get().resources.getStringArray(R.array.pref_package_source_values) + .forEach { + database.saveBean(Source(it, "stable main", true)) + } + } + } + + fun addSource(sourceUrl: String, repo: String, enabled: Boolean) { + database.saveBean(Source(sourceUrl, repo, enabled)) + } + + fun removeSource(sourceUrl: String) { + database.deleteBeanByWhere(Source::class.java, "url == '$sourceUrl'") + } + + fun updateAll(sources: List) { + database.dropAllTable() + database.saveBeans(sources) + } + + fun getAllSources(): List { + return database.findAll(Source::class.java) + } + + fun getEnabledSources(): List { + return getAllSources().filter { it.enabled } + } + + fun getMainPackageSource(): String { + return getEnabledSources() + .map { it.repo } + .singleOrNull { it.trim() == "stable main" } + ?: NeoTermPath.DEFAULT_MAIN_PACKAGE_SOURCE + } + + fun applyChanges() { + database.vacuum() + } +} + diff --git a/app/src/main/java/io/neoterm/component/profile/ProfileComponent.kt b/app/src/main/java/io/neoterm/component/profile/comp.kt similarity index 90% rename from app/src/main/java/io/neoterm/component/profile/ProfileComponent.kt rename to app/src/main/java/io/neoterm/component/profile/comp.kt index f362413..a283c22 100644 --- a/app/src/main/java/io/neoterm/component/profile/ProfileComponent.kt +++ b/app/src/main/java/io/neoterm/component/profile/comp.kt @@ -1,14 +1,11 @@ package io.neoterm.component.profile import io.neolang.visitor.ConfigVisitor -import io.neoterm.frontend.component.helper.ConfigFileBasedComponent -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.logging.NLog +import io.neoterm.component.ConfigFileBasedComponent +import io.neoterm.component.config.NeoTermPath +import io.neoterm.utils.NLog import java.io.File -/** - * @author kiva - */ class ProfileComponent : ConfigFileBasedComponent(NeoTermPath.PROFILE_PATH) { override val checkComponentFileWhenObtained get() = true @@ -63,4 +60,4 @@ class ProfileComponent : ConfigFileBasedComponent(NeoTermPath.PROFIL fun unregisterProfile(metaName: String) { profileRegistry.remove(metaName) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/component/profile/NeoProfile.kt b/app/src/main/java/io/neoterm/component/profile/data.kt similarity index 81% rename from app/src/main/java/io/neoterm/component/profile/NeoProfile.kt rename to app/src/main/java/io/neoterm/component/profile/data.kt index 88e21c4..4f53a06 100644 --- a/app/src/main/java/io/neoterm/component/profile/NeoProfile.kt +++ b/app/src/main/java/io/neoterm/component/profile/data.kt @@ -1,21 +1,18 @@ package io.neoterm.component.profile import io.neolang.visitor.ConfigVisitor +import io.neoterm.component.ComponentManager +import io.neoterm.component.ConfigFileBasedObject +import io.neoterm.component.codegen.CodeGenObject import io.neoterm.component.codegen.CodeGenParameter -import io.neoterm.component.codegen.generators.NeoProfileGenerator -import io.neoterm.component.codegen.interfaces.CodeGenObject -import io.neoterm.component.codegen.interfaces.CodeGenerator +import io.neoterm.component.codegen.CodeGenerator +import io.neoterm.component.codegen.NeoProfileGenerator 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.component.config.NeoConfigureFile +import io.neoterm.utils.NLog import org.jetbrains.annotations.TestOnly import java.io.File -/** - * @author kiva - */ abstract class NeoProfile : CodeGenObject, ConfigFileBasedObject { companion object { private const val PROFILE_NAME = "name" @@ -70,4 +67,4 @@ abstract class NeoProfile : CodeGenObject, ConfigFileBasedObject { protected fun ConfigVisitor.getProfileBoolean(key: String): Boolean? { return this.getBooleanValue(profileMetaPath, key) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/component/session/SessionComponent.kt b/app/src/main/java/io/neoterm/component/session/comp.kt similarity index 85% rename from app/src/main/java/io/neoterm/component/session/SessionComponent.kt rename to app/src/main/java/io/neoterm/component/session/comp.kt index 2fa9b89..9b08c38 100644 --- a/app/src/main/java/io/neoterm/component/session/SessionComponent.kt +++ b/app/src/main/java/io/neoterm/component/session/comp.kt @@ -4,18 +4,10 @@ import android.annotation.SuppressLint import android.content.Context import androidx.appcompat.app.AppCompatActivity import io.neoterm.Globals -import io.neoterm.frontend.component.NeoComponent -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.logging.NLog -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.shell.ShellTermSession -import io.neoterm.frontend.session.xorg.XParameter -import io.neoterm.frontend.session.xorg.XSession -import io.neoterm.frontend.session.xorg.client.XSessionData +import io.neoterm.component.NeoComponent +import io.neoterm.component.config.NeoTermPath +import io.neoterm.utils.NLog -/** - * @author kiva - */ class SessionComponent : NeoComponent { companion object { private var IS_LIBRARIES_LOADED = false @@ -50,7 +42,7 @@ class SessionComponent : NeoComponent { } catch (error: UnsatisfiedLinkError) { NLog.e( "SessionComponent", "Error loading lib " + soPath - + ", reason: " + error.localizedMessage + + ", reason: " + error.localizedMessage ) result = false } @@ -109,4 +101,4 @@ class SessionComponent : NeoComponent { .profile(parameter.shellProfile) .create(context) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/ShellTermSession.kt b/app/src/main/java/io/neoterm/component/session/shell.kt similarity index 55% rename from app/src/main/java/io/neoterm/frontend/session/shell/ShellTermSession.kt rename to app/src/main/java/io/neoterm/component/session/shell.kt index 11e19b8..411b9b2 100644 --- a/app/src/main/java/io/neoterm/frontend/session/shell/ShellTermSession.kt +++ b/app/src/main/java/io/neoterm/component/session/shell.kt @@ -1,13 +1,163 @@ -package io.neoterm.frontend.session.shell +package io.neoterm.component.session import android.content.Context +import io.neolang.visitor.ConfigVisitor import io.neoterm.App import io.neoterm.R import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.session.shell.client.TermSessionCallback +import io.neoterm.bridge.SessionId +import io.neoterm.component.ComponentManager +import io.neoterm.component.colorscheme.ColorSchemeComponent +import io.neoterm.component.config.DefaultValues +import io.neoterm.component.config.NeoPreference +import io.neoterm.component.config.NeoTermPath +import io.neoterm.component.font.FontComponent +import io.neoterm.component.profile.NeoProfile +import io.neoterm.frontend.session.terminal.TermSessionCallback import java.io.File +/** + * @author kiva + */ +class ShellParameter { + var sessionId: SessionId? = null + var executablePath: String? = null + var arguments: Array? = null + var cwd: String? = null + var initialCommand: String? = null + var env: Array>? = null + var sessionCallback: TerminalSession.SessionChangedCallback? = null + var systemShell: Boolean = false + var shellProfile: ShellProfile? = null + + fun executablePath(executablePath: String?): ShellParameter { + this.executablePath = executablePath + return this + } + + fun arguments(arguments: Array?): ShellParameter { + this.arguments = arguments + return this + } + + fun currentWorkingDirectory(cwd: String?): ShellParameter { + this.cwd = cwd + return this + } + + fun initialCommand(initialCommand: String?): ShellParameter { + this.initialCommand = initialCommand + return this + } + + fun environment(env: Array>?): ShellParameter { + this.env = env + return this + } + + fun callback(callback: TerminalSession.SessionChangedCallback?): ShellParameter { + this.sessionCallback = callback + return this + } + + fun systemShell(systemShell: Boolean): ShellParameter { + this.systemShell = systemShell + return this + } + + fun profile(shellProfile: ShellProfile): ShellParameter { + this.shellProfile = shellProfile + return this + } + + fun session(sessionId: SessionId?): ShellParameter { + this.sessionId = sessionId + return this + } + + fun willCreateNewSession(): Boolean { + return sessionId?.equals(SessionId.NEW_SESSION) ?: true + } +} + +/** + * @author kiva + */ +class ShellProfile : NeoProfile() { + companion object { + const val PROFILE_META_NAME = "profile-shell" + + private const val LOGIN_SHELL = "login-shell" + private const val INITIAL_COMMAND = "init-command" + private const val BELL = "bell" + private const val VIBRATE = "vibrate" + private const val EXECVE_WRAPPER = "execve-wrapper" + private const val SPECIAL_VOLUME_KEYS = "special-volume-keys" + private const val AUTO_COMPLETION = "auto-completion" + private const val BACK_KEY_TO_ESC = "back-key-esc" + private const val EXTRA_KEYS = "extra-keys" + private const val FONT = "font" + private const val COLOR_SCHEME = "color-scheme" + private const val WORD_BASED_IME = "word-based-ime" + + fun create(): ShellProfile { + return ShellProfile() + } + } + + override val profileMetaName = PROFILE_META_NAME + + var loginShell = DefaultValues.loginShell + var initialCommand = DefaultValues.initialCommand + + var enableBell = DefaultValues.enableBell + var enableVibrate = DefaultValues.enableVibrate + var enableExecveWrapper = DefaultValues.enableExecveWrapper + var enableSpecialVolumeKeys = DefaultValues.enableSpecialVolumeKeys + var enableAutoCompletion = DefaultValues.enableAutoCompletion + var enableBackKeyToEscape = DefaultValues.enableBackButtonBeMappedToEscape + var enableExtraKeys = DefaultValues.enableExtraKeys + var enableWordBasedIme = DefaultValues.enableWordBasedIme + + var profileFont: String + var profileColorScheme: String + + init { + val fontComp = ComponentManager.getComponent() + val colorComp = ComponentManager.getComponent() + + profileFont = fontComp.getCurrentFontName() + profileColorScheme = colorComp.getCurrentColorSchemeName() + + loginShell = NeoPreference.getLoginShellPath() + initialCommand = NeoPreference.getInitialCommand() + enableBell = NeoPreference.isBellEnabled() + enableVibrate = NeoPreference.isVibrateEnabled() + enableExecveWrapper = NeoPreference.isExecveWrapperEnabled() + enableSpecialVolumeKeys = NeoPreference.isSpecialVolumeKeysEnabled() + enableAutoCompletion = NeoPreference.isAutoCompletionEnabled() + enableBackKeyToEscape = NeoPreference.isBackButtonBeMappedToEscapeEnabled() + enableExtraKeys = NeoPreference.isExtraKeysEnabled() + enableWordBasedIme = NeoPreference.isWordBasedImeEnabled() + } + + override fun onConfigLoaded(configVisitor: ConfigVisitor) { + super.onConfigLoaded(configVisitor) + loginShell = configVisitor.getProfileString(LOGIN_SHELL, loginShell) + initialCommand = configVisitor.getProfileString(INITIAL_COMMAND, initialCommand) + enableBell = configVisitor.getProfileBoolean(BELL, enableBell) + enableVibrate = configVisitor.getProfileBoolean(VIBRATE, enableVibrate) + enableExecveWrapper = configVisitor.getProfileBoolean(EXECVE_WRAPPER, enableExecveWrapper) + enableSpecialVolumeKeys = configVisitor.getProfileBoolean(SPECIAL_VOLUME_KEYS, enableSpecialVolumeKeys) + enableAutoCompletion = configVisitor.getProfileBoolean(AUTO_COMPLETION, enableAutoCompletion) + enableBackKeyToEscape = configVisitor.getProfileBoolean(BACK_KEY_TO_ESC, enableBackKeyToEscape) + enableExtraKeys = configVisitor.getProfileBoolean(EXTRA_KEYS, enableExtraKeys) + enableWordBasedIme = configVisitor.getProfileBoolean(WORD_BASED_IME, enableWordBasedIme) + profileFont = configVisitor.getProfileString(FONT, profileFont) + profileColorScheme = configVisitor.getProfileString(COLOR_SCHEME, profileColorScheme) + } +} + /** * @author kiva */ @@ -244,4 +394,4 @@ open class ShellTermSession private constructor( return "${NeoTermPath.USR_PATH}/bin:${NeoTermPath.USR_PATH}/bin/applets" } } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/frontend/session/xorg/XSession.kt b/app/src/main/java/io/neoterm/component/session/x.kt similarity index 95% rename from app/src/main/java/io/neoterm/frontend/session/xorg/XSession.kt rename to app/src/main/java/io/neoterm/component/session/x.kt index 3794dcf..62e4595 100644 --- a/app/src/main/java/io/neoterm/frontend/session/xorg/XSession.kt +++ b/app/src/main/java/io/neoterm/component/session/x.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.session.xorg +package io.neoterm.component.session import android.app.UiModeManager import android.content.Context @@ -7,6 +7,7 @@ import android.content.pm.PackageManager import android.content.res.Configuration import android.inputmethodservice.Keyboard import android.inputmethodservice.KeyboardView +import android.os.Build import android.os.SystemClock import android.text.InputType import android.view.* @@ -15,14 +16,11 @@ import android.widget.EditText import android.widget.FrameLayout import androidx.appcompat.app.AppCompatActivity import io.neoterm.* -import io.neoterm.frontend.session.xorg.client.XSessionData import io.neoterm.xorg.NeoXorgViewClient import io.neoterm.xorg.R import java.util.* -/** - * @author kiva - */ +class XParameter class XSession constructor(private val mActivity: AppCompatActivity, val mSessionData: XSessionData) : NeoXorgViewClient { @@ -64,17 +62,11 @@ class XSession constructor(private val mActivity: AppCompatActivity, val mSessio } override fun getContext() = mActivity - override fun isKeyboardWithoutTextInputShown() = mSessionData.keyboardWithoutTextInputShown - override fun isPaused() = mSessionData.isPaused - override fun runOnUiThread(runnable: Runnable?) = mActivity.runOnUiThread(runnable) - override fun getGLView() = mSessionData.glView - override fun getWindow() = mActivity.window!! - override fun getWindowManager() = mActivity.windowManager!! override fun showScreenKeyboardWithoutTextInputField(keyboard: Int) { @@ -244,7 +236,7 @@ class XSession constructor(private val mActivity: AppCompatActivity, val mSessio val screenKeyboard = EditText( mActivity, null, - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) android.R.style.TextAppearance_Material_Widget_EditText else android.R.style.TextAppearance_Widget_EditText ) @@ -349,10 +341,10 @@ class XSession constructor(private val mActivity: AppCompatActivity, val mSessio override fun setSystemMousePointerVisible(visible: Int) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - glView?.pointerIcon = android.view.PointerIcon.getSystemIcon( + glView?.pointerIcon = PointerIcon.getSystemIcon( mActivity, - if (visible == 0) android.view.PointerIcon.TYPE_NULL - else android.view.PointerIcon.TYPE_DEFAULT + if (visible == 0) PointerIcon.TYPE_NULL + else PointerIcon.TYPE_DEFAULT ) } } @@ -417,5 +409,18 @@ class XSession constructor(private val mActivity: AppCompatActivity, val mSessio } } } - +} + +class XSessionData { + var videoLayout: FrameLayout? = null + var audioThread: NeoAudioThread? = null + var screenKeyboard: View? = null + var glView: NeoGLView? = null + + var isPaused = false + var client: NeoXorgViewClient? = null + + var keyboardWithoutTextInputShown = false + var screenKeyboardHintMessage: String? = null + var textInput = LinkedList() } diff --git a/app/src/main/java/io/neoterm/component/userscript/UserScript.kt b/app/src/main/java/io/neoterm/component/userscript/UserScript.kt deleted file mode 100644 index 8d677ac..0000000 --- a/app/src/main/java/io/neoterm/component/userscript/UserScript.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.neoterm.component.userscript - -import java.io.File - -/** - * @author kiva - */ -class UserScript(val scriptFile: File) \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/component/userscript/UserScriptComponent.kt b/app/src/main/java/io/neoterm/component/userscript/comp.kt similarity index 83% rename from app/src/main/java/io/neoterm/component/userscript/UserScriptComponent.kt rename to app/src/main/java/io/neoterm/component/userscript/comp.kt index 5cf90ba..4378972 100644 --- a/app/src/main/java/io/neoterm/component/userscript/UserScriptComponent.kt +++ b/app/src/main/java/io/neoterm/component/userscript/comp.kt @@ -3,17 +3,16 @@ package io.neoterm.component.userscript import android.content.Context import android.system.Os import io.neoterm.App -import io.neoterm.frontend.component.NeoComponent -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.logging.NLog +import io.neoterm.component.NeoComponent +import io.neoterm.component.config.NeoTermPath +import io.neoterm.utils.NLog import io.neoterm.utils.extractAssetsDir import java.io.File -/** - * @author kiva - */ +class UserScript(val scriptFile: File) + class UserScriptComponent : NeoComponent { - private var userScripts = listOf() + var userScripts = listOf() private val scriptDir = File(NeoTermPath.USER_SCRIPT_PATH) override fun onServiceInit() = checkForFiles() diff --git a/app/src/main/java/io/neoterm/framework/NeoTermDatabase.java b/app/src/main/java/io/neoterm/framework/NeoTermDatabase.java index a512db4..70d73ee 100644 --- a/app/src/main/java/io/neoterm/framework/NeoTermDatabase.java +++ b/app/src/main/java/io/neoterm/framework/NeoTermDatabase.java @@ -9,7 +9,7 @@ import io.neoterm.App; import io.neoterm.framework.database.*; import io.neoterm.framework.database.bean.TableInfo; import io.neoterm.framework.reflection.Reflect; -import io.neoterm.frontend.logging.NLog; +import io.neoterm.utils.NLog; import java.io.File; import java.io.IOException; diff --git a/app/src/main/java/io/neoterm/frontend/completion/view/CandidatePopupWindow.kt b/app/src/main/java/io/neoterm/frontend/completion/CandidatePopupWindow.kt similarity index 90% rename from app/src/main/java/io/neoterm/frontend/completion/view/CandidatePopupWindow.kt rename to app/src/main/java/io/neoterm/frontend/completion/CandidatePopupWindow.kt index 3c06157..d14d543 100644 --- a/app/src/main/java/io/neoterm/frontend/completion/view/CandidatePopupWindow.kt +++ b/app/src/main/java/io/neoterm/frontend/completion/CandidatePopupWindow.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.completion.view +package io.neoterm.frontend.completion import android.content.Context import android.view.Gravity @@ -11,11 +11,11 @@ import android.widget.PopupWindow import android.widget.TextView import io.neoterm.R import io.neoterm.backend.TerminalColors +import io.neoterm.component.ComponentManager import io.neoterm.component.colorscheme.ColorSchemeComponent -import io.neoterm.frontend.completion.listener.OnCandidateSelectedListener -import io.neoterm.frontend.completion.model.CompletionCandidate -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.terminal.TerminalView +import io.neoterm.component.completion.CompletionCandidate +import io.neoterm.component.completion.OnCandidateSelectedListener +import io.neoterm.frontend.session.view.TerminalView /** * @author kiva @@ -41,14 +41,13 @@ class CandidatePopupWindow(val context: Context) { // Ensure that the popup window will not cover the IME. val rootView = popWindow.contentView if (rootView is MaxHeightView) { - val maxHeight = terminalView.height - rootView.setMaxHeight(maxHeight) + rootView.maxHeight = terminalView.height } popWindow.showAtLocation( terminalView, Gravity.BOTTOM.and(Gravity.START), terminalView.cursorAbsoluteX, - terminalView.cursorAbsoluteY + terminalView.cursorAbsoluteY, ) } } @@ -69,12 +68,12 @@ class CandidatePopupWindow(val context: Context) { val listView = contentView.findViewById(R.id.popup_complete_candidate_list) candidateAdapter = CandidateAdapter(this) listView.adapter = candidateAdapter - listView.setOnItemClickListener({ _, _, position, _ -> + listView.setOnItemClickListener { _, _, position, _ -> val selectedItem = candidates?.get(position) if (selectedItem != null) { onCandidateSelectedListener?.onCandidateSelected(selectedItem) } - }) + } candidateListView = listView popupWindow.contentView = contentView @@ -143,4 +142,4 @@ class CandidatePopupWindow(val context: Context) { description.setTextColor(textColor) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/frontend/completion/view/MaxHeightView.kt b/app/src/main/java/io/neoterm/frontend/completion/MaxHeightView.kt similarity index 82% rename from app/src/main/java/io/neoterm/frontend/completion/view/MaxHeightView.kt rename to app/src/main/java/io/neoterm/frontend/completion/MaxHeightView.kt index 49a0356..e4c8049 100644 --- a/app/src/main/java/io/neoterm/frontend/completion/view/MaxHeightView.kt +++ b/app/src/main/java/io/neoterm/frontend/completion/MaxHeightView.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.completion.view +package io.neoterm.frontend.completion import android.content.Context import android.util.AttributeSet @@ -6,18 +6,11 @@ import android.view.View import android.widget.LinearLayout class MaxHeightView : LinearLayout { + var maxHeight = -1 - private var maxHeight = -1 - - constructor(context: Context) : super(context) {} - - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} - - constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {} - - fun setMaxHeight(maxHeight: Int) { - this.maxHeight = maxHeight - } + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { var finalHeightMeasureSpec = heightMeasureSpec @@ -53,4 +46,4 @@ class MaxHeightView : LinearLayout { super.onMeasure(widthMeasureSpec, finalHeightMeasureSpec) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/frontend/completion/ProviderDetector.kt b/app/src/main/java/io/neoterm/frontend/completion/ProviderDetector.kt deleted file mode 100644 index 9bc9268..0000000 --- a/app/src/main/java/io/neoterm/frontend/completion/ProviderDetector.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.neoterm.frontend.completion - -import io.neoterm.frontend.completion.listener.MarkScoreListener -import io.neoterm.frontend.completion.provider.ICandidateProvider - -/** - * @author kiva - */ -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 - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/completion/listener/MarkScoreListener.kt b/app/src/main/java/io/neoterm/frontend/completion/listener/MarkScoreListener.kt deleted file mode 100644 index 2e8c1d2..0000000 --- a/app/src/main/java/io/neoterm/frontend/completion/listener/MarkScoreListener.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.neoterm.frontend.completion.listener - -/** - * @author kiva - */ - -interface MarkScoreListener { - fun onMarkScore(score: Int) -} diff --git a/app/src/main/java/io/neoterm/frontend/completion/listener/OnAutoCompleteListener.kt b/app/src/main/java/io/neoterm/frontend/completion/listener/OnAutoCompleteListener.kt deleted file mode 100755 index feb7c8e..0000000 --- a/app/src/main/java/io/neoterm/frontend/completion/listener/OnAutoCompleteListener.kt +++ /dev/null @@ -1,16 +0,0 @@ -package io.neoterm.frontend.completion.listener - -/** - * @author Kiva - * * - * @version 1.0 - */ -interface OnAutoCompleteListener { - fun onCompletionRequired(newText: String?) - - fun onKeyCode(keyCode: Int, keyMod: Int) - - fun onCleanUp() - - fun onFinishCompletion(): Boolean -} diff --git a/app/src/main/java/io/neoterm/frontend/completion/listener/OnCandidateSelectedListener.kt b/app/src/main/java/io/neoterm/frontend/completion/listener/OnCandidateSelectedListener.kt deleted file mode 100644 index 89644f4..0000000 --- a/app/src/main/java/io/neoterm/frontend/completion/listener/OnCandidateSelectedListener.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.neoterm.frontend.completion.listener - -import io.neoterm.frontend.completion.model.CompletionCandidate - -/** - * @author kiva - */ -interface OnCandidateSelectedListener { - fun onCandidateSelected(candidate: CompletionCandidate) -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/completion/model/CompletionCandidate.kt b/app/src/main/java/io/neoterm/frontend/completion/model/CompletionCandidate.kt deleted file mode 100644 index e819a26..0000000 --- a/app/src/main/java/io/neoterm/frontend/completion/model/CompletionCandidate.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.neoterm.frontend.completion.model - -/** - * @author kiva - */ -class CompletionCandidate(var completeString: String) { - var displayName: String = completeString - var description: String? = null -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/completion/provider/ICandidateProvider.kt b/app/src/main/java/io/neoterm/frontend/completion/provider/ICandidateProvider.kt deleted file mode 100644 index e3a39b7..0000000 --- a/app/src/main/java/io/neoterm/frontend/completion/provider/ICandidateProvider.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.neoterm.frontend.completion.provider - -import io.neoterm.frontend.completion.model.CompletionCandidate - -/** - * @author kiva - */ - -interface ICandidateProvider { - val providerName: String - - fun provideCandidates(text: String): List? - - fun canComplete(text: String): Boolean -} diff --git a/app/src/main/java/io/neoterm/frontend/component/ComponentDuplicateException.kt b/app/src/main/java/io/neoterm/frontend/component/ComponentDuplicateException.kt deleted file mode 100644 index a47c5ab..0000000 --- a/app/src/main/java/io/neoterm/frontend/component/ComponentDuplicateException.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.component - -/** - * @author kiva - */ -class ComponentDuplicateException(serviceName: String) : RuntimeException("Service $serviceName duplicate") \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/component/ComponentNotFoundException.kt b/app/src/main/java/io/neoterm/frontend/component/ComponentNotFoundException.kt deleted file mode 100644 index d7289ce..0000000 --- a/app/src/main/java/io/neoterm/frontend/component/ComponentNotFoundException.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.neoterm.frontend.component - -/** - * @author kiva - */ -class ComponentNotFoundException(serviceName: String) : RuntimeException("Component `$serviceName' not found") { -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/component/NeoComponent.kt b/app/src/main/java/io/neoterm/frontend/component/NeoComponent.kt deleted file mode 100644 index f54c6d3..0000000 --- a/app/src/main/java/io/neoterm/frontend/component/NeoComponent.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.neoterm.frontend.component - -/** - * @author kiva - */ -interface NeoComponent { - fun onServiceInit() - fun onServiceDestroy() - fun onServiceObtained() -} diff --git a/app/src/main/java/io/neoterm/frontend/component/helper/ConfigFileBasedObject.kt b/app/src/main/java/io/neoterm/frontend/component/helper/ConfigFileBasedObject.kt deleted file mode 100644 index 69cbd83..0000000 --- a/app/src/main/java/io/neoterm/frontend/component/helper/ConfigFileBasedObject.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.neoterm.frontend.component.helper - -import io.neolang.visitor.ConfigVisitor - -/** - * @author kiva - */ -interface ConfigFileBasedObject { - @Throws(RuntimeException::class) - fun onConfigLoaded(configVisitor: ConfigVisitor) -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/config/DefaultValues.kt b/app/src/main/java/io/neoterm/frontend/config/DefaultValues.kt deleted file mode 100644 index 4236d7c..0000000 --- a/app/src/main/java/io/neoterm/frontend/config/DefaultValues.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.neoterm.frontend.config - -/** - * @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" -} diff --git a/app/src/main/java/io/neoterm/frontend/config/NeoConfigureFile.kt b/app/src/main/java/io/neoterm/frontend/config/NeoConfigureFile.kt deleted file mode 100644 index e0b0651..0000000 --- a/app/src/main/java/io/neoterm/frontend/config/NeoConfigureFile.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.neoterm.frontend.config - -import io.neolang.parser.NeoLangParser -import io.neolang.visitor.ConfigVisitor -import java.io.File -import java.nio.file.Files - -/** - * @author kiva - */ -open class NeoConfigureFile(val configureFile: File) { - private val configParser = NeoLangParser() - open protected 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 -} diff --git a/app/src/main/java/io/neoterm/frontend/floating/WindowTermView.kt b/app/src/main/java/io/neoterm/frontend/floating/WindowTermView.kt deleted file mode 100644 index b05b835..0000000 --- a/app/src/main/java/io/neoterm/frontend/floating/WindowTermView.kt +++ /dev/null @@ -1,39 +0,0 @@ -package io.neoterm.frontend.floating - -import android.annotation.SuppressLint -import android.content.Context -import android.view.LayoutInflater -import android.view.View -import io.neoterm.R -import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.TerminalViewClient -import io.neoterm.utils.Terminals - -/** - * @author kiva - */ -class WindowTermView(val context: Context) { - @SuppressLint("InflateParams") - var rootView: View = LayoutInflater.from(context).inflate(R.layout.ui_term_dialog, null, false) - private set - var terminalView: TerminalView = rootView.findViewById(R.id.terminal_view_dialog) - private set - - init { - Terminals.setupTerminalView(terminalView) - } - - fun setTerminalViewClient(terminalViewClient: TerminalViewClient?) { - terminalView.setTerminalViewClient(terminalViewClient) - } - - fun attachSession(terminalSession: TerminalSession?) { - terminalView.attachSession(terminalSession) - } - - fun setInputMethodEnabled(enabled: Boolean) { - terminalView.isFocusable = enabled - terminalView.isFocusableInTouchMode = enabled - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt b/app/src/main/java/io/neoterm/frontend/floating/dialog.kt similarity index 69% rename from app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt rename to app/src/main/java/io/neoterm/frontend/floating/dialog.kt index a62bf20..864ad30 100644 --- a/app/src/main/java/io/neoterm/frontend/floating/TerminalDialog.kt +++ b/app/src/main/java/io/neoterm/frontend/floating/dialog.kt @@ -1,21 +1,23 @@ package io.neoterm.frontend.floating +import android.annotation.SuppressLint import android.content.Context import android.content.DialogInterface +import android.view.LayoutInflater +import android.view.View import androidx.appcompat.app.AlertDialog import io.neoterm.R import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.shell.ShellTermSession -import io.neoterm.frontend.session.shell.client.BasicSessionCallback -import io.neoterm.frontend.session.shell.client.BasicViewClient +import io.neoterm.component.session.ShellParameter +import io.neoterm.component.session.ShellTermSession +import io.neoterm.frontend.session.terminal.BasicSessionCallback +import io.neoterm.frontend.session.terminal.BasicViewClient +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.TerminalViewClient import io.neoterm.utils.Terminals typealias DialogSessionFinished = (TerminalDialog, TerminalSession?) -> Unit -/** - * @author kiva - */ class TerminalDialog(val context: Context) { private val termWindowView = WindowTermView(context) private val terminalSessionCallback: BasicSessionCallback @@ -92,4 +94,29 @@ class TerminalDialog(val context: Context) { } return this } -} \ No newline at end of file +} + +class WindowTermView(val context: Context) { + @SuppressLint("InflateParams") + var rootView: View = LayoutInflater.from(context).inflate(R.layout.ui_term_dialog, null, false) + private set + var terminalView: TerminalView = rootView.findViewById(R.id.terminal_view_dialog) + private set + + init { + Terminals.setupTerminalView(terminalView) + } + + fun setTerminalViewClient(terminalViewClient: TerminalViewClient?) { + terminalView.setTerminalViewClient(terminalViewClient) + } + + fun attachSession(terminalSession: TerminalSession?) { + terminalView.attachSession(terminalSession) + } + + fun setInputMethodEnabled(enabled: Boolean) { + terminalView.isFocusable = enabled + terminalView.isFocusableInTouchMode = enabled + } +} diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/ShellParameter.kt b/app/src/main/java/io/neoterm/frontend/session/shell/ShellParameter.kt deleted file mode 100644 index ff7f37f..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/ShellParameter.kt +++ /dev/null @@ -1,68 +0,0 @@ -package io.neoterm.frontend.session.shell - -import io.neoterm.backend.TerminalSession -import io.neoterm.bridge.SessionId - -/** - * @author kiva - */ -class ShellParameter { - var sessionId: SessionId? = null - var executablePath: String? = null - var arguments: Array? = null - var cwd: String? = null - var initialCommand: String? = null - var env: Array>? = null - var sessionCallback: TerminalSession.SessionChangedCallback? = null - var systemShell: Boolean = false - var shellProfile: ShellProfile? = null - - fun executablePath(executablePath: String?): ShellParameter { - this.executablePath = executablePath - return this - } - - fun arguments(arguments: Array?): ShellParameter { - this.arguments = arguments - return this - } - - fun currentWorkingDirectory(cwd: String?): ShellParameter { - this.cwd = cwd - return this - } - - fun initialCommand(initialCommand: String?): ShellParameter { - this.initialCommand = initialCommand - return this - } - - fun environment(env: Array>?): ShellParameter { - this.env = env - return this - } - - fun callback(callback: TerminalSession.SessionChangedCallback?): ShellParameter { - this.sessionCallback = callback - return this - } - - fun systemShell(systemShell: Boolean): ShellParameter { - this.systemShell = systemShell - return this - } - - fun profile(shellProfile: ShellProfile): ShellParameter { - this.shellProfile = shellProfile - return this - } - - fun session(sessionId: SessionId?): ShellParameter { - this.sessionId = sessionId - return this - } - - fun willCreateNewSession(): Boolean { - return sessionId?.equals(SessionId.NEW_SESSION) ?: true - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/ShellProfile.kt b/app/src/main/java/io/neoterm/frontend/session/shell/ShellProfile.kt deleted file mode 100644 index 8f2bf0d..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/ShellProfile.kt +++ /dev/null @@ -1,87 +0,0 @@ -package io.neoterm.frontend.session.shell - -import io.neolang.visitor.ConfigVisitor -import io.neoterm.component.colorscheme.ColorSchemeComponent -import io.neoterm.component.font.FontComponent -import io.neoterm.component.profile.NeoProfile -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.DefaultValues -import io.neoterm.frontend.config.NeoPreference - -/** - * @author kiva - */ -class ShellProfile : NeoProfile() { - companion object { - const val PROFILE_META_NAME = "profile-shell" - - private const val LOGIN_SHELL = "login-shell" - private const val INITIAL_COMMAND = "init-command" - private const val BELL = "bell" - private const val VIBRATE = "vibrate" - private const val EXECVE_WRAPPER = "execve-wrapper" - private const val SPECIAL_VOLUME_KEYS = "special-volume-keys" - private const val AUTO_COMPLETION = "auto-completion" - private const val BACK_KEY_TO_ESC = "back-key-esc" - private const val EXTRA_KEYS = "extra-keys" - private const val FONT = "font" - private const val COLOR_SCHEME = "color-scheme" - private const val WORD_BASED_IME = "word-based-ime" - - fun create(): ShellProfile { - return ShellProfile() - } - } - - override val profileMetaName = PROFILE_META_NAME - - var loginShell = DefaultValues.loginShell - var initialCommand = DefaultValues.initialCommand - - var enableBell = DefaultValues.enableBell - var enableVibrate = DefaultValues.enableVibrate - var enableExecveWrapper = DefaultValues.enableExecveWrapper - var enableSpecialVolumeKeys = DefaultValues.enableSpecialVolumeKeys - var enableAutoCompletion = DefaultValues.enableAutoCompletion - var enableBackKeyToEscape = DefaultValues.enableBackButtonBeMappedToEscape - var enableExtraKeys = DefaultValues.enableExtraKeys - var enableWordBasedIme = DefaultValues.enableWordBasedIme - - var profileFont: String - var profileColorScheme: String - - init { - val fontComp = ComponentManager.getComponent() - val colorComp = ComponentManager.getComponent() - - profileFont = fontComp.getCurrentFontName() - profileColorScheme = colorComp.getCurrentColorSchemeName() - - loginShell = NeoPreference.getLoginShellPath() - initialCommand = NeoPreference.getInitialCommand() - enableBell = NeoPreference.isBellEnabled() - enableVibrate = NeoPreference.isVibrateEnabled() - enableExecveWrapper = NeoPreference.isExecveWrapperEnabled() - enableSpecialVolumeKeys = NeoPreference.isSpecialVolumeKeysEnabled() - enableAutoCompletion = NeoPreference.isAutoCompletionEnabled() - enableBackKeyToEscape = NeoPreference.isBackButtonBeMappedToEscapeEnabled() - enableExtraKeys = NeoPreference.isExtraKeysEnabled() - enableWordBasedIme = NeoPreference.isWordBasedImeEnabled() - } - - override fun onConfigLoaded(configVisitor: ConfigVisitor) { - super.onConfigLoaded(configVisitor) - loginShell = configVisitor.getProfileString(LOGIN_SHELL, loginShell) - initialCommand = configVisitor.getProfileString(INITIAL_COMMAND, initialCommand) - enableBell = configVisitor.getProfileBoolean(BELL, enableBell) - enableVibrate = configVisitor.getProfileBoolean(VIBRATE, enableVibrate) - enableExecveWrapper = configVisitor.getProfileBoolean(EXECVE_WRAPPER, enableExecveWrapper) - enableSpecialVolumeKeys = configVisitor.getProfileBoolean(SPECIAL_VOLUME_KEYS, enableSpecialVolumeKeys) - enableAutoCompletion = configVisitor.getProfileBoolean(AUTO_COMPLETION, enableAutoCompletion) - enableBackKeyToEscape = configVisitor.getProfileBoolean(BACK_KEY_TO_ESC, enableBackKeyToEscape) - enableExtraKeys = configVisitor.getProfileBoolean(EXTRA_KEYS, enableExtraKeys) - enableWordBasedIme = configVisitor.getProfileBoolean(WORD_BASED_IME, enableWordBasedIme) - profileFont = configVisitor.getProfileString(FONT, profileFont) - profileColorScheme = configVisitor.getProfileString(COLOR_SCHEME, profileColorScheme) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/BasicSessionCallback.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/BasicSessionCallback.kt deleted file mode 100644 index d0bfdb4..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/BasicSessionCallback.kt +++ /dev/null @@ -1,33 +0,0 @@ -package io.neoterm.frontend.session.shell.client - -import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.terminal.TerminalView - -/** - * @author kiva - */ -open class BasicSessionCallback(var terminalView: TerminalView) : TerminalSession.SessionChangedCallback { - override fun onTextChanged(changedSession: TerminalSession?) { - if (changedSession != null) { - terminalView.onScreenUpdated() - } - } - - override fun onTitleChanged(changedSession: TerminalSession?) { - } - - override fun onSessionFinished(finishedSession: TerminalSession?) { - } - - override fun onClipboardText(session: TerminalSession?, text: String?) { - } - - override fun onBell(session: TerminalSession?) { - } - - override fun onColorsChanged(session: TerminalSession?) { - if (session != null) { - terminalView.onScreenUpdated() - } - } -} diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/BellController.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/BellController.kt deleted file mode 100644 index 57e01ab..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/BellController.kt +++ /dev/null @@ -1,41 +0,0 @@ -package io.neoterm.frontend.session.shell.client - -import android.content.Context -import android.media.SoundPool -import android.os.Vibrator -import io.neoterm.R -import io.neoterm.frontend.session.shell.ShellTermSession - -/** - * @author kiva - */ -class BellController constructor() { - companion object { - private val BELL_DELAY_MS = 100 - } - - private var bellId: Int = 0 - private var soundPool: SoundPool? = null - private var lastBellTime = 0L - - fun bellOrVibrate(context: Context, session: ShellTermSession) { - val currentTime = System.currentTimeMillis() - if (currentTime - lastBellTime < BELL_DELAY_MS) { - return - } - lastBellTime = currentTime - - if (session.shellProfile.enableBell) { - if (soundPool == null) { - soundPool = SoundPool.Builder().setMaxStreams(1).build() - bellId = soundPool!!.load(context, R.raw.bell, 1) - } - soundPool?.play(bellId, 1f, 1f, 0, 0, 1f) - } - - if (session.shellProfile.enableVibrate) { - val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator - vibrator.vibrate(100) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermCompleteListener.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/TermCompleteListener.kt deleted file mode 100644 index 538d4c3..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermCompleteListener.kt +++ /dev/null @@ -1,165 +0,0 @@ -package io.neoterm.frontend.session.shell.client - -import android.util.Log -import android.view.KeyEvent -import io.neoterm.BuildConfig -import io.neoterm.frontend.completion.CompletionManager -import io.neoterm.frontend.completion.listener.OnAutoCompleteListener -import io.neoterm.frontend.completion.listener.OnCandidateSelectedListener -import io.neoterm.frontend.completion.model.CompletionCandidate -import io.neoterm.frontend.completion.model.CompletionResult -import io.neoterm.frontend.completion.view.CandidatePopupWindow -import io.neoterm.frontend.terminal.TerminalView -import java.util.* - -/** - * @author kiva - */ -class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteListener, OnCandidateSelectedListener { - private val inputStack = Stack() - private var popupWindow: CandidatePopupWindow? = null - private var lastCompletedIndex = 0 - - override fun onKeyCode(keyCode: Int, keyMod: Int) { - when (keyCode) { - KeyEvent.KEYCODE_DEL -> { - popChar() - fixLastCompletedIndex() - triggerCompletion() - } - - KeyEvent.KEYCODE_ENTER -> { - clearChars() - popupWindow?.dismiss() - } - } - } - - private fun fixLastCompletedIndex() { - val currentText = getCurrentEditingText() - lastCompletedIndex = minOf(lastCompletedIndex, currentText.length - 1) - } - - override fun onCompletionRequired(newText: String?) { - if (newText == null || newText.isEmpty()) { - return - } - pushString(newText) - triggerCompletion() - } - - override fun onCleanUp() { - popupWindow?.dismiss() - popupWindow?.cleanup() - popupWindow = null - terminalView = null - } - - override fun onFinishCompletion(): Boolean { - val popWindow = popupWindow ?: return false - - if (popWindow.isShowing()) { - popWindow.dismiss() - return true - } - return false - } - - override fun onCandidateSelected(candidate: CompletionCandidate) { - val session = terminalView?.currentSession ?: return - val textNeedCompletion = getCurrentEditingText().substring(lastCompletedIndex + 1) - val newText = candidate.completeString - - val deleteLength = newText.indexOf(textNeedCompletion) + textNeedCompletion.length - if (deleteLength > 0) { - for (i in 0 until deleteLength) { - session.write("\b") - popChar() - } - } - - if (BuildConfig.DEBUG) { - Log.e( - "NeoTerm-AC", "currentEditing: $textNeedCompletion, " + - "deleteLength: $deleteLength, completeString: $newText" - ) - } - - pushString(newText) - session.write(newText) - // Trigger next completion - lastCompletedIndex = inputStack.size - triggerCompletion() - } - - private fun triggerCompletion() { - val text = getCurrentEditingText() - if (text.isEmpty()) { - return - } - - val result = CompletionManager.tryCompleteFor(text) - if (!result.hasResult()) { - // A provider accepted the task - // But no candidates are provided - // Give it zero angrily! - result.markScore(0) - onFinishCompletion() - return - } - showAutoCompleteCandidates(result) - } - - private fun showAutoCompleteCandidates(result: CompletionResult) { - val termView = terminalView - var popWindow = popupWindow - - if (termView == null) { - return - } - - if (popWindow == null) { - popWindow = CandidatePopupWindow(termView.context) - popWindow.onCandidateSelectedListener = this - this.popupWindow = popWindow - } - - popWindow.candidates = result.candidates - popWindow.show(termView) - } - - private fun getCurrentEditingText(): String { - val builder = StringBuilder() - val size = inputStack.size - var start = inputStack.lastIndexOf(' ') - if (start < 0) { - // Yes, it is -1, we will do `start + 1` below. - start = -1 - } - - IntRange(start + 1, size - 1) - .map { inputStack[it] } - .takeWhile { !(it == 0.toChar() || it == ' ') } - .forEach { builder.append(it) } - return builder.toString() - } - - private fun clearChars() { - inputStack.clear() - lastCompletedIndex = 0 - } - - private fun popChar() { - if (inputStack.isNotEmpty()) { - inputStack.pop() - } - } - - private fun pushString(string: String) { - string.toCharArray().forEach { pushChar(it) } - } - - private fun pushChar(char: Char) { - inputStack.push(char) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermSessionCallback.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/TermSessionCallback.kt deleted file mode 100644 index 53f4ddf..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermSessionCallback.kt +++ /dev/null @@ -1,56 +0,0 @@ -package io.neoterm.frontend.session.shell.client - -import android.content.ClipData -import android.content.ClipboardManager -import android.content.Context -import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.session.shell.ShellTermSession - -/** - * @author kiva - */ -class TermSessionCallback : TerminalSession.SessionChangedCallback { - var termSessionData: TermSessionData? = null - - var bellController: BellController? = null - - override fun onTextChanged(changedSession: TerminalSession?) { - termSessionData?.termView?.onScreenUpdated() - } - - override fun onTitleChanged(changedSession: TerminalSession?) { - if (changedSession?.title != null) { - termSessionData?.termUI?.requireUpdateTitle(changedSession.title) - } - } - - override fun onSessionFinished(finishedSession: TerminalSession?) { - termSessionData?.termUI?.requireOnSessionFinished() - } - - override fun onClipboardText(session: TerminalSession?, text: String?) { - val termView = termSessionData?.termView - if (termView != null) { - val clipboard = termView.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager - clipboard.primaryClip = ClipData.newPlainText("", text) - } - } - - override fun onBell(session: TerminalSession?) { - val termView = termSessionData?.termView ?: return - val shellSession = session as ShellTermSession - - if (bellController == null) { - bellController = BellController() - } - - bellController?.bellOrVibrate(termView.context, shellSession) - } - - override fun onColorsChanged(session: TerminalSession?) { - val termView = termSessionData?.termView - if (session != null && termView != null) { - termView.onScreenUpdated() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermUiPresenter.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/TermUiPresenter.kt deleted file mode 100644 index b1c1ea3..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermUiPresenter.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.neoterm.frontend.session.shell.client - -/** - * @author kiva - */ -interface TermUiPresenter { - fun requireClose() - fun requireToggleFullScreen() - fun requirePaste() - fun requireUpdateTitle(title: String?) - fun requireOnSessionFinished() - fun requireHideIme() - fun requireFinishAutoCompletion(): Boolean - fun requireCreateNew() - fun requireSwitchToPrevious() - fun requireSwitchToNext() - fun requireSwitchTo(index: Int) -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/CreateNewSessionEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/CreateNewSessionEvent.kt deleted file mode 100644 index c42f28a..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/CreateNewSessionEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -/** - * @author kiva - */ -class CreateNewSessionEvent \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/SwitchIndexedSessionEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/SwitchIndexedSessionEvent.kt deleted file mode 100644 index 9287238..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/SwitchIndexedSessionEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -/** - * @author kiva - */ -class SwitchIndexedSessionEvent(val index: Int) \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/SwitchSessionEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/SwitchSessionEvent.kt deleted file mode 100644 index 1fce05e..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/SwitchSessionEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -/** - * @author kiva - */ -class SwitchSessionEvent(val toNext: Boolean) \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/TabCloseEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/TabCloseEvent.kt deleted file mode 100644 index 2a0104b..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/TabCloseEvent.kt +++ /dev/null @@ -1,9 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -import io.neoterm.ui.term.tab.TermTab - -/** - * @author kiva - */ - -class TabCloseEvent(var termTab: TermTab) diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/TitleChangedEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/TitleChangedEvent.kt deleted file mode 100644 index 5a7404e..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/TitleChangedEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -/** - * @author kiva - */ -class TitleChangedEvent(val title: String) \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/ToggleFullScreenEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/ToggleFullScreenEvent.kt deleted file mode 100644 index d25c014..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/ToggleFullScreenEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -/** - * @author kiva - */ -class ToggleFullScreenEvent() \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/ToggleImeEvent.kt b/app/src/main/java/io/neoterm/frontend/session/shell/client/event/ToggleImeEvent.kt deleted file mode 100644 index 363e9af..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/event/ToggleImeEvent.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.neoterm.frontend.session.shell.client.event - -/** - * @author kiva - */ -class ToggleImeEvent \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermSessionData.kt b/app/src/main/java/io/neoterm/frontend/session/terminal/data.kt similarity index 65% rename from app/src/main/java/io/neoterm/frontend/session/shell/client/TermSessionData.kt rename to app/src/main/java/io/neoterm/frontend/session/terminal/data.kt index 6e940e7..8ace818 100644 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermSessionData.kt +++ b/app/src/main/java/io/neoterm/frontend/session/terminal/data.kt @@ -1,15 +1,12 @@ -package io.neoterm.frontend.session.shell.client +package io.neoterm.frontend.session.terminal import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.completion.listener.OnAutoCompleteListener -import io.neoterm.frontend.session.shell.ShellProfile -import io.neoterm.frontend.session.shell.ShellTermSession -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.extrakey.ExtraKeysView +import io.neoterm.component.completion.OnAutoCompleteListener +import io.neoterm.component.session.ShellProfile +import io.neoterm.component.session.ShellTermSession +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.extrakey.ExtraKeysView -/** - * @author kiva - */ class TermSessionData { var termSession: TerminalSession? = null var sessionCallback: TermSessionCallback? = null @@ -58,4 +55,18 @@ class TermSessionData { this.termView = termView this.extraKeysView = eks } -} \ No newline at end of file +} + +interface TermUiPresenter { + fun requireClose() + fun requireToggleFullScreen() + fun requirePaste() + fun requireUpdateTitle(title: String?) + fun requireOnSessionFinished() + fun requireHideIme() + fun requireFinishAutoCompletion(): Boolean + fun requireCreateNew() + fun requireSwitchToPrevious() + fun requireSwitchToNext() + fun requireSwitchTo(index: Int) +} diff --git a/app/src/main/java/io/neoterm/frontend/session/terminal/events.kt b/app/src/main/java/io/neoterm/frontend/session/terminal/events.kt new file mode 100644 index 0000000..444e376 --- /dev/null +++ b/app/src/main/java/io/neoterm/frontend/session/terminal/events.kt @@ -0,0 +1,11 @@ +package io.neoterm.frontend.session.terminal + +import io.neoterm.ui.term.TermTab + +class CreateNewSessionEvent +class SwitchIndexedSessionEvent(val index: Int) +class SwitchSessionEvent(val toNext: Boolean) +class TabCloseEvent(val termTab: TermTab) +class TitleChangedEvent(val title: String) +class ToggleFullScreenEvent +class ToggleImeEvent diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/BasicViewClient.kt b/app/src/main/java/io/neoterm/frontend/session/terminal/term-basic.kt similarity index 64% rename from app/src/main/java/io/neoterm/frontend/session/shell/client/BasicViewClient.kt rename to app/src/main/java/io/neoterm/frontend/session/terminal/term-basic.kt index b1bd0d6..7b6f513 100644 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/BasicViewClient.kt +++ b/app/src/main/java/io/neoterm/frontend/session/terminal/term-basic.kt @@ -1,17 +1,40 @@ -package io.neoterm.frontend.session.shell.client +package io.neoterm.frontend.session.terminal import android.content.Context import android.view.KeyEvent import android.view.MotionEvent import android.view.inputmethod.InputMethodManager import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.TerminalViewClient +import io.neoterm.component.config.NeoPreference +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.TerminalViewClient + +open class BasicSessionCallback(var terminalView: TerminalView) : TerminalSession.SessionChangedCallback { + override fun onTextChanged(changedSession: TerminalSession?) { + if (changedSession != null) { + terminalView.onScreenUpdated() + } + } + + override fun onTitleChanged(changedSession: TerminalSession?) { + } + + override fun onSessionFinished(finishedSession: TerminalSession?) { + } + + override fun onClipboardText(session: TerminalSession?, text: String?) { + } + + override fun onBell(session: TerminalSession?) { + } + + override fun onColorsChanged(session: TerminalSession?) { + if (session != null) { + terminalView.onScreenUpdated() + } + } +} -/** - * @author kiva - */ class BasicViewClient(val terminalView: TerminalView) : TerminalViewClient { override fun onScale(scale: Float): Float { if (scale < 0.9f || scale > 1.1f) { diff --git a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermViewClient.kt b/app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt similarity index 55% rename from app/src/main/java/io/neoterm/frontend/session/shell/client/TermViewClient.kt rename to app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt index 5392031..9fa7859 100644 --- a/app/src/main/java/io/neoterm/frontend/session/shell/client/TermViewClient.kt +++ b/app/src/main/java/io/neoterm/frontend/session/terminal/term-standard.kt @@ -1,20 +1,30 @@ -package io.neoterm.frontend.session.shell.client +package io.neoterm.frontend.session.terminal +import android.content.ClipData +import android.content.ClipboardManager import android.content.Context import android.media.AudioManager +import android.media.SoundPool +import android.os.Vibrator +import android.util.Log import android.view.InputDevice import android.view.KeyEvent import android.view.MotionEvent import android.view.View import android.view.inputmethod.InputMethodManager +import io.neoterm.BuildConfig +import io.neoterm.R import io.neoterm.backend.KeyHandler import io.neoterm.backend.TerminalSession +import io.neoterm.component.ComponentManager +import io.neoterm.component.completion.* +import io.neoterm.component.config.NeoPreference import io.neoterm.component.extrakey.ExtraKeyComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.session.shell.ShellTermSession -import io.neoterm.frontend.terminal.TerminalViewClient - +import io.neoterm.component.session.ShellTermSession +import io.neoterm.frontend.completion.CandidatePopupWindow +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.TerminalViewClient +import java.util.* /** * @author kiva @@ -267,4 +277,234 @@ class TermViewClient(val context: Context) : TerminalViewClient { NeoPreference.store(NeoPreference.KEY_FONT_SIZE, fontSize) } } -} \ No newline at end of file +} + +/** + * @author kiva + */ +class TermSessionCallback : TerminalSession.SessionChangedCallback { + var termSessionData: TermSessionData? = null + + var bellController: BellController? = null + + override fun onTextChanged(changedSession: TerminalSession?) { + termSessionData?.termView?.onScreenUpdated() + } + + override fun onTitleChanged(changedSession: TerminalSession?) { + if (changedSession?.title != null) { + termSessionData?.termUI?.requireUpdateTitle(changedSession.title) + } + } + + override fun onSessionFinished(finishedSession: TerminalSession?) { + termSessionData?.termUI?.requireOnSessionFinished() + } + + override fun onClipboardText(session: TerminalSession?, text: String?) { + val termView = termSessionData?.termView + if (termView != null) { + val clipboard = termView.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + clipboard.primaryClip = ClipData.newPlainText("", text) + } + } + + override fun onBell(session: TerminalSession?) { + val termView = termSessionData?.termView ?: return + val shellSession = session as ShellTermSession + + if (bellController == null) { + bellController = BellController() + } + + bellController?.bellOrVibrate(termView.context, shellSession) + } + + override fun onColorsChanged(session: TerminalSession?) { + val termView = termSessionData?.termView + if (session != null && termView != null) { + termView.onScreenUpdated() + } + } +} + +class BellController { + companion object { + private val BELL_DELAY_MS = 100 + } + + private var bellId: Int = 0 + private var soundPool: SoundPool? = null + private var lastBellTime = 0L + + fun bellOrVibrate(context: Context, session: ShellTermSession) { + val currentTime = System.currentTimeMillis() + if (currentTime - lastBellTime < BELL_DELAY_MS) { + return + } + lastBellTime = currentTime + + if (session.shellProfile.enableBell) { + if (soundPool == null) { + soundPool = SoundPool.Builder().setMaxStreams(1).build() + bellId = soundPool!!.load(context, R.raw.bell, 1) + } + soundPool?.play(bellId, 1f, 1f, 0, 0, 1f) + } + + if (session.shellProfile.enableVibrate) { + val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + vibrator.vibrate(100) + } + } +} + +class TermCompleteListener(var terminalView: TerminalView?) : OnAutoCompleteListener, OnCandidateSelectedListener { + private val inputStack = Stack() + private var popupWindow: CandidatePopupWindow? = null + private var lastCompletedIndex = 0 + + override fun onKeyCode(keyCode: Int, keyMod: Int) { + when (keyCode) { + KeyEvent.KEYCODE_DEL -> { + popChar() + fixLastCompletedIndex() + triggerCompletion() + } + + KeyEvent.KEYCODE_ENTER -> { + clearChars() + popupWindow?.dismiss() + } + } + } + + private fun fixLastCompletedIndex() { + val currentText = getCurrentEditingText() + lastCompletedIndex = minOf(lastCompletedIndex, currentText.length - 1) + } + + override fun onCompletionRequired(newText: String?) { + if (newText == null || newText.isEmpty()) { + return + } + pushString(newText) + triggerCompletion() + } + + override fun onCleanUp() { + popupWindow?.dismiss() + popupWindow?.cleanup() + popupWindow = null + terminalView = null + } + + override fun onFinishCompletion(): Boolean { + val popWindow = popupWindow ?: return false + + if (popWindow.isShowing()) { + popWindow.dismiss() + return true + } + return false + } + + override fun onCandidateSelected(candidate: CompletionCandidate) { + val session = terminalView?.currentSession ?: return + val textNeedCompletion = getCurrentEditingText().substring(lastCompletedIndex + 1) + val newText = candidate.completeString + + val deleteLength = newText.indexOf(textNeedCompletion) + textNeedCompletion.length + if (deleteLength > 0) { + for (i in 0 until deleteLength) { + session.write("\b") + popChar() + } + } + + if (BuildConfig.DEBUG) { + Log.e( + "NeoTerm-AC", + "currentEditing: $textNeedCompletion, " + + "deleteLength: $deleteLength, completeString: $newText" + ) + } + + pushString(newText) + session.write(newText) + // Trigger next completion + lastCompletedIndex = inputStack.size + triggerCompletion() + } + + private fun triggerCompletion() { + val text = getCurrentEditingText() + if (text.isEmpty()) { + return + } + + val result = CompletionManager.tryCompleteFor(text) + if (!result.hasResult()) { + // A provider accepted the task + // But no candidates are provided + // Give it zero angrily! + result.markScore(0) + onFinishCompletion() + return + } + showAutoCompleteCandidates(result) + } + + private fun showAutoCompleteCandidates(result: CompletionResult) { + val termView = terminalView + var popWindow = popupWindow + + if (termView == null) { + return + } + + if (popWindow == null) { + popWindow = CandidatePopupWindow(termView.context) + popWindow.onCandidateSelectedListener = this + this.popupWindow = popWindow + } + + popWindow.candidates = result.candidates + popWindow.show(termView) + } + + private fun getCurrentEditingText(): String { + val builder = StringBuilder() + val size = inputStack.size + var start = inputStack.lastIndexOf(' ') + if (start < 0) { + // Yes, it is -1, we will do `start + 1` below. + start = -1 + } + + IntRange(start + 1, size - 1) + .map { inputStack[it] } + .takeWhile { !(it == 0.toChar() || it == ' ') } + .forEach { builder.append(it) } + return builder.toString() + } + + private fun clearChars() { + inputStack.clear() + lastCompletedIndex = 0 + } + + private fun popChar() { + if (inputStack.isNotEmpty()) { + inputStack.pop() + } + } + + private fun pushString(string: String) { + string.toCharArray().forEach { pushChar(it) } + } + + private fun pushChar(char: Char) { + inputStack.push(char) + } +} diff --git a/app/src/main/java/io/neoterm/frontend/terminal/GestureAndScaleRecognizer.kt b/app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt old mode 100755 new mode 100644 similarity index 99% rename from app/src/main/java/io/neoterm/frontend/terminal/GestureAndScaleRecognizer.kt rename to app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt index 6ed3b32..0e8167d --- a/app/src/main/java/io/neoterm/frontend/terminal/GestureAndScaleRecognizer.kt +++ b/app/src/main/java/io/neoterm/frontend/session/view/GestureAndScaleRecognizer.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.terminal +package io.neoterm.frontend.session.view import android.content.Context import android.view.GestureDetector diff --git a/app/src/main/java/io/neoterm/frontend/terminal/TerminalRenderer.java b/app/src/main/java/io/neoterm/frontend/session/view/TerminalRenderer.java old mode 100755 new mode 100644 similarity index 99% rename from app/src/main/java/io/neoterm/frontend/terminal/TerminalRenderer.java rename to app/src/main/java/io/neoterm/frontend/session/view/TerminalRenderer.java index a8ee1f5..bb9296d --- a/app/src/main/java/io/neoterm/frontend/terminal/TerminalRenderer.java +++ b/app/src/main/java/io/neoterm/frontend/session/view/TerminalRenderer.java @@ -1,4 +1,4 @@ -package io.neoterm.frontend.terminal; +package io.neoterm.frontend.session.view; import android.graphics.Canvas; import android.graphics.Paint; diff --git a/app/src/main/java/io/neoterm/frontend/terminal/TerminalView.java b/app/src/main/java/io/neoterm/frontend/session/view/TerminalView.java old mode 100755 new mode 100644 similarity index 96% rename from app/src/main/java/io/neoterm/frontend/terminal/TerminalView.java rename to app/src/main/java/io/neoterm/frontend/session/view/TerminalView.java index 9127825..3b28ce9 --- a/app/src/main/java/io/neoterm/frontend/terminal/TerminalView.java +++ b/app/src/main/java/io/neoterm/frontend/session/view/TerminalView.java @@ -1,4 +1,4 @@ -package io.neoterm.frontend.terminal; +package io.neoterm.frontend.session.view; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -23,7 +23,7 @@ import android.view.inputmethod.InputConnection; import android.widget.Scroller; import io.neoterm.R; import io.neoterm.backend.*; -import io.neoterm.frontend.completion.listener.OnAutoCompleteListener; +import io.neoterm.component.completion.OnAutoCompleteListener; /** * View displaying and interacting with a {@link TerminalSession}. @@ -1032,45 +1032,38 @@ public final class TerminalView extends View { @Override public void onDestroyActionMode(ActionMode mode) { } - }; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mActionMode = startActionMode(new ActionMode.Callback2() { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - return callback.onCreateActionMode(mode, menu); - } + mActionMode = startActionMode(new ActionMode.Callback2() { + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + return callback.onCreateActionMode(mode, menu); + } - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - return callback.onActionItemClicked(mode, item); - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - // Ignore. - } - - @Override - public void onGetContentRect(ActionMode mode, View view, Rect outRect) { - int x1 = Math.round(mSelX1 * mRenderer.mFontWidth); - int x2 = Math.round(mSelX2 * mRenderer.mFontWidth); - int y1 = Math.round((mSelY1 - mTopRow) * mRenderer.mFontLineSpacing); - int y2 = Math.round((mSelY2 + 1 - mTopRow) * mRenderer.mFontLineSpacing); - outRect.set(Math.min(x1, x2), y1, Math.max(x1, x2), y2); - } - }, ActionMode.TYPE_FLOATING); - } else { - mActionMode = startActionMode(callback); - } + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + return callback.onActionItemClicked(mode, item); + } + @Override + public void onDestroyActionMode(ActionMode mode) { + // Ignore. + } + @Override + public void onGetContentRect(ActionMode mode, View view, Rect outRect) { + int x1 = Math.round(mSelX1 * mRenderer.mFontWidth); + int x2 = Math.round(mSelX2 * mRenderer.mFontWidth); + int y1 = Math.round((mSelY1 - mTopRow) * mRenderer.mFontLineSpacing); + int y2 = Math.round((mSelY2 + 1 - mTopRow) * mRenderer.mFontLineSpacing); + outRect.set(Math.min(x1, x2), y1, Math.max(x1, x2), y2); + } + }, ActionMode.TYPE_FLOATING); invalidate(); } else { mActionMode.finish(); diff --git a/app/src/main/java/io/neoterm/frontend/terminal/TerminalViewClient.java b/app/src/main/java/io/neoterm/frontend/session/view/TerminalViewClient.java old mode 100755 new mode 100644 similarity index 96% rename from app/src/main/java/io/neoterm/frontend/terminal/TerminalViewClient.java rename to app/src/main/java/io/neoterm/frontend/session/view/TerminalViewClient.java index b5a6eb1..451cbdc --- a/app/src/main/java/io/neoterm/frontend/terminal/TerminalViewClient.java +++ b/app/src/main/java/io/neoterm/frontend/session/view/TerminalViewClient.java @@ -1,4 +1,4 @@ -package io.neoterm.frontend.terminal; +package io.neoterm.frontend.session.view; import android.view.KeyEvent; import android.view.MotionEvent; @@ -11,7 +11,6 @@ import io.neoterm.backend.TerminalSession; *

*/ public interface TerminalViewClient { - /** * Callback function on scale events according to {@link ScaleGestureDetector#getScaleFactor()}. */ diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/combine/CombinedSequence.kt b/app/src/main/java/io/neoterm/frontend/session/view/extrakey/CombinedSequence.kt similarity index 91% rename from app/src/main/java/io/neoterm/frontend/terminal/extrakey/combine/CombinedSequence.kt rename to app/src/main/java/io/neoterm/frontend/session/view/extrakey/CombinedSequence.kt index d3227fc..4e6b91d 100644 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/combine/CombinedSequence.kt +++ b/app/src/main/java/io/neoterm/frontend/session/view/extrakey/CombinedSequence.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.terminal.extrakey.combine +package io.neoterm.frontend.session.view.extrakey /** * @@ -26,4 +26,4 @@ class CombinedSequence private constructor() { return seq } } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/ExtraKeysView.kt b/app/src/main/java/io/neoterm/frontend/session/view/extrakey/ExtraKeysView.kt old mode 100755 new mode 100644 similarity index 91% rename from app/src/main/java/io/neoterm/frontend/terminal/extrakey/ExtraKeysView.kt rename to app/src/main/java/io/neoterm/frontend/session/view/extrakey/ExtraKeysView.kt index ee22fe0..3dd83e9 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/ExtraKeysView.kt +++ b/app/src/main/java/io/neoterm/frontend/session/view/extrakey/ExtraKeysView.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.terminal.extrakey +package io.neoterm.frontend.session.view.extrakey import android.content.Context import android.graphics.Typeface @@ -7,21 +7,15 @@ import android.view.* import android.widget.GridLayout import android.widget.LinearLayout import io.neoterm.R +import io.neoterm.component.ComponentManager +import io.neoterm.component.config.NeoPreference +import io.neoterm.component.config.NeoTermPath import io.neoterm.component.extrakey.ExtraKeyComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.session.shell.client.event.ToggleImeEvent -import io.neoterm.frontend.terminal.extrakey.button.ControlButton -import io.neoterm.frontend.terminal.extrakey.button.IExtraButton -import io.neoterm.frontend.terminal.extrakey.button.RepeatableButton -import io.neoterm.frontend.terminal.extrakey.button.StatedControlButton -import io.neoterm.frontend.terminal.extrakey.impl.ArrowButton +import io.neoterm.frontend.session.terminal.ToggleImeEvent import org.greenrobot.eventbus.EventBus import java.io.File class ExtraKeysView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { - companion object { private val ESC = ControlButton(IExtraButton.KEY_ESC) private val TAB = ControlButton(IExtraButton.KEY_TAB) @@ -68,7 +62,7 @@ class ExtraKeysView(context: Context, attrs: AttributeSet) : LinearLayout(contex init { alpha = DEFAULT_ALPHA gravity = Gravity.TOP - orientation = LinearLayout.VERTICAL + orientation = VERTICAL typeface = Typeface.createFromAsset(context.assets, "eks_font.ttf") extraKeyComponent = ComponentManager.getComponent() diff --git a/app/src/main/java/io/neoterm/frontend/session/view/extrakey/buttons.kt b/app/src/main/java/io/neoterm/frontend/session/view/extrakey/buttons.kt new file mode 100644 index 0000000..9955457 --- /dev/null +++ b/app/src/main/java/io/neoterm/frontend/session/view/extrakey/buttons.kt @@ -0,0 +1,222 @@ +package io.neoterm.frontend.session.view.extrakey + +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.AttributeSet +import android.view.KeyEvent +import android.view.MotionEvent +import android.view.View +import android.widget.Button +import android.widget.ToggleButton +import androidx.appcompat.widget.AppCompatButton +import io.neoterm.R +import io.neoterm.frontend.session.view.TerminalView + +/** + * @author kiva + */ + +open class ControlButton(text: String) : TextButton(text, false) + +/** + * @author kiva + */ + +abstract class IExtraButton : View.OnClickListener { + + var buttonKeys: CombinedSequence? = null + var displayText: String? = null + + override fun toString(): String { + return "${this.javaClass.simpleName} { display: $displayText, code: ${buttonKeys?.keys} }" + } + + abstract override fun onClick(view: View) + + abstract fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button + + companion object { + const val KEY_ESC = "Esc" + const val KEY_TAB = "Tab" + const val KEY_CTRL = "Ctrl" + const val KEY_ALT = "Alt" + const val KEY_PAGE_UP = "PgUp" + const val KEY_PAGE_DOWN = "PgDn" + const val KEY_HOME = "Home" + const val KEY_END = "End" + const val KEY_ARROW_UP_TEXT = "Up" + const val KEY_ARROW_DOWN_TEXT = "Down" + const val KEY_ARROW_LEFT_TEXT = "Left" + const val KEY_ARROW_RIGHT_TEXT = "Right" + const val KEY_SHOW_ALL_BUTTONS = "···" + const val KEY_TOGGLE_IME = "Im" + + const val KEY_ARROW_UP = "▲" + const val KEY_ARROW_DOWN = "▼" + const val KEY_ARROW_LEFT = "◀" + const val KEY_ARROW_RIGHT = "▶" + + var NORMAL_TEXT_COLOR = 0xFFFFFFFF.toInt() + var SELECTED_TEXT_COLOR = 0xFF80DEEA.toInt() + + fun sendKey(view: View, keyName: String) { + var keyCode = 0 + var chars = "" + when (keyName) { + KEY_ESC -> keyCode = KeyEvent.KEYCODE_ESCAPE + KEY_TAB -> keyCode = KeyEvent.KEYCODE_TAB + KEY_ARROW_UP -> keyCode = KeyEvent.KEYCODE_DPAD_UP + KEY_ARROW_LEFT -> keyCode = KeyEvent.KEYCODE_DPAD_LEFT + KEY_ARROW_RIGHT -> keyCode = KeyEvent.KEYCODE_DPAD_RIGHT + KEY_ARROW_DOWN -> keyCode = KeyEvent.KEYCODE_DPAD_DOWN + KEY_ARROW_UP_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_UP + KEY_ARROW_LEFT_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_LEFT + KEY_ARROW_RIGHT_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_RIGHT + KEY_ARROW_DOWN_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_DOWN + KEY_PAGE_UP -> keyCode = KeyEvent.KEYCODE_PAGE_UP + KEY_PAGE_DOWN -> keyCode = KeyEvent.KEYCODE_PAGE_DOWN + KEY_HOME -> keyCode = KeyEvent.KEYCODE_MOVE_HOME + KEY_END -> keyCode = KeyEvent.KEYCODE_MOVE_END + "―" -> chars = "-" + else -> chars = keyName + } + + if (keyCode > 0) { + view.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, keyCode)) + view.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, keyCode)) + } else if (chars.isNotEmpty()) { + val terminalView = view.findViewById(R.id.terminal_view) + val session = terminalView.currentSession + session?.write(chars) + } + } + } +} + +/** + * @author kiva + */ +open class RepeatableButton(buttonText: String) : ControlButton(buttonText) { + + override fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button { + return RepeatableButtonWidget(context, attrs, defStyleAttr) + } + + private class RepeatableButtonWidget(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : + AppCompatButton(context!!, attrs, defStyleAttr) { + + /** + * Milliseconds how long we trigger an action + * when long pressing + */ + private val LONG_CLICK_ACTION_INTERVAL = 100L + + private var isMotionEventUp = true + + var mHandler: Handler = object : Handler(Looper.getMainLooper()) { + override fun handleMessage(msg: android.os.Message) { + if (!isMotionEventUp && isEnabled) { + performClick() + this.sendEmptyMessageDelayed(0, LONG_CLICK_ACTION_INTERVAL) + } + } + } + + init { + this.setOnLongClickListener { + isMotionEventUp = false + mHandler.sendEmptyMessage(0) + false + } + this.setOnTouchListener { _, event -> + if (event.action == MotionEvent.ACTION_UP) { + isMotionEventUp = true + } + false + } + } + + override fun performClick(): Boolean { + return super.performClick() + } + } +} + +/** + * @author kiva + */ + +open class StatedControlButton @JvmOverloads constructor(text: String, var initState: Boolean = false) : + ControlButton(text) { + var toggleButton: ToggleButton? = null + + override fun onClick(view: View) { + setStatus(toggleButton?.isChecked) + } + + override fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button { + val outerButton = ToggleButton(context, null, android.R.attr.buttonBarButtonStyle) + + outerButton.isClickable = true + if (initState) { + outerButton.isChecked = true + outerButton.setTextColor(SELECTED_TEXT_COLOR) + } + + this.toggleButton = outerButton + return outerButton + } + + private fun setStatus(status: Boolean?) { + val button = toggleButton + if (button != null && status != null) { + button.isChecked = status + button.setTextColor( + if (status) SELECTED_TEXT_COLOR + else NORMAL_TEXT_COLOR + ) + } + } + + fun readState(): Boolean { + val button = toggleButton ?: return false + + if (button.isPressed) return true + val result = button.isChecked + if (result) { + button.isChecked = false + button.setTextColor(NORMAL_TEXT_COLOR) + } + return result + } +} + +/** + * @author kiva + */ + +open class TextButton constructor(text: String, val withEnter: Boolean = false) : IExtraButton() { + init { + this.buttonKeys = CombinedSequence.solveString(text) + this.displayText = text + } + + override fun onClick(view: View) { + buttonKeys!!.keys.forEach { + sendKey(view, it) + } + if (withEnter) { + sendKey(view, "\n") + } + } + + override fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button { + return Button(context, attrs, defStyleAttr) + } +} + +/** + * @author kiva + */ +class ArrowButton(arrowText: String) : RepeatableButton(arrowText) diff --git a/app/src/main/java/io/neoterm/frontend/session/xorg/XParameter.java b/app/src/main/java/io/neoterm/frontend/session/xorg/XParameter.java deleted file mode 100644 index 5f67a17..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/xorg/XParameter.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.neoterm.frontend.session.xorg; - -/** - * @author kiva - */ - -public class XParameter { -} diff --git a/app/src/main/java/io/neoterm/frontend/session/xorg/client/XSessionData.kt b/app/src/main/java/io/neoterm/frontend/session/xorg/client/XSessionData.kt deleted file mode 100644 index aa9cac2..0000000 --- a/app/src/main/java/io/neoterm/frontend/session/xorg/client/XSessionData.kt +++ /dev/null @@ -1,25 +0,0 @@ -package io.neoterm.frontend.session.xorg.client - -import android.view.View -import android.widget.FrameLayout -import io.neoterm.NeoAudioThread -import io.neoterm.NeoGLView -import io.neoterm.xorg.NeoXorgViewClient -import java.util.* - -/** - * @author kiva - */ -class XSessionData { - var videoLayout: FrameLayout? = null - var audioThread: NeoAudioThread? = null - var screenKeyboard: View? = null - var glView: NeoGLView? = null - - var isPaused = false - var client: NeoXorgViewClient? = null - - var keyboardWithoutTextInputShown = false - var screenKeyboardHintMessage: String? = null - var textInput = LinkedList() -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/ControlButton.kt b/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/ControlButton.kt deleted file mode 100644 index e9a1ff7..0000000 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/ControlButton.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.neoterm.frontend.terminal.extrakey.button - -/** - * @author kiva - */ - -open class ControlButton(text: String) : TextButton(text, false) \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/IExtraButton.kt b/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/IExtraButton.kt deleted file mode 100644 index 1a0b1dd..0000000 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/IExtraButton.kt +++ /dev/null @@ -1,85 +0,0 @@ -package io.neoterm.frontend.terminal.extrakey.button - -import android.content.Context -import android.util.AttributeSet -import android.view.KeyEvent -import android.view.View -import android.widget.Button -import io.neoterm.R -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.extrakey.combine.CombinedSequence - -/** - * @author kiva - */ - -abstract class IExtraButton : View.OnClickListener { - - var buttonKeys: CombinedSequence? = null - var displayText: String? = null - - override fun toString(): String { - return "${this.javaClass.simpleName} { display: $displayText, code: ${buttonKeys?.keys} }" - } - - abstract override fun onClick(view: View) - - abstract fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button - - companion object { - val KEY_ESC = "Esc" - val KEY_TAB = "Tab" - val KEY_CTRL = "Ctrl" - val KEY_ALT = "Alt" - val KEY_PAGE_UP = "PgUp" - val KEY_PAGE_DOWN = "PgDn" - val KEY_HOME = "Home" - val KEY_END = "End" - val KEY_ARROW_UP_TEXT = "Up" - val KEY_ARROW_DOWN_TEXT = "Down" - val KEY_ARROW_LEFT_TEXT = "Left" - val KEY_ARROW_RIGHT_TEXT = "Right" - val KEY_SHOW_ALL_BUTTONS = "···" - val KEY_TOGGLE_IME = "Im" - - val KEY_ARROW_UP = "▲" - val KEY_ARROW_DOWN = "▼" - val KEY_ARROW_LEFT = "◀" - val KEY_ARROW_RIGHT = "▶" - - var NORMAL_TEXT_COLOR = 0xFFFFFFFF.toInt() - var SELECTED_TEXT_COLOR = 0xFF80DEEA.toInt() - - fun sendKey(view: View, keyName: String) { - var keyCode = 0 - var chars = "" - when (keyName) { - KEY_ESC -> keyCode = KeyEvent.KEYCODE_ESCAPE - KEY_TAB -> keyCode = KeyEvent.KEYCODE_TAB - KEY_ARROW_UP -> keyCode = KeyEvent.KEYCODE_DPAD_UP - KEY_ARROW_LEFT -> keyCode = KeyEvent.KEYCODE_DPAD_LEFT - KEY_ARROW_RIGHT -> keyCode = KeyEvent.KEYCODE_DPAD_RIGHT - KEY_ARROW_DOWN -> keyCode = KeyEvent.KEYCODE_DPAD_DOWN - KEY_ARROW_UP_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_UP - KEY_ARROW_LEFT_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_LEFT - KEY_ARROW_RIGHT_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_RIGHT - KEY_ARROW_DOWN_TEXT -> keyCode = KeyEvent.KEYCODE_DPAD_DOWN - KEY_PAGE_UP -> keyCode = KeyEvent.KEYCODE_PAGE_UP - KEY_PAGE_DOWN -> keyCode = KeyEvent.KEYCODE_PAGE_DOWN - KEY_HOME -> keyCode = KeyEvent.KEYCODE_MOVE_HOME - KEY_END -> keyCode = KeyEvent.KEYCODE_MOVE_END - "―" -> chars = "-" - else -> chars = keyName - } - - if (keyCode > 0) { - view.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, keyCode)) - view.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, keyCode)) - } else if (chars.isNotEmpty()) { - val terminalView = view.findViewById(R.id.terminal_view) - val session = terminalView.currentSession - session?.write(chars) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/RepeatableButton.kt b/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/RepeatableButton.kt deleted file mode 100644 index 302a58e..0000000 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/RepeatableButton.kt +++ /dev/null @@ -1,59 +0,0 @@ -package io.neoterm.frontend.terminal.extrakey.button - -import android.content.Context -import android.os.Handler -import android.os.Looper -import android.util.AttributeSet -import android.view.MotionEvent -import android.widget.Button -import androidx.appcompat.widget.AppCompatButton - - -/** - * @author kiva - */ -open class RepeatableButton(buttonText: String) : ControlButton(buttonText) { - - override fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button { - return RepeatableButtonWidget(context, attrs, defStyleAttr) - } - - private class RepeatableButtonWidget(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : - AppCompatButton(context!!, attrs, defStyleAttr) { - - /** - * Milliseconds how long we trigger an action - * when long pressing - */ - private val LONG_CLICK_ACTION_INTERVAL = 100L - - private var isMotionEventUp = true - - var mHandler: Handler = object : Handler(Looper.getMainLooper()) { - override fun handleMessage(msg: android.os.Message) { - if (!isMotionEventUp && isEnabled) { - performClick() - this.sendEmptyMessageDelayed(0, LONG_CLICK_ACTION_INTERVAL) - } - } - } - - init { - this.setOnLongClickListener { - isMotionEventUp = false - mHandler.sendEmptyMessage(0) - false - } - this.setOnTouchListener { _, event -> - if (event.action == MotionEvent.ACTION_UP) { - isMotionEventUp = true - } - false - } - } - - override fun performClick(): Boolean { - return super.performClick() - } - } -} diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/StatedControlButton.kt b/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/StatedControlButton.kt deleted file mode 100644 index f5e1701..0000000 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/StatedControlButton.kt +++ /dev/null @@ -1,56 +0,0 @@ -package io.neoterm.frontend.terminal.extrakey.button - -import android.content.Context -import android.util.AttributeSet -import android.view.View -import android.widget.Button -import android.widget.ToggleButton - -/** - * @author kiva - */ - -open class StatedControlButton @JvmOverloads constructor(text: String, var initState: Boolean = false) : - ControlButton(text) { - var toggleButton: ToggleButton? = null - - override fun onClick(view: View) { - setStatus(toggleButton?.isChecked) - } - - override fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button { - val outerButton = ToggleButton(context, null, android.R.attr.buttonBarButtonStyle) - - outerButton.isClickable = true - if (initState) { - outerButton.isChecked = true - outerButton.setTextColor(IExtraButton.SELECTED_TEXT_COLOR) - } - - this.toggleButton = outerButton - return outerButton - } - - private fun setStatus(status: Boolean?) { - val button = toggleButton - if (button != null && status != null) { - button.isChecked = status - button.setTextColor( - if (status) SELECTED_TEXT_COLOR - else NORMAL_TEXT_COLOR - ) - } - } - - fun readState(): Boolean { - val button = toggleButton ?: return false - - if (button.isPressed) return true - val result = button.isChecked - if (result) { - button.isChecked = false - button.setTextColor(NORMAL_TEXT_COLOR) - } - return result - } -} diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/TextButton.kt b/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/TextButton.kt deleted file mode 100644 index 9191a7e..0000000 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/button/TextButton.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.neoterm.frontend.terminal.extrakey.button - -import android.content.Context -import android.util.AttributeSet -import android.view.View -import android.widget.Button -import io.neoterm.frontend.terminal.extrakey.combine.CombinedSequence - -/** - * @author kiva - */ - -open class TextButton constructor(text: String, val withEnter: Boolean = false) : IExtraButton() { - init { - this.buttonKeys = CombinedSequence.solveString(text) - this.displayText = text - } - - override fun onClick(view: View) { - buttonKeys!!.keys.forEach { - sendKey(view, it) - } - if (withEnter) { - sendKey(view, "\n") - } - } - - override fun makeButton(context: Context?, attrs: AttributeSet?, defStyleAttr: Int): Button { - return Button(context, attrs, defStyleAttr) - } -} diff --git a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/impl/ArrowButton.kt b/app/src/main/java/io/neoterm/frontend/terminal/extrakey/impl/ArrowButton.kt deleted file mode 100644 index 1a6fc01..0000000 --- a/app/src/main/java/io/neoterm/frontend/terminal/extrakey/impl/ArrowButton.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.neoterm.frontend.terminal.extrakey.impl - -import io.neoterm.frontend.terminal.extrakey.button.RepeatableButton - -/** - * @author kiva - */ -class ArrowButton(arrowText: String) : RepeatableButton(arrowText) diff --git a/app/src/main/java/io/neoterm/services/NeoTermService.kt b/app/src/main/java/io/neoterm/services/NeoTermService.kt index c25b492..76ef9e6 100644 --- a/app/src/main/java/io/neoterm/services/NeoTermService.kt +++ b/app/src/main/java/io/neoterm/services/NeoTermService.kt @@ -14,11 +14,11 @@ import androidx.core.app.NotificationCompat import io.neoterm.R import io.neoterm.backend.EmulatorDebug import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.logging.NLog -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.xorg.XParameter -import io.neoterm.frontend.session.xorg.XSession +import io.neoterm.component.session.ShellParameter +import io.neoterm.component.session.XParameter +import io.neoterm.component.session.XSession import io.neoterm.ui.term.NeoTermActivity +import io.neoterm.utils.NLog import io.neoterm.utils.Terminals diff --git a/app/src/main/java/io/neoterm/setup/ResultListener.kt b/app/src/main/java/io/neoterm/setup/ResultListener.kt deleted file mode 100644 index 3546064..0000000 --- a/app/src/main/java/io/neoterm/setup/ResultListener.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.neoterm.setup - -/** - * @author kiva - */ -interface ResultListener { - fun onResult(error: Exception?) -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/setup/SetupThread.java b/app/src/main/java/io/neoterm/setup/SetupThread.java index 00bf47b..42e5103 100644 --- a/app/src/main/java/io/neoterm/setup/SetupThread.java +++ b/app/src/main/java/io/neoterm/setup/SetupThread.java @@ -5,8 +5,8 @@ import android.system.Os; import android.util.Pair; import androidx.appcompat.app.AppCompatActivity; import io.neoterm.backend.EmulatorDebug; -import io.neoterm.frontend.config.NeoTermPath; -import io.neoterm.frontend.logging.NLog; +import io.neoterm.component.config.NeoTermPath; +import io.neoterm.utils.NLog; import java.io.*; import java.util.ArrayList; diff --git a/app/src/main/java/io/neoterm/setup/SourceConnection.java b/app/src/main/java/io/neoterm/setup/SourceConnection.java index 4c73bea..0fe8f89 100644 --- a/app/src/main/java/io/neoterm/setup/SourceConnection.java +++ b/app/src/main/java/io/neoterm/setup/SourceConnection.java @@ -8,8 +8,6 @@ import java.io.InputStream; */ public interface SourceConnection { InputStream getInputStream() throws IOException; - int getSize(); - void close(); } diff --git a/app/src/main/java/io/neoterm/setup/connections.kt b/app/src/main/java/io/neoterm/setup/connections.kt new file mode 100644 index 0000000..8ba120a --- /dev/null +++ b/app/src/main/java/io/neoterm/setup/connections.kt @@ -0,0 +1,113 @@ +package io.neoterm.setup + +import android.content.Context +import android.net.Uri +import java.io.IOException +import java.io.InputStream +import java.net.HttpURLConnection +import java.net.URL + +/** + * @author kiva + */ + +class BackupFileConnection(context: Context, uri: Uri) : LocalFileConnection(context, uri) + +/** + * @author kiva + */ + +open class LocalFileConnection(context: Context, uri: Uri) : OfflineUriConnection(context, uri) + +/** + * @author kiva + */ + +class NetworkConnection(private val sourceUrl: String) : SourceConnection { + private var connection: HttpURLConnection? = null + + @Throws(IOException::class) + override fun getInputStream(): InputStream { + if (connection == null) { + connection = openHttpConnection() + connection!!.connectTimeout = 8000 + connection!!.readTimeout = 8000 + } + return connection!!.inputStream + } + + override fun getSize(): Int { + return if (connection != null) { + connection!!.contentLength + } else 0 + + } + + override fun close() { + if (connection != null) { + connection!!.disconnect() + } + } + + @Throws(IOException::class) + private fun openHttpConnection(): HttpURLConnection { + val arch = SetupHelper.determineArchName() + + return URL("$sourceUrl/boot/$arch.zip").openConnection() as HttpURLConnection + } +} + +/** + * @author kiva + */ + +abstract class OfflineConnection : SourceConnection { + private var inputStream: InputStream? = null + + @Throws(IOException::class) + protected abstract fun openInputStream(): InputStream + + @Throws(IOException::class) + override fun getInputStream(): InputStream { + if (inputStream == null) { + inputStream = openInputStream() + } + return inputStream!! + } + + override fun getSize(): Int { + if (inputStream != null) { + return try { + inputStream!!.available() + } catch (e: IOException) { + e.printStackTrace() + 0 + } + + } + return 0 + } + + override fun close() { + if (inputStream != null) { + try { + inputStream!!.close() + } catch (ignore: IOException) { + ignore.printStackTrace() + } + + } + } +} + +/** + * @author kiva + */ + +open class OfflineUriConnection(private val context: Context, private val uri: Uri) : OfflineConnection() { + + @Throws(IOException::class) + override fun openInputStream(): InputStream { + return context.contentResolver.openInputStream(uri) + } +} diff --git a/app/src/main/java/io/neoterm/setup/connections/BackupFileConnection.kt b/app/src/main/java/io/neoterm/setup/connections/BackupFileConnection.kt deleted file mode 100644 index da71aeb..0000000 --- a/app/src/main/java/io/neoterm/setup/connections/BackupFileConnection.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.neoterm.setup.connections - -import android.content.Context -import android.net.Uri - -/** - * @author kiva - */ - -class BackupFileConnection(context: Context, uri: Uri) : LocalFileConnection(context, uri) diff --git a/app/src/main/java/io/neoterm/setup/connections/LocalFileConnection.kt b/app/src/main/java/io/neoterm/setup/connections/LocalFileConnection.kt deleted file mode 100644 index 37f1dbb..0000000 --- a/app/src/main/java/io/neoterm/setup/connections/LocalFileConnection.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.neoterm.setup.connections - -import android.content.Context -import android.net.Uri - -/** - * @author kiva - */ - -open class LocalFileConnection(context: Context, uri: Uri) : OfflineUriConnection(context, uri) diff --git a/app/src/main/java/io/neoterm/setup/connections/NetworkConnection.kt b/app/src/main/java/io/neoterm/setup/connections/NetworkConnection.kt deleted file mode 100644 index 3b11fc8..0000000 --- a/app/src/main/java/io/neoterm/setup/connections/NetworkConnection.kt +++ /dev/null @@ -1,46 +0,0 @@ -package io.neoterm.setup.connections - -import io.neoterm.setup.SetupHelper -import io.neoterm.setup.SourceConnection -import java.io.IOException -import java.io.InputStream -import java.net.HttpURLConnection -import java.net.URL - -/** - * @author kiva - */ - -class NetworkConnection(private val sourceUrl: String) : SourceConnection { - private var connection: HttpURLConnection? = null - - @Throws(IOException::class) - override fun getInputStream(): InputStream { - if (connection == null) { - connection = openHttpConnection() - connection!!.connectTimeout = 8000 - connection!!.readTimeout = 8000 - } - return connection!!.inputStream - } - - override fun getSize(): Int { - return if (connection != null) { - connection!!.contentLength - } else 0 - - } - - override fun close() { - if (connection != null) { - connection!!.disconnect() - } - } - - @Throws(IOException::class) - private fun openHttpConnection(): HttpURLConnection { - val arch = SetupHelper.determineArchName() - - return URL("$sourceUrl/boot/$arch.zip").openConnection() as HttpURLConnection - } -} diff --git a/app/src/main/java/io/neoterm/setup/connections/OfflineConnection.kt b/app/src/main/java/io/neoterm/setup/connections/OfflineConnection.kt deleted file mode 100644 index a1b8060..0000000 --- a/app/src/main/java/io/neoterm/setup/connections/OfflineConnection.kt +++ /dev/null @@ -1,48 +0,0 @@ -package io.neoterm.setup.connections - -import io.neoterm.setup.SourceConnection -import java.io.IOException -import java.io.InputStream - -/** - * @author kiva - */ - -abstract class OfflineConnection : SourceConnection { - private var inputStream: InputStream? = null - - @Throws(IOException::class) - protected abstract fun openInputStream(): InputStream - - @Throws(IOException::class) - override fun getInputStream(): InputStream { - if (inputStream == null) { - inputStream = openInputStream() - } - return inputStream!! - } - - override fun getSize(): Int { - if (inputStream != null) { - return try { - inputStream!!.available() - } catch (e: IOException) { - e.printStackTrace() - 0 - } - - } - return 0 - } - - override fun close() { - if (inputStream != null) { - try { - inputStream!!.close() - } catch (ignore: IOException) { - ignore.printStackTrace() - } - - } - } -} diff --git a/app/src/main/java/io/neoterm/setup/connections/OfflineUriConnection.kt b/app/src/main/java/io/neoterm/setup/connections/OfflineUriConnection.kt deleted file mode 100644 index 5fa6193..0000000 --- a/app/src/main/java/io/neoterm/setup/connections/OfflineUriConnection.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.neoterm.setup.connections - -import android.content.Context -import android.net.Uri - -import java.io.IOException -import java.io.InputStream - -/** - * @author kiva - */ - -open class OfflineUriConnection(private val context: Context, private val uri: Uri) : OfflineConnection() { - - @Throws(IOException::class) - override fun openInputStream(): InputStream { - return context.contentResolver.openInputStream(uri) - } -} diff --git a/app/src/main/java/io/neoterm/setup/SetupHelper.kt b/app/src/main/java/io/neoterm/setup/setup.kt similarity index 93% rename from app/src/main/java/io/neoterm/setup/SetupHelper.kt rename to app/src/main/java/io/neoterm/setup/setup.kt index 81658a5..1bfca1a 100644 --- a/app/src/main/java/io/neoterm/setup/SetupHelper.kt +++ b/app/src/main/java/io/neoterm/setup/setup.kt @@ -7,10 +7,17 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import io.neoterm.App import io.neoterm.R -import io.neoterm.frontend.config.NeoTermPath +import io.neoterm.component.config.NeoTermPath import java.io.File import java.util.* +/** + * @author kiva + */ +interface ResultListener { + fun onResult(error: Exception?) +} + /** * @author kiva */ @@ -35,8 +42,7 @@ object SetupHelper { progress.max = 100 progress.show() - SetupThread(activity, connection, prefixFile, resultListener, progress) - .start() + SetupThread(activity, connection, prefixFile, resultListener, progress).start() } private fun makeProgressDialog(context: Context): ProgressDialog { diff --git a/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt b/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt index 0e21a34..ef60883 100644 --- a/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt +++ b/app/src/main/java/io/neoterm/ui/customize/BaseCustomizeActivity.kt @@ -6,12 +6,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import io.neoterm.R import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.shell.client.BasicSessionCallback -import io.neoterm.frontend.session.shell.client.BasicViewClient -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.extrakey.ExtraKeysView +import io.neoterm.component.config.NeoTermPath +import io.neoterm.component.session.ShellParameter +import io.neoterm.frontend.session.terminal.BasicSessionCallback +import io.neoterm.frontend.session.terminal.BasicViewClient +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.extrakey.ExtraKeysView import io.neoterm.utils.Terminals /** @@ -56,4 +56,4 @@ open class BaseCustomizeActivity : AppCompatActivity() { } return super.onOptionsItemSelected(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt b/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt index d824943..f21c989 100644 --- a/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt +++ b/app/src/main/java/io/neoterm/ui/customize/ColorSchemeActivity.kt @@ -18,12 +18,10 @@ import es.dmoral.coloromatic.IndicatorMode import es.dmoral.coloromatic.colormode.ColorMode import io.neoterm.R import io.neoterm.backend.TerminalColors +import io.neoterm.component.ComponentManager import io.neoterm.component.colorscheme.ColorSchemeComponent import io.neoterm.component.colorscheme.NeoColorScheme -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.ui.customize.adapter.ColorItemAdapter -import io.neoterm.ui.customize.model.ColorItem +import io.neoterm.frontend.session.view.TerminalView import io.neoterm.utils.Terminals @@ -32,7 +30,7 @@ import io.neoterm.utils.Terminals */ class ColorSchemeActivity : BaseCustomizeActivity() { private val COMPARATOR = SortedListAdapter.ComparatorBuilder() - .setOrderForModel(ColorItem::class.java) { a, b -> + .setOrderForModel(ColorItem::class.java) { a, b -> a.colorType.compareTo(b.colorType) } .build() @@ -81,13 +79,13 @@ class ColorSchemeActivity : BaseCustomizeActivity() { if (keyCode == KeyEvent.KEYCODE_BACK && event!!.action == KeyEvent.ACTION_DOWN && changed) { AlertDialog.Builder(this) .setMessage(getString(R.string.discard_changes)) - .setPositiveButton(R.string.save, { _, _ -> + .setPositiveButton(R.string.save) { _, _ -> applyColorScheme(editingColorScheme, true) - }) + } .setNegativeButton(android.R.string.no, null) - .setNeutralButton(R.string.exit, { _, _ -> + .setNeutralButton(R.string.exit) { _, _ -> finish() - }) + } .show() return true } @@ -135,10 +133,10 @@ class ColorSchemeActivity : BaseCustomizeActivity() { .setTitle(model.colorName) .setView(view) .setNegativeButton(android.R.string.no, null) - .setPositiveButton(android.R.string.yes, { _, _ -> + .setPositiveButton(android.R.string.yes) { _, _ -> applyColor(edit.text.toString()); - }) - .setNeutralButton(R.string.select_new_value, { _, _ -> + } + .setNeutralButton(R.string.select_new_value) { _, _ -> ColorOMaticDialog.Builder() .initialColor(TerminalColors.parse(model.colorValue)) .colorMode(ColorMode.RGB) @@ -149,7 +147,7 @@ class ColorSchemeActivity : BaseCustomizeActivity() { .showColorIndicator(true) .create() .show(supportFragmentManager, "ColorOMaticDialog") - }) + } .show() } @@ -164,10 +162,10 @@ class ColorSchemeActivity : BaseCustomizeActivity() { AlertDialog.Builder(this) .setTitle(R.string.save_color) .setView(view) - .setPositiveButton(android.R.string.yes, { _, _ -> + .setPositiveButton(android.R.string.yes) { _, _ -> colorScheme.colorName = edit.text.toString() applyColorScheme(colorScheme, finishAfter) - }) + } .setNegativeButton(android.R.string.no, null) .show() } else { @@ -186,4 +184,4 @@ class ColorSchemeActivity : BaseCustomizeActivity() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt b/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt index 1d45e2e..3733bd8 100644 --- a/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt +++ b/app/src/main/java/io/neoterm/ui/customize/CustomizeActivity.kt @@ -9,10 +9,10 @@ import android.widget.ArrayAdapter import android.widget.Spinner import android.widget.Toast import io.neoterm.R +import io.neoterm.component.ComponentManager import io.neoterm.component.colorscheme.ColorSchemeComponent +import io.neoterm.component.config.NeoTermPath import io.neoterm.component.font.FontComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoTermPath import io.neoterm.utils.getPathOfMediaUri import java.io.File import java.nio.file.Files @@ -150,4 +150,4 @@ class CustomizeActivity : BaseCustomizeActivity() { } return super.onOptionsItemSelected(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/customize/adapter/ColorItemAdapter.kt b/app/src/main/java/io/neoterm/ui/customize/adapter/ColorItemAdapter.kt deleted file mode 100644 index 7359d16..0000000 --- a/app/src/main/java/io/neoterm/ui/customize/adapter/ColorItemAdapter.kt +++ /dev/null @@ -1,49 +0,0 @@ -package io.neoterm.ui.customize.adapter - -import android.content.Context -import android.view.LayoutInflater -import android.view.ViewGroup -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter -import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView -import io.neoterm.R -import io.neoterm.component.colorscheme.NeoColorScheme -import io.neoterm.ui.customize.adapter.holder.ColorItemViewHolder -import io.neoterm.ui.customize.model.ColorItem - -/** - * @author kiva - */ -class ColorItemAdapter( - context: Context, - initColorScheme: NeoColorScheme, - comparator: Comparator, - private val listener: ColorItemAdapter.Listener -) : SortedListAdapter(context, ColorItem::class.java, comparator), FastScrollRecyclerView.SectionedAdapter { - - val colorList = mutableListOf() - - init { - (NeoColorScheme.COLOR_TYPE_BEGIN..NeoColorScheme.COLOR_TYPE_END) - .forEach { - colorList.add(ColorItem(it, initColorScheme.getColor(it) ?: "")) - } - edit().add(colorList).commit() - } - - interface Listener { - fun onModelClicked(model: ColorItem) - } - - override fun getSectionName(position: Int): String { - return colorList[position].colorName[0].toString() - } - - override fun onCreateViewHolder( - inflater: LayoutInflater, - parent: ViewGroup, - viewType: Int - ): SortedListAdapter.ViewHolder { - val rootView = inflater.inflate(R.layout.item_color, parent, false) - return ColorItemViewHolder(rootView, listener) - } -} diff --git a/app/src/main/java/io/neoterm/ui/customize/adapter/holder/ColorItemViewHolder.kt b/app/src/main/java/io/neoterm/ui/customize/adapter/holder/ColorItemViewHolder.kt deleted file mode 100644 index 4e8e0ad..0000000 --- a/app/src/main/java/io/neoterm/ui/customize/adapter/holder/ColorItemViewHolder.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.neoterm.ui.customize.adapter.holder - -import android.view.View -import android.widget.TextView -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter -import io.neoterm.R -import io.neoterm.backend.TerminalColors -import io.neoterm.ui.customize.adapter.ColorItemAdapter -import io.neoterm.ui.customize.model.ColorItem - -class ColorItemViewHolder(private val rootView: View, private val listener: ColorItemAdapter.Listener) : - SortedListAdapter.ViewHolder(rootView) { - private val colorItemName: TextView = rootView.findViewById(R.id.color_item_name) - private val colorItemDesc: TextView = rootView.findViewById(R.id.color_item_description) - private val colorView: View = rootView.findViewById(R.id.color_item_view) - - override fun performBind(item: ColorItem) { - rootView.setOnClickListener { listener.onModelClicked(item) } - colorItemName.text = item.colorName - colorItemDesc.text = item.colorValue - if (item.colorValue.isNotEmpty()) { - val color = TerminalColors.parse(item.colorValue) - colorView.setBackgroundColor(color) - colorItemDesc.setTextColor(color) - } - } -} diff --git a/app/src/main/java/io/neoterm/ui/customize/model.kt b/app/src/main/java/io/neoterm/ui/customize/model.kt new file mode 100644 index 0000000..f94e175 --- /dev/null +++ b/app/src/main/java/io/neoterm/ui/customize/model.kt @@ -0,0 +1,90 @@ +package io.neoterm.ui.customize + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter +import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView +import io.neoterm.App +import io.neoterm.R +import io.neoterm.backend.TerminalColors +import io.neoterm.component.colorscheme.NeoColorScheme + +/** + * @author kiva + */ +class ColorItem(var colorType: Int, var colorValue: String) : SortedListAdapter.ViewModel { + override fun isSameModelAs(t: T): Boolean { + if (t is ColorItem) { + return t.colorName == colorName + && t.colorValue == colorValue + && t.colorType == colorType + } + return false + } + + override fun isContentTheSameAs(t: T): Boolean { + return isSameModelAs(t) + } + + var colorName = App.get().resources + .getStringArray(R.array.color_item_names)[colorType - NeoColorScheme.COLOR_TYPE_BEGIN] +} + +/** + * @author kiva + */ +class ColorItemAdapter( + context: Context, + initColorScheme: NeoColorScheme, + comparator: Comparator, + private val listener: ColorItemAdapter.Listener +) : SortedListAdapter(context, ColorItem::class.java, comparator), FastScrollRecyclerView.SectionedAdapter { + + val colorList = mutableListOf() + + init { + (NeoColorScheme.COLOR_TYPE_BEGIN..NeoColorScheme.COLOR_TYPE_END) + .forEach { + colorList.add(ColorItem(it, initColorScheme.getColor(it) ?: "")) + } + edit().add(colorList).commit() + } + + interface Listener { + fun onModelClicked(model: ColorItem) + } + + override fun getSectionName(position: Int): String { + return colorList[position].colorName[0].toString() + } + + override fun onCreateViewHolder( + inflater: LayoutInflater, + parent: ViewGroup, + viewType: Int + ): ViewHolder { + val rootView = inflater.inflate(R.layout.item_color, parent, false) + return ColorItemViewHolder(rootView, listener) + } +} + +class ColorItemViewHolder(private val rootView: View, private val listener: ColorItemAdapter.Listener) : + SortedListAdapter.ViewHolder(rootView) { + private val colorItemName: TextView = rootView.findViewById(R.id.color_item_name) + private val colorItemDesc: TextView = rootView.findViewById(R.id.color_item_description) + private val colorView: View = rootView.findViewById(R.id.color_item_view) + + override fun performBind(item: ColorItem) { + rootView.setOnClickListener { listener.onModelClicked(item) } + colorItemName.text = item.colorName + colorItemDesc.text = item.colorValue + if (item.colorValue.isNotEmpty()) { + val color = TerminalColors.parse(item.colorValue) + colorView.setBackgroundColor(color) + colorItemDesc.setTextColor(color) + } + } +} diff --git a/app/src/main/java/io/neoterm/ui/customize/model/ColorItem.kt b/app/src/main/java/io/neoterm/ui/customize/model/ColorItem.kt deleted file mode 100644 index 4d3468c..0000000 --- a/app/src/main/java/io/neoterm/ui/customize/model/ColorItem.kt +++ /dev/null @@ -1,27 +0,0 @@ -package io.neoterm.ui.customize.model - -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter -import io.neoterm.App -import io.neoterm.R -import io.neoterm.component.colorscheme.NeoColorScheme - -/** - * @author kiva - */ -class ColorItem(var colorType: Int, var colorValue: String) : SortedListAdapter.ViewModel { - override fun isSameModelAs(t: T): Boolean { - if (t is ColorItem) { - return t.colorName == colorName - && t.colorValue == colorValue - && t.colorType == colorType - } - return false - } - - override fun isContentTheSameAs(t: T): Boolean { - return isSameModelAs(t) - } - - var colorName = App.get().resources - .getStringArray(R.array.color_item_names)[colorType - NeoColorScheme.COLOR_TYPE_BEGIN] -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/ui/support/AboutActivity.kt b/app/src/main/java/io/neoterm/ui/other/AboutActivity.kt similarity index 82% rename from app/src/main/java/io/neoterm/ui/support/AboutActivity.kt rename to app/src/main/java/io/neoterm/ui/other/AboutActivity.kt index 0906a82..fd6db93 100644 --- a/app/src/main/java/io/neoterm/ui/support/AboutActivity.kt +++ b/app/src/main/java/io/neoterm/ui/other/AboutActivity.kt @@ -1,4 +1,4 @@ -package io.neoterm.ui.support +package io.neoterm.ui.other import android.content.Intent import android.content.pm.PackageManager @@ -17,7 +17,6 @@ import de.psdev.licensesdialog.model.Notice import de.psdev.licensesdialog.model.Notices import io.neoterm.App import io.neoterm.R -import io.neoterm.ui.setup.SetupActivity /** @@ -36,14 +35,6 @@ class AboutActivity : AppCompatActivity() { } catch (ignored: PackageManager.NameNotFoundException) { } - findViewById(R.id.about_developers_view).setOnClickListener { - AlertDialog.Builder(this) - .setTitle(R.string.about_developers_label) - .setMessage(R.string.about_developers) - .setPositiveButton(android.R.string.yes, null) - .show() - } - findViewById(R.id.about_licenses_view).setOnClickListener { val notices = Notices() notices.addNotice( @@ -141,27 +132,12 @@ class AboutActivity : AppCompatActivity() { openUrl("https://github.com/NeoTerm/NeoTerm") } - findViewById(R.id.about_donate_view).setOnClickListener { - AlertDialog.Builder(this) - .setTitle(R.string.support_donate_label) - .setMessage(R.string.support_donate_dialog_text) - .setPositiveButton(R.string.support_donate_alipay, { _, _ -> - Donation.donateByAlipay(this, "FKX025062MBLAG6E90RYBC") - }) - .setNeutralButton(android.R.string.no, null) - .show() - } - - findViewById(R.id.about_show_help_view).setOnClickListener { - App.get().openHelpLink(); - } - findViewById(R.id.about_reset_app_view).setOnClickListener { AlertDialog.Builder(this) .setMessage(R.string.reset_app_warning) - .setPositiveButton(R.string.yes, { _, _ -> + .setPositiveButton(R.string.yes) { _, _ -> resetApp() - }) + } .setNegativeButton(android.R.string.no, null) .show() } @@ -184,4 +160,4 @@ class AboutActivity : AppCompatActivity() { } return super.onOptionsItemSelected(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/bonus/BonusActivity.kt b/app/src/main/java/io/neoterm/ui/other/BonusActivity.kt similarity index 99% rename from app/src/main/java/io/neoterm/ui/bonus/BonusActivity.kt rename to app/src/main/java/io/neoterm/ui/other/BonusActivity.kt index 517f841..0cfad4d 100644 --- a/app/src/main/java/io/neoterm/ui/bonus/BonusActivity.kt +++ b/app/src/main/java/io/neoterm/ui/other/BonusActivity.kt @@ -1,4 +1,4 @@ -package io.neoterm.ui.bonus +package io.neoterm.ui.other import android.animation.ObjectAnimator import android.content.res.ColorStateList diff --git a/app/src/main/java/io/neoterm/ui/crash/CrashActivity.kt b/app/src/main/java/io/neoterm/ui/other/CrashActivity.kt similarity index 98% rename from app/src/main/java/io/neoterm/ui/crash/CrashActivity.kt rename to app/src/main/java/io/neoterm/ui/other/CrashActivity.kt index fb8afa1..d2f0414 100644 --- a/app/src/main/java/io/neoterm/ui/crash/CrashActivity.kt +++ b/app/src/main/java/io/neoterm/ui/other/CrashActivity.kt @@ -1,4 +1,4 @@ -package io.neoterm.ui.crash +package io.neoterm.ui.other import android.os.Build import android.os.Bundle @@ -56,4 +56,4 @@ class CrashActivity : AppCompatActivity() { } return "Unknown Arch" } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt b/app/src/main/java/io/neoterm/ui/other/SetupActivity.kt similarity index 95% rename from app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt rename to app/src/main/java/io/neoterm/ui/other/SetupActivity.kt index 46babdc..7981aa0 100644 --- a/app/src/main/java/io/neoterm/ui/setup/SetupActivity.kt +++ b/app/src/main/java/io/neoterm/ui/other/SetupActivity.kt @@ -1,4 +1,4 @@ -package io.neoterm.ui.setup +package io.neoterm.ui.other import android.content.ActivityNotFoundException import android.content.Intent @@ -11,14 +11,9 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import io.neoterm.App import io.neoterm.R +import io.neoterm.component.config.NeoTermPath import io.neoterm.component.pm.SourceHelper -import io.neoterm.frontend.config.NeoTermPath -import io.neoterm.setup.ResultListener -import io.neoterm.setup.SetupHelper -import io.neoterm.setup.SourceConnection -import io.neoterm.setup.connections.BackupFileConnection -import io.neoterm.setup.connections.LocalFileConnection -import io.neoterm.setup.connections.NetworkConnection +import io.neoterm.setup.* import io.neoterm.utils.getPathOfMediaUri import io.neoterm.utils.runApt import java.io.File diff --git a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt index d8e7895..671dae0 100644 --- a/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt +++ b/app/src/main/java/io/neoterm/ui/pm/PackageManagerActivity.kt @@ -16,12 +16,10 @@ import androidx.core.view.MenuItemCompat import androidx.recyclerview.widget.LinearLayoutManager import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter import io.neoterm.R +import io.neoterm.component.ComponentManager +import io.neoterm.component.config.NeoPreference import io.neoterm.component.pm.* -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.ui.pm.adapter.PackageAdapter -import io.neoterm.ui.pm.model.PackageModel -import io.neoterm.ui.pm.utils.StringDistance +import io.neoterm.utils.StringDistance import io.neoterm.utils.runApt import java.util.* diff --git a/app/src/main/java/io/neoterm/ui/pm/adapter/PackageAdapter.kt b/app/src/main/java/io/neoterm/ui/pm/adapter/PackageAdapter.kt deleted file mode 100755 index 2086640..0000000 --- a/app/src/main/java/io/neoterm/ui/pm/adapter/PackageAdapter.kt +++ /dev/null @@ -1,35 +0,0 @@ -package io.neoterm.ui.pm.adapter - -import android.content.Context -import android.view.LayoutInflater -import android.view.ViewGroup -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter -import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView -import io.neoterm.R -import io.neoterm.ui.pm.adapter.holder.PackageViewHolder -import io.neoterm.ui.pm.model.PackageModel - -class PackageAdapter( - context: Context, - comparator: Comparator, - private val listener: PackageAdapter.Listener -) : SortedListAdapter(context, PackageModel::class.java, comparator), - FastScrollRecyclerView.SectionedAdapter { - - override fun getSectionName(position: Int): String { - return getItem(position).packageInfo.packageName?.substring(0, 1) ?: "#" - } - - interface Listener { - fun onModelClicked(model: PackageModel) - } - - override fun onCreateViewHolder( - inflater: LayoutInflater, - parent: ViewGroup, - viewType: Int - ): SortedListAdapter.ViewHolder { - val rootView = inflater.inflate(R.layout.item_package, parent, false) - return PackageViewHolder(rootView, listener) - } -} diff --git a/app/src/main/java/io/neoterm/ui/pm/adapter/holder/PackageViewHolder.kt b/app/src/main/java/io/neoterm/ui/pm/adapter/holder/PackageViewHolder.kt deleted file mode 100755 index a17a130..0000000 --- a/app/src/main/java/io/neoterm/ui/pm/adapter/holder/PackageViewHolder.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.neoterm.ui.pm.adapter.holder - -import android.view.View -import android.widget.TextView - -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter - -import io.neoterm.R -import io.neoterm.ui.pm.adapter.PackageAdapter -import io.neoterm.ui.pm.model.PackageModel - -class PackageViewHolder(private val rootView: View, private val listener: PackageAdapter.Listener) : - SortedListAdapter.ViewHolder(rootView) { - private val packageNameView: TextView = rootView.findViewById(R.id.package_item_name) - private val packageDescView: TextView = rootView.findViewById(R.id.package_item_desc) - - override fun performBind(item: PackageModel) { - rootView.setOnClickListener { listener.onModelClicked(item) } - packageNameView.text = item.packageInfo.packageName - packageDescView.text = item.packageInfo.description - } -} diff --git a/app/src/main/java/io/neoterm/ui/pm/model.kt b/app/src/main/java/io/neoterm/ui/pm/model.kt new file mode 100644 index 0000000..bc0b832 --- /dev/null +++ b/app/src/main/java/io/neoterm/ui/pm/model.kt @@ -0,0 +1,76 @@ +package io.neoterm.ui.pm + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter +import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView +import io.neoterm.R +import io.neoterm.component.pm.NeoPackageInfo +import io.neoterm.utils.formatSizeInKB + +class PackageAdapter( + context: Context, + comparator: Comparator, + private val listener: PackageAdapter.Listener +) : SortedListAdapter(context, PackageModel::class.java, comparator), + FastScrollRecyclerView.SectionedAdapter { + + override fun getSectionName(position: Int): String { + return getItem(position).packageInfo.packageName?.substring(0, 1) ?: "#" + } + + interface Listener { + fun onModelClicked(model: PackageModel) + } + + override fun onCreateViewHolder( + inflater: LayoutInflater, + parent: ViewGroup, + viewType: Int + ): ViewHolder { + val rootView = inflater.inflate(R.layout.item_package, parent, false) + return PackageViewHolder(rootView, listener) + } +} + +class PackageViewHolder(private val rootView: View, private val listener: PackageAdapter.Listener) : + SortedListAdapter.ViewHolder(rootView) { + private val packageNameView: TextView = rootView.findViewById(R.id.package_item_name) + private val packageDescView: TextView = rootView.findViewById(R.id.package_item_desc) + + override fun performBind(item: PackageModel) { + rootView.setOnClickListener { listener.onModelClicked(item) } + packageNameView.text = item.packageInfo.packageName + packageDescView.text = item.packageInfo.description + } +} + +/** + * @author kiva + */ + +class PackageModel(val packageInfo: NeoPackageInfo) : SortedListAdapter.ViewModel { + override fun isSameModelAs(t: T): Boolean { + if (t is PackageModel) { + return t.packageInfo.packageName == packageInfo.packageName + } + return false + } + + override fun isContentTheSameAs(t: T): Boolean { + return isSameModelAs(t) + } + + fun getPackageDetails(context: Context): String { + return context.getString( + R.string.package_details, + packageInfo.packageName, packageInfo.version, + packageInfo.dependenciesString, + packageInfo.installedSizeInBytes.formatSizeInKB(), + packageInfo.description, packageInfo.homePage + ) + } +} diff --git a/app/src/main/java/io/neoterm/ui/pm/model/PackageModel.kt b/app/src/main/java/io/neoterm/ui/pm/model/PackageModel.kt deleted file mode 100644 index a52704e..0000000 --- a/app/src/main/java/io/neoterm/ui/pm/model/PackageModel.kt +++ /dev/null @@ -1,35 +0,0 @@ -package io.neoterm.ui.pm.model - -import android.content.Context -import com.github.wrdlbrnft.sortedlistadapter.SortedListAdapter -import io.neoterm.R - -import io.neoterm.component.pm.NeoPackageInfo -import io.neoterm.utils.formatSizeInKB - -/** - * @author kiva - */ - -class PackageModel(val packageInfo: NeoPackageInfo) : SortedListAdapter.ViewModel { - override fun isSameModelAs(t: T): Boolean { - if (t is PackageModel) { - return t.packageInfo.packageName == packageInfo.packageName - } - return false - } - - override fun isContentTheSameAs(t: T): Boolean { - return isSameModelAs(t) - } - - fun getPackageDetails(context: Context): String { - return context.getString( - R.string.package_details, - packageInfo.packageName, packageInfo.version, - packageInfo.dependenciesString, - packageInfo.installedSizeInBytes.formatSizeInKB(), - packageInfo.description, packageInfo.homePage - ) - } -} diff --git a/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt b/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt index 37c1082..0a2156d 100644 --- a/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt +++ b/app/src/main/java/io/neoterm/ui/settings/GeneralSettingsActivity.kt @@ -4,7 +4,7 @@ import android.os.Bundle import android.view.MenuItem import androidx.appcompat.app.AlertDialog import io.neoterm.R -import io.neoterm.frontend.config.NeoPreference +import io.neoterm.component.config.NeoPreference import io.neoterm.utils.runApt /** @@ -56,4 +56,4 @@ class GeneralSettingsActivity : BasePreferenceActivity() { } return super.onOptionsItemSelected(item) } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/support/Donation.kt b/app/src/main/java/io/neoterm/ui/support/Donation.kt deleted file mode 100644 index 8e0eb58..0000000 --- a/app/src/main/java/io/neoterm/ui/support/Donation.kt +++ /dev/null @@ -1,35 +0,0 @@ -package io.neoterm.ui.support - -import android.content.ActivityNotFoundException -import android.content.Intent -import androidx.appcompat.app.AppCompatActivity -import java.net.URISyntaxException - -object Donation { - // 旧版支付宝二维码通用 Intent Scheme Url 格式 - private val INTENT_URL_FORMAT = "intent://platformapi/startapp?saId=10000007&" + - "clientVersion=3.7.0.0718&qrcode=https%3A%2F%2Fqr.alipay.com%2F{payCode}%3F_s" + - "%3Dweb-other&_t=1472443966571#Intent;" + - "scheme=alipayqr;package=com.eg.android.AlipayGphone;end" - - fun donateByAlipay(activity: AppCompatActivity, payCode: String): Boolean { - return startIntentUrl(activity, INTENT_URL_FORMAT.replace("{payCode}", payCode)) - } - - private fun startIntentUrl(activity: AppCompatActivity, intentFullUrl: String): Boolean { - return try { - val intent = Intent.parseUri( - intentFullUrl, - Intent.URI_INTENT_SCHEME - ) - activity.startActivity(intent) - true - } catch (e: URISyntaxException) { - e.printStackTrace() - false - } catch (e: ActivityNotFoundException) { - e.printStackTrace() - false - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/ui/support/HelpActivity.kt b/app/src/main/java/io/neoterm/ui/support/HelpActivity.kt deleted file mode 100644 index a4adbe9..0000000 --- a/app/src/main/java/io/neoterm/ui/support/HelpActivity.kt +++ /dev/null @@ -1,26 +0,0 @@ -package io.neoterm.ui.support - -import android.os.Bundle -import android.view.MenuItem -import androidx.appcompat.app.AppCompatActivity -import io.neoterm.R - -/** - * @author kiva - */ -class HelpActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.ui_faq) - setSupportActionBar(findViewById(R.id.faq_toolbar)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) - } - - override fun onOptionsItemSelected(item: MenuItem?): Boolean { - when (item?.itemId) { - android.R.id.home -> - finish() - } - return super.onOptionsItemSelected(item) - } -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt b/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt index 9962804..acdc9cc 100644 --- a/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt +++ b/app/src/main/java/io/neoterm/ui/term/NeoTermActivity.kt @@ -23,27 +23,21 @@ import io.neoterm.App import io.neoterm.BuildConfig import io.neoterm.R import io.neoterm.backend.TerminalSession +import io.neoterm.component.ComponentManager +import io.neoterm.component.config.NeoPreference import io.neoterm.component.profile.ProfileComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoPermission -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.shell.ShellProfile -import io.neoterm.frontend.session.shell.client.TermSessionCallback -import io.neoterm.frontend.session.shell.client.TermViewClient -import io.neoterm.frontend.session.shell.client.event.* -import io.neoterm.frontend.session.xorg.XParameter -import io.neoterm.frontend.session.xorg.XSession +import io.neoterm.component.session.ShellParameter +import io.neoterm.component.session.ShellProfile +import io.neoterm.component.session.XParameter +import io.neoterm.component.session.XSession +import io.neoterm.frontend.session.terminal.* import io.neoterm.services.NeoTermService import io.neoterm.setup.SetupHelper +import io.neoterm.ui.other.SetupActivity import io.neoterm.ui.pm.PackageManagerActivity import io.neoterm.ui.settings.SettingActivity -import io.neoterm.ui.setup.SetupActivity -import io.neoterm.ui.term.tab.NeoTab -import io.neoterm.ui.term.tab.NeoTabDecorator -import io.neoterm.ui.term.tab.TermTab -import io.neoterm.ui.term.tab.XSessionTab import io.neoterm.utils.FullScreenHelper +import io.neoterm.utils.NeoPermission import io.neoterm.utils.RangedInt import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe diff --git a/app/src/main/java/io/neoterm/ui/term/NeoTermRemoteInterface.kt b/app/src/main/java/io/neoterm/ui/term/NeoTermRemoteInterface.kt index 4a96dbe..05a39da 100644 --- a/app/src/main/java/io/neoterm/ui/term/NeoTermRemoteInterface.kt +++ b/app/src/main/java/io/neoterm/ui/term/NeoTermRemoteInterface.kt @@ -14,12 +14,12 @@ import io.neoterm.App import io.neoterm.R import io.neoterm.bridge.Bridge.* import io.neoterm.bridge.SessionId +import io.neoterm.component.ComponentManager +import io.neoterm.component.config.NeoPreference +import io.neoterm.component.session.ShellParameter import io.neoterm.component.userscript.UserScript import io.neoterm.component.userscript.UserScriptComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.shell.client.TermSessionCallback +import io.neoterm.frontend.session.terminal.TermSessionCallback import io.neoterm.services.NeoTermService import io.neoterm.utils.Terminals import io.neoterm.utils.getPathOfMediaUri @@ -116,8 +116,8 @@ class NeoTermRemoteInterface : AppCompatActivity(), ServiceConnection { private fun handleUserScript() { val filesToHandle = mutableListOf() - val userScriptService = ComponentManager.getComponent() - val userScripts = userScriptService.userScripts + val comp = ComponentManager.getComponent() + val userScripts = comp.userScripts if (userScripts.isEmpty()) { App.get().errorDialog(this, R.string.no_user_script_found, { finish() }) return @@ -241,4 +241,4 @@ class NeoTermRemoteInterface : AppCompatActivity(), ServiceConnection { private fun detectSystemShell(): Boolean { return false } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt b/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt index d8686d2..801c73e 100644 --- a/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt +++ b/app/src/main/java/io/neoterm/ui/term/SessionRemover.kt @@ -1,10 +1,8 @@ package io.neoterm.ui.term import io.neoterm.backend.TerminalSession -import io.neoterm.frontend.session.xorg.XSession +import io.neoterm.component.session.XSession import io.neoterm.services.NeoTermService -import io.neoterm.ui.term.tab.TermTab -import io.neoterm.ui.term.tab.XSessionTab /** * @author kiva diff --git a/app/src/main/java/io/neoterm/ui/term/tab/NeoTab.kt b/app/src/main/java/io/neoterm/ui/term/tab/NeoTab.kt deleted file mode 100644 index 7f8a16a..0000000 --- a/app/src/main/java/io/neoterm/ui/term/tab/NeoTab.kt +++ /dev/null @@ -1,23 +0,0 @@ -package io.neoterm.ui.term.tab - -import android.content.res.Configuration -import de.mrapp.android.tabswitcher.Tab - -/** - * @author kiva - */ -open class NeoTab(title: CharSequence) : Tab(title) { - open fun onPause() {} - - open fun onResume() {} - - open fun onStart() {} - - open fun onStop() {} - - open fun onWindowFocusChanged(hasFocus: Boolean) {} - - open fun onDestroy() {} - - open fun onConfigurationChanged(newConfig: Configuration) {} -} \ No newline at end of file diff --git a/app/src/main/java/io/neoterm/ui/term/tab/TermTab.kt b/app/src/main/java/io/neoterm/ui/term/tab/TermTab.kt deleted file mode 100644 index debaed9..0000000 --- a/app/src/main/java/io/neoterm/ui/term/tab/TermTab.kt +++ /dev/null @@ -1,109 +0,0 @@ -package io.neoterm.ui.term.tab - -import android.content.Context -import android.view.inputmethod.InputMethodManager -import androidx.appcompat.widget.Toolbar -import io.neoterm.component.colorscheme.ColorSchemeComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.session.shell.client.TermSessionData -import io.neoterm.frontend.session.shell.client.TermUiPresenter -import io.neoterm.frontend.session.shell.client.event.* -import org.greenrobot.eventbus.EventBus - -/** - * @author kiva - */ - -class TermTab(title: CharSequence) : NeoTab(title), TermUiPresenter { - companion object { - val PARAMETER_SHOW_EKS = "show_eks" - } - - var termData = TermSessionData() - var toolbar: Toolbar? = null - - fun updateColorScheme() { - val colorSchemeManager = ComponentManager.getComponent() - colorSchemeManager.applyColorScheme( - termData.termView, termData.extraKeysView, - colorSchemeManager.getCurrentColorScheme() - ) - } - - fun cleanup() { - termData.cleanup() - toolbar = null - } - - fun onFullScreenModeChanged(fullScreen: Boolean) { - // Window token changed, we need to recreate PopupWindow - resetAutoCompleteStatus() - } - - override fun requireHideIme() { - val terminalView = termData.termView - if (terminalView != null) { - val imm = terminalView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - if (imm.isActive) { - imm.hideSoftInputFromWindow(terminalView.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) - } - } - } - - override fun requireFinishAutoCompletion(): Boolean { - return termData.onAutoCompleteListener?.onFinishCompletion() ?: false - } - - override fun requireToggleFullScreen() { - EventBus.getDefault().post(ToggleFullScreenEvent()) - } - - override fun requirePaste() { - termData.termView?.pasteFromClipboard() - } - - override fun requireClose() { - requireHideIme() - EventBus.getDefault().post(TabCloseEvent(this)) - } - - override fun requireUpdateTitle(title: String?) { - if (title != null && title.isNotEmpty()) { - this.title = title - EventBus.getDefault().post(TitleChangedEvent(title)) - termData.viewClient?.updateExtraKeys(title) - } - } - - override fun requireOnSessionFinished() { - // do nothing - } - - override fun requireCreateNew() { - EventBus.getDefault().post(CreateNewSessionEvent()) - } - - override fun requireSwitchToPrevious() { - EventBus.getDefault().post(SwitchSessionEvent(toNext = false)) - } - - override fun requireSwitchToNext() { - EventBus.getDefault().post(SwitchSessionEvent(toNext = true)) - } - - override fun requireSwitchTo(index: Int) { - EventBus.getDefault().post(SwitchIndexedSessionEvent(index)) - } - - fun resetAutoCompleteStatus() { - termData.onAutoCompleteListener?.onCleanUp() - termData.onAutoCompleteListener = null - } - - fun resetStatus() { - resetAutoCompleteStatus() - termData.extraKeysView?.updateButtons() - termData.termView?.updateSize() - termData.termView?.onScreenUpdated() - } -} diff --git a/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt b/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt deleted file mode 100644 index dbf3257..0000000 --- a/app/src/main/java/io/neoterm/ui/term/tab/XSessionTab.kt +++ /dev/null @@ -1,42 +0,0 @@ -package io.neoterm.ui.term.tab - -import android.content.res.Configuration -import io.neoterm.frontend.session.xorg.XSession - -/** - * @author kiva - */ -class XSessionTab(title: CharSequence) : NeoTab(title) { - var session: XSession? = null - val sessionData - get() = session?.mSessionData - - override fun onWindowFocusChanged(hasFocus: Boolean) { - super.onWindowFocusChanged(hasFocus) - if (!hasFocus) { - onPause() - } else { - onResume() - } - } - - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - session?.updateScreenOrientation() - } - - override fun onPause() { - session?.onPause() - super.onPause() - } - - override fun onDestroy() { - super.onDestroy() - session?.onDestroy() - } - - override fun onResume() { - super.onResume() - session?.onResume() - } -} diff --git a/app/src/main/java/io/neoterm/ui/term/tab/NeoTabDecorator.kt b/app/src/main/java/io/neoterm/ui/term/tabs.kt similarity index 53% rename from app/src/main/java/io/neoterm/ui/term/tab/NeoTabDecorator.kt rename to app/src/main/java/io/neoterm/ui/term/tabs.kt index 3644998..db7988a 100644 --- a/app/src/main/java/io/neoterm/ui/term/tab/NeoTabDecorator.kt +++ b/app/src/main/java/io/neoterm/ui/term/tabs.kt @@ -1,33 +1,46 @@ -package io.neoterm.ui.term.tab +package io.neoterm.ui.term import android.content.Context +import android.content.res.Configuration import android.graphics.Rect import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.inputmethod.InputMethodManager import android.widget.FrameLayout +import androidx.appcompat.widget.Toolbar import de.mrapp.android.tabswitcher.Tab import de.mrapp.android.tabswitcher.TabSwitcher import de.mrapp.android.tabswitcher.TabSwitcherDecorator -import io.neoterm.Globals import io.neoterm.NeoGLView import io.neoterm.R +import io.neoterm.component.ComponentManager import io.neoterm.component.colorscheme.ColorSchemeComponent -import io.neoterm.frontend.completion.listener.OnAutoCompleteListener -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.DefaultValues -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.session.shell.client.TermCompleteListener -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.extrakey.ExtraKeysView -import io.neoterm.ui.term.NeoTermActivity +import io.neoterm.component.completion.OnAutoCompleteListener +import io.neoterm.component.config.DefaultValues +import io.neoterm.component.config.NeoPreference +import io.neoterm.component.session.XSession +import io.neoterm.frontend.session.terminal.* +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.extrakey.ExtraKeysView import io.neoterm.utils.Terminals +import org.greenrobot.eventbus.EventBus /** * @author kiva */ +open class NeoTab(title: CharSequence) : Tab(title) { + open fun onPause() {} + open fun onResume() {} + open fun onStart() {} + open fun onStop() {} + open fun onWindowFocusChanged(hasFocus: Boolean) {} + open fun onDestroy() {} + open fun onConfigurationChanged(newConfig: Configuration) {} +} + class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { companion object { private var VIEW_TYPE_COUNT = 0 @@ -124,20 +137,16 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { ) ) - if (Globals.HideSystemMousePointer - && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N - ) { - sessionData.glView?.pointerIcon = - android.view.PointerIcon.getSystemIcon( - context, - android.view.PointerIcon.TYPE_NULL - ) - } + sessionData.glView?.pointerIcon = + android.view.PointerIcon.getSystemIcon( + context, + android.view.PointerIcon.TYPE_NULL + ) val r = Rect() videoLayout.getWindowVisibleDisplayFrame(r) sessionData.glView?.callNativeScreenVisibleRect(r.left, r.top, r.right, r.bottom) - videoLayout.viewTreeObserver.addOnGlobalLayoutListener({ + videoLayout.viewTreeObserver.addOnGlobalLayoutListener { val r = Rect() videoLayout.getWindowVisibleDisplayFrame(r) val heightDiff = videoLayout.rootView.height - videoLayout.height // Take system bar into consideration @@ -146,23 +155,29 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { "SDL", "Main window visible region changed: " + r.left + ":" + r.top + ":" + r.width() + ":" + r.height() ) - videoLayout.postDelayed({ - sessionData.glView?.callNativeScreenVisibleRect( - r.left + widthDiff, - r.top + heightDiff, - r.width(), - r.height() - ) - }, 300) - videoLayout.postDelayed({ - sessionData.glView?.callNativeScreenVisibleRect( - r.left + widthDiff, - r.top + heightDiff, - r.width(), - r.height() - ) - }, 600) - }) + videoLayout.postDelayed( + { + sessionData.glView?.callNativeScreenVisibleRect( + r.left + widthDiff, + r.top + heightDiff, + r.width(), + r.height() + ) + }, + 300 + ) + videoLayout.postDelayed( + { + sessionData.glView?.callNativeScreenVisibleRect( + r.left + widthDiff, + r.top + heightDiff, + r.width(), + r.height() + ) + }, + 600 + ) + } } }.start() } @@ -208,4 +223,133 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() { } return -1 } -} \ No newline at end of file +} + +class XSessionTab(title: CharSequence) : NeoTab(title) { + var session: XSession? = null + val sessionData + get() = session?.mSessionData + + override fun onWindowFocusChanged(hasFocus: Boolean) { + super.onWindowFocusChanged(hasFocus) + if (!hasFocus) { + onPause() + } else { + onResume() + } + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + session?.updateScreenOrientation() + } + + override fun onPause() { + session?.onPause() + super.onPause() + } + + override fun onDestroy() { + super.onDestroy() + session?.onDestroy() + } + + override fun onResume() { + super.onResume() + session?.onResume() + } +} + +class TermTab(title: CharSequence) : NeoTab(title), TermUiPresenter { + companion object { + val PARAMETER_SHOW_EKS = "show_eks" + } + + var termData = TermSessionData() + var toolbar: Toolbar? = null + + fun updateColorScheme() { + val colorSchemeManager = ComponentManager.getComponent() + colorSchemeManager.applyColorScheme( + termData.termView, termData.extraKeysView, + colorSchemeManager.getCurrentColorScheme() + ) + } + + fun cleanup() { + termData.cleanup() + toolbar = null + } + + fun onFullScreenModeChanged(fullScreen: Boolean) { + // Window token changed, we need to recreate PopupWindow + resetAutoCompleteStatus() + } + + override fun requireHideIme() { + val terminalView = termData.termView + if (terminalView != null) { + val imm = terminalView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + if (imm.isActive) { + imm.hideSoftInputFromWindow(terminalView.windowToken, InputMethodManager.HIDE_NOT_ALWAYS) + } + } + } + + override fun requireFinishAutoCompletion(): Boolean { + return termData.onAutoCompleteListener?.onFinishCompletion() ?: false + } + + override fun requireToggleFullScreen() { + EventBus.getDefault().post(ToggleFullScreenEvent()) + } + + override fun requirePaste() { + termData.termView?.pasteFromClipboard() + } + + override fun requireClose() { + requireHideIme() + EventBus.getDefault().post(TabCloseEvent(this)) + } + + override fun requireUpdateTitle(title: String?) { + if (title != null && title.isNotEmpty()) { + this.title = title + EventBus.getDefault().post(TitleChangedEvent(title)) + termData.viewClient?.updateExtraKeys(title) + } + } + + override fun requireOnSessionFinished() { + // do nothing + } + + override fun requireCreateNew() { + EventBus.getDefault().post(CreateNewSessionEvent()) + } + + override fun requireSwitchToPrevious() { + EventBus.getDefault().post(SwitchSessionEvent(toNext = false)) + } + + override fun requireSwitchToNext() { + EventBus.getDefault().post(SwitchSessionEvent(toNext = true)) + } + + override fun requireSwitchTo(index: Int) { + EventBus.getDefault().post(SwitchIndexedSessionEvent(index)) + } + + fun resetAutoCompleteStatus() { + termData.onAutoCompleteListener?.onCleanUp() + termData.onAutoCompleteListener = null + } + + fun resetStatus() { + resetAutoCompleteStatus() + termData.extraKeysView?.updateButtons() + termData.termView?.updateSize() + termData.termView?.onScreenUpdated() + } +} diff --git a/app/src/main/java/io/neoterm/utils/CrashHandler.kt b/app/src/main/java/io/neoterm/utils/CrashHandler.kt index f54f249..4d4397c 100644 --- a/app/src/main/java/io/neoterm/utils/CrashHandler.kt +++ b/app/src/main/java/io/neoterm/utils/CrashHandler.kt @@ -2,7 +2,7 @@ package io.neoterm.utils import android.content.Intent import io.neoterm.App -import io.neoterm.ui.crash.CrashActivity +import io.neoterm.ui.other.CrashActivity /** * @author kiva diff --git a/app/src/main/java/io/neoterm/frontend/logging/NLog.kt b/app/src/main/java/io/neoterm/utils/NLog.kt similarity index 99% rename from app/src/main/java/io/neoterm/frontend/logging/NLog.kt rename to app/src/main/java/io/neoterm/utils/NLog.kt index 13c8d18..bca8ffd 100644 --- a/app/src/main/java/io/neoterm/frontend/logging/NLog.kt +++ b/app/src/main/java/io/neoterm/utils/NLog.kt @@ -1,4 +1,4 @@ -package io.neoterm.frontend.logging +package io.neoterm.utils import android.content.Context import android.util.Log diff --git a/app/src/main/java/io/neoterm/frontend/config/NeoPermission.kt b/app/src/main/java/io/neoterm/utils/NeoPermission.kt similarity index 91% rename from app/src/main/java/io/neoterm/frontend/config/NeoPermission.kt rename to app/src/main/java/io/neoterm/utils/NeoPermission.kt index d8c7f46..b89ccfe 100644 --- a/app/src/main/java/io/neoterm/frontend/config/NeoPermission.kt +++ b/app/src/main/java/io/neoterm/utils/NeoPermission.kt @@ -1,10 +1,9 @@ -package io.neoterm.frontend.config +package io.neoterm.utils import android.Manifest import android.content.ActivityNotFoundException import android.content.DialogInterface import android.content.pm.PackageManager -import android.os.Build import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat @@ -17,10 +16,6 @@ object NeoPermission { const val REQUEST_APP_PERMISSION = 10086 fun initAppPermission(context: AppCompatActivity, requestCode: Int) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return - } - if (ContextCompat.checkSelfPermission( context, Manifest.permission.READ_EXTERNAL_STORAGE @@ -56,4 +51,4 @@ object NeoPermission { // for MIUI, we ignore it. } } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java b/app/src/main/java/io/neoterm/utils/StringDistance.java similarity index 82% rename from app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java rename to app/src/main/java/io/neoterm/utils/StringDistance.java index 27e9a95..b55415c 100644 --- a/app/src/main/java/io/neoterm/ui/pm/utils/StringDistance.java +++ b/app/src/main/java/io/neoterm/utils/StringDistance.java @@ -1,4 +1,4 @@ -package io.neoterm.ui.pm.utils; +package io.neoterm.utils; /** * @author kiva @@ -27,9 +27,7 @@ public class StringDistance { int insert = d[i][j - 1] + 1; int delete = d[i - 1][j] + 1; int replace = d[i - 1][j - 1] + 1; - d[i][j] = Math.min(insert, delete) > Math.min(delete, replace) - ? Math.min(delete, replace) - : Math.min(insert, delete); + d[i][j] = Math.min(Math.min(insert, delete), Math.min(delete, replace)); } } } diff --git a/app/src/main/java/io/neoterm/utils/Terminals.kt b/app/src/main/java/io/neoterm/utils/Terminals.kt index 2a44c87..77e9be2 100644 --- a/app/src/main/java/io/neoterm/utils/Terminals.kt +++ b/app/src/main/java/io/neoterm/utils/Terminals.kt @@ -3,16 +3,16 @@ package io.neoterm.utils import android.content.Context import androidx.appcompat.app.AppCompatActivity import io.neoterm.backend.TerminalSession +import io.neoterm.component.ComponentManager +import io.neoterm.component.config.NeoPreference import io.neoterm.component.font.FontComponent import io.neoterm.component.session.SessionComponent -import io.neoterm.frontend.component.ComponentManager -import io.neoterm.frontend.config.NeoPreference -import io.neoterm.frontend.session.shell.ShellParameter -import io.neoterm.frontend.session.xorg.XParameter -import io.neoterm.frontend.session.xorg.XSession -import io.neoterm.frontend.terminal.TerminalView -import io.neoterm.frontend.terminal.TerminalViewClient -import io.neoterm.frontend.terminal.extrakey.ExtraKeysView +import io.neoterm.component.session.ShellParameter +import io.neoterm.component.session.XParameter +import io.neoterm.component.session.XSession +import io.neoterm.frontend.session.view.TerminalView +import io.neoterm.frontend.session.view.TerminalViewClient +import io.neoterm.frontend.session.view.extrakey.ExtraKeysView /** * @author kiva @@ -64,4 +64,4 @@ object Terminals { builder.append('"') return builder.toString() } -} \ No newline at end of file +} diff --git a/app/src/main/java/io/neoterm/utils/utils.kt b/app/src/main/java/io/neoterm/utils/utils.kt index 68f762c..9d3ff94 100644 --- a/app/src/main/java/io/neoterm/utils/utils.kt +++ b/app/src/main/java/io/neoterm/utils/utils.kt @@ -7,7 +7,7 @@ import android.os.Environment import android.provider.DocumentsContract import android.provider.MediaStore import io.neoterm.R -import io.neoterm.frontend.config.NeoTermPath +import io.neoterm.component.config.NeoTermPath import io.neoterm.frontend.floating.TerminalDialog import java.nio.file.Files import java.nio.file.Paths diff --git a/app/src/main/res/layout/popup_auto_complete.xml b/app/src/main/res/layout/popup_auto_complete.xml index 4bb855f..0d0e594 100644 --- a/app/src/main/res/layout/popup_auto_complete.xml +++ b/app/src/main/res/layout/popup_auto_complete.xml @@ -1,13 +1,13 @@ - + - \ No newline at end of file + diff --git a/app/src/main/res/layout/ui_about.xml b/app/src/main/res/layout/ui_about.xml index b0a72ef..b9c69d6 100644 --- a/app/src/main/res/layout/ui_about.xml +++ b/app/src/main/res/layout/ui_about.xml @@ -105,80 +105,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/ui_color_scheme.xml b/app/src/main/res/layout/ui_color_scheme.xml index e996733..bb2c600 100644 --- a/app/src/main/res/layout/ui_color_scheme.xml +++ b/app/src/main/res/layout/ui_color_scheme.xml @@ -27,7 +27,7 @@ android:layout_weight="1.0" android:background="@color/terminal_background"> - - - - - - - -