Browse Source

juci working auto complete

merge-requests/365/head
Jørgen Lien Sellæg 11 years ago
parent
commit
64ce7473ed
  1. 189
      juci/notebook.cc
  2. 21
      juci/notebook.h
  3. 16
      juci/source.cc
  4. 25
      juci/source.h

189
juci/notebook.cc

@ -1,6 +1,5 @@
#include "notebook.h"
#include <fstream>
#include "clangmm.h"
Notebook::Model::Model() {
cc_extension_ = ".cc";
@ -13,7 +12,8 @@ Notebook::View::View() {
view_.set_position(120);
}
Notebook::Controller::Controller(Gtk::Window& window, Keybindings::Controller& keybindings,
Notebook::Controller::Controller(Gtk::Window& window,
Keybindings::Controller& keybindings,
Source::Config& source_cfg,
Directories::Config& dir_cfg) :
source_config_(source_cfg),
@ -24,7 +24,7 @@ Notebook::Controller::Controller(Gtk::Window& window, Keybindings::Controller& k
ispopup = false;
view().pack1(directories_.widget(), true, true);
CreateKeybindings(keybindings);
} // Constructor
} // Constructor
void Notebook::Controller::CreateKeybindings(Keybindings::Controller
@ -98,7 +98,7 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller
[this]() {
OnEditPaste();
});
entry_.view_.entry().signal_activate().
entry_.view_.entry().signal_activate().
connect(
[this]() {
if (is_new_file_) {
@ -131,54 +131,103 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller
});
}
bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button){
if(button->button == 1 && ispopup){
popup_.response(Gtk::RESPONSE_DELETE_EVENT);
return true;
bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button) {
if (button->button == 1 && ispopup) {
popup_.response(Gtk::RESPONSE_DELETE_EVENT);
return true;
}
return false;
}
bool Notebook::Controller::OnKeyRelease(GdkEventKey* key){
if(key->keyval==46){
return GeneratePopup();
}
return false;
bool Notebook::Controller::OnKeyRelease(GdkEventKey* key) {
return GeneratePopup(key->keyval);
}
bool Notebook::Controller::GeneratePopup(){
bool Notebook::Controller::GeneratePopup(int key_id) {
// Get function to fill popup with suggests item vector under is for testing
std::vector<std::string> items;
Gtk::TextIter start = CurrentTextView().get_buffer()->get_insert()->get_iter();
text_vec_.at(CurrentPage())->GetAutoCompleteSuggestions(start.get_line()+1,
start.get_line_offset()+2,
&items);
std::cout << items.size()<< std::endl;
Gtk::TextIter beg = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter end = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter tmp = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter tmp1 = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter line =
CurrentTextView().get_buffer()->get_iter_at_line(tmp.get_line());
if (end.backward_char() && end.backward_char()) {
bool illegal_chars =
end.backward_search("\"", Gtk::TEXT_SEARCH_VISIBLE_ONLY, tmp, tmp1, line)
||
end.backward_search("//", Gtk::TEXT_SEARCH_VISIBLE_ONLY, tmp, tmp1, line);
if (illegal_chars) {
return false;
}
std::string c = text_vec_[CurrentPage()]->buffer()->get_text(end, beg);
switch (key_id) {
case 46:
break;
case 58:
if (c != "::") return false;
break;
case 60:
if (c != "->") return false;
break;
case 62:
if (c != "->") return false;
break;
default:
return false;
}
} else {
return false;
}
std::vector<Source::AutoCompleteData> acdata;
text_vec_.at(CurrentPage())->
GetAutoCompleteSuggestions(beg.get_line()+1,
beg.get_line_offset()+2,
&acdata);
std::map<std::string, std::string> items;
for (auto &data : acdata) {
std::stringstream ss;
std::string return_value;
for (auto &chunk : data.chunks_) {
switch (chunk.kind()) {
case clang::CompletionChunk_ResultType:
return_value = chunk.chunk();
break;
case clang::CompletionChunk_Informative:
break;
default:
ss << chunk.chunk();
break;
}
}
items[ss.str() + " --> " + return_value] = ss.str();
}
// Replace over with get suggestions from zalox! OVER IS JUST FOR TESTING
Gtk::ScrolledWindow popup_scroll_;
Gtk::ListViewText listview_(1,false,Gtk::SelectionMode::SELECTION_SINGLE);
Gtk::ListViewText listview_(1, false, Gtk::SelectionMode::SELECTION_SINGLE);
popup_scroll_.set_policy(Gtk::PolicyType::POLICY_NEVER,
Gtk::PolicyType::POLICY_NEVER);
listview_.set_enable_search(false);
Gtk::PolicyType::POLICY_NEVER);
listview_.set_enable_search(true);
listview_.set_headers_visible(false);
listview_.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
listview_.set_activate_on_single_click(true);
for (auto &i : items) listview_.append(i);
if (items.empty()) {
items["No suggestions found..."] = "";
}
for (auto &i : items) {
listview_.append(i.first);
}
popup_scroll_.add(listview_);
popup_.get_vbox()->pack_start(popup_scroll_);
popup_.set_transient_for(*window_);
popup_.show_all();
int popup_x = popup_.get_width();
int popup_y = items.size()*20;
PopupSetSize(popup_scroll_,popup_x,popup_y);
int x,y;
FindPopupPosition(CurrentTextView(),popup_x,popup_y,x,y);
int popup_y = items.size() * 20;
PopupSetSize(popup_scroll_, popup_x, popup_y);
int x, y;
FindPopupPosition(CurrentTextView(), popup_x, popup_y, x, y);
popup_.move(x, y+15);
PopupSelectHandler(popup_, listview_);
PopupSelectHandler(popup_, listview_, &items);
ispopup = true;
popup_.run();
popup_.hide();
@ -232,9 +281,7 @@ void Notebook::Controller::OnOpenFile(std::string path) {
unsigned pos = path.find_last_of("/\\");
Notebook().append_page(*editor_vec_.back(), path.substr(pos+1));
Notebook().show_all_children();
std::cout << "setting current page"<< std::endl;
Notebook().set_current_page(Pages()-1);
std::cout << "current page set" << std::endl;
Notebook().set_focus_child(text_vec_.back()->view());
OnBufferChange();
}
@ -431,37 +478,37 @@ Gtk::Notebook& Notebook::Controller::Notebook() {
void Notebook::Controller::TextViewHandlers(Gtk::TextView& textview) {
textview.get_buffer()->signal_changed().connect(
[this]() {
OnBufferChange();
});
[this]() {
OnBufferChange();
});
textview.signal_button_release_event().
connect(sigc::mem_fun(*this,&Notebook::Controller::OnMouseRelease),false);
connect(sigc::mem_fun(*this, &Notebook::Controller::OnMouseRelease), false);
textview.signal_key_release_event().
connect(sigc::mem_fun(*this,&Notebook::Controller::OnKeyRelease),false);
connect(sigc::mem_fun(*this, &Notebook::Controller::OnKeyRelease), false);
}
void Notebook::Controller::PopupSelectHandler(Gtk::Dialog &popup,
Gtk::ListViewText &listview){
Gtk::ListViewText &listview,
std::map<std::string, std::string>
*items) {
listview.signal_row_activated().
connect([this, &listview, &popup](const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn*) {
std::string selected =
listview.get_text(listview.get_selected()[0]);
CurrentTextView().get_buffer()->insert_at_cursor(selected);
popup.response(Gtk::RESPONSE_DELETE_EVENT);
});
connect([this, &listview, &popup, items](const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn*) {
std::string selected = items->
at(listview.get_text(listview.get_selected()[0]));
CurrentTextView().get_buffer()->insert_at_cursor(selected);
popup.response(Gtk::RESPONSE_DELETE_EVENT);
});
}
void Notebook::Controller::PopupSetSize(Gtk::ScrolledWindow &scroll,
int &current_x,
int &current_y) {
int &current_x,
int &current_y) {
int textview_x = CurrentTextView().get_width();
int textview_y = 150;
bool is_never_scroll_x = true;
bool is_never_scroll_y = true;
std::cout << textview_x << std::endl;
if (current_x > textview_x) {
current_x = textview_x;
is_never_scroll_x = false;
@ -470,36 +517,36 @@ void Notebook::Controller::PopupSetSize(Gtk::ScrolledWindow &scroll,
current_y = textview_y;
is_never_scroll_y = false;
}
scroll.set_size_request(current_x,current_y);
scroll.set_size_request(current_x, current_y);
if (!is_never_scroll_x && !is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
Gtk::PolicyType::POLICY_AUTOMATIC);
Gtk::PolicyType::POLICY_AUTOMATIC);
} else if (!is_never_scroll_x && is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
Gtk::PolicyType::POLICY_NEVER);
Gtk::PolicyType::POLICY_NEVER);
} else if (is_never_scroll_x && !is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_NEVER,
Gtk::PolicyType::POLICY_AUTOMATIC);
Gtk::PolicyType::POLICY_AUTOMATIC);
}
}
void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview,
int popup_x,
int popup_y,
int &x,
int &y){
int popup_x,
int popup_y,
int &x,
int &y) {
Gdk::Rectangle temp1, temp2;
textview.get_cursor_locations(
CurrentTextView().
get_buffer()->get_insert()->
get_iter(), temp1,temp2);
CurrentTextView().
get_buffer()->get_insert()->
get_iter(), temp1, temp2);
int textview_edge_x = 0;
int textview_edge_y = 0;
textview.buffer_to_window_coords(
Gtk::TextWindowType::TEXT_WINDOW_WIDGET,
temp1.get_x(),
temp1.get_y(),
x, y);
Gtk::TextWindowType::TEXT_WINDOW_WIDGET,
temp1.get_x(),
temp1.get_y(),
x, y);
Glib::RefPtr<Gdk::Window> gdkw =
CurrentTextView().get_window(Gtk::TextWindowType::TEXT_WINDOW_WIDGET);
gdkw->get_origin(textview_edge_x, textview_edge_y);
@ -508,17 +555,17 @@ void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview,
y+=textview_edge_y;
if ((textview_edge_x-x)*-1 > textview.get_width()-popup_x) {
x -= popup_x;
if(x<textview_edge_x) x = textview_edge_x;
if (x < textview_edge_x) x = textview_edge_x;
}
if ((textview_edge_y-y)*-1 > textview.get_height()-popup_y) {
y -= (popup_y+14) + 15;
if(x<textview_edge_y) y = textview_edge_y +15;
if (x < textview_edge_y) y = textview_edge_y +15;
}
}
void Notebook::Controller:: OnSaveFile(std::string path){
void Notebook::Controller:: OnSaveFile(std::string path) {
std::ofstream file;
file.open (path);
file.open(path);
file << CurrentTextView().get_buffer()->get_text();
file.close();
}

21
juci/notebook.h

@ -8,6 +8,7 @@
#include "directories.h"
#include <boost/algorithm/string/case_conv.hpp>
#include <type_traits>
#include <map>
#include <sigc++/sigc++.h>
namespace Notebook {
@ -59,25 +60,29 @@ namespace Notebook {
int Pages();
Directories::Controller& directories() { return directories_; }
Gtk::Paned& view();
bool GeneratePopup();
bool GeneratePopup(int key);
void Search(bool forward);
const Source::Config& source_config() { return source_config_; }
bool OnMouseRelease(GdkEventButton* button);
bool OnKeyRelease(GdkEventKey* key);
protected:
void TextViewHandlers(Gtk::TextView& textview);
void PopupSelectHandler(Gtk::Dialog &popup,
Gtk::ListViewText &listview);
Gtk::ListViewText &listview,
std::map<std::string, std::string>
*items);
private:
void CreateKeybindings(Keybindings::Controller& keybindings);
void FindPopupPosition(Gtk::TextView& textview,
int popup_x,
int popup_y,
int &x,
int &y);
int popup_x,
int popup_y,
int &x,
int &y);
void PopupSetSize(Gtk::ScrolledWindow& scroll,
int &current_x,
int &current_y);
int &current_x,
int &current_y);
Glib::RefPtr<Gtk::Builder> m_refBuilder;
Glib::RefPtr<Gio::SimpleActionGroup> refActionGroup;
Source::Config source_config_;

