diff --git a/src/commands.cc b/src/commands.cc index 159c5656..bad0f01d 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -60,7 +60,7 @@ Buffer* open_fifo(const String& name , const String& filename, bool scroll) const PerArgumentCommandCompleter filename_completer({ [](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos) - { return Completions{ 0_byte, prefix.length(), + { return Completions{ 0_byte, cursor_pos, complete_filename(prefix, context.options()["ignored_files"].get(), cursor_pos) }; } @@ -68,7 +68,7 @@ const PerArgumentCommandCompleter filename_completer({ const PerArgumentCommandCompleter buffer_completer({ [](const Context& context, CompletionFlags flags, const String& prefix, ByteCount cursor_pos) - { return Completions{ 0_byte, prefix.length(), + { return Completions{ 0_byte, cursor_pos, BufferManager::instance().complete_buffer_name(prefix, cursor_pos) }; } }); @@ -956,6 +956,22 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) GlobalHooks::instance().enable_hooks(); }); + struct DisableOption { + DisableOption(Context& context, const char* name) + : m_option(context.options()[name]), + m_prev_value(m_option.get()) + { m_option.set(false); } + + ~DisableOption() { m_option.set(m_prev_value); } + + Option& m_option; + bool m_prev_value; + }; + DisableOption disable_autoinfo(context, "autoinfo"); + DisableOption disable_autoshowcompl(context, "autoshowcompl"); + DisableOption disable_incsearch(context, "incsearch"); + + ClientManager& cm = ClientManager::instance(); if (parser.has_option("buffer")) { @@ -1211,7 +1227,7 @@ const CommandDesc try_catch_cmd = { static Completions complete_colalias(const Context&, CompletionFlags flags, const String& prefix, ByteCount cursor_pos) { - return {0_byte, prefix.length(), + return {0_byte, cursor_pos, ColorRegistry::instance().complete_alias_name(prefix, cursor_pos)}; } diff --git a/src/highlighters.cc b/src/highlighters.cc index 28c208f3..f5b4faa2 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -537,24 +537,25 @@ void expand_unprintable(const Context& context, HighlightFlags flags, DisplayBuf { if (atom_it->type() == DisplayAtom::BufferRange) { - using Utf8It = utf8::utf8_iterator; - for (Utf8It it = buffer.iterator_at(atom_it->begin()), - end = buffer.iterator_at(atom_it->end()); it != end; ++it) + for (auto it = buffer.iterator_at(atom_it->begin()), + end = buffer.iterator_at(atom_it->end()); it < end;) { - Codepoint cp = *it; + Codepoint cp = utf8::codepoint(it); + auto next = utf8::next(it); if (cp != '\n' and not iswprint(cp)) { std::ostringstream oss; oss << "U+" << std::hex << cp; String str = oss.str(); - if (it.base().coord() != atom_it->begin()) - atom_it = ++line.split(atom_it, it.base().coord()); - if ((it+1).base().coord() != atom_it->end()) - atom_it = line.split(atom_it, (it+1).base().coord()); + if (it.coord() != atom_it->begin()) + atom_it = ++line.split(atom_it, it.coord()); + if (next.coord() < atom_it->end()) + atom_it = line.split(atom_it, next.coord()); atom_it->replace(str); atom_it->colors = { Colors::Red, Colors::Black }; break; } + it = next; } } } diff --git a/src/input_handler.cc b/src/input_handler.cc index 459f6751..4c718c21 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -84,6 +84,8 @@ public: { if (key.modifiers == Key::Modifiers::None and isdigit(key.key)) m_count = m_count * 10 + key.key - '0'; + else if (key == Key::Backspace) + m_count /= 10; else { auto it = keymap.find(key); @@ -138,7 +140,7 @@ public: --m_cursor_pos; } } - else if (key == Key::Erase) + else if (key == Key::Delete) { if (m_cursor_pos != m_line.char_length()) m_line = m_line.substr(0, m_cursor_pos) @@ -675,7 +677,7 @@ public: buffer.erase(utf8::previous(pos), pos); } } - else if (key == Key::Erase) + else if (key == Key::Delete) { for (auto& sel : reversed(context().selections())) { diff --git a/src/keys.cc b/src/keys.cc index f21f93ec..2caef9a7 100644 --- a/src/keys.cc +++ b/src/keys.cc @@ -34,6 +34,7 @@ static const KeyAndName keynamemap[] = { { "home", Key::Home }, { "end", Key::End }, { "backtab", Key::BackTab }, + { "del", Key::Delete }, }; KeyList parse_keys(StringView str) diff --git a/src/keys.hh b/src/keys.hh index d64cee2e..262603d8 100644 --- a/src/keys.hh +++ b/src/keys.hh @@ -22,7 +22,7 @@ struct Key { // use UTF-16 surrogate pairs range Backspace = 0xD800, - Erase, + Delete, Escape, Up, Down, diff --git a/src/main.cc b/src/main.cc index a48051ae..46163d7e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -137,8 +137,23 @@ void register_env_vars() [](StringView name, const Context& context) { auto& sel = context.selections().main(); auto beg = sel.min(); - return to_string(beg.line + 1) + ':' + to_string(beg.column + 1) + '+' + + return to_string(beg.line + 1) + '.' + to_string(beg.column + 1) + '+' + to_string((int)context.buffer().distance(beg, sel.max())+1); } + }, { + "selections_desc", + [](StringView name, const Context& context) + { + String res; + for (auto& sel : context.selections()) + { + auto beg = sel.min(); + if (not res.empty()) + res += ':'; + res += to_string(beg.line + 1) + '.' + to_string(beg.column + 1) + '+' + + to_string((int)context.buffer().distance(beg, sel.max())+1); + } + return res; + } }, { "window_width", [](StringView name, const Context& context) @@ -163,7 +178,12 @@ void register_registers() } dyn_regs[] = { { '%', [](const Context& context) { return StringList{{context.buffer().display_name()}}; } }, { '.', [](const Context& context) { return context.selections_content(); } }, - { '#', [](const Context& context) { return StringList{{to_string((int)context.selections().size())}}; } }, + { '#', [](const Context& context) { + StringList res; + for (size_t i = 1; i < context.selections().size(); ++i) + res.push_back(to_string((int)i)); + return res; + } } }; RegisterManager& register_manager = RegisterManager::instance(); diff --git a/src/ncurses.cc b/src/ncurses.cc index f48ef7ee..67f73951 100644 --- a/src/ncurses.cc +++ b/src/ncurses.cc @@ -359,7 +359,7 @@ Key NCursesUI::get_key() else switch (c) { case KEY_BACKSPACE: case 127: return Key::Backspace; - case KEY_DC: return Key::Erase; + case KEY_DC: return Key::Delete; case KEY_UP: return Key::Up; case KEY_DOWN: return Key::Down; case KEY_LEFT: return Key::Left; diff --git a/src/option_manager.cc b/src/option_manager.cc index f2c6576c..0bb2f4df 100644 --- a/src/option_manager.cc +++ b/src/option_manager.cc @@ -56,7 +56,7 @@ Option& OptionManager::get_local_option(const String& name) } -const Option& OptionManager::operator[](const String& name) const +Option& OptionManager::operator[](const String& name) { auto it = find_option(m_options, name); if (it != m_options.end()) @@ -67,6 +67,11 @@ const Option& OptionManager::operator[](const String& name) const throw option_not_found(name); } +const Option& OptionManager::operator[](const String& name) const +{ + return const_cast(*this)[name]; +} + template CandidateList OptionManager::get_matching_names(MatchingFunc func) { diff --git a/src/option_manager.hh b/src/option_manager.hh index 244e1555..92c3ac7b 100644 --- a/src/option_manager.hh +++ b/src/option_manager.hh @@ -88,6 +88,7 @@ public: OptionManager(OptionManager& parent); ~OptionManager(); + Option& operator[] (const String& name); const Option& operator[] (const String& name) const; Option& get_local_option(const String& name); diff --git a/src/utf8_iterator.hh b/src/utf8_iterator.hh index 4fa206b3..cc1d3b47 100644 --- a/src/utf8_iterator.hh +++ b/src/utf8_iterator.hh @@ -104,7 +104,7 @@ public: check_invariant(); other.check_invariant(); CharCount dist = 0; - while (other.m_it != m_it) + while (other.m_it < m_it) { ++dist; ++other;