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
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( |Proxy URL | ).
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( `' ).
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' .' &&
+ ' '.
+
+ 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 = ''
+ 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
+
+
+
+
+
+