note description: "[ Completable text field ]" legal: "See notice at end of class." status: "See notice at end of class." author: "" date: "$Date$" revision: "$Revision$" class EB_EXTERNAL_CMD_COMBO_BOX inherit EV_COMBO_BOX redefine initialize end CODE_COMPLETABLE undefine default_create, is_equal, copy redefine calculate_completion_list_width, possibilities_provider, can_complete, is_focus_back_needed end EB_SHARED_PREFERENCES undefine default_create, is_equal, copy end SHARED_WORKBENCH undefine default_create, is_equal, copy end CURSOR_COMPLETABLE_POSITIONING undefine default_create, is_equal, copy end create default_create, make_with_text feature{NONE} -- Initialization initialize -- Initialize current. do Precursor initialize_code_complete end feature -- Access possibilities_provider: EB_EXTERNAL_CMD_COMPLETION_PROVIDER -- Possibilities provider can_complete_agent: FUNCTION [TUPLE [a_key: EV_KEY; a_ctrl: BOOLEAN; a_alt: BOOLEAN; a_shift: BOOLEAN], BOOLEAN] -- Agent to decide if completion can start feature -- Setting set_can_complete_agent (a_agent: like can_complete_agent) -- Set `can_complete_agent' with `a_agent'. require a_agent_attached: a_agent /= Void do can_complete_agent := a_agent ensure can_complete_agent_set: can_complete_agent = a_agent end feature -- Status report completing_word: BOOLEAN = true -- Has user requested to complete a word. is_key_matched_with_shortcut (a_key: EV_KEY; a_ctrl: BOOLEAN; a_alt: BOOLEAN; a_shift: BOOLEAN; a_shortcut: SHORTCUT_PREFERENCE): BOOLEAN -- Does key combination `a_key', `a_ctrl', `a_alt' and `a_shift' match `a_shortcut'? require a_key_attached: a_key /= Void a_shortcut_attached: a_shortcut /= Void do Result := a_key.code = a_shortcut.key.code and then a_ctrl = a_shortcut.is_ctrl and then a_alt = a_shortcut.is_alt and then a_shift = a_shortcut.is_shift end can_complete (a_key: EV_KEY; a_ctrl: BOOLEAN; a_alt: BOOLEAN; a_shift: BOOLEAN): BOOLEAN -- `a_key' can activate text completion? local l_shortcut_pref: SHORTCUT_PREFERENCE do if a_key /= Void then if can_complete_agent /= Void then Result := can_complete_agent.item ([a_key, a_ctrl, a_alt, a_shift]) end if not Result then l_shortcut_pref := preferences.editor_data.shortcuts.item ("autocomplete") check l_shortcut_pref /= Void end Result := is_key_matched_with_shortcut (a_key, a_ctrl, a_alt, a_shift, l_shortcut_pref) if not Result then l_shortcut_pref := preferences.editor_data.shortcuts.item ("class_autocomplete") check l_shortcut_pref /= Void end Result := is_key_matched_with_shortcut (a_key, a_ctrl, a_alt, a_shift, l_shortcut_pref) end if Result then -- We remove the 'key' character on windows platform. -- On linux the key has not been inserted. -- Fix needed. precompletion_actions.wipe_out precompletion_actions.extend_kamikaze (agent remove_keyed_character (a_key)) end end end end is_focus_back_needed: BOOLEAN -- Should focus be set back after code completion? do Result := not is_destroyed end feature{NONE} -- Implementation place_post_cursor -- Place cursor after completion do end back_delete_char -- Back delete character. do if text_length > 0 and caret_position > 1 then select_region (caret_position - 1, caret_position - 1) delete_selection end end delete_char -- Delete character. do if text_length > 0 and caret_position <= text_length then select_region (caret_position, caret_position) delete_selection end end insert_string (a_str: STRING_32) -- Insert `a_str' at cursor position. do insert_text (a_str) set_caret_position (caret_position + a_str.count) end insert_char (a_char: CHARACTER_32) -- Insert `a_char' at cursor position. do insert_text (create {STRING_32}.make_filled (a_char, 1)) set_caret_position (caret_position + 1) end replace_char (a_char: CHARACTER_32) -- Replace current char with `a_char'. do delete_char insert_char (a_char) end block_focus_in_actions -- Block focus in actions do focus_in_actions.block end resume_focus_in_actions -- Resume focus in actions do focus_in_actions.resume end block_focus_out_actions -- Block focus out actions. do focus_out_actions.block end resume_focus_out_actions -- Resume focus out actions. do focus_out_actions.resume end handle_character (a_char: CHARACTER_32) -- Handle `a_char' do if not unwanted_characters.item (a_char.code) then insert_char (a_char) end end handle_extended_ctrled_key (ev_key: EV_KEY) -- Process the push on Ctrl + an extended key. do end handle_extended_key (ev_key: EV_KEY) -- Process the push on an extended key. do if ev_key.code = 40 then -- Backspace back_delete_char elseif ev_key.code = 67 then -- Delete delete_char end end remove_keyed_character (a_key: EV_KEY) -- We remove the 'key' character on windows platform. -- On linux the key has not been inserted. -- Fix needed. require a_key_not_void: a_key /= Void do if not {PLATFORM}.is_unix then if caret_position > 1 then if is_same_key (a_key, text.item (caret_position - 1)) then back_delete_char end end end end is_same_key (a_key: EV_KEY; a_char_code: CHARACTER_32): BOOLEAN -- Is `a_key' a `a_char_code' character? require a_key_not_void: a_key /= Void local l_string: STRING_32 l_keys: EV_KEY_CONSTANTS do create l_keys l_string := l_keys.key_strings.item (a_key.code) if l_string /= Void then if l_string.count = 1 then if l_string.item (1) = a_char_code and then a_char_code /= '.' then Result := True end elseif l_string.same_string ({STRING_32} "Space") then Result := True elseif a_key.is_numpad then if l_string.item (l_string.count) = a_char_code then Result := True end end end end feature{NONE} -- Position calculation cursor_screen_x: INTEGER -- Cursor screen x position do Result := screen_x end cursor_screen_y: INTEGER -- Cursor screen y position do Result := screen_y end use_preferred_height: BOOLEAN -- User preferred height? do Result := preferences.development_window_data.remember_completion_list_size end preferred_height: INTEGER -- Preferred height do Result := preferences.development_window_data.completion_list_height end working_area_height: INTEGER -- Height of the working area. Normally current screen. local l_screen: EV_RECTANGLE do l_screen := (create {EV_SCREEN}).monitor_area_from_position (cursor_screen_x, cursor_screen_y) Result := l_screen.height end line_height: INTEGER -- Line height do Result := height end calculate_completion_list_width: INTEGER -- Determine the width the completion list should have do Result := preferences.metric_tool_data.criterion_completion_list_width end note copyright: "Copyright (c) 1984-2018, Eiffel Software" license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)" licensing_options: "http://www.eiffel.com/licensing" copying: "[ This file is part of Eiffel Software's Eiffel Development Environment. Eiffel Software's Eiffel Development Environment is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License (available at the URL listed under "license" above). Eiffel Software's Eiffel Development Environment is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Eiffel Software's Eiffel Development Environment; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ]" 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