]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ControlCommandBuffer.cpp
fix scrolling bug: 3320 and 3652, maybe not perfect
[lyx.git] / src / frontends / controllers / ControlCommandBuffer.cpp
1 /**
2  * \file ControlCommandBuffer.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars
7  * \author Asger and Jürgen
8  * \author John Levon
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "ControlCommandBuffer.h"
16
17 #include "BufferView.h"
18 #include "Cursor.h"
19 #include "LyXFunc.h"
20 #include "LyXAction.h"
21 #include "FuncRequest.h"
22
23 #include "frontends/LyXView.h"
24
25 #include "support/lyxalgo.h"
26 #include "support/lstrings.h"
27
28 using std::back_inserter;
29 using std::transform;
30 using std::string;
31 using std::vector;
32
33 namespace lyx {
34
35 using support::prefixIs;
36
37 namespace frontend {
38
39 namespace {
40
41 class prefix_p {
42 public:
43         string p;
44         prefix_p(string const & s)
45                 : p(s) {}
46         bool operator()(string const & s) const {
47                 return prefixIs(s, p);
48         }
49 };
50
51 } // end of anon namespace
52
53
54 ControlCommandBuffer::ControlCommandBuffer(LyXView & lv)
55         : lv_(lv), history_pos_(history_.end())
56 {
57         transform(lyxaction.func_begin(), lyxaction.func_end(),
58                 back_inserter(commands_), firster());
59 }
60
61
62 string const ControlCommandBuffer::historyUp()
63 {
64         if (history_pos_ == history_.begin())
65                 return string();
66
67         return *(--history_pos_);
68 }
69
70
71 string const ControlCommandBuffer::historyDown()
72 {
73         if (history_pos_ == history_.end())
74                 return string();
75         if (history_pos_ + 1 == history_.end())
76                 return string();
77
78         return *(++history_pos_);
79 }
80
81
82 docstring const ControlCommandBuffer::getCurrentState() const
83 {
84         return lv_.view()->cursor().currentState();
85 }
86
87
88 void ControlCommandBuffer::hide() const
89 {
90         lv_.getToolbars().display("minibuffer", false);
91 }
92
93
94 vector<string> const
95 ControlCommandBuffer::completions(string const & prefix, string & new_prefix)
96 {
97         vector<string> comp;
98
99         copy_if(commands_.begin(), commands_.end(),
100                 back_inserter(comp), prefix_p(prefix));
101
102         if (comp.empty()) {
103                 new_prefix = prefix;
104                 return comp;
105         }
106
107         if (comp.size() == 1) {
108                 new_prefix = comp[0];
109                 return vector<string>();
110         }
111
112         // find maximal available prefix
113         string const tmp = comp[0];
114         string test = prefix;
115         if (tmp.length() > test.length())
116                 test += tmp[test.length()];
117         while (test.length() < tmp.length()) {
118                 vector<string> vtmp;
119                 copy_if(comp.begin(), comp.end(),
120                         back_inserter(vtmp), prefix_p(test));
121                 if (vtmp.size() != comp.size()) {
122                         test.erase(test.length() - 1);
123                         break;
124                 }
125                 test += tmp[test.length()];
126         }
127
128         new_prefix = test;
129         return comp;
130 }
131
132
133 void ControlCommandBuffer::dispatch(string const & str)
134 {
135         if (str.empty())
136                 return;
137
138         history_.push_back(str);
139         history_pos_ = history_.end();
140         FuncRequest func = lyxaction.lookupFunc(str);
141         func.origin = FuncRequest::COMMANDBUFFER;
142         lv_.dispatch(func);
143 }
144
145 } // namespace frontend
146 } // namespace lyx