1 //this file is part of notepad++
2 //Copyright (C)2003 Don HO <donho@altern.org>
3 //
4 //This program is free software; you can redistribute it and/or
5 //modify it under the terms of the GNU General Public License
6 //as published by the Free Software Foundation; either
7 //version 2 of the License, or (at your option) any later version.
8 //
9 //This program is distributed in the hope that it will be useful,
10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //GNU General Public License for more details.
13 //
14 //You should have received a copy of the GNU General Public License
15 //along with this program; if not, write to the Free Software
16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 /**
18  * plugin DLL interface
19  *
20  * License: GPL-2.0 or later
21  */
22 module npp_demo.plugin_dll;
23 
24 
25 version (Windows):
26 
27 //pragma(lib, "kernel32");
28 //pragma(lib, "user32");
29 
30 private static import core.runtime;
31 private static import core.stdc.ctype;
32 private static import core.stdc.string;
33 private static import core.sys.windows.basetsd;
34 private static import core.sys.windows.winbase;
35 private static import core.sys.windows.windef;
36 private static import core.sys.windows.winnt;
37 private static import core.sys.windows.winuser;
38 private static import npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs;
39 private static import npp_api.PowerEditor.MISC.PluginsManager.PluginInterface;
40 private static import npp_api.PowerEditor.ScitillaComponent.GoToLineDlg;
41 private static import npp_api.PowerEditor.menuCmdID;
42 private static import npp_api.pluginfunc.auto_pFunc;
43 private static import npp_api.pluginfunc.basic_interface;
44 private static import npp_api.pluginfunc.extra_interfece;
45 private static import npp_api.pluginfunc.npp_msgs;
46 private static import npp_api.pluginfunc.scintilla_msg;
47 private static import npp_api.pluginfunc.string;
48 private static import npp_api.scintilla.Scintilla;
49 private static import npp_demo.commands;
50 private static import npp_demo.config;
51 private static import npp_demo.GoToLineDlg;
52 
53 mixin npp_api.pluginfunc.auto_pFunc.mixin_menu_index_change_check!(`Close_HTML_XML_tag_automatically`) insertHtmlCloseTag;
54 
55 extern (C)
56 __gshared npp_api.PowerEditor.MISC.PluginsManager.PluginInterface.NppData gshared_nppData;
57 
58 /**
59  * Initialization of your plugin data
60  * It will be called while plugin loading
61  */
62 pragma(inline, true)
63 nothrow
64 void pluginInit(core.sys.windows.basetsd.HANDLE hModule)
65 
66 	in
67 	{
68 	}
69 
70 	do
71 	{
72 		// Initialize dockable demo dialog
73 		npp_demo.GoToLineDlg._goToLine = new npp_demo.GoToLineDlg.demo_dlg();
74 		npp_demo.GoToLineDlg._goToLine.initialize(cast(core.sys.windows.windef.HINSTANCE)(hModule), core.sys.windows.windef.NULL);
75 	}
76 
77 pragma(inline, true)
78 nothrow
79 void pluginBeNotified(ref npp_api.scintilla.Scintilla.SCNotification notifyCode)
80 
81 	do
82 	{
83 		switch (notifyCode.nmhdr.code) {
84 			case npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPN_SHUTDOWN:
85 				break;
86 
87 			case npp_api.scintilla.Scintilla.SCN_CHARADDED:
88 				npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.LangType docType;
89 				npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTLANGTYPE(.nppData._nppHandle, docType);
90 				bool isDocTypeHTML = ((docType == npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.LangType.L_HTML) || (docType == npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.LangType.L_XML) || (docType == npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.LangType.L_PHP));
91 
92 				if (.menu_index[.search_index!(`Close_HTML_XML_tag_automatically`)].func_item._init2Check && isDocTypeHTML) {
93 					if (notifyCode.ch == '>') {
94 						char[512] buf;
95 						int currentEdit;
96 						npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit);
97 						core.sys.windows.windef.HWND hCurrentEditView = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle);
98 						int currentPos = cast(int)(npp_api.pluginfunc.scintilla_msg.send_SCI_GETCURRENTPOS(hCurrentEditView));
99 						int beginPos = currentPos - cast(int)(buf.length - 1);
100 						int startPos = (beginPos > 0) ? (beginPos) : (0);
101 						int size = currentPos - startPos;
102 						char[516] insertString = "</";
103 
104 						if (size >= 3) {
105 							npp_api.scintilla.Scintilla.Sci_TextRange tr = {{startPos, currentPos}, &(buf[0])};
106 
107 							npp_api.pluginfunc.scintilla_msg.send_SCI_GETTEXTRANGE(hCurrentEditView, tr);
108 
109 							if (buf[size - 2] != '/') {
110 								const (char)* pBegin = &(buf[0]);
111 								const (char)* pCur = &(buf[size - 2]);
112 								int  insertStringSize = 2;
113 
114 								for (; (pCur > pBegin) && (*pCur != '<') && (*pCur != '>') ;) {
115 									pCur--;
116 								}
117 
118 								if (*pCur == '<') {
119 									++pCur;
120 
121 									while ((core.stdc..string.strchr(":_-.", *pCur) != null) || (core.stdc.ctype.isalnum(*pCur) != 0)) {
122 										insertString[insertStringSize++] = *pCur;
123 										++pCur;
124 									}
125 								}
126 
127 								insertString[insertStringSize++] = '>';
128 								insertString[insertStringSize] = '\0';
129 
130 								if (insertStringSize > 3) {
131 									npp_api.pluginfunc.scintilla_msg.send_SCI_BEGINUNDOACTION(hCurrentEditView);
132 									npp_api.pluginfunc.scintilla_msg.send_SCI_REPLACESEL(hCurrentEditView, &(insertString[0]));
133 									npp_api.pluginfunc.scintilla_msg.send_SCI_SETSEL(hCurrentEditView, currentPos, currentPos);
134 									npp_api.pluginfunc.scintilla_msg.send_SCI_ENDUNDOACTION(hCurrentEditView);
135 								}
136 							}
137 						}
138 					}
139 				}
140 
141 				break;
142 
143 			default:
144 				return;
145 		}
146 	}
147 
148 /*
149  * Notepad++ interface functions
150  */
151 mixin npp_api.pluginfunc.extra_interfece.npp_plugin_interface!(npp_demo.config.plugin_def);