@@ -104,18 +104,18 @@ void ContextMenuHandler::do_plugin_menu_inclusion(bool invalidate) {
104104
105105void ContextMenuHandler::process_ignore_all () {
106106 auto mut = m_speller_container.modify ();
107- mut->ignore_word (m_selected_word .str );
107+ mut->ignore_word (m_last_selected_word .str );
108108 m_word_under_cursor_length =
109- static_cast <TextPosition>(m_selected_word .str .length ());
109+ static_cast <TextPosition>(m_last_selected_word .str .length ());
110110 m_editor.set_cursor_pos (m_word_under_cursor_pos +
111111 m_word_under_cursor_length);
112112}
113113
114114void ContextMenuHandler::process_add_to_dictionary () {
115115 auto mut = m_speller_container.modify ();
116- mut->add_to_dictionary (m_selected_word .str );
116+ mut->add_to_dictionary (m_last_selected_word .str );
117117 m_word_under_cursor_length =
118- static_cast <TextPosition>(m_selected_word .str .length ());
118+ static_cast <TextPosition>(m_last_selected_word .str .length ());
119119 m_editor.set_cursor_pos (m_word_under_cursor_pos +
120120 m_word_under_cursor_length);
121121}
@@ -243,7 +243,7 @@ void ContextMenuHandler::precalculate_menu() {
243243 m_settings.data .suggestions_mode == SuggestionMode::context_menu) {
244244 update_word_under_cursor_data ();
245245 if (!m_word_under_cursor_is_correct) {
246- suggestion_menu_items = get_suggestion_menu_items ();
246+ suggestion_menu_items = select_word_and_get_suggestion_menu_items ();
247247 suggestion_menu_items.emplace_back (MenuItem::Separator{});
248248 }
249249 }
@@ -309,44 +309,57 @@ void ContextMenuHandler::init_suggestions_box(
309309 suggestion_button.display (true , false );
310310}
311311
312- std::vector<MenuItem>
313- ContextMenuHandler::get_suggestion_menu_items () {
314- if (!m_speller_container.active_speller ().is_working ())
315- return {}; // Word is already off-screen
316-
312+ bool ContextMenuHandler::select_word_under_cursor () {
317313 auto pos = m_word_under_cursor_pos;
318314 ACTIVE_VIEW_BLOCK (m_editor);
319315 if (m_settings.data .select_word_on_context_menu_click )
320316 m_editor.set_selection (pos, pos + m_word_under_cursor_length);
321- std::vector<MenuItem> suggestion_menu_items;
322- m_selected_word = m_editor.get_mapped_wstring_range (m_word_under_cursor_pos, m_word_under_cursor_pos + static_cast <TextPosition>(m_word_under_cursor_length));
323- SpellCheckerHelpers::apply_word_conversions (m_settings, m_selected_word.str );
317+ m_last_selected_word =
318+ m_editor.get_mapped_wstring_range (m_word_under_cursor_pos, m_word_under_cursor_pos + static_cast <TextPosition>(m_word_under_cursor_length));
319+ SpellCheckerHelpers::apply_word_conversions (m_settings, m_last_selected_word.str );
320+ return true ;
321+ }
324322
325- m_last_suggestions = m_speller_container.active_speller ().get_suggestions (
326- m_selected_word.str .c_str ());
323+ std::vector<MenuItem> ContextMenuHandler::select_word_and_get_suggestion_menu_items () {
324+ if (!m_speller_container.active_speller ().is_working ())
325+ return {}; // Word is already off-screen
327326
328- for (int i = 0 ; i < static_cast <int >(m_last_suggestions.size ()); i++) {
329- if (i >= m_settings.data .suggestion_count )
330- break ;
327+ select_word_under_cursor ();
328+ std::vector<MenuItem> suggestion_menu_items;
329+ m_last_suggestions = m_speller_container.active_speller ().get_suggestions (
330+ m_last_selected_word.str .c_str ());
331+ m_last_suggestions.resize (std::min (static_cast <int >(m_last_suggestions.size ()), m_settings.data .suggestion_count ));
331332
333+ int i = 0 ;
334+ for (; i < static_cast <int >(m_last_suggestions.size ()); ++i) {
332335 auto item = m_last_suggestions[i].c_str ();
333336 suggestion_menu_items.emplace_back (item, static_cast <BYTE>(i + 1 ));
334337 }
335338
339+ if (m_settings.data .always_suggest_capitalized_word && !m_last_selected_word.str .empty () && std::ranges::all_of (m_last_selected_word.str , &is_lower)) {
340+ auto copy = m_last_selected_word.str ;
341+ copy.front () = make_upper (copy.front ());
342+ if (std::ranges::find (m_last_suggestions, copy) == m_last_suggestions.end ()) {
343+ auto &last = m_last_suggestions.emplace_back (std::move (copy));
344+ ++i;
345+ suggestion_menu_items.emplace_back (last.c_str (), static_cast <BYTE>(i + 1 ));
346+ }
347+ }
348+
336349 if (!m_last_suggestions.empty ()) {
337- MenuItem replace_all_item (wstring_printf (rc_str (IDS_REPLACE_ALL_PS).c_str (), m_selected_word .str .c_str ()).c_str (), -1 );
350+ MenuItem replace_all_item (wstring_printf (rc_str (IDS_REPLACE_ALL_PS).c_str (), m_last_selected_word .str .c_str ()).c_str (), -1 );
338351 replace_all_item.children = suggestion_menu_items;
339352 suggestion_menu_items.emplace_back (MenuItem::Separator{});
340353 std::for_each (replace_all_item.children .begin (), replace_all_item.children .end (), [](auto &item) { item.id += menu_id::replace_all_start; });
341354 suggestion_menu_items.push_back (std::move (replace_all_item));
342355 }
343356
344- SpellCheckerHelpers::apply_word_conversions (m_settings, m_selected_word .str );
357+ SpellCheckerHelpers::apply_word_conversions (m_settings, m_last_selected_word .str );
345358 auto menu_string = wstring_printf (rc_str (IDS_IGNORE_PS_FOR_CURRENT_SESSION).c_str (),
346- m_selected_word .str .c_str ());
359+ m_last_selected_word .str .c_str ());
347360 suggestion_menu_items.emplace_back (menu_string.c_str (), menu_id::ignore_all);
348361 menu_string =
349- wstring_printf (rc_str (IDS_ADD_PS_TO_DICTIONARY).c_str (), m_selected_word .str .c_str ());;
362+ wstring_printf (rc_str (IDS_ADD_PS_TO_DICTIONARY).c_str (), m_last_selected_word .str .c_str ());;
350363 suggestion_menu_items.emplace_back (menu_string.c_str (),
351364 menu_id::add_to_dictionary);
352365
0 commit comments