forked from bruderstein/PythonScript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NppPluginIface_DocTabMap.cpp
166 lines (133 loc) · 5.47 KB
/
NppPluginIface_DocTabMap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* NppPluginIface_DocTabMap.h
*
* This file is part of the Notepad++ Plugin Interface Lib.
* Copyright 2008 - 2009 Thell Fowler ([email protected])
*
* This program is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Notepad++ Plugin Interface Lib extension providing mapping of Notepad++ tab bufferID and
* visibility to Scintilla Document pointers, as well as tracking the currently open files
* by docID and a docId to bufferID map.
*
* For an example of using this see NppPluginIface_ActionIndex.
*
*/
#include "NppPluginIface_DocTabMap.h"
#include <set>
#include <map>
// <--- Notepad++ Scintilla Components for BufferID to pDoc --->
#define TIXMLA_USE_STL
#include "Buffer.h"
// <--- Boost --->
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
namespace npp_plugin {
namespace doctabmap {
// The main class for storing the document to buffer state information.
struct DocTab {
HWND _view;
int _tab;
BufferID _bufferID;
Document _pDoc;
bool _isVisible;
DocTab( HWND view, int tab, BufferID bufferID, Document pDoc, bool isVisible)
:_view(view), _tab(tab), _bufferID(bufferID), _pDoc(pDoc), _isVisible(isVisible){};
};
// Boost mulit_index_container setup for tracking tab visibility states.
using boost::multi_index::multi_index_container;
using namespace boost::multi_index;
// Namespace for the DocTab multi_index_container.
namespace doctabmap_mic {
// DocTab_set index key for comp_visible_key.
struct dt_visible_key{};
// DocTab_set composite index key for unique view/visible combination.
struct comp_visible_key:composite_key<
DocTab,
BOOST_MULTI_INDEX_MEMBER(DocTab, HWND, _view),
BOOST_MULTI_INDEX_MEMBER(DocTab, bool, _isVisible)
>{};
// Multi Index Container for indexing N++ Doc Tab state data.
typedef multi_index_container<
DocTab,
indexed_by<
ordered_unique< tag<dt_visible_key>, comp_visible_key >
>
> DocTab_set;
// Index definition type for the DocTab_set container.
typedef DocTab_set::index<dt_visible_key>::type dts_by_visibleTab;
// The one and only DocTab_set container.
DocTab_set dts;
// A set for storing active and ready open documents
std::set<int> open_docs;
// A map for storing buffer id to doc id. Usefull for doc open/close operations.
std::map< int, int > buff2doc_map;
} // End namespace doctabmap_mic
using namespace doctabmap_mic;
// Public index to the DocTab_set.
dts_by_visibleTab& visibleTab_index = dts.get<dt_visible_key>();
// Update the tab mapping between bufferIDs and pDocs for message filtering.
void update_DocTabMap()
{
// Since there isn't a buffer-deactivate message to remove an entry we empty the set and
// rebuild on buffer activated messages.
if ( dts.size() > 0 ) {
dts.clear();
open_docs.clear();
}
// Populate the DocTab_set
// The tab and buffer ID aren't really needed, yet I believe there may be some other
// uses for that information so they've been left in there.
bool isVisible = false;
for ( int view = MAIN_VIEW; view <= SUB_VIEW; view++ ) {
HWND targetView = hViewByInt(view);
Document viewDocID = (Document)::SendMessage( targetView, SCI_GETDOCPOINTER, 0, 0);
int nb_openfiles_view = ( view == MAIN_VIEW ) ? ( PRIMARY_VIEW ) : ( SECOND_VIEW );
int nb_Tabs = ::SendMessage( hNpp(), NPPM_GETNBOPENFILES, 0, nb_openfiles_view );
for ( int tab = 0; tab < nb_Tabs; tab++ ) {
int tabBuffID = ::SendMessage( hNpp(), NPPM_GETBUFFERIDFROMPOS, tab, view);
if ( tabBuffID > 0 ) {
BufferID pBuff = (BufferID)tabBuffID;;
Document pDoc = pBuff->getDocument();
isVisible = ( pDoc == viewDocID ) ? ( true ) : ( false );
dts.insert(
DocTab( targetView, tab, pBuff, pDoc, isVisible)
);
open_docs.insert( (int)pDoc );
if ( buff2doc_map.find( (int)pBuff ) == buff2doc_map.end() ) {
buff2doc_map[ (int)pBuff ] = (int)pDoc;
}
}
}
}
}
// Returns the Scintilla Document ID for the visible document in the specified view.
// ( MAIN_VIEW = 0, SUB_VIEW = 1 )
int getVisibleDocId_by_View( int view )
{
// The tuple is composed of the HWND for the view and a bool for 'is visible' to lookup
// the Doc ID based on the composite key from the index.
DocTab _DocTab = *(visibleTab_index.find( boost::make_tuple( hViewByInt( view ), true ) ) );
return ( _DocTab._pDoc );
}
// Returns the Scintilla Document ID matching a buffer ID.
int getDocIdFromBufferId( int bufferID ) { return ( buff2doc_map[bufferID] ); }
// Returns true if a document is currently open and ready.
bool fileIsOpen( int pDoc )
{
if ( open_docs.find( pDoc ) != open_docs.end() ) return ( true );
else return ( false );
}
} // End namespace: doctabmap
} // End namespace: npp_plugin