note description: "Objects that represent a line in the editor." legal: "See notice at end of class." status: "See notice at end of class." author: "Christophe Bonnard / Arnaud PICHERY [ aranud@mail.dotcom.fr] " date: "$Date$" revision: "$Revision$" class EDITOR_LINE inherit VIEWER_LINE rename wide_image_from_start_to_cursor as dummy1, wide_image_from_cursor_to_end as dummy2, image_from_start_to_cursor as dummy3, image_from_cursor_to_end as dummy4 end create make_empty_line, make, make_from_lexer, make_unix_style, make_windows_style, make_from_lexer_and_style feature -- Initialization make_from_lexer (lexer: EDITOR_SCANNER) -- Create a line using token from `lexer'. -- Defaults to Unix EOL style. require lexer_exists: lexer /= Void do make_from_lexer_and_style (lexer, False) end make_from_lexer_and_style (lexer: EDITOR_SCANNER; a_windows_style: BOOLEAN) -- Create a line using token from `lexer' in `a_windows_style'. require lexer_exists: lexer /= Void local t_eol : EDITOR_TOKEN_EOL t_begin : EDITOR_TOKEN_LINE_NUMBER lexer_first_token, lexer_end_token : detachable EDITOR_TOKEN do create t_eol.make_with_style (a_windows_style) create t_begin.make lexer_end_token := lexer.end_token if lexer_end_token /= Void then -- The lexer has parsed something. lexer_first_token := lexer.first_token check lexer_first_token /= Void end -- Implied by `end_token' is attached, the lexer should ensure. lexer_end_token.set_next_token (t_eol) t_eol.set_previous_token (lexer_end_token) t_begin.set_next_token (lexer_first_token) lexer_first_token.set_previous_token (t_begin) else -- We have given an empty string to the parser. -- He has not produced any token. t_begin.set_next_token (t_eol) t_eol.set_previous_token (t_begin) end real_first_token := t_begin eol_token := t_eol update_token_information end feature -- Transformation replace_from_lexer (lexer: EDITOR_SCANNER; t_before, t_after: EDITOR_TOKEN) -- Replace tokens between `t_before' and `t_after' -- by tokens from `lexer'. require lexer_exists: lexer /= Void t_before_exists: t_before /= Void t_after_exists: t_after /= Void local first_t, last_t: detachable EDITOR_TOKEN do last_t := lexer.end_token if last_t /= Void then -- The lexer has parsed something. first_t := lexer.first_token check first_t /= Void end -- Implied by `end_token' attached, the scanner should ensure. last_t.set_next_token (t_after) t_after.set_previous_token (last_t) first_t.set_previous_token (t_before) t_before.set_next_token (first_t) else t_before.set_next_token (t_after) t_after.set_previous_token (t_before) end update_token_information end --| FIXME --| Christophe, 27 jan 2000 --| Should we avoid the case "t_before = Void" or --| redirect it to `replace_beginning_from_lexer'? replace_beginning_from_lexer (lexer: EDITOR_SCANNER; t_after: EDITOR_TOKEN) -- Replace tokens before `t_after' by tokens from `lexer'. require lexer_exists: lexer /= Void t_after_exists: t_after /= Void local t: detachable EDITOR_TOKEN do t := lexer.end_token if t /= Void then -- The lexer has parsed something. t.set_next_token (t_after) real_first_token := lexer.first_token else real_first_token := t_after end t_after.set_previous_token (t) update_token_information end rebuild_from_lexer (lexer: EDITOR_SCANNER; in_v_string: BOOLEAN) -- Rebuild Current using token from `lexer'. If lexer is scanning a line that is part of -- a verbatim string then `in_v_string' should be True. -- EOL style defaults to Unix. do rebuild_from_lexer_and_style (lexer, in_v_string, False) end rebuild_from_lexer_and_style (lexer: EDITOR_SCANNER; in_v_string: BOOLEAN; a_windows_style: BOOLEAN) -- Rebuild Current using token from `lexer'. If lexer is scanning a line that is part of -- a verbatim string then `in_v_string' should be True. -- EOL style is windows style, when `a_windows_style' is set, otherwise unix style. do if attached previous as l_previous and then ((l_previous.part_of_verbatim_string and then not l_previous.end_of_verbatim_string) or l_previous.start_of_verbatim_string) then lexer.set_in_verbatim_string (True) else lexer.set_in_verbatim_string (False) end make_from_lexer_and_style (lexer, a_windows_style) end feature -- Status Report wide_image_from_start_to_cursor (text_cursor: TEXT_CURSOR): STRING_32 -- Substring of the line starting at the beginning of -- the line and ending at the cursor position (not -- included) require text_cursor.line = Current local local_token : detachable EDITOR_TOKEN cursor_token : EDITOR_TOKEN l_string_32 : STRING_32 do cursor_token := text_cursor.token create l_string_32.make (50) -- Retrieve the string in the token situated before -- the cursor from local_token := first_token until local_token = cursor_token or else local_token = eol_token loop check local_token /= Void end -- A line should not have void token before the cursor token. l_string_32.append (local_token.wide_image) local_token := local_token.next end -- Append the current string with the portion of the current -- token that is before the cursor. if local_token /= Void then l_string_32.append (local_token.wide_image.substring(1, text_cursor.pos_in_token - 1)) end Result := l_string_32 ensure Result_not_void: Result /= Void end wide_image_from_cursor_to_end (text_cursor: TEXT_CURSOR): STRING_32 -- Substring of the line starting at the cursor -- position (included) and ending at the end of the line require text_cursor.line = Current local local_token : detachable EDITOR_TOKEN cursor_token : EDITOR_TOKEN l_string_32 : STRING_32 do cursor_token := text_cursor.token create l_string_32.make (50) -- Append the current string with the portion of the current -- token that is after the cursor. l_string_32.append(cursor_token.wide_image.substring(text_cursor.pos_in_token, cursor_token.length)) -- Retrieve the string in the token situated before -- the cursor from local_token := cursor_token.next until local_token = eol_token or else local_token = Void loop l_string_32.append(local_token.wide_image) local_token := local_token.next end Result := l_string_32 ensure Result_not_void: Result /= Void end auto_indented: BOOLEAN -- Was this line auto-indented by the editor (i.e. extra tabs were added when created)? part_of_verbatim_string: BOOLEAN -- Is Current part of a verbatim string, i.e part of a string which covers more than one line? -- Redefine this and have the lexer set this flag so you can tell if indeed this is the case. -- Required because gobo lexer works line by line. Defult: False end_of_verbatim_string: BOOLEAN -- Is current the end of a verbatim string? start_of_verbatim_string: BOOLEAN -- Is current the start of a verbatim string? feature -- Obsolete image_from_start_to_cursor (text_cursor: TEXT_CURSOR): STRING -- Substring of the line starting at the beginning of -- the line and ending at the cursor position (not -- included) obsolete "Use `wide_image_from_start_to_cursor' instead. [2017-05-31]" require text_cursor.line = Current do Result := wide_image_from_cursor_to_end (text_cursor).as_string_8 ensure Result_not_void: Result /= Void end image_from_cursor_to_end (text_cursor: TEXT_CURSOR): STRING -- Substring of the line starting at the cursor -- position (included) and ending at the end of the line obsolete "Use `wide_image_from_cursor_to_end' instead. [2017-05-31]" require text_cursor.line = Current do Result := wide_image_from_cursor_to_end (text_cursor).as_string_8 ensure Result_not_void: Result /= Void end feature -- Status Setting set_auto_indented (a_flag: BOOLEAN) -- Set `auto_indented' to `a_flag' do auto_indented := a_flag ensure value_set: auto_indented = a_flag end set_part_of_verbatim_string (a_flag: BOOLEAN) -- Set `part_of_verbatim_string' to `a_flag' do part_of_verbatim_string := a_flag ensure value_set: part_of_verbatim_string = a_flag end set_end_of_verbatim_string (a_flag: BOOLEAN) -- Set `end_of_verbatim_string' to `a_flag' do end_of_verbatim_string := a_flag ensure value_set: end_of_verbatim_string = a_flag end set_start_of_verbatim_string (a_flag: BOOLEAN) -- Set `start_of_verbatim_string' to `a_flag' do start_of_verbatim_string := a_flag ensure value_set: start_of_verbatim_string = a_flag end note copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class EDITOR_LINE