16
juci/source.cc

@ -135,7 +135,8 @@ void Source::Controller::OnLineEdit() { }
void Source::Controller::
GetAutoCompleteSuggestions(int line_number,
int column,
std::vector<std::string> *suggestions) {
std::vector<Source::AutoCompleteData>
*suggestions) {
parsing.lock();
model().GetAutoCompleteSuggestions(view().get_buffer()
->get_text().raw(),
@ -149,19 +150,20 @@ void Source::Model::
GetAutoCompleteSuggestions(const std::string& buffer,
int line_number,
int column,
std::vector<std::string> *suggestions) {
std::vector<Source::AutoCompleteData>
*suggestions) {
clang::CodeCompleteResults results(&tu_,
file_path(),
buffer,
line_number,
column);
for (int i = 0; i < results.size(); i++) {
std::stringstream ss;
const vector<clang::CompletionChunk> c = results.get(i).get_chunks();
for (auto &stringchunk : c) {
ss << stringchunk.chunk();
const vector<clang::CompletionChunk> chunks_ = results.get(i).get_chunks();
std::vector<AutoCompleteChunk> chunks;
for (auto &chunk : chunks_) {
chunks.emplace_back(chunk);
}
suggestions->emplace_back(ss.str());
suggestions->emplace_back(chunks);
}
}

25
juci/source.h

@ -74,6 +74,24 @@ namespace Source {
string GetLine(const Gtk::TextIter &begin);
}; // class View
class AutoCompleteChunk {
public:
explicit AutoCompleteChunk(const clang::CompletionChunk &chunk) :
chunk_(chunk.chunk()), kind_(chunk.kind()) { }
const std::string& chunk() const { return chunk_; }
const clang::CompletionChunkKind& kind() const { return kind_; }
private:
std::string chunk_;
enum clang::CompletionChunkKind kind_;
};
class AutoCompleteData {
public:
explicit AutoCompleteData(const std::vector<AutoCompleteChunk> &chunks) :
chunks_(chunks) { }
std::vector<AutoCompleteChunk> chunks_;
};
class Model{
public:
// constructor for Source::Model
@ -98,7 +116,8 @@ namespace Source {
void GetAutoCompleteSuggestions(const std::string& buffer,
int line_number,
int column,
std::vector<std::string> *suggestions);
std::vector<AutoCompleteData>
*suggestions);
~Model() { }
int ReParse(const std::string &buffer);
std::vector<Range> ExtractTokens(int, int);
@ -113,7 +132,6 @@ namespace Source {
int token_kind);
void HighlightCursor(clang::Token *token,
std::vector<Range> *source_ranges);
std::vector<const char*> get_compilation_commands();
};
@ -127,7 +145,8 @@ namespace Source {
void OnOpenFile(const string &filename);
void GetAutoCompleteSuggestions(int line_number,
int column,
std::vector<std::string> *suggestions);
std::vector<AutoCompleteData>
*suggestions);
Glib::RefPtr<Gtk::TextBuffer> buffer();
private:

Loading…
Cancel
Save