diff --git a/changelog.txt b/changelog.txt index 79a5a412b..6cabba47f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -8,6 +8,10 @@ Legend + : added - : removed +2016-12-01 v1.24.0 +------------------ ++ abap syntax highlighting + 2016-11-22 ------------------ + supported object list @debugpage diff --git a/src/zabapgit.prog.abap b/src/zabapgit.prog.abap index d115af037..ef48a5c98 100644 --- a/src/zabapgit.prog.abap +++ b/src/zabapgit.prog.abap @@ -3,7 +3,7 @@ REPORT zabapgit LINE-SIZE 100. * See http://www.abapgit.org CONSTANTS: gc_xml_version TYPE string VALUE 'v1.0.0', "#EC NOTEXT - gc_abap_version TYPE string VALUE 'v1.23.6'. "#EC NOTEXT + gc_abap_version TYPE string VALUE 'v1.24.5'. "#EC NOTEXT ******************************************************************************** * The MIT License (MIT) diff --git a/src/zabapgit_css_common.w3mi.data.css b/src/zabapgit_css_common.w3mi.data.css index 7fdaf42f7..d326d2f69 100644 --- a/src/zabapgit_css_common.w3mi.data.css +++ b/src/zabapgit_css_common.w3mi.data.css @@ -499,6 +499,11 @@ table.diff_tab code { font-family: inherit; white-space: pre; } + +table.diff_tab code span.keyword { color: #0a69ce; } +table.diff_tab code span.text { color: #48ce4f; } +table.diff_tab code span.comment { color: #808080; font-style: italic; } + table.diff_tab tbody tr:first-child td { padding-top: 0.5em; } table.diff_tab tbody tr:last-child td { padding-bottom: 0.5em; } @@ -582,3 +587,21 @@ table.tag { } table.tag td { padding: 0.2em 0.5em; } table.tag td.label { background-color: #b3c1cc; } + +/* TUTORIAL */ + +div.tutorial { + margin-top: 3px; + background-color: #f2f2f2; + padding: 0.5em 1em 0.5em 1em; +} + +div.tutorial hr { border-color: #CCC; } +div.tutorial h1 { + font-size: 18pt; + color: #404040; +} +div.tutorial h2 { + font-size: 14pt; + color: #404040; +} diff --git a/src/zabapgit_css_common.w3mi.xml b/src/zabapgit_css_common.w3mi.xml index b5ce02b7f..ddab44689 100644 --- a/src/zabapgit_css_common.w3mi.xml +++ b/src/zabapgit_css_common.w3mi.xml @@ -15,13 +15,13 @@ MI ZABAPGIT_CSS_COMMON filename - common.css + ~wwwtmp.css MI ZABAPGIT_CSS_COMMON filesize - 12136 + 12615 MI diff --git a/src/zabapgit_definitions.prog.abap b/src/zabapgit_definitions.prog.abap index 4ecc74b25..139849bfe 100644 --- a/src/zabapgit_definitions.prog.abap +++ b/src/zabapgit_definitions.prog.abap @@ -171,7 +171,9 @@ CONSTANTS: BEGIN OF gc_action, repo_toggle_fav TYPE string VALUE 'repo_toggle_fav', abapgit_home TYPE string VALUE 'abapgit_home', + abapgit_wiki TYPE string VALUE 'abapgit_wiki', abapgit_install TYPE string VALUE 'abapgit_install', + abapgit_install_pi TYPE string VALUE 'abapgit_install_pi', zip_import TYPE string VALUE 'zip_import', zip_export TYPE string VALUE 'zip_export', @@ -203,6 +205,8 @@ CONSTANTS: BEGIN OF gc_action, go_branch_overview TYPE string VALUE 'go_branch_overview', go_playground TYPE string VALUE 'go_playground', go_debuginfo TYPE string VALUE 'go_debuginfo', - go_settings type string value 'go_settings', + go_settings TYPE STRING VALUE 'go_settings', + go_tutorial TYPE STRING VALUE 'go_tutorial', jump TYPE string VALUE 'jump', + jump_pkg TYPE string VALUE 'jump_pkg', END OF gc_action. \ No newline at end of file diff --git a/src/zabapgit_gui_pages.prog.abap b/src/zabapgit_gui_pages.prog.abap index 255a32c09..910211fd0 100644 --- a/src/zabapgit_gui_pages.prog.abap +++ b/src/zabapgit_gui_pages.prog.abap @@ -13,6 +13,8 @@ INCLUDE zabapgit_repo_browser_util. * Components and templates INCLUDE zabapgit_view_repo. +INCLUDE zabapgit_view_tutorial. +INCLUDE zabapgit_syntax_highlighter. * Pages INCLUDE zabapgit_page_commit. diff --git a/src/zabapgit_gui_router.prog.abap b/src/zabapgit_gui_router.prog.abap index e148953cb..3c259c095 100644 --- a/src/zabapgit_gui_router.prog.abap +++ b/src/zabapgit_gui_router.prog.abap @@ -96,15 +96,22 @@ CLASS lcl_gui_router IMPLEMENTATION. WHEN gc_action-go_playground. " Create playground page ei_page = get_page_playground( ). ev_state = gc_event_state-new_page. + WHEN gc_action-go_tutorial. " Go to tutorial + lcl_app=>user( )->set_repo_show( '' ). " Clear show_id + ev_state = gc_event_state-re_render. " Assume we are on main page " SAP GUI actions - WHEN gc_action-jump. + WHEN gc_action-jump. " Open object editor lcl_html_action_utils=>jump_decode( EXPORTING iv_string = iv_getdata IMPORTING ev_obj_type = ls_item-obj_type ev_obj_name = ls_item-obj_name ). lcl_objects=>jump( ls_item ). ev_state = gc_event_state-no_more_act. + WHEN gc_action-jump_pkg. " Open SE80 + lcl_services_repo=>open_se80( |{ iv_getdata }| ). + ev_state = gc_event_state-no_more_act. + " DB actions WHEN gc_action-db_display OR gc_action-db_edit. " DB Display/Edit ei_page = get_page_db_by_name( iv_name = iv_action iv_getdata = iv_getdata ). @@ -125,9 +132,15 @@ CLASS lcl_gui_router IMPLEMENTATION. WHEN gc_action-abapgit_home. " Go abapGit homepage lcl_services_abapgit=>open_abapgit_homepage( ). ev_state = gc_event_state-no_more_act. + WHEN gc_action-abapgit_wiki. " Go abapGit wikipage + lcl_services_abapgit=>open_abapgit_wikipage( ). + ev_state = gc_event_state-no_more_act. WHEN gc_action-abapgit_install. " Install abapGit lcl_services_abapgit=>install_abapgit( ). ev_state = gc_event_state-re_render. + WHEN gc_action-abapgit_install_pi. " Install abapGit plugins + lcl_services_abapgit=>install_abapgit_pi( ). + ev_state = gc_event_state-re_render. " Repository services actions WHEN gc_action-repo_newoffline. " New offline repo diff --git a/src/zabapgit_object_clas.prog.abap b/src/zabapgit_object_clas.prog.abap index a978ed0e2..5549a80c8 100644 --- a/src/zabapgit_object_clas.prog.abap +++ b/src/zabapgit_object_clas.prog.abap @@ -21,6 +21,8 @@ CLASS lcl_object_clas DEFINITION INHERITING FROM lcl_objects_program. TYPES: ty_sotr_tt TYPE STANDARD TABLE OF ty_sotr WITH DEFAULT KEY. + TYPES: ty_seocompotx_tt TYPE STANDARD TABLE OF seocompotx WITH DEFAULT KEY. + DATA mv_skip_testclass TYPE abap_bool. METHODS deserialize_abap @@ -216,11 +218,21 @@ CLASS lcl_object_clas IMPLEMENTATION. DATA: lt_reposrc TYPE STANDARD TABLE OF ty_reposrc, ls_reposrc LIKE LINE OF lt_reposrc, - lt_includes TYPE STANDARD TABLE OF ty_includes. + lt_includes TYPE STANDARD TABLE OF ty_includes, + lv_clsname TYPE seoclsname. - lt_includes = get_all_class_includes( ). - ASSERT lines( lt_includes ) > 0. + lv_clsname = ms_item-obj_name. + + CASE ms_item-obj_type. + WHEN 'CLAS'. + lt_includes = get_all_class_includes( ). + ASSERT lines( lt_includes ) > 0. + WHEN 'INTF'. + APPEND cl_oo_classname_service=>get_interfacepool_name( lv_clsname ) TO lt_includes. + WHEN OTHERS. + ASSERT 0 = 1. + ENDCASE. SELECT unam udat utime FROM reposrc INTO TABLE lt_reposrc @@ -616,15 +628,16 @@ CLASS lcl_object_clas IMPLEMENTATION. METHOD serialize_xml. - DATA: ls_vseoclass TYPE vseoclass, - lv_cp TYPE program, - lt_tpool TYPE textpool_table, - lv_object TYPE dokhl-object, - lv_state TYPE dokhl-dokstate, - ls_vseointerf TYPE vseointerf, - ls_clskey TYPE seoclskey, - lt_sotr TYPE ty_sotr_tt, - lt_lines TYPE tlinetab. + DATA: ls_vseoclass TYPE vseoclass, + lv_cp TYPE program, + lt_tpool TYPE textpool_table, + lv_object TYPE dokhl-object, + lv_state TYPE dokhl-dokstate, + lt_descriptions TYPE ty_seocompotx_tt, + ls_vseointerf TYPE vseointerf, + ls_clskey TYPE seoclskey, + lt_sotr TYPE ty_sotr_tt, + lt_lines TYPE tlinetab. ls_clskey-clsname = ms_item-obj_name. @@ -712,6 +725,14 @@ CLASS lcl_object_clas IMPLEMENTATION. ig_data = lt_lines ). ENDIF. + SELECT * FROM seocompotx INTO TABLE lt_descriptions + WHERE clsname = ls_clskey-clsname. + DELETE lt_descriptions WHERE descript IS INITIAL. + IF lines( lt_descriptions ) > 0. + io_xml->add( iv_name = 'DESCRIPTIONS' + ig_data = lt_descriptions ). + ENDIF. + ENDMETHOD. "serialize_xml METHOD lif_object~deserialize. @@ -871,14 +892,15 @@ CLASS lcl_object_clas IMPLEMENTATION. METHOD deserialize_abap. - DATA: ls_vseoclass TYPE vseoclass, - ls_vseointerf TYPE vseointerf, - lt_source TYPE seop_source_string, - lt_locals_def TYPE seop_source_string, - lt_locals_imp TYPE seop_source_string, - lt_locals_mac TYPE seop_source_string, - lt_testclasses TYPE seop_source_string, - ls_clskey TYPE seoclskey. + DATA: ls_vseoclass TYPE vseoclass, + ls_vseointerf TYPE vseointerf, + lt_source TYPE seop_source_string, + lt_locals_def TYPE seop_source_string, + lt_locals_imp TYPE seop_source_string, + lt_locals_mac TYPE seop_source_string, + lt_testclasses TYPE seop_source_string, + lt_descriptions TYPE ty_seocompotx_tt, + ls_clskey TYPE seoclskey. lt_source = mo_files->read_abap( ). @@ -977,6 +999,11 @@ CLASS lcl_object_clas IMPLEMENTATION. it_source = lt_source ). ENDTRY. + io_xml->read( EXPORTING iv_name = 'DESCRIPTIONS' + CHANGING cg_data = lt_descriptions ). + DELETE FROM seocompotx WHERE clsname = ls_clskey-clsname. + INSERT seocompotx FROM TABLE lt_descriptions. + lcl_objects_activation=>add_item( ms_item ). ENDMETHOD. "deserialize diff --git a/src/zabapgit_object_susc.prog.abap b/src/zabapgit_object_susc.prog.abap index 1583f08fe..5830bc7b4 100644 --- a/src/zabapgit_object_susc.prog.abap +++ b/src/zabapgit_object_susc.prog.abap @@ -32,6 +32,7 @@ CLASS lcl_object_susc IMPLEMENTATION. METHOD lif_object~get_metadata. rs_metadata = get_metadata( ). + rs_metadata-delete_tadir = abap_true. ENDMETHOD. "lif_object~get_metadata METHOD lif_object~exists. diff --git a/src/zabapgit_object_wdyn.prog.abap b/src/zabapgit_object_wdyn.prog.abap index 5f9763e4c..41e34d645 100644 --- a/src/zabapgit_object_wdyn.prog.abap +++ b/src/zabapgit_object_wdyn.prog.abap @@ -522,8 +522,8 @@ CLASS lcl_object_wdyn IMPLEMENTATION. ls_component_key TYPE wdy_md_component_key, ls_view_key TYPE wdy_md_view_key. - FIELD-SYMBOLS: LIKE LINE OF lt_objects. - + FIELD-SYMBOLS: LIKE LINE OF lt_objects, + LIKE LINE OF rs_component-ctlr_metadata. CLEAR mt_components. CLEAR mt_sources. @@ -550,6 +550,21 @@ CLASS lcl_object_wdyn IMPLEMENTATION. definition-component_name ASCENDING definition-controller_name ASCENDING. + LOOP AT rs_component-ctlr_metadata ASSIGNING . + SORT -descriptions. + SORT -controller_usages. + SORT -controller_components. + SORT -controller_component_texts. + SORT -controller_parameters. + SORT -controller_parameter_texts. + SORT -context_nodes. + SORT -context_attributes. + SORT -context_mappings. + SORT -fieldgroups. + SORT -controller_exceptions. + SORT -controller_exception_texts. + ENDLOOP. + SORT mt_components BY component_name ASCENDING controller_name ASCENDING diff --git a/src/zabapgit_page.prog.abap b/src/zabapgit_page.prog.abap index 8d99436c1..0f5d31f6f 100644 --- a/src/zabapgit_page.prog.abap +++ b/src/zabapgit_page.prog.abap @@ -137,7 +137,10 @@ CLASS lcl_gui_page_super IMPLEMENTATION. IF iv_show_package = abap_true. ro_html->add( '' ). - ro_html->add( |{ io_repo->get_package( ) }| ). + ro_html->add( '' ). + ro_html->add_anchor( iv_txt = io_repo->get_package( ) + iv_act = |{ gc_action-jump_pkg }?{ io_repo->get_package( ) }| ). + ro_html->add( '' ). ENDIF. ro_html->add( '' ). diff --git a/src/zabapgit_page_debug.prog.abap b/src/zabapgit_page_debug.prog.abap index 151ca4017..e7bd0446a 100644 --- a/src/zabapgit_page_debug.prog.abap +++ b/src/zabapgit_page_debug.prog.abap @@ -6,10 +6,9 @@ CLASS lcl_gui_page_debuginfo DEFINITION FINAL INHERITING FROM lcl_gui_page_super PUBLIC SECTION. METHODS lif_gui_page~render REDEFINITION. + PRIVATE SECTION. METHODS scripts RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper. - - PRIVATE SECTION. METHODS render_debug_info RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper. METHODS render_supported_object_types diff --git a/src/zabapgit_page_diff.prog.abap b/src/zabapgit_page_diff.prog.abap index e026a1d8e..0cab80365 100644 --- a/src/zabapgit_page_diff.prog.abap +++ b/src/zabapgit_page_diff.prog.abap @@ -54,9 +54,9 @@ CLASS lcl_gui_page_diff DEFINITION FINAL INHERITING FROM lcl_gui_page_super. EXPORTING ev_lattr TYPE string ev_rattr TYPE string. METHODS append_diff - IMPORTING it_remote TYPE ty_files_tt - it_local TYPE ty_files_item_tt - is_status TYPE ty_result + IMPORTING it_remote TYPE ty_files_tt + it_local TYPE ty_files_item_tt + is_status TYPE ty_result RAISING lcx_exception. ENDCLASS. "lcl_gui_page_diff @@ -121,8 +121,8 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. METHOD append_diff. DATA: - ls_r_dummy LIKE LINE OF it_remote ##NEEDED, - ls_l_dummy LIKE LINE OF it_local ##NEEDED. + ls_r_dummy LIKE LINE OF it_remote ##NEEDED, + ls_l_dummy LIKE LINE OF it_local ##NEEDED. FIELD-SYMBOLS: LIKE LINE OF it_remote, @@ -202,14 +202,14 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. CREATE OBJECT ro_html. - ro_html->add( '' ). "#EC NOTEXT - ro_html->add( '' ). "#EC NOTEXT - ro_html->add( '' ). "#EC NOTEXT - ro_html->add( 'LOCAL' ). "#EC NOTEXT - ro_html->add( '' ). "#EC NOTEXT - ro_html->add( 'REMOTE' ). "#EC NOTEXT - ro_html->add( '' ). "#EC NOTEXT - ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( 'LOCAL' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( 'REMOTE' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT + ro_html->add( '' ). "#EC NOTEXT ENDMETHOD. " render_table_head. @@ -255,19 +255,24 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. METHOD render_lines. - DATA: lt_diffs TYPE lcl_diff=>ty_diffs_tt, + DATA: lo_highlighter TYPE REF TO lcl_code_highlighter, + lt_diffs TYPE lcl_diff=>ty_diffs_tt, lv_local TYPE string, lv_remote TYPE string, lv_lattr TYPE string, lv_rattr TYPE string, + lv_highlight TYPE abap_bool, lv_insert_nav TYPE abap_bool. FIELD-SYMBOLS LIKE LINE OF lt_diffs. - + CREATE OBJECT lo_highlighter. CREATE OBJECT ro_html. + lt_diffs = is_diff-o_diff->get( ). + lv_highlight = boolc( is_diff-filename CP '*.abap' ). + LOOP AT lt_diffs ASSIGNING . IF -short = abap_false. lv_insert_nav = abap_true. @@ -280,11 +285,19 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ENDIF. IF is_diff-mod = c_mod-remote. " Remote file leading changes - lv_local = escape( val = -old format = cl_abap_format=>e_html_attr ). - lv_remote = escape( val = -new format = cl_abap_format=>e_html_attr ). + lv_local = -old. + lv_remote = -new. ELSE. " Local leading changes or both were modified - lv_local = escape( val = -new format = cl_abap_format=>e_html_attr ). - lv_remote = escape( val = -old format = cl_abap_format=>e_html_attr ). + lv_local = -new. + lv_remote = -old. + ENDIF. + + IF lv_highlight = abap_true. + lv_local = lo_highlighter->process_line( lv_local ). + lv_remote = lo_highlighter->process_line( lv_remote ). + ELSE. + lv_local = escape( val = lv_local format = cl_abap_format=>e_html_attr ). + lv_remote = escape( val = lv_remote format = cl_abap_format=>e_html_attr ). ENDIF. get_line_hl( EXPORTING iv_mod = is_diff-mod @@ -313,21 +326,21 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. " Both file changed ? Or line updated ? - All yellow IF iv_mod = c_mod-both OR iv_result = lcl_diff=>c_diff-update. - ev_lattr = ' class="diff_upd"'. "#EC NOTEXT - ev_rattr = ' class="diff_upd"'. "#EC NOTEXT + ev_lattr = ' class="diff_upd"'. "#EC NOTEXT + ev_rattr = ' class="diff_upd"'. "#EC NOTEXT ELSEIF iv_mod = c_mod-local. " Changed locally CASE iv_result. WHEN lcl_diff=>c_diff-insert. - ev_lattr = ' class="diff_ins"'. "#EC NOTEXT + ev_lattr = ' class="diff_ins"'. "#EC NOTEXT WHEN lcl_diff=>c_diff-delete. - ev_rattr = ' class="diff_del"'. "#EC NOTEXT + ev_rattr = ' class="diff_del"'. "#EC NOTEXT ENDCASE. ELSEIF iv_mod = c_mod-remote. " Changed remotely - invert sides CASE iv_result. WHEN lcl_diff=>c_diff-insert. - ev_rattr = ' class="diff_ins"'. "#EC NOTEXT + ev_rattr = ' class="diff_ins"'. "#EC NOTEXT WHEN lcl_diff=>c_diff-delete. - ev_lattr = ' class="diff_del"'. "#EC NOTEXT + ev_lattr = ' class="diff_del"'. "#EC NOTEXT ENDCASE. ENDIF. @@ -343,6 +356,11 @@ CLASS lcl_gui_page_diff IMPLEMENTATION. ro_html->add( title( 'DIFF' ) ). LOOP AT mt_diff_files INTO ls_diff_file. + lcl_progress=>show( iv_key = 'Diff' + iv_current = sy-tabix + iv_total = lines( mt_diff_files ) + iv_text = |Render Diff - { ls_diff_file-filename }| ). + ro_html->add( render_diff( ls_diff_file ) ). ENDLOOP. diff --git a/src/zabapgit_page_main.prog.abap b/src/zabapgit_page_main.prog.abap index a294c53a8..7ab201350 100644 --- a/src/zabapgit_page_main.prog.abap +++ b/src/zabapgit_page_main.prog.abap @@ -114,9 +114,10 @@ CLASS lcl_gui_page_main IMPLEMENTATION. METHOD lif_gui_page~render. - DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt, - lx_error TYPE REF TO lcx_exception, - lo_repo LIKE LINE OF lt_repos. + DATA: lt_repos TYPE lcl_repo_srv=>ty_repo_tt, + lx_error TYPE REF TO lcx_exception, + lo_tutorial TYPE REF TO lcl_gui_view_tutorial, + lo_repo LIKE LINE OF lt_repos. retrieve_active_repo( ). " Get and validate key of user default repo @@ -137,8 +138,13 @@ CLASS lcl_gui_page_main IMPLEMENTATION. IF lines( lt_repos ) = 0 AND lx_error IS INITIAL. ro_html->add( render_explore( ) ). ELSE. - lo_repo = lcl_app=>repo_srv( )->get( mv_show ). - ro_html->add( render_repo( lo_repo ) ). + IF mv_show IS INITIAL. + CREATE OBJECT lo_tutorial. + ro_html->add( lo_tutorial->lif_gui_page~render( ) ). + ELSE. + lo_repo = lcl_app=>repo_srv( )->get( mv_show ). + ro_html->add( render_repo( lo_repo ) ). + ENDIF. ENDIF. ro_html->add( footer( ) ). @@ -165,17 +171,10 @@ CLASS lcl_gui_page_main IMPLEMENTATION. lo_repo = lcl_app=>repo_srv( )->get( mv_show ). CATCH lcx_exception. CLEAR mv_show. + lcl_app=>user( )->set_repo_show( mv_show ). ENDTRY. ENDIF. - IF mv_show IS INITIAL. " Fall back to first available repo - READ TABLE lt_repos INTO lo_repo INDEX 1. - IF sy-subrc = 0. - mv_show = lo_repo->get_key( ). - lcl_app=>user( )->set_repo_show( mv_show ). - ENDIF. - ENDIF. - IF lv_show_old <> mv_show AND NOT mv_show IS INITIAL. CREATE OBJECT mo_repo_content EXPORTING @@ -186,28 +185,32 @@ CLASS lcl_gui_page_main IMPLEMENTATION. METHOD build_main_menu. - DATA lo_betasub TYPE REF TO lcl_html_toolbar. + DATA: lo_advsub TYPE REF TO lcl_html_toolbar, + lo_helpsub TYPE REF TO lcl_html_toolbar. CREATE OBJECT ro_menu. - CREATE OBJECT lo_betasub. + CREATE OBJECT lo_advsub. + CREATE OBJECT lo_helpsub. - lo_betasub->add( iv_txt = 'Database util' iv_act = gc_action-go_db ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Package to zip' iv_act = gc_action-zip_package ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Transport to zip' iv_act = gc_action-zip_transport ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Object to files' iv_act = gc_action-zip_object ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Test changed by' iv_act = c_actions-changed_by ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Page playground' iv_act = gc_action-go_playground ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Debug info' iv_act = gc_action-go_debuginfo ) ##NO_TEXT. - lo_betasub->add( iv_txt = 'Settings' iv_act = gc_action-go_settings ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Database util' iv_act = gc_action-go_db ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Package to zip' iv_act = gc_action-zip_package ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Transport to zip' iv_act = gc_action-zip_transport ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Object to files' iv_act = gc_action-zip_object ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Test changed by' iv_act = c_actions-changed_by ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Page playground' iv_act = gc_action-go_playground ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Debug info' iv_act = gc_action-go_debuginfo ) ##NO_TEXT. + lo_advsub->add( iv_txt = 'Settings' iv_act = gc_action-go_settings ) ##NO_TEXT. - ro_menu->add( iv_txt = 'Clone' iv_act = gc_action-repo_clone ) ##NO_TEXT. - ro_menu->add( iv_txt = 'Explore' iv_act = gc_action-go_explore ) ##NO_TEXT. - ro_menu->add( iv_txt = 'New offline repo' iv_act = gc_action-repo_newoffline ) ##NO_TEXT. - IF lcl_services_abapgit=>needs_installation( ) = abap_true. - ro_menu->add( iv_txt = 'Get abapGit' iv_act = gc_action-abapgit_install ) ##NO_TEXT. - ENDIF. - ro_menu->add( iv_txt = 'Advanced' io_sub = lo_betasub ) ##NO_TEXT. + lo_helpsub->add( iv_txt = 'Tutorial' iv_act = gc_action-go_tutorial ) ##NO_TEXT. + lo_helpsub->add( iv_txt = 'abapGit wiki' iv_act = gc_action-abapgit_wiki ) ##NO_TEXT. + + ro_menu->add( iv_txt = '+ Clone' iv_act = gc_action-repo_clone ) ##NO_TEXT. + ro_menu->add( iv_txt = '+ Offline' iv_act = gc_action-repo_newoffline ) ##NO_TEXT. + ro_menu->add( iv_txt = 'Explore' iv_act = gc_action-go_explore ) ##NO_TEXT. + + ro_menu->add( iv_txt = 'Advanced' io_sub = lo_advsub ) ##NO_TEXT. + ro_menu->add( iv_txt = 'Help' io_sub = lo_helpsub ) ##NO_TEXT. ENDMETHOD. "build main_menu @@ -285,9 +288,9 @@ CLASS lcl_gui_page_main IMPLEMENTATION. IF lo_favbar->count( ) > 0. ro_html->add( lo_favbar->render( iv_sort = abap_true ) ). ELSE. - ro_html->add( 'No favorites found. Please' - && ' click icon repo toolbar to add' - && ' it as favourite. Choose a repo there →' ). + ro_html->add( `No favorites so far. For more info please check ` ). + ro_html->add_anchor( iv_txt = 'tutorial' iv_act = gc_action-go_tutorial ). + ro_html->add( '' ). ENDIF. ro_html->add( '' ). diff --git a/src/zabapgit_page_settings.prog.abap b/src/zabapgit_page_settings.prog.abap index a81637801..4f11a9d5c 100644 --- a/src/zabapgit_page_settings.prog.abap +++ b/src/zabapgit_page_settings.prog.abap @@ -3,14 +3,22 @@ *&---------------------------------------------------------------------* CLASS lcl_gui_page_settings DEFINITION FINAL INHERITING FROM lcl_gui_page_super. + PUBLIC SECTION. + METHODS lif_gui_page~render REDEFINITION. METHODS lif_gui_page~on_event REDEFINITION. CONSTANTS: BEGIN OF c_action, save_settings TYPE string VALUE 'save_settings', END OF c_action. + PRIVATE SECTION. + + DATA: + mo_settings TYPE REF TO lcl_settings, + mv_error TYPE abap_bool. + METHODS render_proxy RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper. METHODS render_development_internals @@ -32,14 +40,13 @@ CLASS lcl_gui_page_settings DEFINITION FINAL INHERITING FROM lcl_gui_page_super. RAISING lcx_exception. METHODS read_settings. - DATA: - mo_settings TYPE REF TO lcl_settings, - mv_error TYPE abap_bool. + ENDCLASS. CLASS lcl_gui_page_settings IMPLEMENTATION. METHOD lif_gui_page~render. + CREATE OBJECT ro_html. read_settings( ). @@ -52,10 +59,15 @@ CLASS lcl_gui_page_settings IMPLEMENTATION. ro_html->add( |
| ). ro_html->add( render_development_internals( ) ). ro_html->add( render_form_end( ) ). + + ro_html->add( footer( ) ). + ENDMETHOD. METHOD render_proxy. + CREATE OBJECT ro_html. + ro_html->add( |

Proxy

| ). ro_html->add( || ). ro_html->add( |
| ). @@ -66,11 +78,14 @@ CLASS lcl_gui_page_settings IMPLEMENTATION. ro_html->add( `` ). ro_html->add( |
| ). ro_html->add( |
| ). + ENDMETHOD. METHOD lif_gui_page~on_event. + DATA: lt_post_fields TYPE tihttpnvp. + CASE iv_action. WHEN c_action-save_settings. lt_post_fields = parse_post( it_postdata ). @@ -86,10 +101,12 @@ CLASS lcl_gui_page_settings IMPLEMENTATION. ev_state = gc_event_state-go_back. ENDCASE. + ENDMETHOD. METHOD build_settings. + DATA ls_post_field TYPE ihttpnvp. CREATE OBJECT mo_settings. @@ -111,22 +128,27 @@ CLASS lcl_gui_page_settings IMPLEMENTATION. ELSE. mo_settings->set_run_critical_tests( abap_false ). ENDIF. + ENDMETHOD. METHOD validate_settings. + IF ( mo_settings->get_proxy_url( ) IS NOT INITIAL AND mo_settings->get_proxy_port( ) IS INITIAL ) OR ( mo_settings->get_proxy_url( ) IS INITIAL AND mo_settings->get_proxy_port( ) IS NOT INITIAL ). MESSAGE 'If specifying proxy, specify both URL and port' TYPE 'W'. ENDIF. + ENDMETHOD. METHOD parse_post. + DATA lv_serialized_post_data TYPE string. CONCATENATE LINES OF it_postdata INTO lv_serialized_post_data. rt_post_fields = cl_http_utility=>if_http_utility~string_to_fields( lv_serialized_post_data ). + ENDMETHOD. @@ -141,36 +163,47 @@ CLASS lcl_gui_page_settings IMPLEMENTATION. ENDMETHOD. METHOD render_form_begin. + CREATE OBJECT ro_html. ro_html->add( '
' ). ro_html->add( `
` ). + ENDMETHOD. METHOD render_form_end. + CREATE OBJECT ro_html. ro_html->add( '' ). ro_html->add( '
' ). ro_html->add( '
' ). + ENDMETHOD. METHOD read_settings. + DATA lo_settings_persistence TYPE REF TO lcl_persistence_settings. + lo_settings_persistence = lcl_app=>settings( ). mo_settings = lo_settings_persistence->read( ). + ENDMETHOD. METHOD render_development_internals. + DATA lv_checked TYPE string. + IF mo_settings->get_run_critical_tests( ) = abap_true. lv_checked = 'checked'. ENDIF. + CREATE OBJECT ro_html. ro_html->add( |

abapGit Development Internals settings

| ). ro_html->add( ` Enable critical unit tests (see LTCL_DANGEROUS)` ). ro_html->add( |
| ). ro_html->add( |
| ). + ENDMETHOD. ENDCLASS. \ No newline at end of file diff --git a/src/zabapgit_page_stage.prog.abap b/src/zabapgit_page_stage.prog.abap index bd254fdaa..9c1893be2 100644 --- a/src/zabapgit_page_stage.prog.abap +++ b/src/zabapgit_page_stage.prog.abap @@ -239,9 +239,11 @@ CLASS lcl_gui_page_stage IMPLEMENTATION. iv_style = 'display: none' iv_txt = 'Commit' iv_opt = gc_html_opt-emphas ) ##NO_TEXT. - ro_html->add_anchor( iv_act = |{ c_action-stage_all }| - iv_id = 'act_commit_all' - iv_txt = 'Add all and commit') ##NO_TEXT. + IF lines( ms_files-local ) > 0. + ro_html->add_anchor( iv_act = |{ c_action-stage_all }| + iv_id = 'act_commit_all' + iv_txt = 'Add all and commit') ##NO_TEXT. + ENDIF. ro_html->add( '' ). ENDMETHOD. "render_menu diff --git a/src/zabapgit_popups.prog.abap b/src/zabapgit_popups.prog.abap index 89d8ba4b8..6ee6af2f0 100644 --- a/src/zabapgit_popups.prog.abap +++ b/src/zabapgit_popups.prog.abap @@ -59,7 +59,13 @@ CLASS lcl_popups DEFINITION FINAL. default_button TYPE char1 DEFAULT '1' display_cancel_button TYPE char1 DEFAULT abap_true RETURNING VALUE(rv_answer) TYPE char1 - RAISING lcx_exception. + RAISING lcx_exception, + popup_to_inform + IMPORTING + titlebar TYPE clike + text_message TYPE clike + RAISING lcx_exception. + ENDCLASS. @@ -438,4 +444,22 @@ CLASS lcl_popups IMPLEMENTATION. ENDMETHOD. "popup_to_confirm + METHOD popup_to_inform. + + DATA: lv_line1 TYPE char70, + lv_line2 TYPE char70. + + lv_line1 = text_message. + IF strlen( text_message ) > 70. + lv_line2 = text_message+70. + ENDIF. + + CALL FUNCTION 'POPUP_TO_INFORM' + EXPORTING + titel = titlebar + txt1 = lv_line1 + txt2 = lv_line2. + + ENDMETHOD. " popup_to_inform. + ENDCLASS. \ No newline at end of file diff --git a/src/zabapgit_sap_package.prog.abap b/src/zabapgit_sap_package.prog.abap index 2600c9c24..f9c214669 100644 --- a/src/zabapgit_sap_package.prog.abap +++ b/src/zabapgit_sap_package.prog.abap @@ -215,9 +215,10 @@ CLASS lcl_sap_package IMPLEMENTATION. ENDIF. ls_child-devclass = iv_child. + ls_child-dlvunit = li_parent->software_component. ls_child-ctext = iv_child. ls_child-parentcl = iv_parent. - ls_child-component = li_parent->transport_layer. + ls_child-pdevclass = li_parent->transport_layer. ls_child-as4user = sy-uname. create( ls_child ). @@ -247,6 +248,12 @@ CLASS lcl_sap_package IMPLEMENTATION. ls_package = is_package. + " Set software component to 'HOME' if none is set at this point. + " Otherwise SOFTWARE_COMPONENT_INVALID will be raised. + IF ls_package-dlvunit IS INITIAL. + ls_package-dlvunit = 'HOME'. + ENDIF. + cl_package_factory=>create_new_package( EXPORTING i_reuse_deleted_object = abap_true @@ -348,7 +355,7 @@ CLASS lcl_sap_package IMPLEMENTATION. ls_package-devclass = iv_package. ls_package-ctext = iv_package. ls_package-parentcl = '$TMP'. - ls_package-component = 'LOCAL'. + ls_package-dlvunit = 'LOCAL'. ls_package-as4user = sy-uname. create( ls_package ). diff --git a/src/zabapgit_services_abapgit.prog.abap b/src/zabapgit_services_abapgit.prog.abap index 98ba52ce8..1b7fb6efa 100644 --- a/src/zabapgit_services_abapgit.prog.abap +++ b/src/zabapgit_services_abapgit.prog.abap @@ -6,6 +6,7 @@ CLASS lcl_services_abapgit DEFINITION FINAL. PUBLIC SECTION. CONSTANTS c_abapgit_homepage TYPE string VALUE 'http://www.abapgit.org' ##NO_TEXT. + CONSTANTS c_abapgit_wikipage TYPE string VALUE 'https://github.com/larshp/abapGit/wiki'. CONSTANTS c_package_abapgit TYPE devclass VALUE '$ABAPGIT'. CONSTANTS c_package_plugins TYPE devclass VALUE '$ABAPGIT_PLUGINS'. CONSTANTS c_abapgit_url TYPE string VALUE 'https://github.com/larshp/abapGit.git'. @@ -14,11 +15,29 @@ CLASS lcl_services_abapgit DEFINITION FINAL. CLASS-METHODS open_abapgit_homepage RAISING lcx_exception. + CLASS-METHODS open_abapgit_wikipage + RAISING lcx_exception. + CLASS-METHODS install_abapgit RAISING lcx_exception lcx_cancel. - CLASS-METHODS needs_installation - RETURNING VALUE(rv_not_completely_installed) TYPE abap_bool. + CLASS-METHODS install_abapgit_pi + RAISING lcx_exception lcx_cancel. + + CLASS-METHODS is_installed + RETURNING VALUE(rv_installed) TYPE abap_bool. + + CLASS-METHODS is_installed_pi + RETURNING VALUE(rv_installed) TYPE abap_bool. + + PRIVATE SECTION. + + CLASS-METHODS do_install + IMPORTING iv_title TYPE c + iv_text TYPE c + iv_url TYPE string + iv_package TYPE devclass + RAISING lcx_exception. ENDCLASS. "lcl_services_abapgit @@ -35,71 +54,121 @@ CLASS lcl_services_abapgit IMPLEMENTATION. ENDMETHOD. "open_abapgit_homepage + METHOD open_abapgit_wikipage. + + cl_gui_frontend_services=>execute( + EXPORTING document = c_abapgit_wikipage + EXCEPTIONS OTHERS = 1 ). + IF sy-subrc <> 0. + lcx_exception=>raise( 'Opening page in external browser failed.' ). + ENDIF. + + ENDMETHOD. "open_abapgit_wikipage + METHOD install_abapgit. - DATA lv_text TYPE c LENGTH 100. - DATA lv_answer TYPE c LENGTH 1. - DATA lo_repo TYPE REF TO lcl_repo_online. - DATA lv_url TYPE string. - DATA lv_target_package TYPE devclass. + CONSTANTS lc_title TYPE c LENGTH 40 VALUE 'Install abapGit'. + DATA lv_text TYPE c LENGTH 100. - lv_text = |Installing current version ABAPGit to package { c_package_abapgit } | - && |and plugins to { c_package_plugins }|. + IF is_installed( ) = abap_true. + lv_text = 'Seems like abapGit package is already installed. No changes to be done'. + lcl_popups=>popup_to_inform( + titlebar = lc_title + text_message = lv_text ). + RETURN. + ENDIF. + + lv_text = |Confirm to install current version of ABAPGit to package { c_package_abapgit }|. + + do_install( iv_title = lc_title + iv_text = lv_text + iv_url = c_abapgit_url + iv_package = c_package_abapgit ). + + ENDMETHOD. "install_abapgit + + METHOD install_abapgit_pi. + + CONSTANTS lc_title TYPE c LENGTH 40 VALUE 'Install abapGit plugins'. + DATA lv_text TYPE c LENGTH 100. + + IF is_installed_pi( ) = abap_true. + lv_text = 'Seems like abapGit plugins package is already installed. No changes to be done'. + lcl_popups=>popup_to_inform( + titlebar = lc_title + text_message = lv_text ). + RETURN. + ENDIF. + + lv_text = |Confirm to install current version ABAPGit plugins to package { + c_package_plugins }|. + + do_install( iv_title = lc_title + iv_text = lv_text + iv_url = c_plugins_url + iv_package = c_package_plugins ). + + ENDMETHOD. "install_abapgit_pi + + METHOD do_install. + + DATA lo_repo TYPE REF TO lcl_repo_online. + DATA lv_answer TYPE c LENGTH 1. lv_answer = lcl_popups=>popup_to_confirm( - titlebar = 'Install abapGit' - text_question = lv_text + titlebar = iv_title + text_question = iv_text text_button_1 = 'Continue' text_button_2 = 'Cancel' default_button = '2' display_cancel_button = abap_false ). "#EC NOTEXT IF lv_answer <> '1'. - RETURN. ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + RETURN. ENDIF. - DO 2 TIMES. - CASE sy-index. - WHEN 1. - lv_url = c_abapgit_url. - lv_target_package = c_package_abapgit. - WHEN 2. - lv_url = c_plugins_url. - lv_target_package = c_package_plugins. - ENDCASE. + IF abap_false = lcl_app=>repo_srv( )->is_repo_installed( + iv_url = iv_url + iv_target_package = iv_package ). - IF abap_false = lcl_app=>repo_srv( )->is_repo_installed( - iv_url = lv_url - iv_target_package = lv_target_package ). + lcl_sap_package=>create_local( iv_package ). - lcl_sap_package=>create_local( lv_target_package ). + lo_repo = lcl_app=>repo_srv( )->new_online( + iv_url = iv_url + iv_branch_name = 'refs/heads/master' + iv_package = iv_package ) ##NO_TEXT. - lo_repo = lcl_app=>repo_srv( )->new_online( - iv_url = lv_url - iv_branch_name = 'refs/heads/master' "TODO replace with HEAD ? - iv_package = lv_target_package ) ##NO_TEXT. - - lo_repo->status( ). " check for errors - lo_repo->deserialize( ). - ENDIF. - ENDDO. + lo_repo->status( ). " check for errors + lo_repo->deserialize( ). + ENDIF. COMMIT WORK. - ENDMETHOD. "install_abapgit + ENDMETHOD. " do_install. - METHOD needs_installation. + + METHOD is_installed. TRY. - IF lcl_app=>repo_srv( )->is_repo_installed( c_abapgit_url ) = abap_false - OR lcl_app=>repo_srv( )->is_repo_installed( c_plugins_url ) = abap_false. - rv_not_completely_installed = abap_true. - ENDIF. + rv_installed = lcl_app=>repo_srv( )->is_repo_installed( c_abapgit_url ). + " TODO, alternative checks for presence in the system CATCH lcx_exception. " cannot be installed anyway in this case, e.g. no connection - rv_not_completely_installed = abap_false. + rv_installed = abap_false. ENDTRY. - ENDMETHOD. "needs_installation + ENDMETHOD. "is_installed + + METHOD is_installed_pi. + + TRY. + rv_installed = lcl_app=>repo_srv( )->is_repo_installed( c_plugins_url ). + " TODO, alternative checks for presence in the system + CATCH lcx_exception. + " cannot be installed anyway in this case, e.g. no connection + rv_installed = abap_false. + ENDTRY. + + ENDMETHOD. "is_installed_pi ENDCLASS. "lcl_services_abapgit \ No newline at end of file diff --git a/src/zabapgit_services_repo.prog.abap b/src/zabapgit_services_repo.prog.abap index eb1e2bfc5..0a4858a85 100644 --- a/src/zabapgit_services_repo.prog.abap +++ b/src/zabapgit_services_repo.prog.abap @@ -43,6 +43,10 @@ CLASS lcl_services_repo DEFINITION FINAL. IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key RAISING lcx_exception. + CLASS-METHODS open_se80 + IMPORTING iv_package TYPE devclass + RAISING lcx_exception. + ENDCLASS. "lcl_services_repo CLASS lcl_services_repo IMPLEMENTATION. @@ -296,4 +300,16 @@ CLASS lcl_services_repo IMPLEMENTATION. ENDMETHOD. " toggle_favorite. + METHOD open_se80. + + CALL FUNCTION 'RS_TOOL_ACCESS' + EXPORTING + OPERATION = 'SHOW' + IN_NEW_WINDOW = 'X' + OBJECT_NAME = iv_package + OBJECT_TYPE = 'DEVC' + WITH_OBJECTLIST = 'X'. + + ENDMETHOD. " open_se80. + ENDCLASS. "lcl_services_repo \ No newline at end of file diff --git a/src/zabapgit_syntax_highlighter.prog.abap b/src/zabapgit_syntax_highlighter.prog.abap new file mode 100644 index 000000000..8ccef3149 --- /dev/null +++ b/src/zabapgit_syntax_highlighter.prog.abap @@ -0,0 +1,763 @@ +*&---------------------------------------------------------------------* +*& Include ZABAPGIT_SYNTAX_HIGHLIGHTER +*&---------------------------------------------------------------------* +*&---------------------------------------------------------------------* +*& Class lcl_code_highligher +*&---------------------------------------------------------------------* + +CLASS ltcl_code_highlighter1 DEFINITION DEFERRED. +CLASS ltcl_code_highlighter2 DEFINITION DEFERRED. + +*----------------------------------------------------------------------* +* CLASS lcl_code_highlighter DEFINITION +*----------------------------------------------------------------------* +CLASS lcl_code_highlighter DEFINITION FRIENDS ltcl_code_highlighter1 ltcl_code_highlighter2. + + PUBLIC SECTION. + CLASS-METHODS: + class_constructor. + + METHODS: + process_line + IMPORTING iv_line TYPE string + RETURNING VALUE(rv_line) TYPE string. + + PRIVATE SECTION. + CONSTANTS: + BEGIN OF c_token, + keyword TYPE c VALUE 'K', + text TYPE c VALUE 'T', + comment TYPE c VALUE 'C', + none TYPE c VALUE 'N', + END OF c_token. + + CONSTANTS: + BEGIN OF c_css, + keyword TYPE string VALUE 'keyword', + text TYPE string VALUE 'text', + comment TYPE string VALUE 'comment', + none TYPE string VALUE 'none', + END OF c_css. + + TYPES: + BEGIN OF ty_match, + token TYPE char1, " Type of matches + offset TYPE i, " Beginning position of the string that should be formatted + length TYPE i, " Length of the string that should be formatted + text_tag TYPE string, " Type of text tag + END OF ty_match. + + TYPES: + ty_match_tt TYPE STANDARD TABLE OF ty_match WITH DEFAULT KEY. + + TYPES: + BEGIN OF ty_regex, + regex TYPE REF TO cl_abap_regex, + token TYPE char1, + END OF ty_regex. + + CLASS-DATA: + BEGIN OF c_regex, + comment TYPE string, + text TYPE string, + keyword TYPE string, + END OF c_regex. + + CLASS-DATA: mo_regex_table TYPE TABLE OF ty_regex. + + METHODS: + parse_line + IMPORTING iv_line TYPE string + RETURNING VALUE(rt_matches) TYPE ty_match_tt. + + METHODS: + order_matches + IMPORTING iv_line TYPE string + CHANGING ct_matches TYPE ty_match_tt. + + METHODS: + format_line + IMPORTING iv_line TYPE string + it_matches TYPE ty_match_tt + RETURNING VALUE(rv_line) TYPE string. + + METHODS: + apply_style + IMPORTING iv_line TYPE string + iv_class TYPE string + RETURNING VALUE(rv_line) TYPE string. + +ENDCLASS. "lcl_code_highlighter DEFINITION + +*----------------------------------------------------------------------* +* Macros +*----------------------------------------------------------------------* + +DEFINE _add_regex. + + CREATE OBJECT ls_regex_table-regex + EXPORTING + pattern = c_regex-&1 + ignore_case = abap_true. + + ls_regex_table-token = c_token-&1. + APPEND ls_regex_table TO mo_regex_table. + +END-OF-DEFINITION. + +*----------------------------------------------------------------------* +* CLASS lcl_code_highlighter IMPLEMENTATION +*----------------------------------------------------------------------* +CLASS lcl_code_highlighter IMPLEMENTATION. + + METHOD class_constructor. + + DATA: ls_regex_table TYPE ty_regex. + + c_regex-comment = '##|"|^\*'. + c_regex-text = '`|''|\||\{|\}'. + c_regex-keyword = '&&|\b(' && + '\*-INPUT|\?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY' && + '|ACCORDING|ACOS|ACTIVATION|ACTUAL|ADD|ADD-CORRESPONDING|ADJACENT|AFTER|ALIAS' && + '|ALIASES|ALIGN|ALL|ALLOCATE|ALPHA|ANALYSIS|ANALYZER|AND|ANY|APPEND|APPENDAGE' && + '|APPENDING|APPLICATION|ARCHIVE|AREA|ARITHMETIC|AS|ASCENDING|ASIN|ASPECT|ASSERT' && + '|ASSIGN|ASSIGNED|ASSIGNING|ASSOCIATION|ASYNCHRONOUS|AT|ATAN|ATTRIBUTES|AUTHORITY' && + '|AUTHORITY-CHECK|AVG|BACK|BACKGROUND|BACKUP|BACKWARD|BADI|BASE|BEFORE|BEGIN' && + '|BETWEEN|BIG|BINARY|BINDING|BIT|BIT-AND|BIT-NOT|BIT-OR|BIT-XOR|BLACK|BLANK' && + '|BLANKS|BLOB|BLOCK|BLOCKS|BLUE|BOUND|BOUNDARIES|BOUNDS|BOXED|BREAK-POINT|BT' && + '|BUFFER|BY|BYPASSING|BYTE|BYTE-CA|BYTE-CN|BYTE-CO|BYTE-CS|BYTE-NA|BYTE-NS' && + '|BYTE-ORDER|C|CA|CALL|CALLING|CASE|CAST|CASTING|CATCH|CEIL|CENTER|CENTERED' && + '|CHAIN|CHAIN-INPUT|CHAIN-REQUEST|CHANGE|CHANGING|CHANNELS|CHARACTER|CHARLEN' && + '|CHAR-TO-HEX|CHECK|CHECKBOX|CI_|CIRCULAR|CLASS|CLASS-CODING|CLASS-DATA' && + '|CLASS-EVENTS|CLASS-METHODS|CLASS-POOL|CLEANUP|CLEAR|CLIENT|CLOB|CLOCK|CLOSE' && + '|CN|CNT|CO|COALESCE|CODE|CODING|COL_BACKGROUND|COL_GROUP|COL_HEADING|COL_KEY' && + '|COL_NEGATIVE|COL_NORMAL|COL_POSITIVE|COL_TOTAL|COLLECT|COLOR|COLUMN|COLUMNS' && + '|COMMENT|COMMENTS|COMMIT|COMMON|COMMUNICATION|COMPARING|COMPONENT|COMPONENTS' && + '|COMPRESSION|COMPUTE|CONCAT|CONCATENATE|COND|CONDENSE|CONDITION|CONNECT' && + '|CONNECTION|CONSTANTS|CONTEXT|CONTEXTS|CONTINUE|CONTROL|CONTROLS|CONV|CONVERSION' && + '|CONVERT|COPIES|COPY|CORRESPONDING|COS|COSH|COUNT|COUNTRY|COVER|CP|CPI|CREATE' && + '|CREATING|CRITICAL|CS|CURRENCY|CURRENCY_CONVERSION|CURRENT|CURSOR|CURSOR-SELECTION' && + '|CUSTOMER|CUSTOMER-FUNCTION|DANGEROUS|DATA|DATABASE|DATAINFO|DATASET|DATE' && + '|DAYLIGHT|DBMAXLEN|DD/MM/YY|DD/MM/YYYY|DDMMYY|DEALLOCATE|DECIMAL_SHIFT|DECIMALS' && + '|DECLARATIONS|DEEP|DEFAULT|DEFERRED|DEFINE|DEFINING|DEFINITION|DELETE|DELETING' && + '|DEMAND|DEPARTMENT|DESCENDING|DESCRIBE|DESTINATION|DETAIL|DIALOG|DIRECTORY' && + '|DISCONNECT|DISPLAY|DISPLAY-MODE|DISTANCE|DISTINCT|DIV|DIVIDE|DIVIDE-CORRESPONDING' && + '|DIVISION|DO|DUMMY|DUPLICATE|DUPLICATES|DURATION|DURING|DYNAMIC|DYNPRO|E|EACH' && + '|EDIT|EDITOR-CALL|ELSE|ELSEIF|EMPTY|ENABLED|ENABLING|ENCODING|END|ENDAT|ENDCASE' && + '|ENDCATCH|ENDCHAIN|ENDCLASS|ENDDO|ENDENHANCEMENT|END-ENHANCEMENT-SECTION' && + '|ENDEXEC|ENDFOR|ENDFORM|ENDFUNCTION|ENDIAN|ENDIF|ENDING|ENDINTERFACE' && + '|END-LINES|ENDLOOP|ENDMETHOD|ENDMODULE|END-OF-DEFINITION|END-OF-FILE' && + '|END-OF-PAGE|END-OF-SELECTION|ENDON|ENDPROVIDE|ENDSELECT|ENDTRY|ENDWHILE' && + '|ENGINEERING|ENHANCEMENT|ENHANCEMENT-POINT|ENHANCEMENTS|ENHANCEMENT-SECTION' && + '|ENTRIES|ENTRY|ENVIRONMENT|EQ|EQUAL|EQUIV|ERRORMESSAGE|ERRORS|ESCAPE|ESCAPING' && + '|EVENT|EVENTS|EXACT|EXCEPT|EXCEPTION|EXCEPTIONS|EXCEPTION-TABLE|EXCLUDE|EXCLUDING' && + '|EXEC|EXECUTE|EXISTS|EXIT|EXIT-COMMAND|EXP|EXPAND|EXPANDING|EXPIRATION|EXPLICIT' && + '|EXPONENT|EXPORT|EXPORTING|EXTEND|EXTENDED|EXTENSION|EXTRACT|FAIL|FETCH|FIELD' && + '|FIELD-GROUPS|FIELDS|FIELD-SYMBOL|FIELD-SYMBOLS|FILE|FILTER|FILTERS|FILTER-TABLE' && + '|FINAL|FIND|FIRST|FIRST-LINE|FIXED-POINT|FKEQ|FKGE|FLOOR|FLUSH|FONT|FOR|FORM' && + '|FORMAT|FORWARD|FOUND|FRAC|FRAME|FRAMES|FREE|FRIENDS|FROM|FUNCTION|FUNCTIONALITY' && + '|FUNCTION-POOL|FURTHER|GAPS|GE|GENERATE|GET|GIVING|GKEQ|GKGE|GLOBAL|GRANT|GREATER' && + '|GREEN|GROUP|GROUPS|GT|HANDLE|HANDLER|HARMLESS|HASHED|HAVING|HDB|HEADER|HEADERS' && + '|HEADING|HEAD-LINES|HELP-ID|HELP-REQUEST|HIDE|HIGH|HINT|HOLD|HOTSPOT|I|ICON|ID' && + '|IDENTIFICATION|IDENTIFIER|IDS|IF|IGNORE|IGNORING|IMMEDIATELY|IMPLEMENTATION' && + '|IMPLEMENTATIONS|IMPLEMENTED|IMPLICIT|IMPORT|IMPORTING|IN|INACTIVE|INCL|INCLUDE' && + '|INCLUDES|INCLUDING|INCREMENT|INDEX|INDEX-LINE|INFOTYPES|INHERITING|INIT|INITIAL' && + '|INITIALIZATION|INNER|INOUT|INPUT|INSERT|INSTANCES|INTENSIFIED|INTERFACE' && + '|INTERFACE-POOL|INTERFACES|INTERNAL|INTERVALS|INTO|INVERSE|INVERTED-DATE|IS' && + '|ISO|ITERATOR|ITNO|JOB|JOIN|KEEP|KEEPING|KERNEL|KEY|KEYS|KEYWORDS|KIND' && + '|LANGUAGE|LAST|LATE|LAYOUT|LE|LEADING|LEAVE|LEFT|LEFT-JUSTIFIED|LEFTPLUS' && + '|LEFTSPACE|LEGACY|LENGTH|LESS|LET|LEVEL|LEVELS|LIKE|LINE|LINE-COUNT|LINEFEED' && + '|LINES|LINE-SELECTION|LINE-SIZE|LIST|LISTBOX|LIST-PROCESSING|LITTLE|LLANG' && + '|LOAD|LOAD-OF-PROGRAM|LOB|LOCAL|LOCALE|LOCATOR|LOG|LOG10|LOGFILE|LOGICAL' && + '|LOG-POINT|LONG|LOOP|LOW|LOWER|LPAD|LPI|LT|M|MAIL|MAIN|MAJOR-ID|MAPPING|MARGIN' && + '|MARK|MASK|MATCH|MATCHCODE|MAX|MAXIMUM|MEDIUM|MEMBERS|MEMORY|MESH|MESSAGE' && + '|MESSAGE-ID|MESSAGES|MESSAGING|METHOD|METHODS|MIN|MINIMUM|MINOR-ID|MM/DD/YY' && + '|MM/DD/YYYY|MMDDYY|MOD|MODE|MODIF|MODIFIER|MODIFY|MODULE|MOVE|MOVE-CORRESPONDING' && + '|MULTIPLY|MULTIPLY-CORRESPONDING|NA|NAME|NAMETAB|NATIVE|NB|NE|NESTED|NESTING' && + '|NEW|NEW-LINE|NEW-PAGE|NEW-SECTION|NEXT|NO|NODE|NODES|NO-DISPLAY' && + '|NO-EXTENSION|NO-GAP|NO-GAPS|NO-GROUPING|NO-HEADING|NON-UNICODE|NON-UNIQUE' && + '|NO-SCROLLING|NO-SIGN|NOT|NO-TITLE|NO-TOPOFPAGE|NO-ZERO|NP|NS|NULL|NUMBER' && + '|NUMOFCHAR|O|OBJECT|OBJECTS|OBLIGATORY|OCCURRENCE|OCCURRENCES|OCCURS|OF|OFF' && + '|OFFSET|OLE|ON|ONLY|OPEN|OPTION|OPTIONAL|OPTIONS|OR|ORDER|OTHER|OTHERS|OUT' && + '|OUTER|OUTPUT|OUTPUT-LENGTH|OVERFLOW|OVERLAY|PACK|PACKAGE|PAD|PADDING|PAGE' && + '|PAGES|PARAMETER|PARAMETERS|PARAMETER-TABLE|PART|PARTIALLY|PATTERN|PERCENTAGE' && + '|PERFORM|PERFORMING|PERSON|PF|PF-STATUS|PINK|PLACES|POOL|POS_HIGH|POS_LOW' && + '|POSITION|PRAGMAS|PRECOMPILED|PREFERRED|PRESERVING|PRIMARY|PRINT|PRINT-CONTROL' && + '|PRIORITY|PRIVATE|PROCEDURE|PROCESS|PROGRAM|PROPERTY|PROTECTED|PROVIDE|PUBLIC' && + '|PUSHBUTTON|PUT|QUEUE-ONLY|QUICKINFO|RADIOBUTTON|RAISE|RAISING|RANGE|RANGES' && + '|RAW|READ|READER|READ-ONLY|RECEIVE|RECEIVED|RECEIVER|RECEIVING|RED|REDEFINITION' && + '|REDUCE|REDUCED|REF|REFERENCE|REFRESH|REGEX|REJECT|REMOTE|RENAMING|REPLACE' && + '|REPLACEMENT|REPLACING|REPORT|REQUEST|REQUESTED|RESERVE|RESET|RESOLUTION' && + '|RESPECTING|RESPONSIBLE|RESULT|RESULTS|RESUMABLE|RESUME|RETRY|RETURN|RETURNCODE' && + '|RETURNING|RIGHT|RIGHT-JUSTIFIED|RIGHTPLUS|RIGHTSPACE|RISK|RMC_COMMUNICATION_FAILURE' && + '|RMC_INVALID_STATUS|RMC_SYSTEM_FAILURE|ROLE|ROLLBACK|ROUND|ROWS|RTTI|RUN|SAP|SAP-SPOOL' && + '|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC|SCIENTIFIC_WITH_LEADING_ZERO' && + '|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH|SECONDARY|SECONDS|SECTION|SELECT|SELECTION' && + '|SELECTIONS|SELECTION-SCREEN|SELECTION-SET|SELECTION-SETS|SELECTION-TABLE|SELECT-OPTIONS' && + '|SELECTOR|SELECTOR|SEND|SEPARATE|SEPARATED|SET|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN' && + '|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE' && + '|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP' && + '|STANDARD|STARTING|START-OF-SELECTION|STATE|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO' && + '|STEP-LOOP|STOP|STRLEN|STRUCTURE|STRUCTURES|STYLE|SUBKEY|SUBMATCHES|SUBMIT|SUBROUTINE' && + '|SUBSCREEN|SUBSTRING|SUBTRACT|SUBTRACT-CORRESPONDING|SUFFIX|SUM|SUMMARY|SUMMING|SUPPLIED' && + '|SUPPLY|SUPPRESS|SWITCH|SWITCHSTATES|SYMBOL|SYNCPOINTS|SYNTAX|SYNTAX-CHECK|SYNTAX-TRACE' && + '|SYSTEM-CALL|SYSTEM-EXCEPTIONS|SYSTEM-EXIT|TAB|TABBED|TABLE|TABLES|TABLEVIEW|TABSTRIP' && + '|TAN|TANH|TARGET|TASK|TASKS|TEST|TESTING|TEXT|TEXTPOOL|THEN|THROW|TIME|TIMES|TIMESTAMP' && + '|TIMEZONE|TITLE|TITLEBAR|TITLE-LINES|TO|TOKENIZATION|TOKENS|TOP-LINES|TOP-OF-PAGE' && + '|TRACE-FILE|TRACE-TABLE|TRAILING|TRANSACTION|TRANSFER|TRANSFORMATION|TRANSLATE' && + '|TRANSPORTING|TRMAC|TRUNC|TRUNCATE|TRUNCATION|TRY|TYPE|TYPE-POOL|TYPE-POOLS|TYPES' && + '|ULINE|UNASSIGN|UNDER|UNICODE|UNION|UNIQUE|UNIT|UNIT_CONVERSION|UNIX|UNPACK|UNTIL' && + '|UNWIND|UP|UPDATE|UPPER|USER|USER-COMMAND|USING|UTF-8|VALID|VALUE|VALUE-REQUEST|VALUES' && + '|VARY|VARYING|VERIFICATION-MESSAGE|VERSION|VIA|VIEW|VISIBLE|WAIT|WARNING|WHEN|WHENEVER' && + '|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITHOUT|WITH-TITLE|WORD|WORK' && + '|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE' && + ')\b'. + + " Initialize instances of regular expressions + _add_regex keyword. + _add_regex comment. + _add_regex text. + + ENDMETHOD. "class_constructor + + METHOD parse_line. + + DATA: + lo_regex TYPE REF TO cl_abap_regex, + lo_matcher TYPE REF TO cl_abap_matcher, + lt_result TYPE match_result_tab, + ls_match TYPE ty_match. + + FIELD-SYMBOLS: + TYPE ty_regex, + TYPE match_result, + TYPE ty_match. + + LOOP AT mo_regex_table ASSIGNING . + lo_regex = -regex. + lo_matcher = lo_regex->create_matcher( text = iv_line ). + lt_result = lo_matcher->find_all( ). + + LOOP AT lt_result ASSIGNING . + ls_match-token = -token. + ls_match-offset = -offset. + ls_match-length = -length. + + IF ls_match-token = c_token-text. + ls_match-text_tag = substring( val = iv_line off = ls_match-offset len = ls_match-length ). + ENDIF. + + APPEND ls_match TO rt_matches. + ENDLOOP. + ENDLOOP. + + ENDMETHOD. " parse_line + + METHOD order_matches. + + DATA: + lv_index TYPE sy-tabix, + lv_line_len TYPE i, + lv_prev_token TYPE c, + lv_last_pos TYPE i VALUE 0, + lv_length TYPE i, + ls_match TYPE ty_match. + + FIELD-SYMBOLS: + TYPE ty_match, + TYPE ty_match. + + SORT ct_matches BY offset. + + lv_line_len = strlen( iv_line ). + + LOOP AT ct_matches ASSIGNING . + lv_index = sy-tabix. + + " Delete matches after open text match + IF lv_prev_token = c_token-text AND -token <> c_token-text. + DELETE ct_matches INDEX lv_index. + CONTINUE. + ENDIF. + + CASE -token. + WHEN c_token-comment. + -length = lv_line_len - -offset. + DELETE ct_matches FROM lv_index + 1. + CONTINUE. + WHEN c_token-text. + IF lv_prev_token = c_token-text. + IF -text_tag = -text_tag. + -length = -offset + -length - -offset. + CLEAR lv_prev_token. + ELSEIF -text_tag = '}' AND -text_tag = '{'. + -length = -offset - -offset - 1. " Shifted } out of highlight + -offset = -offset + 1. " Shifted { out of highlight + CLEAR lv_prev_token. + ELSEIF -text_tag = '{'. + -length = -offset - -offset. + CLEAR lv_prev_token. + ELSEIF -text_tag = '}'. + -length = -offset - -offset. + -offset = -offset + 1. " Shifted } out of highlight + CLEAR lv_prev_token. + ENDIF. + DELETE ct_matches INDEX lv_index. + CONTINUE. + ENDIF. + ENDCASE. + + lv_prev_token = -token. + ASSIGN TO . + ENDLOOP. + + " Add entries refering to parts of text that should not be formatted + LOOP AT ct_matches ASSIGNING . + IF -offset > lv_last_pos. + lv_length = -offset - lv_last_pos. + ls_match-token = c_token-none. + ls_match-offset = lv_last_pos. + ls_match-length = lv_length. + INSERT ls_match INTO ct_matches INDEX sy-tabix. + ENDIF. + lv_last_pos = -offset + -length. + ENDLOOP. + + " Add remainder of the string + IF lv_line_len > lv_last_pos. + lv_length = lv_line_len - lv_last_pos. + ls_match-token = c_token-none. + ls_match-offset = lv_last_pos. + ls_match-length = lv_length. + APPEND ls_match TO ct_matches. + ENDIF. + + ENDMETHOD. " order_matches. + + METHOD format_line. + + DATA: + lv_chunk TYPE string, + lv_css_class TYPE string. + + FIELD-SYMBOLS: + TYPE ty_match. + + LOOP AT it_matches ASSIGNING . + lv_chunk = substring( val = iv_line off = -offset len = -length ). + + CASE -token. + WHEN c_token-keyword. + lv_css_class = c_css-keyword. + WHEN c_token-comment. + lv_css_class = c_css-comment. + WHEN c_token-text. + lv_css_class = c_css-text. + WHEN c_token-none. + CLEAR: lv_css_class. + ENDCASE. + + lv_chunk = me->apply_style( iv_line = lv_chunk + iv_class = lv_css_class ). + + rv_line = rv_line && lv_chunk. + ENDLOOP. + + ENDMETHOD. "format_line + + METHOD apply_style. + + DATA lv_escaped TYPE string. + + lv_escaped = escape( val = iv_line format = cl_abap_format=>e_html_attr ). + IF iv_class IS NOT INITIAL. + rv_line = |{ lv_escaped }|. + ELSE. + rv_line = lv_escaped. + ENDIF. + + ENDMETHOD. "apply_style + + METHOD process_line. + + DATA: lt_matches TYPE ty_match_tt. + + IF strlen( iv_line ) = 0. + RETURN. + ENDIF. + + lt_matches = me->parse_line( iv_line ). + + me->order_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches ). + + rv_line = me->format_line( iv_line = iv_line + it_matches = lt_matches ). + + ENDMETHOD. " process_line + +ENDCLASS. " lcl_code_highlighter IMPLEMENTATION + +*----------------------------------------------------------------------* +* CLASS ltcl_code_highlighter definition +*----------------------------------------------------------------------* +CLASS ltcl_code_highlighter1 DEFINITION FINAL + FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + + PRIVATE SECTION. + + DATA: + mo TYPE REF TO lcl_code_highlighter, + mt_after_parse TYPE lcl_code_highlighter=>ty_match_tt, + ms_match TYPE lcl_code_highlighter=>ty_match, + mt_after_order TYPE lcl_code_highlighter=>ty_match_tt. + + METHODS: + setup, + test IMPORTING iv_line TYPE string, + test01 FOR TESTING, + test02 FOR TESTING, + test03 FOR TESTING, + test04 FOR TESTING, + test05 FOR TESTING, + test06 FOR TESTING, + test07 FOR TESTING. + +ENDCLASS. " ltcl_code_highlighter +*----------------------------------------------------------------------* +* CLASS ltcl_code_highlighter IMPLEMENTATION +*----------------------------------------------------------------------* +CLASS ltcl_code_highlighter1 IMPLEMENTATION. + + DEFINE _generate_parse. + ms_match-token = &1. + ms_match-offset = &2. + ms_match-length = &3. + ms_match-text_tag = &4. + APPEND ms_match to mt_after_parse. + END-OF-DEFINITION. + + DEFINE _generate_order. + ms_match-token = &1. + ms_match-offset = &2. + ms_match-length = &3. + ms_match-text_tag = &4. + APPEND ms_match to mt_after_order. + END-OF-DEFINITION. + + METHOD setup. + CREATE OBJECT mo. + CLEAR mt_after_parse. + CLEAR mt_after_order. + ENDMETHOD. " setup + + METHOD test. + + DATA: lt_matches_act TYPE lcl_code_highlighter=>ty_match_tt. + + + lt_matches_act = mo->parse_line( iv_line ). + + SORT lt_matches_act BY offset. + + cl_abap_unit_assert=>assert_equals( exp = mt_after_parse + act = lt_matches_act + msg = | Error during parsing: { iv_line }| ). + + IF lines( mt_after_order ) > 0. + mo->order_matches( EXPORTING iv_line = iv_line + CHANGING ct_matches = lt_matches_act ). + + cl_abap_unit_assert=>assert_equals( exp = mt_after_order + act = lt_matches_act + msg = | Error during ordering: { iv_line }| ). + ENDIF. + + ENDMETHOD. + + +****************************************************** +* Test parsing and ordering of comments * +****************************************************** + METHOD test01. + + DATA: lv_line TYPE string. + + lv_line = '* commented out line with key word data'. + + " Generate table with expected values after parsing + _generate_parse 'C' 0 1 ''. + _generate_parse 'K' 12 3 ''. + _generate_parse 'K' 16 4 ''. + _generate_parse 'K' 21 4 ''. + _generate_parse 'K' 26 3 ''. + _generate_parse 'K' 30 4 ''. + _generate_parse 'K' 35 4 ''. + + " Generate table with expected values after ordering + _generate_order 'C' 0 39 ''. + + test( lv_line ). + + ENDMETHOD. + +****************************************************** +* Test parsing and ordering of remainder of string * +****************************************************** + METHOD test02. + + DATA: lv_line TYPE string. + + lv_line = 'data: lv_var_name type string.'. + + " Generate table with expected values after parsing + _generate_parse 'K' 0 4 ''. + _generate_parse 'K' 18 4 ''. + + " Generate table with expected values after ordering + _generate_order 'K' 0 4 ''. + _generate_order 'N' 4 14 ''. + _generate_order 'K' 18 4 ''. + _generate_order 'N' 22 8 ''. + + test( lv_line ). + + ENDMETHOD. + +****************************************************** +* Test parsing and ordering of key words & texts * +****************************************************** + METHOD test03. + + DATA: lv_line TYPE string. + + lv_line = 'call function ''FM_NAME''. " Commented'. + + " Generate table with expected values after parsing + _generate_parse 'K' 0 4 ''. + _generate_parse 'K' 5 8 ''. + _generate_parse 'T' 14 1 ''''. + _generate_parse 'T' 22 1 ''''. + _generate_parse 'C' 25 1 ''. + + " Generate table with expected values after ordering + _generate_order 'K' 0 4 ''. + _generate_order 'N' 4 1 ''. + _generate_order 'K' 5 8 ''. + _generate_order 'N' 13 1 ''. + _generate_order 'T' 14 9 ''''. + _generate_order 'N' 23 2 ''. + _generate_order 'C' 25 11 ''. + + test( lv_line ). + + ENDMETHOD. + +****************************************************** +* Test parsing and ordering of key words in texts * +****************************************************** + METHOD test04. + + DATA: lv_line TYPE string. + + lv_line = 'constants: lc_var type string value ''simpletext data simpletext''.'. + + " Generate table with expected values after parsing + _generate_parse 'K' 0 9 ''. + _generate_parse 'K' 18 4 ''. + _generate_parse 'K' 30 5 ''. + _generate_parse 'T' 36 1 ''''. + _generate_parse 'K' 48 4 ''. + _generate_parse 'T' 63 1 ''''. + + " Generate table with expected values after ordering + _generate_order 'K' 0 9 ''. + _generate_order 'N' 9 9 ''. + _generate_order 'K' 18 4 ''. + _generate_order 'N' 22 8 ''. + _generate_order 'K' 30 5 ''. + _generate_order 'N' 35 1 ''. + _generate_order 'T' 36 28 ''''. + _generate_order 'N' 64 1 ''. + + test( lv_line ). + + ENDMETHOD. + +****************************************************** +* Test parsing and ordering texts in curly brackets * +****************************************************** + METHOD test05. + + DATA: lv_line TYPE string. + + lv_line = 'a = |{ b }={ c }|.'. + + " Generate table with expected values after parsing + _generate_parse 'T' 4 1 '|'. + _generate_parse 'T' 5 1 '{'. + _generate_parse 'T' 9 1 '}'. + _generate_parse 'T' 11 1 '{'. + _generate_parse 'K' 13 1 ''. + _generate_parse 'T' 15 1 '}'. + _generate_parse 'T' 16 1 '|'. + + " Generate table with expected values after ordering + _generate_order 'N' 0 4 ''. + _generate_order 'T' 4 1 '|'. + _generate_order 'N' 5 5 ''. + _generate_order 'T' 10 1 '}'. + _generate_order 'N' 11 2 ''. + _generate_order 'K' 13 1 ''. + _generate_order 'N' 14 2 ''. + _generate_order 'T' 16 1 '}'. + _generate_order 'N' 17 1 ''. + + test( lv_line ). + + ENDMETHOD. + +****************************************************** +* Test parsing and ordering of texts * +****************************************************** + METHOD test06. + + DATA: lv_line TYPE string. + + lv_line = 'lv_line = lc_constant && |XYZ { ''ab'' && |ac{ ''UU'' }| }|'. + + " Generate table with expected values after parsing + _generate_parse 'K' 22 2 ''. + _generate_parse 'T' 25 1 '|'. + _generate_parse 'T' 30 1 '{'. + _generate_parse 'T' 32 1 ''''. + _generate_parse 'T' 35 1 ''''. + _generate_parse 'K' 37 2 ''. + _generate_parse 'T' 40 1 '|'. + _generate_parse 'T' 43 1 '{'. + _generate_parse 'T' 45 1 ''''. + _generate_parse 'T' 48 1 ''''. + _generate_parse 'T' 50 1 '}'. + _generate_parse 'T' 51 1 '|'. + _generate_parse 'T' 53 1 '}'. + _generate_parse 'T' 54 1 '|'. + + " Generate table with expected values after ordering + _generate_order 'N' 00 22 ''. + _generate_order 'K' 22 2 ''. + _generate_order 'N' 24 1 ''. + _generate_order 'T' 25 5 '|'. + _generate_order 'N' 30 2 ''. + _generate_order 'T' 32 4 ''''. + _generate_order 'N' 36 1 ''. + _generate_order 'K' 37 2 ''. + _generate_order 'N' 39 1 ''. + _generate_order 'T' 40 3 '|'. + _generate_order 'N' 43 2 ''. + _generate_order 'T' 45 4 ''''. + _generate_order 'N' 49 2 ''. + _generate_order 'T' 51 1 '}'. + _generate_order 'N' 52 2 ''. + _generate_order 'T' 54 1 '}'. + + test( lv_line ). + + ENDMETHOD. + + METHOD test07. + + DATA: lv_line TYPE string. + + lv_line = 'SELECT * FROM foo'. + + " Generate table with expected values after parsing + _generate_parse 'K' 0 6 ''. + _generate_parse 'K' 9 4 ''. + + test( lv_line ). + + ENDMETHOD. + +ENDCLASS. + +CLASS ltcl_code_highlighter2 DEFINITION FINAL + FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + + PRIVATE SECTION. + + DATA: + mo TYPE REF TO lcl_code_highlighter. + + METHODS: setup. + METHODS: process_line FOR TESTING. + METHODS: format_line FOR TESTING. + METHODS: apply_style FOR TESTING. + +ENDCLASS. " ltcl_code_highlighter + +*----------------------------------------------------------------------* +* CLASS ltcl_code_highlighter IMPLEMENTATION +*----------------------------------------------------------------------* +CLASS ltcl_code_highlighter2 IMPLEMENTATION. + + + METHOD setup. + CREATE OBJECT mo. + ENDMETHOD. + + METHOD format_line. + + DATA: + lv_line TYPE string, + lv_line_act TYPE string, + lv_line_exp TYPE string. + + lv_line = 'call function ''FM_NAME''. " Commented'. + + lv_line_exp = + 'call' && + ' function' && + ' 'FM_NAME'.' && + ' " Commented'. + + lv_line_act = mo->process_line( lv_line ). + + cl_abap_unit_assert=>assert_equals( exp = lv_line_exp + act = lv_line_act + msg = | Error during formating: { lv_line }| ). + + ENDMETHOD. " format_line + + METHOD apply_style. + DATA: + lv_line_act TYPE string. + + " Call the method and compare results + lv_line_act = mo->apply_style( iv_line = 'CALL FUNCTION' + iv_class = lcl_code_highlighter=>c_css-keyword ). + + cl_abap_unit_assert=>assert_equals( act = lv_line_act + exp = 'CALL FUNCTION' + msg = 'Failure during applying of style.' ). + ENDMETHOD. " apply_style + + METHOD process_line. + DATA: + lv_line_act TYPE string. + + " Call the method with empty parameter and compare results + lv_line_act = mo->process_line( iv_line = '' ). + + cl_abap_unit_assert=>assert_equals( act = lv_line_act + exp = '' + msg = 'Failure in method process_line.' ). + + " Call the method with non-empty line and compare results + lv_line_act = mo->process_line( iv_line = '* CALL FUNCTION' ). + + cl_abap_unit_assert=>assert_equals( act = lv_line_act + exp = '* CALL FUNCTION' + msg = 'Failure in method process_line.' ). + ENDMETHOD. " process_line + +ENDCLASS. " ltcl_code_highlighter \ No newline at end of file diff --git a/src/zabapgit_syntax_highlighter.prog.xml b/src/zabapgit_syntax_highlighter.prog.xml new file mode 100644 index 000000000..6e2f1cb34 --- /dev/null +++ b/src/zabapgit_syntax_highlighter.prog.xml @@ -0,0 +1,48 @@ + + + + + + ZABAPGIT_SYNTAX_HIGHLIGHTER + A + + + X + + + + + + I + + + + 0000-00-00 + + 0000-00-00 + + + + + E + + + 0000-00-00 + + 0000-00-00 + + + X + + + + R + + Include ZABAPGIT_SYNTAX_HIGHLIGHTER + 35 + + + + + + diff --git a/src/zabapgit_unit_test.prog.abap b/src/zabapgit_unit_test.prog.abap index 9ff966597..dd6c4a514 100644 --- a/src/zabapgit_unit_test.prog.abap +++ b/src/zabapgit_unit_test.prog.abap @@ -97,7 +97,9 @@ CLASS lth_critical_tests IMPLEMENTATION. "These tests may fail if you are locking the entries (e.g. the ZABAPGIT transaction is open) IF lo_settings->get_run_critical_tests( ) = abap_false. - cl_abap_unit_assert=>fail( 'Cancelled. You can enable these tests at the Settings page' ). + cl_abap_unit_assert=>fail( + msg = 'Cancelled. You can enable these tests at the Settings page' + level = if_aunit_constants=>tolerable ). ENDIF. ENDMETHOD. @@ -1846,69 +1848,69 @@ CLASS ltcl_file_status IMPLEMENTATION. LIKE LINE OF lt_results, LIKE LINE OF lt_state. - "STATE FILE SHA1 - _append_state 'zclass1.clas.xml' 'C1_F1'. + "STATE FILE SHA1 + _append_state '$$zclass1.clas.xml' 'C1_F1'. " class1 testclasses is new locally, abap is new remotely " class2 is completely new remotely - _append_state 'zdoma1.doma.xml' 'D1'. - _append_state 'zdoma2.doma.xml' 'D2'. - _append_state 'zdoma3.doma.xml' 'D3'. + _append_state '$$zdoma1.doma.xml' 'D1'. + _append_state '$$zdoma2.doma.xml' 'D2'. + _append_state '$$zdoma3.doma.xml' 'D3'. " doma4 is new locally " doma5 is new remotely - _append_state 'zdoma6.doma.xml' 'D6'. + _append_state '$$zdoma6.doma.xml' 'D6'. " doma7 is not in state - emulate brocken cache " doma8 is not in state - emulate brocken cache - _append_state 'zdoma9.doma.xml' 'D9'. - _append_state 'xfeld.doma.xml' 'XFELD'. " from different package - _append_state 'num01.doma.xml' 'NUM01'. " another from different package + _append_state '$$zdoma9.doma.xml' 'D9'. + _append_state 'num01.doma.xml' 'NUM01'. " another from different package + _append_state 'xfeld.doma.xml' 'XFELD'. " from different package - "LOCAL TYPE NAME FILE SHA1 - _append_local 'CLAS' 'ZCLASS1' 'zclass1.clas.testclasses.abap' 'C1_F3'. - _append_local 'CLAS' 'ZCLASS1' 'zclass1.clas.xml' 'C1_F1'. - _append_local 'DOMA' 'ZDOMA1' 'zdoma1.doma.xml' 'D1'. - _append_local 'DOMA' 'ZDOMA2' 'zdoma2.doma.xml' 'D2_CHANGED_L'. - _append_local 'DOMA' 'ZDOMA3' 'zdoma3.doma.xml' 'D3'. - _append_local 'DOMA' 'ZDOMA4' 'zdoma4.doma.xml' 'D4'. - _append_local 'DOMA' 'ZDOMA6' 'zdoma6.doma.xml' 'D6_CHANGED_L'. - _append_local 'DOMA' 'ZDOMA7' 'zdoma7.doma.xml' 'D7'. - _append_local 'DOMA' 'ZDOMA8' 'zdoma8.doma.xml' 'D8'. + "LOCAL TYPE NAME FILE SHA1 + _append_local 'CLAS' '$$ZCLASS1' '$$zclass1.clas.testclasses.abap' 'C1_F3'. + _append_local 'CLAS' '$$ZCLASS1' '$$zclass1.clas.xml' 'C1_F1'. + _append_local 'DOMA' '$$ZDOMA1' '$$zdoma1.doma.xml' 'D1'. + _append_local 'DOMA' '$$ZDOMA2' '$$zdoma2.doma.xml' 'D2_CHANGED_L'. + _append_local 'DOMA' '$$ZDOMA3' '$$zdoma3.doma.xml' 'D3'. + _append_local 'DOMA' '$$ZDOMA4' '$$zdoma4.doma.xml' 'D4'. + _append_local 'DOMA' '$$ZDOMA6' '$$zdoma6.doma.xml' 'D6_CHANGED_L'. + _append_local 'DOMA' '$$ZDOMA7' '$$zdoma7.doma.xml' 'D7'. + _append_local 'DOMA' '$$ZDOMA8' '$$zdoma8.doma.xml' 'D8'. " dome9 was deleted from local system. Can be found by existing state - "REMOTE FILE SHA1 - _append_remote 'textfile.txt' 'T1'. - _append_remote 'zclass1.clas.abap' 'C1_F2'. " Must be before xml for tougher test - _append_remote 'zclass1.clas.xml' 'C1_F1'. - _append_remote 'zclass2.clas.abap' 'C1_F2'. " Must be before xml for tougher test - _append_remote 'zclass2.clas.xml' 'C1_F1'. - _append_remote 'zdoma1.doma.xml' 'D1'. - _append_remote 'zdoma2.doma.xml' 'D2'. - _append_remote 'zdoma3.doma.xml' 'D3_CHANGED_R'. - _append_remote 'zdoma5.doma.xml' 'D5'. - _append_remote 'zdoma6.doma.xml' 'D6_CHANGED_R'. - _append_remote 'zdoma7.doma.xml' 'D7'. - _append_remote 'zdoma8.doma.xml' 'D8_CHANGED_R'. " This one is changed - _append_remote 'zdoma9.doma.xml' 'D9'. " This one is deleted locally - _append_remote 'xfeld.doma.xml' 'XFELD'. " Object from different package - _append_remote 'num01.doma.xml' 'NUM01_CHANGED'. " Changed object from different package + "REMOTE FILE SHA1 + _append_remote 'textfile.txt' 'T1'. + _append_remote '$$zclass1.clas.abap' 'C1_F2'. " Must be before xml for tougher test + _append_remote '$$zclass1.clas.xml' 'C1_F1'. + _append_remote '$$zclass2.clas.abap' 'C1_F2'. " Must be before xml for tougher test + _append_remote '$$zclass2.clas.xml' 'C1_F1'. + _append_remote '$$zdoma1.doma.xml' 'D1'. + _append_remote '$$zdoma2.doma.xml' 'D2'. + _append_remote '$$zdoma3.doma.xml' 'D3_CHANGED_R'. + _append_remote '$$zdoma5.doma.xml' 'D5'. + _append_remote '$$zdoma6.doma.xml' 'D6_CHANGED_R'. + _append_remote '$$zdoma7.doma.xml' 'D7'. + _append_remote '$$zdoma8.doma.xml' 'D8_CHANGED_R'. " This one is changed + _append_remote '$$zdoma9.doma.xml' 'D9'. " This one is deleted locally + _append_remote 'xfeld.doma.xml' 'XFELD'. " Object from different package + _append_remote 'num01.doma.xml' 'NUM01_CHANGED'. " Changed object from different package - "EXP RESULT TYPE NAME MATCH LST RST PKG PATH FILE - _append_result '' '' ' ' ' ' 'A' '' '/' 'textfile.txt'. - _append_result 'CLAS' 'ZCLASS1' ' ' ' ' 'A' '$Z$' '/' 'zclass1.clas.abap'. - _append_result 'CLAS' 'ZCLASS1' ' ' 'A' ' ' '$Z$' '/' 'zclass1.clas.testclasses.abap'. - _append_result 'CLAS' 'ZCLASS1' 'X' ' ' ' ' '$Z$' '/' 'zclass1.clas.xml'. - _append_result 'CLAS' 'ZCLASS2' ' ' ' ' 'A' '' '/' 'zclass2.clas.abap'. - _append_result 'CLAS' 'ZCLASS2' ' ' ' ' 'A' '' '/' 'zclass2.clas.xml'. - _append_result 'DOMA' 'NUM01' ' ' ' ' 'M' 'SUTI' '/' 'num01.doma.xml'. - _append_result 'DOMA' 'XFELD' 'X' ' ' ' ' 'SUTI' '/' 'xfeld.doma.xml'. - _append_result 'DOMA' 'ZDOMA1' 'X' ' ' ' ' '$Z$' '/' 'zdoma1.doma.xml'. - _append_result 'DOMA' 'ZDOMA2' ' ' 'M' ' ' '$Z$' '/' 'zdoma2.doma.xml'. - _append_result 'DOMA' 'ZDOMA3' ' ' ' ' 'M' '$Z$' '/' 'zdoma3.doma.xml'. - _append_result 'DOMA' 'ZDOMA4' ' ' 'A' ' ' '$Z$' '/' 'zdoma4.doma.xml'. - _append_result 'DOMA' 'ZDOMA5' ' ' ' ' 'A' '' '/' 'zdoma5.doma.xml'. - _append_result 'DOMA' 'ZDOMA6' ' ' 'M' 'M' '$Z$' '/' 'zdoma6.doma.xml'. - _append_result 'DOMA' 'ZDOMA7' 'X' ' ' ' ' '$Z$' '/' 'zdoma7.doma.xml'. - _append_result 'DOMA' 'ZDOMA8' ' ' 'M' 'M' '$Z$' '/' 'zdoma8.doma.xml'. - _append_result 'DOMA' 'ZDOMA9' ' ' 'D' ' ' '' '/' 'zdoma9.doma.xml'. + "EXP RESULT TYPE NAME MATCH LST RST PKG PATH FILE + _append_result '' '' ' ' ' ' 'A' '' '/' 'textfile.txt'. + _append_result 'CLAS' '$$ZCLASS1' ' ' ' ' 'A' '$Z$' '/' '$$zclass1.clas.abap'. + _append_result 'CLAS' '$$ZCLASS1' ' ' 'A' ' ' '$Z$' '/' '$$zclass1.clas.testclasses.abap'. + _append_result 'CLAS' '$$ZCLASS1' 'X' ' ' ' ' '$Z$' '/' '$$zclass1.clas.xml'. + _append_result 'CLAS' '$$ZCLASS2' ' ' ' ' 'A' '' '/' '$$zclass2.clas.abap'. + _append_result 'CLAS' '$$ZCLASS2' ' ' ' ' 'A' '' '/' '$$zclass2.clas.xml'. + _append_result 'DOMA' '$$ZDOMA1' 'X' ' ' ' ' '$Z$' '/' '$$zdoma1.doma.xml'. + _append_result 'DOMA' '$$ZDOMA2' ' ' 'M' ' ' '$Z$' '/' '$$zdoma2.doma.xml'. + _append_result 'DOMA' '$$ZDOMA3' ' ' ' ' 'M' '$Z$' '/' '$$zdoma3.doma.xml'. + _append_result 'DOMA' '$$ZDOMA4' ' ' 'A' ' ' '$Z$' '/' '$$zdoma4.doma.xml'. + _append_result 'DOMA' '$$ZDOMA5' ' ' ' ' 'A' '' '/' '$$zdoma5.doma.xml'. + _append_result 'DOMA' '$$ZDOMA6' ' ' 'M' 'M' '$Z$' '/' '$$zdoma6.doma.xml'. + _append_result 'DOMA' '$$ZDOMA7' 'X' ' ' ' ' '$Z$' '/' '$$zdoma7.doma.xml'. + _append_result 'DOMA' '$$ZDOMA8' ' ' 'M' 'M' '$Z$' '/' '$$zdoma8.doma.xml'. + _append_result 'DOMA' '$$ZDOMA9' ' ' 'D' ' ' '' '/' '$$zdoma9.doma.xml'. + _append_result 'DOMA' 'NUM01' ' ' ' ' 'M' 'SUTI' '/' 'num01.doma.xml'. + _append_result 'DOMA' 'XFELD' 'X' ' ' ' ' 'SUTI' '/' 'xfeld.doma.xml'. lt_results_exp = lt_results. lt_results = lcl_file_status=>calculate_status( @@ -1983,10 +1985,10 @@ CLASS ltcl_sap_package IMPLEMENTATION. CREATE OBJECT lo_log. "EXP RESULT TYPE NAME MATCH LST RST PKG PATH FILE - _append_result 'CLAS' 'ZCLASS1' ' ' ' ' 'A' '$Z$' '/' 'zclass1.clas.abap'. - _append_result 'CLAS' 'ZCLASS1' 'X' ' ' ' ' '$Z$' '/' 'zclass1.clas.xml'. - _append_result 'DOMA' 'ZDOMA1' 'X' ' ' ' ' '$Z$' '/sub' 'zdoma1.doma.xml'. - _append_result 'DOMA' 'ZDOMA2' ' ' 'M' ' ' '$Z$' '/' 'zdoma2.doma.xml'. + _append_result 'CLAS' '$$ZCLASS1' ' ' ' ' 'A' '$Z$' '/' '$$zclass1.clas.abap'. + _append_result 'CLAS' '$$ZCLASS1' 'X' ' ' ' ' '$Z$' '/' '$$zclass1.clas.xml'. + _append_result 'DOMA' '$$ZDOMA1' 'X' ' ' ' ' '$Z$' '/sub' '$$zdoma1.doma.xml'. + _append_result 'DOMA' '$$ZDOMA2' ' ' 'M' ' ' '$Z$' '/' '$$zdoma2.doma.xml'. lcl_sap_package=>check( io_log = lo_log it_results = lt_results @@ -2002,10 +2004,10 @@ CLASS ltcl_sap_package IMPLEMENTATION. CREATE OBJECT lo_log. "EXP RESULT TYPE NAME MATCH LST RST PKG PATH FILE - _append_result 'CLAS' 'ZCLASS1' ' ' ' ' 'A' '$Z$' '/' 'zclass1.clas.abap'. - _append_result 'CLAS' 'ZCLASS1' 'X' ' ' ' ' '$Z$' '/' 'zclass1.clas.xml'. - _append_result 'DOMA' 'ZDOMA1' 'X' ' ' ' ' '$Z$' '/' 'zdoma1.doma.xml'. - _append_result 'DOMA' 'ZDOMA2' ' ' 'M' ' ' '$Z$' '/' 'zdoma1.doma.xml'. + _append_result 'CLAS' '$$ZCLASS1' ' ' ' ' 'A' '$Z$' '/' '$$zclass1.clas.abap'. + _append_result 'CLAS' '$$ZCLASS1' 'X' ' ' ' ' '$Z$' '/' '$$zclass1.clas.xml'. + _append_result 'DOMA' '$$ZDOMA1' 'X' ' ' ' ' '$Z$' '/' '$$zdoma1.doma.xml'. + _append_result 'DOMA' '$$ZDOMA2' ' ' 'M' ' ' '$Z$' '/' '$$zdoma1.doma.xml'. lcl_sap_package=>check( io_log = lo_log it_results = lt_results @@ -2021,9 +2023,9 @@ CLASS ltcl_sap_package IMPLEMENTATION. CREATE OBJECT lo_log. "EXP RESULT TYPE NAME MATCH LST RST PKG PATH FILE - _append_result 'CLAS' 'ZCLASS1' ' ' ' ' 'A' '$Z$' '/' 'zclass1.clas.abap'. - _append_result 'CLAS' 'ZCLASS1' 'X' ' ' ' ' '$Z$' '/' 'zclass1.clas.xml'. - _append_result 'DOMA' 'ZDOMA1' 'X' ' ' ' ' '$Z$' '/' ''. + _append_result 'CLAS' '$$ZCLASS1' ' ' ' ' 'A' '$Z$' '/' '$$zclass1.clas.abap'. + _append_result 'CLAS' '$$ZCLASS1' 'X' ' ' ' ' '$Z$' '/' '$$zclass1.clas.xml'. + _append_result 'DOMA' '$$ZDOMA1' 'X' ' ' ' ' '$Z$' '/' ''. lcl_sap_package=>check( io_log = lo_log it_results = lt_results diff --git a/src/zabapgit_view_tutorial.prog.abap b/src/zabapgit_view_tutorial.prog.abap new file mode 100644 index 000000000..e264ac50c --- /dev/null +++ b/src/zabapgit_view_tutorial.prog.abap @@ -0,0 +1,68 @@ +*&---------------------------------------------------------------------* +*& Include ZABAPGIT_PAGE_TUTORIAL +*&---------------------------------------------------------------------* + +CLASS lcl_gui_view_tutorial DEFINITION FINAL INHERITING FROM lcl_gui_page_super. + PUBLIC SECTION. + METHODS lif_gui_page~render REDEFINITION. + + PRIVATE SECTION. + METHODS render_content + RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper. + +ENDCLASS. "lcl_gui_view_tutorial + +CLASS lcl_gui_view_tutorial IMPLEMENTATION. + + METHOD lif_gui_page~render. + + CREATE OBJECT ro_html. + + ro_html->add( '
' ). + ro_html->add( render_content( ) ). + ro_html->add( '
' ). + + ENDMETHOD. "lif_gui_page~render + + METHOD render_content. + + CREATE OBJECT ro_html. + + _add '

