From 5df956a37a02ea2c4af24e6ddef6881567785d2c Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Sat, 7 Nov 2020 03:54:38 -0500 Subject: [PATCH] Toggle display of hidden characters on diff page (#4136) * Toggle display of hidden characters on diff page Time for something new... I added a toggle switch to the diff page that allows you to show otherwise hidden characters. - CR end-of-line - Spaces - Tabs - Byte-order-mark Closes https://github.com/abapGit/abapGit/issues/2124 Closes https://github.com/abapGit/abapGit/issues/3676 Improves https://github.com/abapGit/abapGit/issues/2804 * Add ini Co-authored-by: Lars Hvam --- .../zcl_abapgit_syntax_highlighter.clas.abap | 62 +++++++++++++++++-- src/syntax/zcl_abapgit_syntax_txt.clas.abap | 35 +++++++++++ src/syntax/zcl_abapgit_syntax_txt.clas.xml | 16 +++++ src/ui/zcl_abapgit_gui_page_diff.clas.abap | 22 +++++-- 4 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 src/syntax/zcl_abapgit_syntax_txt.clas.abap create mode 100644 src/syntax/zcl_abapgit_syntax_txt.clas.xml diff --git a/src/syntax/zcl_abapgit_syntax_highlighter.clas.abap b/src/syntax/zcl_abapgit_syntax_highlighter.clas.abap index c0c6af637..bb71430b6 100644 --- a/src/syntax/zcl_abapgit_syntax_highlighter.clas.abap +++ b/src/syntax/zcl_abapgit_syntax_highlighter.clas.abap @@ -8,6 +8,7 @@ CLASS zcl_abapgit_syntax_highlighter DEFINITION CLASS-METHODS create IMPORTING !iv_filename TYPE string + !iv_hidden_chars TYPE abap_bool DEFAULT abap_false RETURNING VALUE(ro_instance) TYPE REF TO zcl_abapgit_syntax_highlighter . METHODS process_line @@ -37,6 +38,7 @@ CLASS zcl_abapgit_syntax_highlighter DEFINITION CONSTANTS c_token_none TYPE c VALUE '.' ##NO_TEXT. DATA: mt_rules TYPE STANDARD TABLE OF ty_rule . + DATA mv_hidden_chars TYPE abap_bool . METHODS add_rule IMPORTING @@ -50,7 +52,6 @@ CLASS zcl_abapgit_syntax_highlighter DEFINITION RETURNING VALUE(rt_matches) TYPE ty_match_tt . METHODS order_matches - ABSTRACT IMPORTING !iv_line TYPE string CHANGING @@ -77,6 +78,14 @@ CLASS zcl_abapgit_syntax_highlighter DEFINITION !iv_string TYPE string RETURNING VALUE(rv_result) TYPE abap_bool . + METHODS set_hidden_chars + IMPORTING + !iv_hidden_chars TYPE abap_bool . + METHODS show_hidden_chars + IMPORTING + !iv_line TYPE string + RETURNING + VALUE(rv_line) TYPE string . PRIVATE SECTION. ENDCLASS. @@ -108,8 +117,11 @@ CLASS zcl_abapgit_syntax_highlighter IMPLEMENTATION. DATA lv_escaped TYPE string. - lv_escaped = escape( val = iv_line - format = cl_abap_format=>e_html_attr ). + lv_escaped = escape( val = iv_line + format = cl_abap_format=>e_html_text ). + + lv_escaped = show_hidden_chars( lv_escaped ). + IF iv_class IS NOT INITIAL. rv_line = |{ lv_escaped }|. ELSE. @@ -132,10 +144,15 @@ CLASS zcl_abapgit_syntax_highlighter IMPLEMENTATION. CREATE OBJECT ro_instance TYPE zcl_abapgit_syntax_js. ELSEIF iv_filename CP '*.json'. CREATE OBJECT ro_instance TYPE zcl_abapgit_syntax_json. + ELSEIF iv_filename CP '*.txt' OR iv_filename CP '*.ini' OR iv_filename CP '*.text'. + CREATE OBJECT ro_instance TYPE zcl_abapgit_syntax_txt. ELSE. CLEAR ro_instance. ENDIF. + IF ro_instance IS BOUND. + ro_instance->set_hidden_chars( iv_hidden_chars ). + ENDIF. ENDMETHOD. @@ -213,6 +230,10 @@ CLASS zcl_abapgit_syntax_highlighter IMPLEMENTATION. ENDMETHOD. + METHOD order_matches. + ENDMETHOD. + + METHOD parse_line. DATA: @@ -262,7 +283,7 @@ CLASS zcl_abapgit_syntax_highlighter IMPLEMENTATION. DATA: lt_matches TYPE ty_match_tt. IF iv_line IS INITIAL OR is_whitespace( iv_line ) = abap_true. - rv_line = iv_line. + rv_line = show_hidden_chars( iv_line ). RETURN. ENDIF. @@ -278,4 +299,37 @@ CLASS zcl_abapgit_syntax_highlighter IMPLEMENTATION. it_matches = lt_matches ). ENDMETHOD. + + + METHOD set_hidden_chars. + mv_hidden_chars = iv_hidden_chars. + ENDMETHOD. + + + METHOD show_hidden_chars. + + DATA lv_bom TYPE x LENGTH 3. + + rv_line = iv_line. + + IF mv_hidden_chars = abap_true. + REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN rv_line WITH ' → '. + REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf(1) IN rv_line WITH '¶'. + REPLACE ALL OCCURRENCES OF ` ` IN rv_line WITH '·'. + + IF strlen( rv_line ) BETWEEN 1 AND 2. + lv_bom = zcl_abapgit_convert=>string_to_xstring( rv_line ). + IF lv_bom(2) = cl_abap_char_utilities=>byte_order_mark_big. + rv_line = ''. " UTF-16 big-endian (FE FF) + ENDIF. + IF lv_bom(2) = cl_abap_char_utilities=>byte_order_mark_little. + rv_line = ''. " UTF-16 little-endian (FF FE) + ENDIF. + IF lv_bom(3) = cl_abap_char_utilities=>byte_order_mark_utf8. + rv_line = '¤'. " UTF-8 (EF BB BF) + ENDIF. + ENDIF. + ENDIF. + + ENDMETHOD. ENDCLASS. diff --git a/src/syntax/zcl_abapgit_syntax_txt.clas.abap b/src/syntax/zcl_abapgit_syntax_txt.clas.abap new file mode 100644 index 000000000..3822b6253 --- /dev/null +++ b/src/syntax/zcl_abapgit_syntax_txt.clas.abap @@ -0,0 +1,35 @@ +CLASS zcl_abapgit_syntax_txt DEFINITION + PUBLIC + INHERITING FROM zcl_abapgit_syntax_highlighter + CREATE PUBLIC . + + PUBLIC SECTION. + + METHODS constructor . + + METHODS process_line + REDEFINITION . + PROTECTED SECTION. + PRIVATE SECTION. +ENDCLASS. + + + +CLASS zcl_abapgit_syntax_txt IMPLEMENTATION. + + + METHOD constructor. + + super->constructor( ). + + " No rules for plain text files + + ENDMETHOD. + + + METHOD process_line. + + rv_line = show_hidden_chars( iv_line ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/syntax/zcl_abapgit_syntax_txt.clas.xml b/src/syntax/zcl_abapgit_syntax_txt.clas.xml new file mode 100644 index 000000000..580a55b12 --- /dev/null +++ b/src/syntax/zcl_abapgit_syntax_txt.clas.xml @@ -0,0 +1,16 @@ + + + + + + ZCL_ABAPGIT_SYNTAX_TXT + E + Plain Text Highlighting + 1 + X + X + X + + + + diff --git a/src/ui/zcl_abapgit_gui_page_diff.clas.abap b/src/ui/zcl_abapgit_gui_page_diff.clas.abap index 8d52ecd08..46acb6a85 100644 --- a/src/ui/zcl_abapgit_gui_page_diff.clas.abap +++ b/src/ui/zcl_abapgit_gui_page_diff.clas.abap @@ -111,11 +111,13 @@ CLASS zcl_abapgit_gui_page_diff DEFINITION CONSTANTS: BEGIN OF c_actions, - toggle_unified TYPE string VALUE 'toggle_unified', + toggle_unified TYPE string VALUE 'toggle_unified', + toggle_hidden_chars TYPE string VALUE 'toggle_hidden_chars', END OF c_actions . DATA mt_delayed_lines TYPE zif_abapgit_definitions=>ty_diffs_tt . DATA mv_repo_key TYPE zif_abapgit_persistence=>ty_repo-key . DATA mv_seed TYPE string . " Unique page id to bind JS sessionStorage + DATA mv_hidden_chars TYPE abap_bool . METHODS render_diff IMPORTING @@ -292,9 +294,13 @@ CLASS zcl_abapgit_gui_page_diff IMPLEMENTATION. METHOD add_menu_end. - io_menu->add( iv_txt = 'Split/Unified view' + io_menu->add( iv_txt = 'Split/Unified' iv_act = c_actions-toggle_unified ). + io_menu->add( iv_txt = '¶' + iv_title = 'Toggle Hidden Characters' + iv_act = c_actions-toggle_hidden_chars ). + ENDMETHOD. @@ -646,7 +652,7 @@ CLASS zcl_abapgit_gui_page_diff IMPLEMENTATION. " Content IF is_diff-type <> 'binary'. ri_html->add( '
' ). - ri_html->add( || ). + ri_html->add( |
| ). ri_html->add( render_table_head( is_diff ) ). ri_html->add( render_lines( is_diff ) ). ri_html->add( '
' ). @@ -741,7 +747,8 @@ CLASS zcl_abapgit_gui_page_diff IMPLEMENTATION. FIELD-SYMBOLS LIKE LINE OF lt_diffs. - lo_highlighter = zcl_abapgit_syntax_highlighter=>create( is_diff-filename ). + lo_highlighter = zcl_abapgit_syntax_highlighter=>create( iv_filename = is_diff-filename + iv_hidden_chars = mv_hidden_chars ). CREATE OBJECT ri_html TYPE zcl_abapgit_html. lt_diffs = is_diff-o_diff->get( ). @@ -997,7 +1004,12 @@ CLASS zcl_abapgit_gui_page_diff IMPLEMENTATION. WHEN c_actions-toggle_unified. " Toggle file diplay mv_unified = zcl_abapgit_persistence_user=>get_instance( )->toggle_diff_unified( ). - rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. + + WHEN c_actions-toggle_hidden_chars. " Toggle display of hidden characters + + mv_hidden_chars = boolc( mv_hidden_chars = abap_false ). + rs_handled-state = zcl_abapgit_gui=>c_event_state-re_render. WHEN OTHERS.