私はGlib::RegexとGtk::TextViewをGtk::TextBuffer-sで実験しており、構文の強調表示をGtk::TextTag-sで実行しようとしています。
構文を更新するための私のコード(行の最初と最後でイテレーターを受け取ります)
void MainWindow::update_syntax(const Gtk::TextBuffer::iterator& start, const Gtk::TextBuffer::iterator& end) {
std::vector<Glib::ustring> keywords;
keywords.push_back("class");
keywords.push_back("struct");
Glib::MatchInfo info;
auto regex = Glib::Regex::create(R"((\w+))");
auto ok = regex->match(start.get_visible_text(end), info);
std::map<Glib::ustring, std::pair<Glib::RefPtr<Gtk::TextMark>, Glib::RefPtr<Gtk::TextMark>>> marks;
do {
std::cout << "word: " << info.fetch(1) << std::endl;
for (auto kw : keywords) {
if (info.fetch(1) == kw) {
int start_offset, end_offset;
info.fetch_pos(1, start_offset, end_offset);
std::cout << info.fetch(1) << " (at: [" << start_offset << ";" << end_offset << "])" << std::endl;
marks["keyword"] = std::make_pair(
this->m_buffer->create_mark(
this->m_buffer->get_iter_at_offset(start.get_offset() + start_offset)
),
this->m_buffer->create_mark(
this->m_buffer->get_iter_at_offset(start.get_offset() + end_offset)
)
);
}
}
} while(info.next());
for (auto mark : marks) {
this->m_buffer->apply_tag_by_name(mark.first,
mark.second.first->get_iter(), mark.second.second->get_iter());
}
}
したがって、フローは、その行のすべての単語に一致する単純な正規表現を作成し、後でタグが設定される範囲を指定するマークのマップを作成することです。ここではGtk::Markを使用しています。これは、バッファーを変更するたびにイテレーターが無効になるためです。
ここで何が問題なのかを説明するために、この関数からのデバッグ出力とそのon_insert
前のスロットを投稿します。
void MainWindow::on_insert(const Gtk::TextBuffer::iterator& pos,
const Glib::ustring& text, int bytes)
{
std::cout << text << " (added at[" << pos.get_offset() <<
"]; with [" << bytes << "]bytes)" << std::endl << std::endl;
したがって、class class
TextViewへの書き込みの出力により、最初の1つが強調表示され、2番目の出力が取得されないという結果になります。ログ:
c (added at[1]; with [1]bytes)
word: c
l (added at[2]; with [1]bytes)
word: cl
a (added at[3]; with [1]bytes)
word: cla
s (added at[4]; with [1]bytes)
word: clas
s (added at[5]; with [1]bytes)
word: class
class (keyword at: [0;5])
(added at[6]; with [1]bytes)
word: class
class (keyword at: [0;5])
word: r
c (added at[7]; with [1]bytes)
word: class
class (keyword at: [0;5])
word: rd
l (added at[8]; with [1]bytes)
word: class
class (keyword at: [0;5])
word: rd
a (added at[9]; with [1]bytes)
word: class
class (keyword at: [0;5])
word: rd
word: a
s (added at[10]; with [1]bytes)
word: class
class (keyword at: [0;5])
word: rd
word: as
s (added at[11]; with [1]bytes)
word: class
class (keyword at: [0;5])
word: rd
word: ass
最後の行は、2つのオフセットだけ移動したことを示していることに気付くのは簡単です。タグが適用されている可能性があります。また、ここで明確でないことは、:word: rd
です。keyword
タグの名前として使用します。そして、このコードがまだイテレータを使用していたときにinfo.fetch(1)
返さ"keyword"
れたので、正規表現もタグと一致している可能性がありますか?
GlibとGtkの経験がある人が答えを知っていることを願っています、ありがとう。