Tutorial

'. + _add '
'. + + _add '

Repository list and favorites

'. + _add '

    '. + _add '
  • To choose a repo press at the favorite bar.
  • '. + _add '
  • To add a repo as favorite'. + _add ' click icon at repo toolbar.
  • '. + _add '

'. + + + _add '

Adding and cloning repos

'. + _add '

    '. + _add `
  • To clone a remote repo (e.g. from github) click `. + ro_html->add_anchor( iv_txt = '+ Clone' iv_act = gc_action-repo_clone ). + _add ' from the top menu. This will copy a remote repo to your system.
  • '. + _add `
  • To add a local package as a repo click `. + ro_html->add_anchor( iv_txt = '+ Offline' iv_act = gc_action-repo_newoffline ). + _add ' from the top menu. This will track a repo which already exist in'. + _add ' the system with abapGit. You''ll be able to attach it to remote origin'. + _add ' or just serialize as a zip file
  • '. + _add '

'. + + _add '

abapGit related repositories

'. + + _add '

    '. + _add '
  • '. + ro_html->add_anchor( iv_txt = 'install abapGit repo' iv_act = gc_action-abapgit_install ). + _add ' - To keep abapGit up-to-date (or also to contribute) you need to'. + _add 'install it as a repository.
  • '. + _add '
  • '. + ro_html->add_anchor( iv_txt = 'install abapGit plugins' iv_act = gc_action-abapgit_install_pi ). + _add ' - you can also install plugins to extend supported object types
  • '. + _add '

'. + + ENDMETHOD. " render_content. + +ENDCLASS. "lcl_gui_view_tutorial \ No newline at end of file diff --git a/src/zabapgit_view_tutorial.prog.xml b/src/zabapgit_view_tutorial.prog.xml new file mode 100644 index 000000000..d7ba73043 --- /dev/null +++ b/src/zabapgit_view_tutorial.prog.xml @@ -0,0 +1,48 @@ + + + + + + ZABAPGIT_VIEW_TUTORIAL + A + + + X + + + + + + I + + + + 0000-00-00 + + 0000-00-00 + + + + + E + + + 0000-00-00 + + 0000-00-00 + + + X + + + + R + + Include ZABAPGIT_PAGE_TUTORIAL + 30 + + + + + +