├── .gitignore ├── DoxyIt.sln ├── LICENSE ├── README.md ├── appveyor.yml ├── img ├── Demo.gif ├── Demo2.gif └── Settings.png ├── src ├── Dialogs │ ├── AboutDialog.cpp │ ├── AboutDialog.h │ ├── Hyperlinks.cpp │ ├── Hyperlinks.h │ ├── SettingsDialog.cpp │ ├── SettingsDialog.h │ ├── StaticDialog.cpp │ ├── StaticDialog.h │ ├── Version.rc │ ├── Window.h │ ├── resource.h │ └── resource.rc ├── DoxyIt.cpp ├── DoxyIt.vcxproj ├── DoxyIt.vcxproj.filters ├── JumpLocations.cpp ├── JumpLocations.h ├── Npp │ ├── Notepad_plus_msgs.h │ ├── PluginInterface.h │ ├── Sci_Position.h │ ├── Scintilla.h │ └── menuCmdID.h ├── Parsers │ ├── C_Parser.cpp │ ├── Null_Parser.cpp │ ├── Parsers.cpp │ ├── Parsers.h │ └── Python_Parser.cpp ├── PluginDefinition.cpp ├── PluginDefinition.h ├── ScintillaEditor.h ├── Utilities │ ├── Utils.cpp │ ├── Utils.h │ ├── trex.cpp │ └── trex.h └── Version.h └── tests ├── test.c ├── test.cpp ├── test.cs ├── test.java ├── test.js ├── test.php └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | 290 | 291 | /Unicode Realeas 292 | /Unicode Release 293 | /ResEdit-x64 294 | -------------------------------------------------------------------------------- /DoxyIt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.645 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DoxyIt", "src\DoxyIt.vcxproj", "{1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Debug|Win32.Build.0 = Debug|Win32 18 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Debug|x64.ActiveCfg = Debug|x64 19 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Debug|x64.Build.0 = Debug|x64 20 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Release|Win32.ActiveCfg = Release|Win32 21 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Release|Win32.Build.0 = Release|Win32 22 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Release|x64.ActiveCfg = Release|x64 23 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | 3 | GNU GENERAL PUBLIC LICENSE 4 | Version 2, June 1991 5 | 6 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 7 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 8 | Everyone is permitted to copy and distribute verbatim copies 9 | of this license document, but changing it is not allowed. 10 | 11 | Preamble 12 | 13 | The licenses for most software are designed to take away your 14 | freedom to share and change it. By contrast, the GNU General Public 15 | License is intended to guarantee your freedom to share and change free 16 | software--to make sure the software is free for all its users. This 17 | General Public License applies to most of the Free Software 18 | Foundation's software and to any other program whose authors commit to 19 | using it. (Some other Free Software Foundation software is covered by 20 | the GNU Lesser General Public License instead.) You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not 24 | price. Our General Public Licenses are designed to make sure that you 25 | have the freedom to distribute copies of free software (and charge for 26 | this service if you wish), that you receive source code or can get it 27 | if you want it, that you can change the software or use pieces of it 28 | in new free programs; and that you know you can do these things. 29 | 30 | To protect your rights, we need to make restrictions that forbid 31 | anyone to deny you these rights or to ask you to surrender the rights. 32 | These restrictions translate to certain responsibilities for you if you 33 | distribute copies of the software, or if you modify it. 34 | 35 | For example, if you distribute copies of such a program, whether 36 | gratis or for a fee, you must give the recipients all the rights that 37 | you have. You must make sure that they, too, receive or can get the 38 | source code. And you must show them these terms so they know their 39 | rights. 40 | 41 | We protect your rights with two steps: (1) copyright the software, and 42 | (2) offer you this license which gives you legal permission to copy, 43 | distribute and/or modify the software. 44 | 45 | Also, for each author's protection and ours, we want to make certain 46 | that everyone understands that there is no warranty for this free 47 | software. If the software is modified by someone else and passed on, we 48 | want its recipients to know that what they have is not the original, so 49 | that any problems introduced by others will not reflect on the original 50 | authors' reputations. 51 | 52 | Finally, any free program is threatened constantly by software 53 | patents. We wish to avoid the danger that redistributors of a free 54 | program will individually obtain patent licenses, in effect making the 55 | program proprietary. To prevent this, we have made it clear that any 56 | patent must be licensed for everyone's free use or not licensed at all. 57 | 58 | The precise terms and conditions for copying, distribution and 59 | modification follow. 60 | 61 | GNU GENERAL PUBLIC LICENSE 62 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 63 | 64 | 0. This License applies to any program or other work which contains 65 | a notice placed by the copyright holder saying it may be distributed 66 | under the terms of this General Public License. The "Program", below, 67 | refers to any such program or work, and a "work based on the Program" 68 | means either the Program or any derivative work under copyright law: 69 | that is to say, a work containing the Program or a portion of it, 70 | either verbatim or with modifications and/or translated into another 71 | language. (Hereinafter, translation is included without limitation in 72 | the term "modification".) Each licensee is addressed as "you". 73 | 74 | Activities other than copying, distribution and modification are not 75 | covered by this License; they are outside its scope. The act of 76 | running the Program is not restricted, and the output from the Program 77 | is covered only if its contents constitute a work based on the 78 | Program (independent of having been made by running the Program). 79 | Whether that is true depends on what the Program does. 80 | 81 | 1. You may copy and distribute verbatim copies of the Program's 82 | source code as you receive it, in any medium, provided that you 83 | conspicuously and appropriately publish on each copy an appropriate 84 | copyright notice and disclaimer of warranty; keep intact all the 85 | notices that refer to this License and to the absence of any warranty; 86 | and give any other recipients of the Program a copy of this License 87 | along with the Program. 88 | 89 | You may charge a fee for the physical act of transferring a copy, and 90 | you may at your option offer warranty protection in exchange for a fee. 91 | 92 | 2. You may modify your copy or copies of the Program or any portion 93 | of it, thus forming a work based on the Program, and copy and 94 | distribute such modifications or work under the terms of Section 1 95 | above, provided that you also meet all of these conditions: 96 | 97 | a) You must cause the modified files to carry prominent notices 98 | stating that you changed the files and the date of any change. 99 | 100 | b) You must cause any work that you distribute or publish, that in 101 | whole or in part contains or is derived from the Program or any 102 | part thereof, to be licensed as a whole at no charge to all third 103 | parties under the terms of this License. 104 | 105 | c) If the modified program normally reads commands interactively 106 | when run, you must cause it, when started running for such 107 | interactive use in the most ordinary way, to print or display an 108 | announcement including an appropriate copyright notice and a 109 | notice that there is no warranty (or else, saying that you provide 110 | a warranty) and that users may redistribute the program under 111 | these conditions, and telling the user how to view a copy of this 112 | License. (Exception: if the Program itself is interactive but 113 | does not normally print such an announcement, your work based on 114 | the Program is not required to print an announcement.) 115 | 116 | These requirements apply to the modified work as a whole. If 117 | identifiable sections of that work are not derived from the Program, 118 | and can be reasonably considered independent and separate works in 119 | themselves, then this License, and its terms, do not apply to those 120 | sections when you distribute them as separate works. But when you 121 | distribute the same sections as part of a whole which is a work based 122 | on the Program, the distribution of the whole must be on the terms of 123 | this License, whose permissions for other licensees extend to the 124 | entire whole, and thus to each and every part regardless of who wrote it. 125 | 126 | Thus, it is not the intent of this section to claim rights or contest 127 | your rights to work written entirely by you; rather, the intent is to 128 | exercise the right to control the distribution of derivative or 129 | collective works based on the Program. 130 | 131 | In addition, mere aggregation of another work not based on the Program 132 | with the Program (or with a work based on the Program) on a volume of 133 | a storage or distribution medium does not bring the other work under 134 | the scope of this License. 135 | 136 | 3. You may copy and distribute the Program (or a work based on it, 137 | under Section 2) in object code or executable form under the terms of 138 | Sections 1 and 2 above provided that you also do one of the following: 139 | 140 | a) Accompany it with the complete corresponding machine-readable 141 | source code, which must be distributed under the terms of Sections 142 | 1 and 2 above on a medium customarily used for software interchange; or, 143 | 144 | b) Accompany it with a written offer, valid for at least three 145 | years, to give any third party, for a charge no more than your 146 | cost of physically performing source distribution, a complete 147 | machine-readable copy of the corresponding source code, to be 148 | distributed under the terms of Sections 1 and 2 above on a medium 149 | customarily used for software interchange; or, 150 | 151 | c) Accompany it with the information you received as to the offer 152 | to distribute corresponding source code. (This alternative is 153 | allowed only for noncommercial distribution and only if you 154 | received the program in object code or executable form with such 155 | an offer, in accord with Subsection b above.) 156 | 157 | The source code for a work means the preferred form of the work for 158 | making modifications to it. For an executable work, complete source 159 | code means all the source code for all modules it contains, plus any 160 | associated interface definition files, plus the scripts used to 161 | control compilation and installation of the executable. However, as a 162 | special exception, the source code distributed need not include 163 | anything that is normally distributed (in either source or binary 164 | form) with the major components (compiler, kernel, and so on) of the 165 | operating system on which the executable runs, unless that component 166 | itself accompanies the executable. 167 | 168 | If distribution of executable or object code is made by offering 169 | access to copy from a designated place, then offering equivalent 170 | access to copy the source code from the same place counts as 171 | distribution of the source code, even though third parties are not 172 | compelled to copy the source along with the object code. 173 | 174 | 4. You may not copy, modify, sublicense, or distribute the Program 175 | except as expressly provided under this License. Any attempt 176 | otherwise to copy, modify, sublicense or distribute the Program is 177 | void, and will automatically terminate your rights under this License. 178 | However, parties who have received copies, or rights, from you under 179 | this License will not have their licenses terminated so long as such 180 | parties remain in full compliance. 181 | 182 | 5. You are not required to accept this License, since you have not 183 | signed it. However, nothing else grants you permission to modify or 184 | distribute the Program or its derivative works. These actions are 185 | prohibited by law if you do not accept this License. Therefore, by 186 | modifying or distributing the Program (or any work based on the 187 | Program), you indicate your acceptance of this License to do so, and 188 | all its terms and conditions for copying, distributing or modifying 189 | the Program or works based on it. 190 | 191 | 6. Each time you redistribute the Program (or any work based on the 192 | Program), the recipient automatically receives a license from the 193 | original licensor to copy, distribute or modify the Program subject to 194 | these terms and conditions. You may not impose any further 195 | restrictions on the recipients' exercise of the rights granted herein. 196 | You are not responsible for enforcing compliance by third parties to 197 | this License. 198 | 199 | 7. If, as a consequence of a court judgment or allegation of patent 200 | infringement or for any other reason (not limited to patent issues), 201 | conditions are imposed on you (whether by court order, agreement or 202 | otherwise) that contradict the conditions of this License, they do not 203 | excuse you from the conditions of this License. If you cannot 204 | distribute so as to satisfy simultaneously your obligations under this 205 | License and any other pertinent obligations, then as a consequence you 206 | may not distribute the Program at all. For example, if a patent 207 | license would not permit royalty-free redistribution of the Program by 208 | all those who receive copies directly or indirectly through you, then 209 | the only way you could satisfy both it and this License would be to 210 | refrain entirely from distribution of the Program. 211 | 212 | If any portion of this section is held invalid or unenforceable under 213 | any particular circumstance, the balance of the section is intended to 214 | apply and the section as a whole is intended to apply in other 215 | circumstances. 216 | 217 | It is not the purpose of this section to induce you to infringe any 218 | patents or other property right claims or to contest validity of any 219 | such claims; this section has the sole purpose of protecting the 220 | integrity of the free software distribution system, which is 221 | implemented by public license practices. Many people have made 222 | generous contributions to the wide range of software distributed 223 | through that system in reliance on consistent application of that 224 | system; it is up to the author/donor to decide if he or she is willing 225 | to distribute software through any other system and a licensee cannot 226 | impose that choice. 227 | 228 | This section is intended to make thoroughly clear what is believed to 229 | be a consequence of the rest of this License. 230 | 231 | 8. If the distribution and/or use of the Program is restricted in 232 | certain countries either by patents or by copyrighted interfaces, the 233 | original copyright holder who places the Program under this License 234 | may add an explicit geographical distribution limitation excluding 235 | those countries, so that distribution is permitted only in or among 236 | countries not thus excluded. In such case, this License incorporates 237 | the limitation as if written in the body of this License. 238 | 239 | 9. The Free Software Foundation may publish revised and/or new versions 240 | of the General Public License from time to time. Such new versions will 241 | be similar in spirit to the present version, but may differ in detail to 242 | address new problems or concerns. 243 | 244 | Each version is given a distinguishing version number. If the Program 245 | specifies a version number of this License which applies to it and "any 246 | later version", you have the option of following the terms and conditions 247 | either of that version or of any later version published by the Free 248 | Software Foundation. If the Program does not specify a version number of 249 | this License, you may choose any version ever published by the Free Software 250 | Foundation. 251 | 252 | 10. If you wish to incorporate parts of the Program into other free 253 | programs whose distribution conditions are different, write to the author 254 | to ask for permission. For software which is copyrighted by the Free 255 | Software Foundation, write to the Free Software Foundation; we sometimes 256 | make exceptions for this. Our decision will be guided by the two goals 257 | of preserving the free status of all derivatives of our free software and 258 | of promoting the sharing and reuse of software generally. 259 | 260 | NO WARRANTY 261 | 262 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 263 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 264 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 265 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 266 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 267 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 268 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 269 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 270 | REPAIR OR CORRECTION. 271 | 272 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 273 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 274 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 275 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 276 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 277 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 278 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 279 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 280 | POSSIBILITY OF SUCH DAMAGES. 281 | 282 | END OF TERMS AND CONDITIONS 283 | 284 | How to Apply These Terms to Your New Programs 285 | 286 | If you develop a new program, and you want it to be of the greatest 287 | possible use to the public, the best way to achieve this is to make it 288 | free software which everyone can redistribute and change under these terms. 289 | 290 | To do so, attach the following notices to the program. It is safest 291 | to attach them to the start of each source file to most effectively 292 | convey the exclusion of warranty; and each file should have at least 293 | the "copyright" line and a pointer to where the full notice is found. 294 | 295 | {description} 296 | Copyright (C) {year} {fullname} 297 | 298 | This program is free software; you can redistribute it and/or modify 299 | it under the terms of the GNU General Public License as published by 300 | the Free Software Foundation; either version 2 of the License, or 301 | (at your option) any later version. 302 | 303 | This program is distributed in the hope that it will be useful, 304 | but WITHOUT ANY WARRANTY; without even the implied warranty of 305 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 306 | GNU General Public License for more details. 307 | 308 | You should have received a copy of the GNU General Public License along 309 | with this program; if not, write to the Free Software Foundation, Inc., 310 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 311 | 312 | Also add information on how to contact you by electronic and paper mail. 313 | 314 | If the program is interactive, make it output a short notice like this 315 | when it starts in an interactive mode: 316 | 317 | Gnomovision version 69, Copyright (C) year name of author 318 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 319 | This is free software, and you are welcome to redistribute it 320 | under certain conditions; type `show c' for details. 321 | 322 | The hypothetical commands `show w' and `show c' should show the appropriate 323 | parts of the General Public License. Of course, the commands you use may 324 | be called something other than `show w' and `show c'; they could even be 325 | mouse-clicks or menu items--whatever suits your program. 326 | 327 | You should also get your employer (if you work as a programmer) or your 328 | school, if any, to sign a "copyright disclaimer" for the program, if 329 | necessary. Here is a sample; alter the names: 330 | 331 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 332 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 333 | 334 | {signature of Ty Coon}, 1 April 1989 335 | Ty Coon, President of Vice 336 | 337 | This General Public License does not permit incorporating your program into 338 | proprietary programs. If your program is a subroutine library, you may 339 | consider it more useful to permit linking proprietary applications with the 340 | library. If this is what you want to do, use the GNU Lesser General 341 | Public License instead of this License. 342 | 343 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DoxyIt 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/mma3iba7vlvjk6jf?svg=true)](https://ci.appveyor.com/project/dail8859/doxyit) 4 | 5 | Notepad++ plugin for [Doxygen](http://www.doxygen.org) commenting. This also provides helpful features for creating and editing comment blocks, even if Doxygen isn't desired. 6 | 7 | The release versions of DoxyIt can be downloaded [here](https://github.com/dail8859/DoxyIt/releases). 8 | 9 | Currently there is support for: 10 | - C 11 | - C++ 12 | - Python 13 | - Java 14 | - PHP 15 | - JavaScript 16 | - C# 17 | - User Defined Languages 18 | 19 | **Note:** DoxyIt uses very simplistic parsing mechanisms and does not enforce valid language syntax, meaning it can easily be fooled. Thus, it is up to the user to ensure the function/method is syntactically valid when attempting to generate Doxygen function commenting as described below. 20 | 21 | ## Usage 22 | ### Doxygen Function Commenting 23 | Just start by opening a function block above the function. 24 | 25 | ![Demo](/img/Demo.gif) 26 | 27 | You can also manually trigger the function documentation (this is sometimes required for specific settings). Place the cursor on the line directly above the function definition and press `Ctrl+Alt+Shift+D` (or through the menu command *Plugins > DoxyIt > DoxyIt - Function*). 28 | 29 | **Note:** Function commenting for User Defined Languages inserts a comment block but does not parse any text. 30 | 31 | ### Doxygen File Commenting 32 | Using the menu command *Plugins > DoxyIt > DoxyIt - File* will insert a Doxygen comment block for the file at the current cursor position. 33 | 34 | ### Active Commenting 35 | Even if Doxygen commands aren't desired, you can still take advantage of the active commenting feature. A new comment block can be started by typing the opening string and pressing `Enter`. Adding a new line within the block will extend it. 36 | 37 | ![Demo2](/img/Demo2.gif) 38 | 39 | **Note:** If DoxyIt is configured to use long strings to indicate the start of a comment block, only the first 3 characters need to be typed. 40 | 41 | ## Settings 42 | Each language can be configured to have any string to indicate the start, middle, and end of a document block. The settings dialog also provides a live preview of what a documentation block would look like: 43 | 44 | ![Settings Dialog](/img/Settings.png) 45 | 46 | ### Doxygen Commenting Format 47 | The format string is used to customize the Doxygen Function Commenting block generated. There are currently a few keywords that are used. 48 | - `$FILENAME` - The current file name. 49 | - `$FUNCTION` - The name of the function/method. 50 | - `$PARAM` - Expands to a single function/method parameter. Any line containing this will get repeated for each parameter. 51 | - `$COMPUTER` - Current computer name. 52 | - `$USER` - User account name of current user (for example, smith). 53 | - `$FULLUSER` - Full user name of current user (for example, Jeff Smith). 54 | - `$DATE` - Current date and time, format ISO 8601 (for example, 2009-06-30T18:30:00). 55 | - `$DATE_a` - Abbreviated weekday name 56 | - `$DATE_A` - Full weekday name 57 | - `$DATE_b` - Abbreviated month name 58 | - `$DATE_B` - Full month name 59 | - `$DATE_c` - Date and time representation appropriate for locale 60 | - `$DATE_d` - Day of month as decimal number (01 - 31) 61 | - `$DATE_H` - Hour in 24-hour format (00 - 23) 62 | - `$DATE_I` - Hour in 12-hour format (01 - 12) 63 | - `$DATE_j` - Day of year as decimal number (001 - 366) 64 | - `$DATE_m` - Month as decimal number (01 - 12) 65 | - `$DATE_M` - Minute as decimal number (00 - 59) 66 | - `$DATE_p` - Current locale's A.M./P.M. indicator for 12-hour clock 67 | - `$DATE_S` - Second as decimal number (00 - 59) 68 | - `$DATE_U` - Week of year as decimal number, with Sunday as first day of week (00 - 53) 69 | - `$DATE_w` - Weekday as decimal number (0 - 6; Sunday is 0) 70 | - `$DATE_W` - Week of year as decimal number, with Monday as first day of week (00 - 53) 71 | - `$DATE_x` - Date representation for current locale 72 | - `$DATE_X` - Time representation for current locale 73 | - `$DATE_y` - Year without century, as decimal number (00 - 99) 74 | - `$DATE_Y` - Year with century, as decimal number 75 | - `$DATE_z`, `$DATE_Z` - Either the time-zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown 76 | - `$@` - Expands to the prefix character for Doxygen commands. 77 | - `$|` - Marks the alignment position. This flag is only valid for lines containing $PARAM. 78 | - `$(...)` - Defines a location to jump to when pressing the Tab key. Text within the parenthesis is used as a default value. 79 | 80 | Not all keywords are valid for User Defined Languages. 81 | 82 | ### Jump Locations 83 | The function and file formats can specify jump locations. These are areas of text that can be jumped to by pressing the `Tab` key. Using `$(...)` will use the text within the parenthesis as a default value for the location. Jump locations with the same default text will be edited simultaneously. Pressing the `Esc` key will remove all marked jump locations. 84 | 85 | ### UDL Support 86 | Custom UDLs can be added by pressing the `+` button next to the list of supported languages. The name entered for the UDL must match the name of the desired UDL. Pressing the `-` button will remove the selected UDL. Function commenting is partially supported for UDLs. It will insert a comment block at the current location but will not attempt to parse any text. 87 | 88 | ## Installation 89 | Use the built in Plugin Admin to install the plugin. 90 | 91 | ## Development 92 | The code is developed using Visual Studio 2017. Building the code will generate a DLL which can be used by Notepad++. For convenience, Visual Studio copies the DLL into the Notepad++ plugin directory. 93 | 94 | ## License 95 | This code is released under the [GNU General Public License version 2](http://www.gnu.org/licenses/gpl-2.0.txt). 96 | 97 | The [T-Rex Regular Expression library](http://tiny-rex.sourceforge.net/) used in this project has been released under the [zlib/libpng License](http://opensource.org/licenses/zlib-license.php). (C) 2003-2006 Alberto Demichelis 98 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.4.4.{build} 2 | image: Visual Studio 2017 3 | 4 | platform: 5 | - x64 6 | - Win32 7 | 8 | configuration: 9 | - Release 10 | - Debug 11 | 12 | install: 13 | - if "%platform%"=="x64" set archi=amd64 14 | - if "%platform%"=="x64" set build_platform=x64 15 | 16 | - if "%platform%"=="Win32" set archi=x86 17 | - if "%platform%"=="Win32" set build_platform=Win32 18 | 19 | - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" %archi% 20 | 21 | build: 22 | parallel: true 23 | verbosity: minimal 24 | 25 | build_script: 26 | - cd "%APPVEYOR_BUILD_FOLDER%" 27 | - msbuild DoxyIt.sln /p:Configuration="%configuration%" /p:Platform="%build_platform%" /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" 28 | 29 | after_build: 30 | - cd "%APPVEYOR_BUILD_FOLDER%" 31 | - ps: >- 32 | 33 | $BuildPath = "$($env:APPVEYOR_BUILD_FOLDER)\bin\$($env:CONFIGURATION)_$($env:BUILD_PLATFORM)" 34 | 35 | Push-AppveyorArtifact "$($BuildPath)\DoxyIt.dll" -FileName DoxyIt.dll 36 | 37 | if ($($env:APPVEYOR_REPO_TAG) -eq "true" -and $env:CONFIGURATION -eq "Release") { 38 | if ($env:BUILD_PLATFORM -eq "x64"){ 39 | $ZipFileName = "DoxyIt_$($env:APPVEYOR_REPO_TAG_NAME)_x64.zip" 40 | } 41 | if ($env:BUILD_PLATFORM -eq "Win32"){ 42 | $ZipFileName = "DoxyIt_$($env:APPVEYOR_REPO_TAG_NAME).zip" 43 | } 44 | 7z a $ZipFileName "$($BuildPath)\DoxyIt.dll" 45 | } 46 | 47 | artifacts: 48 | - path: DoxyIt*.zip 49 | name: releases 50 | 51 | deploy: 52 | provider: GitHub 53 | auth_token: 54 | secure: qrw+nu8dQKFLG+lNmky6buHsvHFwlibAai0r0aJ3MYbyBniONVxvgnmyx37bPh44 55 | artifact: releases 56 | draft: true 57 | prerelease: false 58 | force_update: true 59 | on: 60 | appveyor_repo_tag: true 61 | configuration: Release -------------------------------------------------------------------------------- /img/Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dail8859/DoxyIt/8c251ad6ee8eef6aef2d5b4cad73017c42a87450/img/Demo.gif -------------------------------------------------------------------------------- /img/Demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dail8859/DoxyIt/8c251ad6ee8eef6aef2d5b4cad73017c42a87450/img/Demo2.gif -------------------------------------------------------------------------------- /img/Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dail8859/DoxyIt/8c251ad6ee8eef6aef2d5b4cad73017c42a87450/img/Settings.png -------------------------------------------------------------------------------- /src/Dialogs/AboutDialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include 20 | #include "PluginDefinition.h" 21 | #include "resource.h" 22 | #include "Hyperlinks.h" 23 | #include "Version.h" 24 | 25 | #ifdef _WIN64 26 | #define BITNESS TEXT("(64 bit)") 27 | #else 28 | #define BITNESS TEXT("(32 bit)") 29 | #endif 30 | 31 | INT_PTR CALLBACK abtDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { 32 | switch (uMsg) { 33 | case WM_INITDIALOG: 34 | ConvertStaticToHyperlink(hwndDlg, IDC_GITHUB); 35 | ConvertStaticToHyperlink(hwndDlg, IDC_README); 36 | Edit_SetText(GetDlgItem(hwndDlg, IDC_VERSION), TEXT("DoxyIt v") VERSION_TEXT TEXT(" ") VERSION_STAGE TEXT(" ") BITNESS); 37 | return true; 38 | case WM_COMMAND: 39 | switch (LOWORD(wParam)) { 40 | case IDOK: 41 | DestroyWindow(hwndDlg); 42 | return true; 43 | case IDC_GITHUB: 44 | ShellExecute(hwndDlg, TEXT("open"), TEXT("https://github.com/dail8859/DoxyIt/"), NULL, NULL, SW_SHOWNORMAL); 45 | return true; 46 | case IDC_README: 47 | ShellExecute(hwndDlg, TEXT("open"), TEXT("https://github.com/dail8859/DoxyIt/blob/v") VERSION_TEXT TEXT("/README.md"), NULL, NULL, SW_SHOWNORMAL); 48 | return true; 49 | } 50 | case WM_DESTROY: 51 | DestroyWindow(hwndDlg); 52 | return true; 53 | } 54 | return false; 55 | } 56 | -------------------------------------------------------------------------------- /src/Dialogs/AboutDialog.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #ifndef ABOUTDIALOG_H 20 | #define ABOUTDIALOG_H 21 | 22 | INT_PTR CALLBACK abtDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 23 | 24 | #endif -------------------------------------------------------------------------------- /src/Dialogs/Hyperlinks.cpp: -------------------------------------------------------------------------------- 1 | // Hyperlinks.cpp 2 | // 3 | // Copyright 2002 Neal Stublen 4 | // All rights reserved. 5 | // 6 | // http://www.awesoftware.com 7 | // 8 | 9 | #include 10 | 11 | #include "Hyperlinks.h" 12 | 13 | 14 | #define PROP_ORIGINAL_FONT TEXT("_Hyperlink_Original_Font_") 15 | #define PROP_ORIGINAL_PROC TEXT("_Hyperlink_Original_Proc_") 16 | #define PROP_STATIC_HYPERLINK TEXT("_Hyperlink_From_Static_") 17 | #define PROP_UNDERLINE_FONT TEXT("_Hyperlink_Underline_Font_") 18 | 19 | 20 | LRESULT CALLBACK _HyperlinkParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 21 | { 22 | WNDPROC pfnOrigProc = (WNDPROC) GetProp(hwnd, PROP_ORIGINAL_PROC); 23 | 24 | switch (message) 25 | { 26 | case WM_CTLCOLORSTATIC: 27 | { 28 | HDC hdc = (HDC) wParam; 29 | HWND hwndCtl = (HWND) lParam; 30 | 31 | BOOL fHyperlink = (NULL != GetProp(hwndCtl, PROP_STATIC_HYPERLINK)); 32 | if (fHyperlink) 33 | { 34 | LRESULT lr = CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam); 35 | SetTextColor(hdc, RGB(0, 0, 192)); 36 | return lr; 37 | } 38 | 39 | break; 40 | } 41 | case WM_DESTROY: 42 | { 43 | SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast(pfnOrigProc)); 44 | RemoveProp(hwnd, PROP_ORIGINAL_PROC); 45 | break; 46 | } 47 | } 48 | return CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam); 49 | } 50 | 51 | LRESULT CALLBACK _HyperlinkProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 52 | { 53 | WNDPROC pfnOrigProc = (WNDPROC) GetProp(hwnd, PROP_ORIGINAL_PROC); 54 | 55 | switch (message) 56 | { 57 | case WM_DESTROY: 58 | { 59 | SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast(pfnOrigProc)); 60 | RemoveProp(hwnd, PROP_ORIGINAL_PROC); 61 | 62 | HFONT hOrigFont = (HFONT) GetProp(hwnd, PROP_ORIGINAL_FONT); 63 | SendMessage(hwnd, WM_SETFONT, (WPARAM) hOrigFont, 0); 64 | RemoveProp(hwnd, PROP_ORIGINAL_FONT); 65 | 66 | HFONT hFont = (HFONT) GetProp(hwnd, PROP_UNDERLINE_FONT); 67 | DeleteObject(hFont); 68 | RemoveProp(hwnd, PROP_UNDERLINE_FONT); 69 | 70 | RemoveProp(hwnd, PROP_STATIC_HYPERLINK); 71 | 72 | break; 73 | } 74 | case WM_MOUSEMOVE: 75 | { 76 | if (GetCapture() != hwnd) 77 | { 78 | HFONT hFont = (HFONT) GetProp(hwnd, PROP_UNDERLINE_FONT); 79 | SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, FALSE); 80 | InvalidateRect(hwnd, NULL, FALSE); 81 | SetCapture(hwnd); 82 | } 83 | else 84 | { 85 | RECT rect; 86 | GetWindowRect(hwnd, &rect); 87 | 88 | POINT pt = { LOWORD(lParam), HIWORD(lParam) }; 89 | ClientToScreen(hwnd, &pt); 90 | 91 | if (!PtInRect(&rect, pt)) 92 | { 93 | HFONT hFont = (HFONT) GetProp(hwnd, PROP_ORIGINAL_FONT); 94 | SendMessage(hwnd, WM_SETFONT, (WPARAM) hFont, FALSE); 95 | InvalidateRect(hwnd, NULL, FALSE); 96 | ReleaseCapture(); 97 | } 98 | } 99 | break; 100 | } 101 | case WM_SETCURSOR: 102 | { 103 | // Since IDC_HAND is not available on all operating systems, 104 | // we will load the arrow cursor if IDC_HAND is not present. 105 | HCURSOR hCursor = LoadCursor(NULL, IDC_HAND); 106 | if (NULL == hCursor) 107 | { 108 | hCursor = LoadCursor(NULL, IDC_ARROW); 109 | } 110 | SetCursor(hCursor); 111 | return TRUE; 112 | } 113 | } 114 | 115 | return CallWindowProc(pfnOrigProc, hwnd, message, wParam, lParam); 116 | } 117 | 118 | BOOL ConvertStaticToHyperlink(HWND hwndCtl) 119 | { 120 | // Subclass the parent so we can color the controls as we desire. 121 | 122 | HWND hwndParent = GetParent(hwndCtl); 123 | if (NULL != hwndParent) 124 | { 125 | WNDPROC pfnOrigProc = (WNDPROC) GetWindowLongPtr(hwndParent, GWLP_WNDPROC); 126 | if (pfnOrigProc != _HyperlinkParentProc) 127 | { 128 | SetProp(hwndParent, PROP_ORIGINAL_PROC, (HANDLE) pfnOrigProc); 129 | SetWindowLongPtr(hwndParent, GWLP_WNDPROC, reinterpret_cast(_HyperlinkParentProc)); 130 | } 131 | } 132 | 133 | // Make sure the control will send notifications. 134 | 135 | LONG_PTR dwStyle = GetWindowLongPtr(hwndCtl, GWL_STYLE); 136 | SetWindowLongPtr(hwndCtl, GWL_STYLE, dwStyle | SS_NOTIFY); 137 | 138 | // Subclass the existing control. 139 | 140 | WNDPROC pfnOrigProc = (WNDPROC) GetWindowLongPtr(hwndCtl, GWLP_WNDPROC); 141 | SetProp(hwndCtl, PROP_ORIGINAL_PROC, (HANDLE) pfnOrigProc); 142 | SetWindowLongPtr(hwndCtl, GWLP_WNDPROC, reinterpret_cast(_HyperlinkProc)); 143 | 144 | // Create an updated font by adding an underline. 145 | 146 | HFONT hOrigFont = (HFONT) SendMessage(hwndCtl, WM_GETFONT, 0, 0); 147 | SetProp(hwndCtl, PROP_ORIGINAL_FONT, (HANDLE) hOrigFont); 148 | 149 | LOGFONT lf; 150 | GetObject(hOrigFont, sizeof(lf), &lf); 151 | lf.lfUnderline = TRUE; 152 | 153 | HFONT hFont = CreateFontIndirect(&lf); 154 | SetProp(hwndCtl, PROP_UNDERLINE_FONT, (HANDLE) hFont); 155 | 156 | // Set a flag on the control so we know what color it should be. 157 | 158 | SetProp(hwndCtl, PROP_STATIC_HYPERLINK, (HANDLE) 1); 159 | 160 | return TRUE; 161 | } 162 | 163 | BOOL ConvertStaticToHyperlink(HWND hwndParent, UINT uiCtlId) 164 | { 165 | return ConvertStaticToHyperlink(GetDlgItem(hwndParent, uiCtlId)); 166 | } 167 | -------------------------------------------------------------------------------- /src/Dialogs/Hyperlinks.h: -------------------------------------------------------------------------------- 1 | // Hyperlinks.h 2 | // 3 | // Copyright 2002 Neal Stublen 4 | // All rights reserved. 5 | // 6 | // http://www.awesoftware.com 7 | // 8 | 9 | #ifndef HYPERLINKS_H 10 | #define HYPERLINKS_H 11 | 12 | BOOL ConvertStaticToHyperlink(HWND hwndCtl); 13 | BOOL ConvertStaticToHyperlink(HWND hwndParent, UINT uiCtlId); 14 | 15 | #endif -------------------------------------------------------------------------------- /src/Dialogs/SettingsDialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include 20 | #include "SettingsDialog.h" 21 | #include "PluginDefinition.h" 22 | #include "Hyperlinks.h" 23 | 24 | const wchar_t *msg = TEXT("An option is blank (or all whitespace). If this is desired, it is recommended that you disable Active Commenting! Continue anyways?"); 25 | const wchar_t *help = TEXT("\ 26 | Format Keywords:\r\n\ 27 | $FILENAME - The current file name.\r\n\ 28 | $FUNCTION - The name of the function/method.\r\n\ 29 | $PARAM - Expands to a single function/method parameter. Any line containing this will get repeated for each parameter.\r\n\ 30 | $COMPUTER - Current computer name.\r\n\ 31 | $USER - User account name of current user.\r\n\ 32 | $FULLUSER - full user name of current user.\r\n\ 33 | $DATE - Current date and time, format ISO 8601.\r\n\ 34 | $DATE_a - Abbreviated weekday name\r\n\ 35 | $DATE_A - Full weekday name\r\n\ 36 | $DATE_b - Abbreviated month name\r\n\ 37 | $DATE_B - Full month name\r\n\ 38 | $DATE_c - Date and time representation appropriate for locale\r\n\ 39 | $DATE_d - Day of month as decimal number (01 - 31)\r\n\ 40 | $DATE_H - Hour in 24 - hour format (00 - 23)\r\n\ 41 | $DATE_I - Hour in 12 - hour format (01 - 12)\r\n\ 42 | $DATE_j - Day of year as decimal number (001 - 366)\r\n\ 43 | $DATE_m - Month as decimal number (01 - 12)\r\n\ 44 | $DATE_M - Minute as decimal number (00 - 59)\r\n\ 45 | $DATE_p - Current locale's A.M./P.M. indicator for 12-hour clock\r\n\ 46 | $DATE_S - Second as decimal number (00 - 59)\r\n\ 47 | $DATE_U - Week of year as decimal number, with Sunday as first day of week (00 - 53)\r\n\ 48 | $DATE_w - Weekday as decimal number (0 - 6; Sunday is 0)\r\n\ 49 | $DATE_W - Week of year as decimal number, with Monday as first day of week (00 - 53)\r\n\ 50 | $DATE_x - Date representation for current locale\r\n\ 51 | $DATE_X - Time representation for current locale\r\n\ 52 | $DATE_y - Year without century, as decimal number (00 - 99)\r\n\ 53 | $DATE_Y - Year with century, as decimal number\r\n\ 54 | $DATE_z, $DATE_Z - Either the time - zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown\r\n\ 55 | $@ - Expands to the prefix character for Doxygen commands.\r\n\ 56 | $| - Marks the alignment position. This is only valid for lines containing $PARAM.\r\n\ 57 | \r\n\ 58 | $(...) - Defines a location to jump to when pressing the Tab key. Text within the parenthesis is used as a default value.\r\n\ 59 | \r\n"); 60 | 61 | 62 | INT_PTR CALLBACK inputDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 63 | { 64 | switch(uMsg) 65 | { 66 | case WM_INITDIALOG: 67 | SetFocus(GetDlgItem(hwndDlg, IDC_EDIT_LANG)); 68 | Edit_LimitText(GetDlgItem(hwndDlg, IDC_EDIT_LANG), 30); 69 | return true; 70 | case WM_COMMAND: 71 | switch(LOWORD(wParam)) 72 | { 73 | case IDOK: 74 | { 75 | wchar_t *text; 76 | int len = Edit_GetTextLength(GetDlgItem(hwndDlg, IDC_EDIT_LANG)); 77 | 78 | text = new wchar_t[len + 1]; 79 | Edit_GetText(GetDlgItem(hwndDlg, IDC_EDIT_LANG), text, len + 1); 80 | EndDialog(hwndDlg, (INT_PTR) text); 81 | return true; 82 | } 83 | default: 84 | return false; 85 | } 86 | case WM_CLOSE: 87 | case WM_DESTROY: 88 | EndDialog(hwndDlg, NULL); 89 | return true; 90 | } 91 | 92 | return false; 93 | } 94 | 95 | void SettingsDialog::init(HINSTANCE hInst, NppData nppData) 96 | { 97 | _nppData = nppData; 98 | Window::init(hInst, nppData._nppHandle); 99 | } 100 | 101 | void SettingsDialog::doDialog() 102 | { 103 | if (!isCreated()) create(IDD_SETTINGSDLG); 104 | goToCenter(); 105 | 106 | initParserSettings(); 107 | loadParserSettings(); 108 | updatePreview(); 109 | } 110 | 111 | void SettingsDialog::initParserSettings() 112 | { 113 | _parserSettings.clear(); 114 | for(unsigned int i = 0; i < parsers.size(); ++i) 115 | _parserSettings.push_back(parsers[i].ps); 116 | } 117 | 118 | void SettingsDialog::storeParserSettings(int index) 119 | { 120 | wchar_t *dtext; 121 | wchar_t text[256]; // Edit_LimitText is used to limit to 255 chars 122 | int len; 123 | 124 | ParserSettings *prev_ps = &_parserSettings[index]; 125 | 126 | Edit_GetText(GetDlgItem(_hSelf, IDC_EDIT_START), text, 256); 127 | prev_ps->doc_start = toString(text); 128 | 129 | Edit_GetText(GetDlgItem(_hSelf, IDC_EDIT_LINE), text, 256); 130 | prev_ps->doc_line = toString(text); 131 | 132 | Edit_GetText(GetDlgItem(_hSelf, IDC_EDIT_END), text, 256); 133 | prev_ps->doc_end = toString(text); 134 | 135 | Edit_GetText(GetDlgItem(_hSelf, IDC_EDIT_PREFIX), text, 256); 136 | prev_ps->command_prefix = toString(text); 137 | 138 | len = Edit_GetTextLength(GetDlgItem(_hSelf, IDC_EDIT_FORMAT)) + 1; 139 | dtext = (wchar_t *) malloc(sizeof(wchar_t) * len); 140 | Edit_GetText(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), dtext, len); 141 | 142 | if(Button_GetCheck(GetDlgItem(_hSelf, IDC_RAD_FUNCTION)) == BST_CHECKED) 143 | prev_ps->function_format = toString(dtext); 144 | else 145 | prev_ps->file_format = toString(dtext); 146 | 147 | free(dtext); 148 | 149 | // Go ahead and get the align checkbox even though it doesnt apply to external parsers 150 | prev_ps->align = (Button_GetCheck(GetDlgItem(_hSelf, IDC_CHB_ALIGN)) == BST_CHECKED); 151 | } 152 | 153 | // Note: Setting the text of edit boxes causes notifications to be generated, which update the 154 | // preview multiple times when calling loadParserSettings(). The 'updating' flag is used to 155 | // temporarily ignore notifications. 156 | void SettingsDialog::loadParserSettings() 157 | { 158 | int index = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 159 | 160 | _current = &_parserSettings[index]; 161 | 162 | // Load the edit controls with the new parsers settings 163 | _updating = true; 164 | 165 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_START), toWideString(_current->doc_start).c_str()); 166 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_LINE), toWideString(_current->doc_line).c_str()); 167 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_END), toWideString(_current->doc_end).c_str()); 168 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_PREFIX), toWideString(_current->command_prefix).c_str()); 169 | 170 | Button_SetCheck(GetDlgItem(_hSelf, IDC_CHB_ALIGN), _current->align); // Cannot be last! Doesn't update preview 171 | 172 | if(Button_GetCheck(GetDlgItem(_hSelf, IDC_RAD_FUNCTION)) == BST_CHECKED) 173 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), toWideString(_current->function_format).c_str()); 174 | else 175 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), toWideString(_current->file_format).c_str()); 176 | 177 | if(!parsers[index].external) 178 | { 179 | _updating = false; // NOTE: if the main proc ignores the following messages, it does not redraw them correctly 180 | EnableWindow(GetDlgItem(_hSelf, IDC_CHB_ALIGN), TRUE); 181 | EnableWindow(GetDlgItem(_hSelf, IDC_BTN_REMOVE), FALSE); 182 | _updating = true; // just to be safe incase we add anything later 183 | } 184 | else 185 | { 186 | Button_SetCheck(GetDlgItem(_hSelf, IDC_CHB_ALIGN), BST_UNCHECKED); 187 | 188 | _updating = false; // NOTE: if the main proc ignores the following messages, it does not redraw them correctly 189 | EnableWindow(GetDlgItem(_hSelf, IDC_CHB_ALIGN), FALSE); 190 | EnableWindow(GetDlgItem(_hSelf, IDC_BTN_REMOVE), TRUE); 191 | _updating = true; // just to be safe incase we add anything later 192 | } 193 | 194 | _updating = false; 195 | } 196 | 197 | void SettingsDialog::removeParserSettings() 198 | { 199 | int index = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 200 | 201 | _parserSettings.erase(_parserSettings.begin() + index); 202 | parsers.erase(parsers.begin() + index); 203 | 204 | ComboBox_DeleteString(GetDlgItem(_hSelf, IDC_CMB_LANG), index); 205 | ComboBox_SetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG), index - 1); 206 | _previousSelection = index - 1; 207 | 208 | loadParserSettings(); 209 | updatePreview(); 210 | } 211 | 212 | void SettingsDialog::addParserSettings() 213 | { 214 | wchar_t *text; 215 | HWND cmb = GetDlgItem(_hSelf, IDC_CMB_LANG); 216 | 217 | text = (wchar_t *) DialogBox((HINSTANCE) _hInst, MAKEINTRESOURCE(IDD_NEWLANG), _hSelf, inputDlgProc); 218 | if(text == NULL) return; // user canceled the dialog 219 | 220 | std::wstring name(text); 221 | delete[] text; 222 | 223 | // make sure len > 0 && no white space 224 | if(name.length() == 0 || name.find(TEXT(' ')) != std::string::npos) 225 | { 226 | MessageBox(NULL, TEXT("Error: New language name cannot be blank or contain whitespace."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); 227 | return; 228 | } 229 | 230 | // make sure not already in list (case insensitive!) 231 | for(auto const &p : parsers) 232 | { 233 | if(_wcsicmp(p.lang.c_str(), name.c_str()) == 0) 234 | { 235 | MessageBox(NULL, TEXT("Error: Naming conflict with another language."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); 236 | return; 237 | } 238 | } 239 | 240 | addNewParser(toString(name.c_str())); 241 | _parserSettings.push_back(parsers.back().ps); 242 | 243 | name += TEXT('*'); 244 | ComboBox_SetCurSel(cmb, ComboBox_AddString(cmb, name.c_str())); 245 | 246 | // Update the window 247 | storeParserSettings(_previousSelection); 248 | loadParserSettings(); 249 | updatePreview(); 250 | _previousSelection = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 251 | 252 | MessageBox(NULL, TEXT("Please note: Custom configurations do not parse function/method defintions, but can still be used to insert comment blocks."), NPP_PLUGIN_NAME, MB_OK|MB_ICONINFORMATION); 253 | } 254 | 255 | bool SettingsDialog::validateText(std::string text, int idc) 256 | { 257 | if(text.length() != 0 && !isWhiteSpace(text)) 258 | return true; 259 | 260 | SetFocus(GetDlgItem(_hSelf, idc)); 261 | return false; 262 | } 263 | 264 | bool SettingsDialog::validateSettings() 265 | { 266 | for(unsigned int i = 0; i < parsers.size(); ++i) 267 | { 268 | bool ret = true; 269 | const ParserSettings *ps = &_parserSettings[i]; 270 | 271 | if(!validateText(ps->doc_start, IDC_EDIT_START)) ret = false; 272 | if(!validateText(ps->doc_line, IDC_EDIT_LINE)) ret = false; 273 | if(!validateText(ps->doc_end, IDC_EDIT_END)) ret = false; 274 | if(!validateText(ps->command_prefix, IDC_EDIT_PREFIX)) ret = false; 275 | 276 | if(!ret) 277 | { 278 | ComboBox_SetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG), i); 279 | loadParserSettings(); 280 | updatePreview(); 281 | return false; 282 | } 283 | } 284 | 285 | return true; 286 | } 287 | 288 | void SettingsDialog::saveSettings() 289 | { 290 | for(unsigned int i = 0; i < parsers.size(); ++i) 291 | parsers[i].ps = _parserSettings[i]; 292 | } 293 | 294 | void SettingsDialog::updatePreview() 295 | { 296 | std::string block; 297 | int prev_eol_mode; 298 | int index = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 299 | 300 | // Set eol mode to "\r\n" so it will display correctly in the dialogbox 301 | prev_eol_mode = editor.GetEOLMode(); 302 | editor.SetEOLMode(SC_EOL_CRLF); 303 | 304 | if(Button_GetCheck(GetDlgItem(_hSelf, IDC_RAD_FUNCTION)) == BST_CHECKED) 305 | { 306 | // Get the parser and have it parse the example 307 | const Parser *p = &parsers[index]; 308 | 309 | if(!p->external) 310 | { 311 | block = FormatFunctionBlock(p, _current, p->example.c_str()); 312 | block += "\r\n" + p->example; 313 | } 314 | else // External parsers dont have any example text to parse 315 | { 316 | block = FormatFunctionBlock(p, _current, NULL); 317 | } 318 | } 319 | else // IDC_RAD_FILE is set 320 | { 321 | block = FormatFileBlock(_current); 322 | } 323 | 324 | // Restore the eol mode 325 | editor.SetEOLMode(prev_eol_mode); 326 | 327 | // Set the preview 328 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_PREVIEW), toWideString(block).c_str()); 329 | } 330 | 331 | void SettingsDialog::swapFormat() 332 | { 333 | wchar_t *text; 334 | unsigned int len; 335 | static int last_rad = IDC_RAD_FUNCTION; // In case the selected radio button is clicked again 336 | 337 | // Get the text length, dynamically allocate it 338 | len = Edit_GetTextLength(GetDlgItem(_hSelf, IDC_EDIT_FORMAT)) + 1; 339 | text = (wchar_t *) malloc(sizeof(wchar_t) * len); 340 | Edit_GetText(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), text, len); 341 | 342 | if(Button_GetCheck(GetDlgItem(_hSelf, IDC_RAD_FUNCTION)) == BST_CHECKED && last_rad == IDC_RAD_FILE) 343 | { 344 | _current->file_format = toString(text); 345 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), toWideString(_current->function_format).c_str()); 346 | last_rad = IDC_RAD_FUNCTION; 347 | } 348 | else if(Button_GetCheck(GetDlgItem(_hSelf, IDC_RAD_FILE)) == BST_CHECKED && last_rad == IDC_RAD_FUNCTION) 349 | { 350 | _current->function_format = toString(text); 351 | Edit_SetText(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), toWideString(_current->file_format).c_str()); 352 | last_rad = IDC_RAD_FILE; 353 | } 354 | 355 | free(text); 356 | } 357 | 358 | INT_PTR CALLBACK SettingsDialog::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) 359 | { 360 | if(_updating) return true; 361 | 362 | switch(message) 363 | { 364 | case WM_INITDIALOG: 365 | { 366 | HWND cmb = GetDlgItem(_hSelf, IDC_CMB_LANG); 367 | long lfHeight = -MulDiv(10, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72); 368 | 369 | //for(unsigned int i = 0; i < parsers.size(); ++i) 370 | for(auto const &p : parsers) 371 | { 372 | if(p.external) 373 | { 374 | std::wstring name = p.language_name + TEXT("*"); 375 | ComboBox_AddString(cmb, name.c_str()); 376 | } 377 | else 378 | { 379 | ComboBox_AddString(cmb, p.language_name.c_str()); 380 | } 381 | } 382 | ComboBox_SetCurSel(cmb, _previousSelection); 383 | 384 | // I have no idea what these values do, but these work 385 | _monoFont = CreateFont(lfHeight,0,0,0,0,0,0,0,0,0,0,0,0,TEXT("Courier New")); 386 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_START), _monoFont, false); 387 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_LINE), _monoFont, false); 388 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_END), _monoFont, false); 389 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_PREFIX), _monoFont, false); 390 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_PREVIEW), _monoFont, false); 391 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), _monoFont, false); 392 | SetWindowFont(GetDlgItem(_hSelf, IDC_EDIT_FORMAT), _monoFont, false); 393 | SetWindowFont(GetDlgItem(_hSelf, IDC_BTN_ADD), _monoFont, false); 394 | SetWindowFont(GetDlgItem(_hSelf, IDC_BTN_REMOVE), _monoFont, false); 395 | 396 | // Limit the input boxes 397 | Edit_LimitText(GetDlgItem(_hSelf, IDC_EDIT_START), 255); 398 | Edit_LimitText(GetDlgItem(_hSelf, IDC_EDIT_LINE), 255); 399 | Edit_LimitText(GetDlgItem(_hSelf, IDC_EDIT_END), 255); 400 | Edit_LimitText(GetDlgItem(_hSelf, IDC_EDIT_PREFIX), 1); 401 | 402 | Button_SetCheck(GetDlgItem(_hSelf, IDC_RAD_FUNCTION), BST_CHECKED); 403 | 404 | ConvertStaticToHyperlink(_hSelf, IDC_SETTINGS_HELP); 405 | 406 | return true; 407 | } 408 | case WM_COMMAND: 409 | switch(HIWORD(wParam)) 410 | { 411 | case CBN_SELCHANGE: 412 | storeParserSettings(_previousSelection); 413 | loadParserSettings(); 414 | updatePreview(); 415 | _previousSelection = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 416 | return true; 417 | case BN_CLICKED: 418 | switch(LOWORD(wParam)) 419 | { 420 | case IDOK: 421 | _previousSelection = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 422 | storeParserSettings(_previousSelection); 423 | if(validateSettings()) 424 | { 425 | saveSettings(); 426 | display(false); 427 | } 428 | else if(MessageBox(_hSelf, msg, NPP_PLUGIN_NAME, MB_YESNO|MB_ICONEXCLAMATION) == IDYES) 429 | { 430 | saveSettings(); 431 | display(false); 432 | } 433 | return true; 434 | case IDCANCEL: 435 | display(false); 436 | return true; 437 | case IDC_BTN_ADD: 438 | addParserSettings(); 439 | return true; 440 | case IDC_BTN_REMOVE: 441 | { 442 | int index = ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG)); 443 | std::wstring message = TEXT("Do you want to remove ") + parsers[index].language_name + TEXT("?"); 444 | 445 | if(MessageBox(_hSelf, message.c_str(), NPP_PLUGIN_NAME, MB_YESNO|MB_ICONEXCLAMATION) == IDYES) 446 | removeParserSettings(); 447 | 448 | return true; 449 | } 450 | case IDC_CHB_ALIGN: 451 | storeParserSettings(ComboBox_GetCurSel(GetDlgItem(_hSelf, IDC_CMB_LANG))); 452 | updatePreview(); 453 | return true; 454 | case IDC_RAD_FUNCTION: 455 | case IDC_RAD_FILE: 456 | swapFormat(); 457 | updatePreview(); 458 | return true; 459 | case IDC_SETTINGS_HELP: 460 | MessageBox(NULL, help, NPP_PLUGIN_NAME, MB_OK); 461 | return true; 462 | } 463 | case EN_CHANGE: 464 | storeParserSettings(_previousSelection); 465 | updatePreview(); 466 | return true; 467 | case EN_MAXTEXT: 468 | MessageBeep(MB_ICONERROR); 469 | return true; 470 | } 471 | default: 472 | return StaticDialog::dlgProc(_HSource, message, wParam, lParam); 473 | } 474 | 475 | return false; 476 | } 477 | -------------------------------------------------------------------------------- /src/Dialogs/SettingsDialog.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #ifndef SETTINGSDIALOG_H 20 | #define SETTINGSDIALOG_H 21 | 22 | #include 23 | #include "Parsers.h" 24 | #include "PluginInterface.h" 25 | #include "StaticDialog.h" 26 | #include "resource.h" 27 | 28 | 29 | class SettingsDialog final : public StaticDialog 30 | { 31 | private: 32 | std::vector _parserSettings; 33 | HFONT _monoFont; 34 | NppData _nppData; 35 | HWND _HSource; 36 | int _previousSelection; 37 | bool _updating; 38 | ParserSettings *_current; 39 | 40 | public: 41 | SettingsDialog() : StaticDialog(), _previousSelection(0), _updating(false), _current(NULL), _monoFont(NULL) {} 42 | ~SettingsDialog() { destroy(); } 43 | 44 | void init(HINSTANCE hInst, NppData nppData); 45 | void doDialog(); 46 | void destroy() { if(_monoFont) DeleteObject(_monoFont); } 47 | 48 | private: 49 | void initParserSettings(); 50 | void storeParserSettings(int index); 51 | void loadParserSettings(); 52 | void removeParserSettings(); 53 | void addParserSettings(); 54 | bool validateText(std::string text, int idc); 55 | bool validateSettings(); 56 | void saveSettings(); 57 | void updatePreview(); 58 | void swapFormat(); 59 | 60 | protected: 61 | INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); 62 | }; 63 | 64 | #endif -------------------------------------------------------------------------------- /src/Dialogs/StaticDialog.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2003 Don HO 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 | // Note that the GPL places important restrictions on "derived works", yet 10 | // it does not provide a detailed definition of that term. To avoid 11 | // misunderstandings, we consider an application to constitute a 12 | // "derivative work" for the purpose of this license if it does any of the 13 | // following: 14 | // 1. Integrates source code from Notepad++. 15 | // 2. Integrates/includes/aggregates Notepad++ into a proprietary executable 16 | // installer, such as those produced by InstallShield. 17 | // 3. Links to a library or executes a program that does any of the above. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 | 28 | #include 29 | #include 30 | #include "StaticDialog.h" 31 | 32 | 33 | 34 | StaticDialog::~StaticDialog() 35 | { 36 | if (isCreated()) 37 | { 38 | // Prevent run_dlgProc from doing anything, since its virtual 39 | ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, (LONG_PTR) NULL); 40 | destroy(); 41 | } 42 | } 43 | 44 | 45 | void StaticDialog::destroy() 46 | { 47 | ::SendMessage(_hParent, NPPM_MODELESSDIALOG, MODELESSDIALOGREMOVE, (WPARAM)_hSelf); 48 | ::DestroyWindow(_hSelf); 49 | } 50 | 51 | 52 | POINT StaticDialog::getTopPoint(HWND hwnd, bool isLeft) const 53 | { 54 | RECT rc; 55 | ::GetWindowRect(hwnd, &rc); 56 | 57 | POINT p; 58 | if (isLeft) 59 | p.x = rc.left; 60 | else 61 | p.x = rc.right; 62 | 63 | p.y = rc.top; 64 | ::ScreenToClient(_hSelf, &p); 65 | return p; 66 | } 67 | 68 | 69 | void StaticDialog::goToCenter() 70 | { 71 | RECT rc; 72 | ::GetClientRect(_hParent, &rc); 73 | POINT center; 74 | center.x = rc.left + (rc.right - rc.left)/2; 75 | center.y = rc.top + (rc.bottom - rc.top)/2; 76 | ::ClientToScreen(_hParent, ¢er); 77 | 78 | int x = center.x - (_rc.right - _rc.left)/2; 79 | int y = center.y - (_rc.bottom - _rc.top)/2; 80 | 81 | ::SetWindowPos(_hSelf, HWND_TOP, x, y, _rc.right - _rc.left, _rc.bottom - _rc.top, SWP_SHOWWINDOW); 82 | } 83 | 84 | 85 | void StaticDialog::display(bool toShow) const 86 | { 87 | if (toShow) 88 | { 89 | // If the user has switched from a dual monitor to a single monitor since we last 90 | // displayed the dialog, then ensure that it's still visible on the single monitor. 91 | RECT workAreaRect = {0}; 92 | RECT rc = {0}; 93 | ::SystemParametersInfo(SPI_GETWORKAREA, 0, &workAreaRect, 0); 94 | ::GetWindowRect(_hSelf, &rc); 95 | int newLeft = rc.left; 96 | int newTop = rc.top; 97 | int margin = ::GetSystemMetrics(SM_CYSMCAPTION); 98 | 99 | if (newLeft > ::GetSystemMetrics(SM_CXVIRTUALSCREEN)-margin) 100 | newLeft -= rc.right - workAreaRect.right; 101 | if (newLeft + (rc.right - rc.left) < ::GetSystemMetrics(SM_XVIRTUALSCREEN)+margin) 102 | newLeft = workAreaRect.left; 103 | if (newTop > ::GetSystemMetrics(SM_CYVIRTUALSCREEN)-margin) 104 | newTop -= rc.bottom - workAreaRect.bottom; 105 | if (newTop + (rc.bottom - rc.top) < ::GetSystemMetrics(SM_YVIRTUALSCREEN)+margin) 106 | newTop = workAreaRect.top; 107 | 108 | if ((newLeft != rc.left) || (newTop != rc.top)) // then the virtual screen size has shrunk 109 | // Remember that MoveWindow wants width/height. 110 | ::MoveWindow(_hSelf, newLeft, newTop, rc.right - rc.left, rc.bottom - rc.top, TRUE); 111 | } 112 | 113 | Window::display(toShow); 114 | } 115 | 116 | 117 | HGLOBAL StaticDialog::makeRTLResource(int dialogID, DLGTEMPLATE **ppMyDlgTemplate) 118 | { 119 | // Get Dlg Template resource 120 | HRSRC hDialogRC = ::FindResource(_hInst, MAKEINTRESOURCE(dialogID), RT_DIALOG); 121 | if (!hDialogRC) 122 | return NULL; 123 | 124 | HGLOBAL hDlgTemplate = ::LoadResource(_hInst, hDialogRC); 125 | if (!hDlgTemplate) 126 | return NULL; 127 | 128 | DLGTEMPLATE *pDlgTemplate = (DLGTEMPLATE *)::LockResource(hDlgTemplate); 129 | if (!pDlgTemplate) 130 | return NULL; 131 | 132 | // Duplicate Dlg Template resource 133 | unsigned long sizeDlg = ::SizeofResource(_hInst, hDialogRC); 134 | HGLOBAL hMyDlgTemplate = ::GlobalAlloc(GPTR, sizeDlg); 135 | *ppMyDlgTemplate = (DLGTEMPLATE *)::GlobalLock(hMyDlgTemplate); 136 | 137 | ::memcpy(*ppMyDlgTemplate, pDlgTemplate, sizeDlg); 138 | 139 | DLGTEMPLATEEX *pMyDlgTemplateEx = (DLGTEMPLATEEX *)*ppMyDlgTemplate; 140 | if (pMyDlgTemplateEx->signature == 0xFFFF) 141 | pMyDlgTemplateEx->exStyle |= WS_EX_LAYOUTRTL; 142 | else 143 | (*ppMyDlgTemplate)->dwExtendedStyle |= WS_EX_LAYOUTRTL; 144 | 145 | return hMyDlgTemplate; 146 | } 147 | 148 | void StaticDialog::create(int dialogID, bool isRTL, bool msgDestParent) 149 | { 150 | if (isRTL) 151 | { 152 | DLGTEMPLATE *pMyDlgTemplate = NULL; 153 | HGLOBAL hMyDlgTemplate = makeRTLResource(dialogID, &pMyDlgTemplate); 154 | _hSelf = ::CreateDialogIndirectParam(_hInst, pMyDlgTemplate, _hParent, dlgProc, (LPARAM)this); 155 | ::GlobalFree(hMyDlgTemplate); 156 | } 157 | else 158 | _hSelf = ::CreateDialogParam(_hInst, MAKEINTRESOURCE(dialogID), _hParent, dlgProc, (LPARAM)this); 159 | 160 | if (!_hSelf) 161 | { 162 | DWORD err = ::GetLastError(); 163 | char errMsg[256]; 164 | sprintf(errMsg, "CreateDialogParam() return NULL.\rGetLastError() == %u", err); 165 | ::MessageBoxA(NULL, errMsg, "In StaticDialog::create()", MB_OK); 166 | return; 167 | } 168 | 169 | // if the destination of message NPPM_MODELESSDIALOG is not its parent, then it's the grand-parent 170 | ::SendMessage(msgDestParent?_hParent:(::GetParent(_hParent)), NPPM_MODELESSDIALOG, MODELESSDIALOGADD, (WPARAM)_hSelf); 171 | } 172 | 173 | 174 | INT_PTR CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 175 | { 176 | switch (message) 177 | { 178 | case WM_INITDIALOG: 179 | { 180 | StaticDialog *pStaticDlg = (StaticDialog *)(lParam); 181 | pStaticDlg->_hSelf = hwnd; 182 | ::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)lParam); 183 | ::GetWindowRect(hwnd, &(pStaticDlg->_rc)); 184 | pStaticDlg->run_dlgProc(message, wParam, lParam); 185 | 186 | return TRUE; 187 | } 188 | 189 | default: 190 | { 191 | StaticDialog *pStaticDlg = reinterpret_cast(::GetWindowLongPtr(hwnd, GWLP_USERDATA)); 192 | if (!pStaticDlg) 193 | return FALSE; 194 | return pStaticDlg->run_dlgProc(message, wParam, lParam); 195 | } 196 | } 197 | } 198 | 199 | void StaticDialog::alignWith(HWND handle, HWND handle2Align, PosAlign pos, POINT & point) 200 | { 201 | RECT rc, rc2; 202 | ::GetWindowRect(handle, &rc); 203 | 204 | point.x = rc.left; 205 | point.y = rc.top; 206 | 207 | switch (pos) 208 | { 209 | case PosAlign::left: 210 | { 211 | ::GetWindowRect(handle2Align, &rc2); 212 | point.x -= rc2.right - rc2.left; 213 | break; 214 | } 215 | case PosAlign::right: 216 | { 217 | ::GetWindowRect(handle, &rc2); 218 | point.x += rc2.right - rc2.left; 219 | break; 220 | } 221 | case PosAlign::top: 222 | { 223 | ::GetWindowRect(handle2Align, &rc2); 224 | point.y -= rc2.bottom - rc2.top; 225 | break; 226 | } 227 | case PosAlign::bottom: 228 | { 229 | ::GetWindowRect(handle, &rc2); 230 | point.y += rc2.bottom - rc2.top; 231 | break; 232 | } 233 | } 234 | 235 | ::ScreenToClient(_hSelf, &point); 236 | } 237 | -------------------------------------------------------------------------------- /src/Dialogs/StaticDialog.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2003 Don HO 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 | // Note that the GPL places important restrictions on "derived works", yet 10 | // it does not provide a detailed definition of that term. To avoid 11 | // misunderstandings, we consider an application to constitute a 12 | // "derivative work" for the purpose of this license if it does any of the 13 | // following: 14 | // 1. Integrates source code from Notepad++. 15 | // 2. Integrates/includes/aggregates Notepad++ into a proprietary executable 16 | // installer, such as those produced by InstallShield. 17 | // 3. Links to a library or executes a program that does any of the above. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 | #pragma once 28 | #include "Notepad_plus_msgs.h" 29 | #include "Window.h" 30 | 31 | 32 | typedef HRESULT (WINAPI * ETDTProc) (HWND, DWORD); 33 | 34 | enum class PosAlign { left, right, top, bottom }; 35 | 36 | 37 | struct DLGTEMPLATEEX 38 | { 39 | WORD dlgVer; 40 | WORD signature; 41 | DWORD helpID; 42 | DWORD exStyle; 43 | DWORD style; 44 | WORD cDlgItems; 45 | short x; 46 | short y; 47 | short cx; 48 | short cy; 49 | // The structure has more fields but are variable length 50 | }; 51 | 52 | 53 | 54 | class StaticDialog : public Window 55 | { 56 | public : 57 | virtual ~StaticDialog(); 58 | 59 | virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); 60 | 61 | virtual bool isCreated() const 62 | { 63 | return (_hSelf != NULL); 64 | } 65 | 66 | void goToCenter(); 67 | 68 | void display(bool toShow = true) const; 69 | 70 | POINT getTopPoint(HWND hwnd, bool isLeft = true) const; 71 | 72 | bool isCheckedOrNot(int checkControlID) const 73 | { 74 | return (BST_CHECKED == ::SendMessage(::GetDlgItem(_hSelf, checkControlID), BM_GETCHECK, 0, 0)); 75 | } 76 | 77 | virtual void destroy() override; 78 | 79 | 80 | protected: 81 | RECT _rc; 82 | static INT_PTR CALLBACK dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 83 | virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) = 0; 84 | 85 | void alignWith(HWND handle, HWND handle2Align, PosAlign pos, POINT & point); 86 | HGLOBAL makeRTLResource(int dialogID, DLGTEMPLATE **ppMyDlgTemplate); 87 | }; -------------------------------------------------------------------------------- /src/Dialogs/Version.rc: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "Version.h" 4 | 5 | 6 | // 7 | // Version Information resources 8 | // 9 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 10 | 1 VERSIONINFO 11 | FILEVERSION VERSION_NUM 12 | PRODUCTVERSION VERSION_NUM 13 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 14 | FILEFLAGS VS_FF_SPECIALBUILD 15 | FILEOS VOS__WINDOWS32 16 | FILETYPE VFT_DLL 17 | FILESUBTYPE VFT2_UNKNOWN 18 | { 19 | BLOCK "StringFileInfo" 20 | { 21 | BLOCK "040904b0" 22 | { 23 | VALUE "Comments", "Notepad++ plugin for Doxygen commenting" 24 | VALUE "CompanyName", "Justin Dailey " 25 | VALUE "FileDescription", "Notepad++ plugin for Doxygen commenting" 26 | VALUE "FileVersion", VERSION_TEXT 27 | VALUE "InternalName", "DoxyIt" 28 | VALUE "OriginalFilename", "DoxyIt.dll" 29 | VALUE "ProductName", "DoxyIt" 30 | VALUE "ProductVersion", VERSION_TEXT 31 | VALUE "SpecialBuild", "UNICODE" 32 | } 33 | } 34 | BLOCK "VarFileInfo" 35 | { 36 | VALUE "Translation", 0x0409, 0x01B5 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Dialogs/Window.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2003 Don HO 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 | // Note that the GPL places important restrictions on "derived works", yet 10 | // it does not provide a detailed definition of that term. To avoid 11 | // misunderstandings, we consider an application to constitute a 12 | // "derivative work" for the purpose of this license if it does any of the 13 | // following: 14 | // 1. Integrates source code from Notepad++. 15 | // 2. Integrates/includes/aggregates Notepad++ into a proprietary executable 16 | // installer, such as those produced by InstallShield. 17 | // 3. Links to a library or executes a program that does any of the above. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 | #pragma once 28 | #include 29 | 30 | 31 | 32 | 33 | class Window 34 | { 35 | public: 36 | //! \name Constructors & Destructor 37 | //@{ 38 | Window() = default; 39 | Window(const Window&) = delete; 40 | virtual ~Window() = default; 41 | //@} 42 | 43 | 44 | virtual void init(HINSTANCE hInst, HWND parent) 45 | { 46 | _hInst = hInst; 47 | _hParent = parent; 48 | } 49 | 50 | virtual void destroy() = 0; 51 | 52 | virtual void display(bool toShow = true) const 53 | { 54 | ::ShowWindow(_hSelf, toShow ? SW_SHOW : SW_HIDE); 55 | } 56 | 57 | 58 | virtual void reSizeTo(RECT & rc) // should NEVER be const !!! 59 | { 60 | ::MoveWindow(_hSelf, rc.left, rc.top, rc.right, rc.bottom, TRUE); 61 | redraw(); 62 | } 63 | 64 | 65 | virtual void reSizeToWH(RECT& rc) // should NEVER be const !!! 66 | { 67 | ::MoveWindow(_hSelf, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); 68 | redraw(); 69 | } 70 | 71 | 72 | virtual void redraw(bool forceUpdate = false) const 73 | { 74 | ::InvalidateRect(_hSelf, nullptr, TRUE); 75 | if (forceUpdate) 76 | ::UpdateWindow(_hSelf); 77 | } 78 | 79 | 80 | virtual void getClientRect(RECT & rc) const 81 | { 82 | ::GetClientRect(_hSelf, &rc); 83 | } 84 | 85 | virtual void getWindowRect(RECT & rc) const 86 | { 87 | ::GetWindowRect(_hSelf, &rc); 88 | } 89 | 90 | virtual int getWidth() const 91 | { 92 | RECT rc; 93 | ::GetClientRect(_hSelf, &rc); 94 | return (rc.right - rc.left); 95 | } 96 | 97 | virtual int getHeight() const 98 | { 99 | RECT rc; 100 | ::GetClientRect(_hSelf, &rc); 101 | if (::IsWindowVisible(_hSelf) == TRUE) 102 | return (rc.bottom - rc.top); 103 | return 0; 104 | } 105 | 106 | virtual bool isVisible() const 107 | { 108 | return (::IsWindowVisible(_hSelf)?true:false); 109 | } 110 | 111 | HWND getHSelf() const 112 | { 113 | //assert(_hSelf != 0); 114 | return _hSelf; 115 | } 116 | 117 | HWND getHParent() const { 118 | return _hParent; 119 | } 120 | 121 | void getFocus() const { 122 | ::SetFocus(_hSelf); 123 | } 124 | 125 | HINSTANCE getHinst() const 126 | { 127 | //assert(_hInst != 0); 128 | return _hInst; 129 | } 130 | 131 | 132 | Window& operator = (const Window&) = delete; 133 | 134 | 135 | protected: 136 | HINSTANCE _hInst = NULL; 137 | HWND _hParent = NULL; 138 | HWND _hSelf = NULL; 139 | }; -------------------------------------------------------------------------------- /src/Dialogs/resource.h: -------------------------------------------------------------------------------- 1 | #ifndef IDC_STATIC 2 | #define IDC_STATIC (-1) 3 | #endif 4 | 5 | #define IDD_SETTINGSDLG 101 6 | #define IDD_ABOUTDLG 103 7 | #define IDD_NEWLANG 105 8 | #define IDC_SETTINGS_HELP 1000 9 | #define IDC_EDIT_PREFIX 1001 10 | #define IDC_GITHUB 1001 11 | #define IDC_EDIT_FORMAT 1002 12 | #define IDC_EDIT_LANG 1002 13 | #define IDC_VERSION 1002 14 | #define IDC_README 1003 15 | #define IDC_RAD_FUNCTION 1004 16 | #define IDC_BTN_REMOVE 1006 17 | #define IDC_CMB_LANG 1007 18 | #define IDC_EDIT_START 1008 19 | #define IDC_EDIT_LINE 1009 20 | #define IDC_EDIT_END 1010 21 | #define IDC_EDIT_PREVIEW 1011 22 | #define IDC_BTN_ADD 1012 23 | #define IDC_CHB_ALIGN 1013 24 | #define IDC_RAD_FILE 1014 25 | -------------------------------------------------------------------------------- /src/Dialogs/resource.rc: -------------------------------------------------------------------------------- 1 | // Generated by ResEdit 1.5.11 2 | // Copyright (C) 2006-2012 3 | // http://www.resedit.net 4 | 5 | #include 6 | #include 7 | #include 8 | #include "resource.h" 9 | 10 | 11 | 12 | 13 | // 14 | // Dialog resources 15 | // 16 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 17 | IDD_ABOUTDLG DIALOGEX 0, 0, 223, 130 18 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_BORDER | WS_SYSMENU 19 | FONT 8, "MS Shell Dlg", 0, 0, 0x1 20 | { 21 | PUSHBUTTON "Close", IDOK, 86, 109, 50, 14 22 | GROUPBOX "", IDC_VERSION, 10, 9, 201, 93, BS_CENTER 23 | LTEXT "Author : Justin Dailey ", IDC_STATIC, 30, 26, 180, 8 24 | LTEXT "The DoxyIt code is hosted on", IDC_STATIC, 30, 43, 180, 8 25 | LTEXT "GitHub", IDC_GITHUB, 127, 43, 22, 8, SS_LEFT | SS_NOTIFY, WS_EX_LEFT 26 | LTEXT "For detailed usage, view the", IDC_STATIC, 30, 62, 110, 8, SS_LEFT 27 | LTEXT "readme", IDC_README, 124, 62, 24, 8, SS_LEFT | SS_NOTIFY, WS_EX_LEFT 28 | LTEXT "This code is licensed under GPLv2", IDC_STATIC, 30, 80, 111, 8, SS_LEFT 29 | } 30 | 31 | 32 | 33 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 34 | IDD_NEWLANG DIALOG 0, 0, 227, 23 35 | STYLE DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU 36 | EXSTYLE WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW 37 | CAPTION "DoxyIt - New Supported Language" 38 | FONT 8, "Ms Shell Dlg" 39 | { 40 | DEFPUSHBUTTON "OK", IDOK, 169, 5, 50, 14 41 | EDITTEXT IDC_EDIT_LANG, 45, 4, 119, 14, ES_AUTOHSCROLL 42 | LTEXT "UDL Name:", IDC_STATIC, 5, 7, 38, 8, SS_LEFT 43 | } 44 | 45 | 46 | 47 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 48 | IDD_SETTINGSDLG DIALOG 0, 0, 387, 289 49 | STYLE DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU 50 | EXSTYLE WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW 51 | CAPTION "DoxyIt - Settings" 52 | FONT 8, "Ms Shell Dlg" 53 | { 54 | PUSHBUTTON "OK", IDOK, 270, 270, 50, 14 55 | PUSHBUTTON "Cancel", IDCANCEL, 325, 270, 50, 14 56 | COMBOBOX IDC_CMB_LANG, 42, 5, 53, 13, CBS_DROPDOWNLIST | CBS_HASSTRINGS 57 | LTEXT "Language:", IDC_STATIC, 5, 7, 35, 8, SS_LEFT 58 | EDITTEXT IDC_EDIT_START, 35, 34, 55, 12, ES_AUTOHSCROLL 59 | EDITTEXT IDC_EDIT_LINE, 35, 51, 55, 12, ES_AUTOHSCROLL 60 | EDITTEXT IDC_EDIT_END, 35, 68, 55, 12, ES_AUTOHSCROLL 61 | LTEXT "Start:", IDC_STATIC, 12, 37, 18, 8, SS_LEFT, WS_EX_RIGHT 62 | LTEXT "Line:", IDC_STATIC, 14, 54, 16, 8, SS_LEFT, WS_EX_RIGHT 63 | LTEXT "End:", IDC_STATIC, 14, 71, 16, 8, SS_LEFT, WS_EX_RIGHT 64 | EDITTEXT IDC_EDIT_PREVIEW, 11, 145, 364, 115, WS_VSCROLL | NOT WS_BORDER | NOT WS_TABSTOP | ES_AUTOHSCROLL | ES_MULTILINE | ES_READONLY 65 | LTEXT "Prefix:", IDC_STATIC, 10, 88, 20, 8, SS_LEFT, WS_EX_RIGHT 66 | EDITTEXT IDC_EDIT_PREFIX, 35, 85, 15, 12, ES_AUTOHSCROLL 67 | GROUPBOX "Settings", IDC_STATIC, 5, 23, 90, 109 68 | GROUPBOX "Preview", IDC_STATIC, 5, 134, 375, 131 69 | AUTOCHECKBOX "Align", IDC_CHB_ALIGN, 35, 106, 31, 8 70 | GROUPBOX "Format: ", IDC_STATIC, 100, 23, 280, 109 71 | EDITTEXT IDC_EDIT_FORMAT, 106, 34, 269, 93, WS_VSCROLL | NOT WS_TABSTOP | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_WANTRETURN 72 | AUTORADIOBUTTON "Function", IDC_RAD_FUNCTION, 133, 23, 38, 8 73 | AUTORADIOBUTTON "File", IDC_RAD_FILE, 176, 23, 21, 8 74 | LTEXT "Help", IDC_SETTINGS_HELP, 359, 13, 16, 8, SS_LEFT 75 | PUSHBUTTON "-", IDC_BTN_REMOVE, 100, 4, 14, 14 76 | PUSHBUTTON "+", IDC_BTN_ADD, 113, 4, 14, 14 77 | } 78 | -------------------------------------------------------------------------------- /src/DoxyIt.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "PluginDefinition.h" 20 | #include "Parsers.h" 21 | 22 | extern FuncItem funcItem[nbFunc]; 23 | 24 | BOOL APIENTRY DllMain(HANDLE hModule, DWORD reasonForCall, LPVOID lpReserved ) 25 | { 26 | switch (reasonForCall) 27 | { 28 | case DLL_PROCESS_ATTACH: 29 | pluginInit(hModule); 30 | break; 31 | case DLL_PROCESS_DETACH: 32 | pluginCleanUp(); 33 | break; 34 | case DLL_THREAD_ATTACH: 35 | break; 36 | case DLL_THREAD_DETACH: 37 | break; 38 | } 39 | return TRUE; 40 | } 41 | 42 | extern "C" __declspec(dllexport) void setInfo(NppData notepadPlusData) 43 | { 44 | setNppInfo(notepadPlusData); 45 | } 46 | 47 | extern "C" __declspec(dllexport) const wchar_t * getName() 48 | { 49 | return NPP_PLUGIN_NAME; 50 | } 51 | 52 | extern "C" __declspec(dllexport) FuncItem * getFuncsArray(int *nbF) 53 | { 54 | *nbF = nbFunc; 55 | return funcItem; 56 | } 57 | 58 | 59 | extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode) 60 | { 61 | handleNotification(notifyCode); 62 | } 63 | 64 | extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam) 65 | { 66 | return TRUE; 67 | } 68 | 69 | #ifdef UNICODE 70 | extern "C" __declspec(dllexport) BOOL isUnicode() 71 | { 72 | return TRUE; 73 | } 74 | #endif //UNICODE 75 | -------------------------------------------------------------------------------- /src/DoxyIt.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {1590D7CD-7D3A-4AB7-A355-EE02F7FB987D} 23 | DoxyIt 24 | Win32Proj 25 | 26 | 27 | 28 | DynamicLibrary 29 | Unicode 30 | v141 31 | 32 | 33 | DynamicLibrary 34 | Unicode 35 | v141 36 | 37 | 38 | DynamicLibrary 39 | Unicode 40 | v141 41 | true 42 | 43 | 44 | DynamicLibrary 45 | Unicode 46 | v141 47 | true 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | <_ProjectFileVersion>10.0.30319.1 71 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 72 | $(SolutionDir)bin\$(Configuration)_$(Platform)\build\ 73 | true 74 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 75 | $(SolutionDir)bin\$(Configuration)_$(Platform)\build\ 76 | true 77 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 78 | $(SolutionDir)bin\$(Configuration)_$(Platform)\build\ 79 | false 80 | $(SolutionDir)bin\$(Configuration)_$(Platform)\ 81 | $(SolutionDir)bin\$(Configuration)_$(Platform)\build\ 82 | false 83 | 84 | 85 | $(ProjectName) 86 | 87 | 88 | $(ProjectName) 89 | 90 | 91 | 92 | .\Dialogs;.\Parsers;.\Npp;.\Utilities;.\;%(AdditionalIncludeDirectories) 93 | WIN32;NDEBUG;_WINDOWS;_USRDLL;$(ProjectName)_EXPORTS;__STDC_WANT_SECURE_LIB__=1;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 94 | MultiThreaded 95 | Level3 96 | ProgramDatabase 97 | true 98 | Size 99 | true 100 | MaxSpeed 101 | Sync 102 | true 103 | true 104 | 105 | 106 | shlwapi.lib;%(AdditionalDependencies) 107 | $(OutDir)$(ProjectName).dll 108 | true 109 | Windows 110 | true 111 | true 112 | true 113 | true 114 | $(OutDir)$(ProjectName).lib 115 | MachineX86 116 | 117 | 118 | if EXIST "%PROGRAMFILES(X86)%\Notepad++\plugins\" ( 119 | mkdir "%PROGRAMFILES(X86)%\Notepad++\plugins\$(TargetName)" 120 | copy "$(TargetPath)" "%PROGRAMFILES(X86)%\Notepad++\plugins\$(TargetName)" 121 | ) 122 | 123 | 124 | 125 | 126 | .\Dialogs;.\Parsers;.\Npp;.\Utilities;.\;%(AdditionalIncludeDirectories) 127 | WIN32;NDEBUG;_WINDOWS;_USRDLL;$(ProjectName)_EXPORTS;__STDC_WANT_SECURE_LIB__=1;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 128 | MultiThreaded 129 | Level3 130 | ProgramDatabase 131 | true 132 | Size 133 | true 134 | MaxSpeed 135 | Sync 136 | true 137 | true 138 | 139 | 140 | shlwapi.lib;%(AdditionalDependencies) 141 | $(OutDir)$(ProjectName).dll 142 | true 143 | Windows 144 | true 145 | true 146 | true 147 | true 148 | $(OutDir)$(ProjectName).lib 149 | 150 | 151 | if EXIST "C:\Program Files\Notepad++\plugins\" ( 152 | mkdir "C:\Program Files\Notepad++\plugins\$(TargetName)" 153 | copy "$(TargetPath)" "C:\Program Files\Notepad++\plugins\$(TargetName)" 154 | ) 155 | 156 | 157 | 158 | 159 | Disabled 160 | .\Dialogs;.\Parsers;.\Npp;.\Utilities;.\;%(AdditionalIncludeDirectories) 161 | WIN32;_DEBUG;_WINDOWS;_USRDLL;$(ProjectName)_EXPORTS;__STDC_WANT_SECURE_LIB__=1;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 162 | EnableFastChecks 163 | MultiThreadedDebug 164 | Level3 165 | ProgramDatabase 166 | true 167 | 168 | 169 | shlwapi.lib;%(AdditionalDependencies) 170 | $(OutDir)$(ProjectName).dll 171 | true 172 | $(OutDir)$(ProjectName).pdb 173 | Windows 174 | true 175 | true 176 | $(OutDir)$(ProjectName).lib 177 | MachineX86 178 | 179 | 180 | if EXIST "%PROGRAMFILES(X86)%\Notepad++\plugins\" ( 181 | mkdir "%PROGRAMFILES(X86)%\Notepad++\plugins\$(TargetName)" 182 | copy "$(TargetPath)" "%PROGRAMFILES(X86)%\Notepad++\plugins\$(TargetName)" 183 | ) 184 | 185 | 186 | 187 | 188 | Disabled 189 | .\Dialogs;.\Parsers;.\Npp;.\Utilities;.\;%(AdditionalIncludeDirectories) 190 | WIN32;_DEBUG;_WINDOWS;_USRDLL;$(ProjectName)_EXPORTS;__STDC_WANT_SECURE_LIB__=1;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 191 | EnableFastChecks 192 | MultiThreadedDebug 193 | Level3 194 | ProgramDatabase 195 | true 196 | 197 | 198 | shlwapi.lib;%(AdditionalDependencies) 199 | $(OutDir)$(ProjectName).dll 200 | true 201 | $(OutDir)$(ProjectName).pdb 202 | Windows 203 | true 204 | true 205 | $(OutDir)$(ProjectName).lib 206 | 207 | 208 | if EXIST "C:\Program Files\Notepad++\plugins\" ( 209 | mkdir "C:\Program Files\Notepad++\plugins\$(TargetName)" 210 | copy "$(TargetPath)" "C:\Program Files\Notepad++\plugins\$(TargetName)" 211 | ) 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /src/DoxyIt.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx 15 | 16 | 17 | {f8b5d458-ad04-4abd-aa76-b28effad87ec} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files\Parsers 41 | 42 | 43 | Source Files\Parsers 44 | 45 | 46 | Source Files\Parsers 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files\Parsers 56 | 57 | 58 | Source Files 59 | 60 | 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | Header Files 97 | 98 | 99 | Header Files 100 | 101 | 102 | Header Files 103 | 104 | 105 | Header Files 106 | 107 | 108 | Header Files 109 | 110 | 111 | Header Files 112 | 113 | 114 | 115 | 116 | Resource Files 117 | 118 | 119 | Resource Files 120 | 121 | 122 | -------------------------------------------------------------------------------- /src/JumpLocations.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2017 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "JumpLocations.h" 20 | #include "PluginDefinition.h" 21 | #include "Utils.h" 22 | #include 23 | 24 | typedef std::pair Location; 25 | 26 | const Location INVALID_LOCATION = std::make_pair(INVALID_POSITION, INVALID_POSITION); 27 | const char *JUMPLOCATION_REGEX = "\\$\\((.*?)\\)"; 28 | 29 | static bool IsLocationValid(const Location& location) 30 | { 31 | return location.first != INVALID_LOCATION.first && location.second != INVALID_LOCATION.second; 32 | } 33 | 34 | static void PreProcessJumpLocation(Location& location) 35 | { 36 | if (IsLocationValid(location)) 37 | { 38 | // For empty locations e.g. "$()" replace it with "()" 39 | if (location.second - location.first == strlen("$()")) 40 | { 41 | editor.SetTargetRange(location.first, location.second); 42 | editor.ReplaceTarget(-1, "()"); 43 | } 44 | else 45 | { 46 | // Remove the "$(" and ")" to just keep the text 47 | std::string text = GetTextRange(location.first, location.second); 48 | editor.SetTargetRange(location.first, location.second); 49 | editor.ReplaceTarget((int)text.length() - 3, &text[2]); 50 | } 51 | 52 | // Set the location to the new range 53 | location.first = editor.GetTargetStart(); 54 | location.second = editor.GetTargetEnd(); 55 | } 56 | } 57 | 58 | static Location FindNextJumpLocation(int startPosition, bool wrap) 59 | { 60 | int curPos = startPosition; 61 | int length = editor.GetTextLength(); 62 | 63 | // Check to see if the position is inside an indicator range already 64 | if (editor.IndicatorAllOnFor(curPos) & (1 << JUMPLOCATION_INDICATOR)) 65 | { 66 | return std::make_pair(editor.IndicatorStart(JUMPLOCATION_INDICATOR, curPos), editor.IndicatorEnd(JUMPLOCATION_INDICATOR, curPos)); 67 | } 68 | 69 | int start = editor.IndicatorEnd(JUMPLOCATION_INDICATOR, curPos); 70 | int end = editor.IndicatorEnd(JUMPLOCATION_INDICATOR, start); 71 | 72 | if (wrap && (start == 0 || start >= length)) 73 | { 74 | // Start again at the top of the file 75 | start = editor.IndicatorEnd(JUMPLOCATION_INDICATOR, 0); 76 | end = editor.IndicatorEnd(JUMPLOCATION_INDICATOR, start); 77 | } 78 | 79 | if (start != 0 && start < length) 80 | { 81 | return std::make_pair(start, end); 82 | } 83 | 84 | return INVALID_LOCATION; 85 | } 86 | 87 | static void SelectMatchingJumpLocations(const Location& location) 88 | { 89 | if (IsLocationValid(location)) 90 | { 91 | std::string jumpLocationText = GetTextRange(location.first, location.second); 92 | 93 | // A location of "()" is interpreted as an empty jump 94 | // location which should not match other emtpy locations 95 | if (jumpLocationText == "()") 96 | { 97 | return; 98 | } 99 | 100 | int startPos = 0; 101 | do { 102 | auto match = FindNextJumpLocation(startPos, false); 103 | startPos = match.second + 1; 104 | 105 | if (IsLocationValid(match)) 106 | { 107 | if (match.first != location.first) 108 | { 109 | std::string nextLocationText = GetTextRange(match.first, match.second); 110 | 111 | if (jumpLocationText == nextLocationText) 112 | { 113 | editor.AddSelection(match.second, match.first); 114 | } 115 | } 116 | } 117 | else 118 | { 119 | break; 120 | } 121 | } while (startPos != INVALID_POSITION); 122 | } 123 | } 124 | 125 | static void MarkJumpLocationsInRange(int start, int end) 126 | { 127 | std::vector jumpLocations; 128 | 129 | // Find all the jump locations 130 | int startPos = start; 131 | auto match = FindInRange(JUMPLOCATION_REGEX, startPos, end, true); 132 | while (IsLocationValid(match)) 133 | { 134 | jumpLocations.push_back(match); 135 | startPos = match.second; 136 | match = FindInRange(JUMPLOCATION_REGEX, startPos, end, true); 137 | } 138 | 139 | // Iterate them backwards since the text could be modified by PreProcessJumpLocation 140 | editor.SetIndicatorCurrent(JUMPLOCATION_INDICATOR); 141 | for (auto it = jumpLocations.rbegin(); it != jumpLocations.rend(); ++it) 142 | { 143 | PreProcessJumpLocation(*it); 144 | editor.IndicatorFillRange(it->first, it->second - it->first); 145 | } 146 | } 147 | 148 | static bool GoToJumpLocation(const Location& location) 149 | { 150 | if (IsLocationValid(location)) 151 | { 152 | editor.SetSel(location.first, location.second); 153 | SelectMatchingJumpLocations(location); 154 | editor.RotateSelection(); // Rotate to the selection that was made first 155 | 156 | // Turn these off incase they were being shown 157 | editor.AutoCCancel(); 158 | editor.CallTipCancel(); 159 | 160 | editor.ChooseCaretX(); 161 | 162 | return true; 163 | } 164 | 165 | return false; 166 | } 167 | 168 | static bool IsLocationOnJumpLocation(const Location& location) 169 | { 170 | return IsLocationValid(location) && 171 | location.first != location.second && 172 | location.first == editor.IndicatorStart(JUMPLOCATION_INDICATOR, location.first) && 173 | location.second == editor.IndicatorEnd(JUMPLOCATION_INDICATOR, location.second - 1); 174 | } 175 | 176 | void ProcessTextRangeForNewJumpLocations(int startPosition, int endPosition) 177 | { 178 | MarkJumpLocationsInRange(startPosition, endPosition); 179 | 180 | // Since this is a new text range, don't wrap because it wouldn't 181 | // make sense to jump above the position. 182 | GoToNextJumpLocation(startPosition, false); 183 | } 184 | 185 | bool GoToNextJumpLocation(int startPosition, bool wrap) 186 | { 187 | auto selection = std::make_pair(editor.GetSelectionStart(), editor.GetSelectionEnd()); 188 | bool selectionWasOnJumpLocation = IsLocationOnJumpLocation(selection); 189 | 190 | if (selectionWasOnJumpLocation) 191 | { 192 | editor.SetIndicatorCurrent(JUMPLOCATION_INDICATOR); 193 | editor.IndicatorClearRange(selection.first, selection.second - selection.first); 194 | } 195 | 196 | auto location = FindNextJumpLocation(startPosition, wrap); 197 | 198 | if (IsLocationValid(location)) 199 | { 200 | return GoToJumpLocation(location); 201 | } 202 | else if (selectionWasOnJumpLocation) 203 | { 204 | // The last jump location has been cleared, so move the cursor to the end of it 205 | editor.GotoPos(selection.second); 206 | return true; 207 | } 208 | else 209 | { 210 | return false; 211 | } 212 | } 213 | 214 | void ClearJumpLocations() 215 | { 216 | editor.SetIndicatorCurrent(JUMPLOCATION_INDICATOR); 217 | editor.IndicatorClearRange(0, editor.GetTextLength()); 218 | } 219 | -------------------------------------------------------------------------------- /src/JumpLocations.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2017 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #pragma once 20 | 21 | const int JUMPLOCATION_INDICATOR = 15; 22 | 23 | void ProcessTextRangeForNewJumpLocations(int startPosition, int endPosition); 24 | bool GoToNextJumpLocation(int startPosition, bool wrap = true); 25 | void ClearJumpLocations(); 26 | -------------------------------------------------------------------------------- /src/Npp/Notepad_plus_msgs.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2003 Don HO 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 | // Note that the GPL places important restrictions on "derived works", yet 10 | // it does not provide a detailed definition of that term. To avoid 11 | // misunderstandings, we consider an application to constitute a 12 | // "derivative work" for the purpose of this license if it does any of the 13 | // following: 14 | // 1. Integrates source code from Notepad++. 15 | // 2. Integrates/includes/aggregates Notepad++ into a proprietary executable 16 | // installer, such as those produced by InstallShield. 17 | // 3. Links to a library or executes a program that does any of the above. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 | 28 | 29 | #ifndef NOTEPAD_PLUS_MSGS_H 30 | #define NOTEPAD_PLUS_MSGS_H 31 | 32 | #include 33 | #include 34 | 35 | enum LangType {L_TEXT, L_PHP , L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,\ 36 | L_HTML, L_XML, L_MAKEFILE, L_PASCAL, L_BATCH, L_INI, L_ASCII, L_USER,\ 37 | L_ASP, L_SQL, L_VB, L_JS, L_CSS, L_PERL, L_PYTHON, L_LUA, \ 38 | L_TEX, L_FORTRAN, L_BASH, L_FLASH, L_NSIS, L_TCL, L_LISP, L_SCHEME,\ 39 | L_ASM, L_DIFF, L_PROPS, L_PS, L_RUBY, L_SMALLTALK, L_VHDL, L_KIX, L_AU3,\ 40 | L_CAML, L_ADA, L_VERILOG, L_MATLAB, L_HASKELL, L_INNO, L_SEARCHRESULT,\ 41 | L_CMAKE, L_YAML, L_COBOL, L_GUI4CLI, L_D, L_POWERSHELL, L_R, L_JSP,\ 42 | L_COFFEESCRIPT, L_JSON, L_JAVASCRIPT, L_FORTRAN_77, L_BAANC, L_SREC,\ 43 | L_IHEX, L_TEHEX, L_SWIFT,\ 44 | L_ASN1, L_AVS, L_BLITZBASIC, L_PUREBASIC, L_FREEBASIC, \ 45 | L_CSOUND, L_ERLANG, L_ESCRIPT, L_FORTH, L_LATEX, \ 46 | L_MMIXAL, L_NIMROD, L_NNCRONTAB, L_OSCRIPT, L_REBOL, \ 47 | L_REGISTRY, L_RUST, L_SPICE, L_TXT2TAGS, L_VISUALPROLOG,\ 48 | // Don't use L_JS, use L_JAVASCRIPT instead 49 | // The end of enumated language type, so it should be always at the end 50 | L_EXTERNAL}; 51 | 52 | enum winVer{ WV_UNKNOWN, WV_WIN32S, WV_95, WV_98, WV_ME, WV_NT, WV_W2K, WV_XP, WV_S2003, WV_XPX64, WV_VISTA, WV_WIN7, WV_WIN8, WV_WIN81, WV_WIN10}; 53 | enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64 }; 54 | 55 | 56 | 57 | //Here you can find how to use these messages : http://docs.notepad-plus-plus.org/index.php/Messages_And_Notifications 58 | #define NPPMSG (WM_USER + 1000) 59 | 60 | #define NPPM_GETCURRENTSCINTILLA (NPPMSG + 4) 61 | #define NPPM_GETCURRENTLANGTYPE (NPPMSG + 5) 62 | #define NPPM_SETCURRENTLANGTYPE (NPPMSG + 6) 63 | 64 | #define NPPM_GETNBOPENFILES (NPPMSG + 7) 65 | #define ALL_OPEN_FILES 0 66 | #define PRIMARY_VIEW 1 67 | #define SECOND_VIEW 2 68 | 69 | #define NPPM_GETOPENFILENAMES (NPPMSG + 8) 70 | 71 | 72 | #define NPPM_MODELESSDIALOG (NPPMSG + 12) 73 | #define MODELESSDIALOGADD 0 74 | #define MODELESSDIALOGREMOVE 1 75 | 76 | #define NPPM_GETNBSESSIONFILES (NPPMSG + 13) 77 | #define NPPM_GETSESSIONFILES (NPPMSG + 14) 78 | #define NPPM_SAVESESSION (NPPMSG + 15) 79 | #define NPPM_SAVECURRENTSESSION (NPPMSG + 16) 80 | 81 | struct sessionInfo { 82 | TCHAR* sessionFilePathName; 83 | int nbFile; 84 | TCHAR** files; 85 | }; 86 | 87 | #define NPPM_GETOPENFILENAMESPRIMARY (NPPMSG + 17) 88 | #define NPPM_GETOPENFILENAMESSECOND (NPPMSG + 18) 89 | 90 | #define NPPM_CREATESCINTILLAHANDLE (NPPMSG + 20) 91 | #define NPPM_DESTROYSCINTILLAHANDLE (NPPMSG + 21) 92 | #define NPPM_GETNBUSERLANG (NPPMSG + 22) 93 | 94 | #define NPPM_GETCURRENTDOCINDEX (NPPMSG + 23) 95 | #define MAIN_VIEW 0 96 | #define SUB_VIEW 1 97 | 98 | #define NPPM_SETSTATUSBAR (NPPMSG + 24) 99 | #define STATUSBAR_DOC_TYPE 0 100 | #define STATUSBAR_DOC_SIZE 1 101 | #define STATUSBAR_CUR_POS 2 102 | #define STATUSBAR_EOF_FORMAT 3 103 | #define STATUSBAR_UNICODE_TYPE 4 104 | #define STATUSBAR_TYPING_MODE 5 105 | 106 | #define NPPM_GETMENUHANDLE (NPPMSG + 25) 107 | #define NPPPLUGINMENU 0 108 | #define NPPMAINMENU 1 109 | // INT NPPM_GETMENUHANDLE(INT menuChoice, 0) 110 | // Return: menu handle (HMENU) of choice (plugin menu handle or Notepad++ main menu handle) 111 | 112 | #define NPPM_ENCODESCI (NPPMSG + 26) 113 | //ascii file to unicode 114 | //int NPPM_ENCODESCI(MAIN_VIEW/SUB_VIEW, 0) 115 | //return new unicodeMode 116 | 117 | #define NPPM_DECODESCI (NPPMSG + 27) 118 | //unicode file to ascii 119 | //int NPPM_DECODESCI(MAIN_VIEW/SUB_VIEW, 0) 120 | //return old unicodeMode 121 | 122 | #define NPPM_ACTIVATEDOC (NPPMSG + 28) 123 | //void NPPM_ACTIVATEDOC(int view, int index2Activate) 124 | 125 | #define NPPM_LAUNCHFINDINFILESDLG (NPPMSG + 29) 126 | //void NPPM_LAUNCHFINDINFILESDLG(TCHAR * dir2Search, TCHAR * filtre) 127 | 128 | #define NPPM_DMMSHOW (NPPMSG + 30) 129 | //void NPPM_DMMSHOW(0, tTbData->hClient) 130 | 131 | #define NPPM_DMMHIDE (NPPMSG + 31) 132 | //void NPPM_DMMHIDE(0, tTbData->hClient) 133 | 134 | #define NPPM_DMMUPDATEDISPINFO (NPPMSG + 32) 135 | //void NPPM_DMMUPDATEDISPINFO(0, tTbData->hClient) 136 | 137 | #define NPPM_DMMREGASDCKDLG (NPPMSG + 33) 138 | //void NPPM_DMMREGASDCKDLG(0, &tTbData) 139 | 140 | #define NPPM_LOADSESSION (NPPMSG + 34) 141 | //void NPPM_LOADSESSION(0, const TCHAR* file name) 142 | 143 | #define NPPM_DMMVIEWOTHERTAB (NPPMSG + 35) 144 | //void WM_DMM_VIEWOTHERTAB(0, tTbData->pszName) 145 | 146 | #define NPPM_RELOADFILE (NPPMSG + 36) 147 | //BOOL NPPM_RELOADFILE(BOOL withAlert, TCHAR *filePathName2Reload) 148 | 149 | #define NPPM_SWITCHTOFILE (NPPMSG + 37) 150 | //BOOL NPPM_SWITCHTOFILE(0, TCHAR *filePathName2switch) 151 | 152 | #define NPPM_SAVECURRENTFILE (NPPMSG + 38) 153 | //BOOL NPPM_SAVECURRENTFILE(0, 0) 154 | 155 | #define NPPM_SAVEALLFILES (NPPMSG + 39) 156 | //BOOL NPPM_SAVEALLFILES(0, 0) 157 | 158 | #define NPPM_SETMENUITEMCHECK (NPPMSG + 40) 159 | //void WM_PIMENU_CHECK(UINT funcItem[X]._cmdID, TRUE/FALSE) 160 | 161 | #define NPPM_ADDTOOLBARICON (NPPMSG + 41) 162 | //void WM_ADDTOOLBARICON(UINT funcItem[X]._cmdID, toolbarIcons icon) 163 | struct toolbarIcons { 164 | HBITMAP hToolbarBmp; 165 | HICON hToolbarIcon; 166 | }; 167 | 168 | #define NPPM_GETWINDOWSVERSION (NPPMSG + 42) 169 | //winVer NPPM_GETWINDOWSVERSION(0, 0) 170 | 171 | #define NPPM_DMMGETPLUGINHWNDBYNAME (NPPMSG + 43) 172 | //HWND WM_DMM_GETPLUGINHWNDBYNAME(const TCHAR *windowName, const TCHAR *moduleName) 173 | // if moduleName is NULL, then return value is NULL 174 | // if windowName is NULL, then the first found window handle which matches with the moduleName will be returned 175 | 176 | #define NPPM_MAKECURRENTBUFFERDIRTY (NPPMSG + 44) 177 | //BOOL NPPM_MAKECURRENTBUFFERDIRTY(0, 0) 178 | 179 | #define NPPM_GETENABLETHEMETEXTUREFUNC (NPPMSG + 45) 180 | //BOOL NPPM_GETENABLETHEMETEXTUREFUNC(0, 0) 181 | 182 | #define NPPM_GETPLUGINSCONFIGDIR (NPPMSG + 46) 183 | //INT NPPM_GETPLUGINSCONFIGDIR(int strLen, TCHAR *str) 184 | // Get user's plugin config directory path. It's useful if plugins want to save/load parameters for the current user 185 | // Returns the number of TCHAR copied/to copy. 186 | // Users should call it with "str" be NULL to get the required number of TCHAR (not including the terminating nul character), 187 | // allocate "str" buffer with the return value + 1, then call it again to get the path. 188 | 189 | #define NPPM_MSGTOPLUGIN (NPPMSG + 47) 190 | //BOOL NPPM_MSGTOPLUGIN(TCHAR *destModuleName, CommunicationInfo *info) 191 | // return value is TRUE when the message arrive to the destination plugins. 192 | // if destModule or info is NULL, then return value is FALSE 193 | struct CommunicationInfo { 194 | long internalMsg; 195 | const TCHAR * srcModuleName; 196 | void * info; // defined by plugin 197 | }; 198 | 199 | #define NPPM_MENUCOMMAND (NPPMSG + 48) 200 | //void NPPM_MENUCOMMAND(0, int cmdID) 201 | // uncomment //#include "menuCmdID.h" 202 | // in the beginning of this file then use the command symbols defined in "menuCmdID.h" file 203 | // to access all the Notepad++ menu command items 204 | 205 | #define NPPM_TRIGGERTABBARCONTEXTMENU (NPPMSG + 49) 206 | //void NPPM_TRIGGERTABBARCONTEXTMENU(int view, int index2Activate) 207 | 208 | #define NPPM_GETNPPVERSION (NPPMSG + 50) 209 | // int NPPM_GETNPPVERSION(0, 0) 210 | // return version 211 | // ex : v4.6 212 | // HIWORD(version) == 4 213 | // LOWORD(version) == 6 214 | 215 | #define NPPM_HIDETABBAR (NPPMSG + 51) 216 | // BOOL NPPM_HIDETABBAR(0, BOOL hideOrNot) 217 | // if hideOrNot is set as TRUE then tab bar will be hidden 218 | // otherwise it'll be shown. 219 | // return value : the old status value 220 | 221 | #define NPPM_ISTABBARHIDDEN (NPPMSG + 52) 222 | // BOOL NPPM_ISTABBARHIDDEN(0, 0) 223 | // returned value : TRUE if tab bar is hidden, otherwise FALSE 224 | 225 | #define NPPM_GETPOSFROMBUFFERID (NPPMSG + 57) 226 | // INT NPPM_GETPOSFROMBUFFERID(UINT_PTR bufferID, INT priorityView) 227 | // Return VIEW|INDEX from a buffer ID. -1 if the bufferID non existing 228 | // if priorityView set to SUB_VIEW, then SUB_VIEW will be search firstly 229 | // 230 | // VIEW takes 2 highest bits and INDEX (0 based) takes the rest (30 bits) 231 | // Here's the values for the view : 232 | // MAIN_VIEW 0 233 | // SUB_VIEW 1 234 | 235 | #define NPPM_GETFULLPATHFROMBUFFERID (NPPMSG + 58) 236 | // INT NPPM_GETFULLPATHFROMBUFFERID(UINT_PTR bufferID, TCHAR *fullFilePath) 237 | // Get full path file name from a bufferID. 238 | // Return -1 if the bufferID non existing, otherwise the number of TCHAR copied/to copy 239 | // User should call it with fullFilePath be NULL to get the number of TCHAR (not including the nul character), 240 | // allocate fullFilePath with the return values + 1, then call it again to get full path file name 241 | 242 | #define NPPM_GETBUFFERIDFROMPOS (NPPMSG + 59) 243 | // LRESULT NPPM_GETBUFFERIDFROMPOS(INT index, INT iView) 244 | // wParam: Position of document 245 | // lParam: View to use, 0 = Main, 1 = Secondary 246 | // Returns 0 if invalid 247 | 248 | #define NPPM_GETCURRENTBUFFERID (NPPMSG + 60) 249 | // LRESULT NPPM_GETCURRENTBUFFERID(0, 0) 250 | // Returns active Buffer 251 | 252 | #define NPPM_RELOADBUFFERID (NPPMSG + 61) 253 | // VOID NPPM_RELOADBUFFERID(UINT_PTR bufferID, BOOL alert) 254 | // Reloads Buffer 255 | // wParam: Buffer to reload 256 | // lParam: 0 if no alert, else alert 257 | 258 | 259 | #define NPPM_GETBUFFERLANGTYPE (NPPMSG + 64) 260 | // INT NPPM_GETBUFFERLANGTYPE(UINT_PTR bufferID, 0) 261 | // wParam: BufferID to get LangType from 262 | // lParam: 0 263 | // Returns as int, see LangType. -1 on error 264 | 265 | #define NPPM_SETBUFFERLANGTYPE (NPPMSG + 65) 266 | // BOOL NPPM_SETBUFFERLANGTYPE(UINT_PTR bufferID, INT langType) 267 | // wParam: BufferID to set LangType of 268 | // lParam: LangType 269 | // Returns TRUE on success, FALSE otherwise 270 | // use int, see LangType for possible values 271 | // L_USER and L_EXTERNAL are not supported 272 | 273 | #define NPPM_GETBUFFERENCODING (NPPMSG + 66) 274 | // INT NPPM_GETBUFFERENCODING(UINT_PTR bufferID, 0) 275 | // wParam: BufferID to get encoding from 276 | // lParam: 0 277 | // returns as int, see UniMode. -1 on error 278 | 279 | #define NPPM_SETBUFFERENCODING (NPPMSG + 67) 280 | // BOOL NPPM_SETBUFFERENCODING(UINT_PTR bufferID, INT encoding) 281 | // wParam: BufferID to set encoding of 282 | // lParam: encoding 283 | // Returns TRUE on success, FALSE otherwise 284 | // use int, see UniMode 285 | // Can only be done on new, unedited files 286 | 287 | #define NPPM_GETBUFFERFORMAT (NPPMSG + 68) 288 | // INT NPPM_GETBUFFERFORMAT(UINT_PTR bufferID, 0) 289 | // wParam: BufferID to get EolType format from 290 | // lParam: 0 291 | // returns as int, see EolType format. -1 on error 292 | 293 | #define NPPM_SETBUFFERFORMAT (NPPMSG + 69) 294 | // BOOL NPPM_SETBUFFERFORMAT(UINT_PTR bufferID, INT format) 295 | // wParam: BufferID to set EolType format of 296 | // lParam: format 297 | // Returns TRUE on success, FALSE otherwise 298 | // use int, see EolType format 299 | 300 | 301 | #define NPPM_HIDETOOLBAR (NPPMSG + 70) 302 | // BOOL NPPM_HIDETOOLBAR(0, BOOL hideOrNot) 303 | // if hideOrNot is set as TRUE then tool bar will be hidden 304 | // otherwise it'll be shown. 305 | // return value : the old status value 306 | 307 | #define NPPM_ISTOOLBARHIDDEN (NPPMSG + 71) 308 | // BOOL NPPM_ISTOOLBARHIDDEN(0, 0) 309 | // returned value : TRUE if tool bar is hidden, otherwise FALSE 310 | 311 | #define NPPM_HIDEMENU (NPPMSG + 72) 312 | // BOOL NPPM_HIDEMENU(0, BOOL hideOrNot) 313 | // if hideOrNot is set as TRUE then menu will be hidden 314 | // otherwise it'll be shown. 315 | // return value : the old status value 316 | 317 | #define NPPM_ISMENUHIDDEN (NPPMSG + 73) 318 | // BOOL NPPM_ISMENUHIDDEN(0, 0) 319 | // returned value : TRUE if menu is hidden, otherwise FALSE 320 | 321 | #define NPPM_HIDESTATUSBAR (NPPMSG + 74) 322 | // BOOL NPPM_HIDESTATUSBAR(0, BOOL hideOrNot) 323 | // if hideOrNot is set as TRUE then STATUSBAR will be hidden 324 | // otherwise it'll be shown. 325 | // return value : the old status value 326 | 327 | #define NPPM_ISSTATUSBARHIDDEN (NPPMSG + 75) 328 | // BOOL NPPM_ISSTATUSBARHIDDEN(0, 0) 329 | // returned value : TRUE if STATUSBAR is hidden, otherwise FALSE 330 | 331 | #define NPPM_GETSHORTCUTBYCMDID (NPPMSG + 76) 332 | // BOOL NPPM_GETSHORTCUTBYCMDID(int cmdID, ShortcutKey *sk) 333 | // get your plugin command current mapped shortcut into sk via cmdID 334 | // You may need it after getting NPPN_READY notification 335 | // returned value : TRUE if this function call is successful and shortcut is enable, otherwise FALSE 336 | 337 | #define NPPM_DOOPEN (NPPMSG + 77) 338 | // BOOL NPPM_DOOPEN(0, const TCHAR *fullPathName2Open) 339 | // fullPathName2Open indicates the full file path name to be opened. 340 | // The return value is TRUE (1) if the operation is successful, otherwise FALSE (0). 341 | 342 | #define NPPM_SAVECURRENTFILEAS (NPPMSG + 78) 343 | // BOOL NPPM_SAVECURRENTFILEAS (BOOL asCopy, const TCHAR* filename) 344 | 345 | #define NPPM_GETCURRENTNATIVELANGENCODING (NPPMSG + 79) 346 | // INT NPPM_GETCURRENTNATIVELANGENCODING(0, 0) 347 | // returned value : the current native language encoding 348 | 349 | #define NPPM_ALLOCATESUPPORTED (NPPMSG + 80) 350 | // returns TRUE if NPPM_ALLOCATECMDID is supported 351 | // Use to identify if subclassing is necessary 352 | 353 | #define NPPM_ALLOCATECMDID (NPPMSG + 81) 354 | // BOOL NPPM_ALLOCATECMDID(int numberRequested, int* startNumber) 355 | // sets startNumber to the initial command ID if successful 356 | // Returns: TRUE if successful, FALSE otherwise. startNumber will also be set to 0 if unsuccessful 357 | 358 | #define NPPM_ALLOCATEMARKER (NPPMSG + 82) 359 | // BOOL NPPM_ALLOCATEMARKER(int numberRequested, int* startNumber) 360 | // sets startNumber to the initial command ID if successful 361 | // Allocates a marker number to a plugin 362 | // Returns: TRUE if successful, FALSE otherwise. startNumber will also be set to 0 if unsuccessful 363 | 364 | #define NPPM_GETLANGUAGENAME (NPPMSG + 83) 365 | // INT NPPM_GETLANGUAGENAME(int langType, TCHAR *langName) 366 | // Get programming language name from the given language type (LangType) 367 | // Return value is the number of copied character / number of character to copy (\0 is not included) 368 | // You should call this function 2 times - the first time you pass langName as NULL to get the number of characters to copy. 369 | // You allocate a buffer of the length of (the number of characters + 1) then call NPPM_GETLANGUAGENAME function the 2nd time 370 | // by passing allocated buffer as argument langName 371 | 372 | #define NPPM_GETLANGUAGEDESC (NPPMSG + 84) 373 | // INT NPPM_GETLANGUAGEDESC(int langType, TCHAR *langDesc) 374 | // Get programming language short description from the given language type (LangType) 375 | // Return value is the number of copied character / number of character to copy (\0 is not included) 376 | // You should call this function 2 times - the first time you pass langDesc as NULL to get the number of characters to copy. 377 | // You allocate a buffer of the length of (the number of characters + 1) then call NPPM_GETLANGUAGEDESC function the 2nd time 378 | // by passing allocated buffer as argument langDesc 379 | 380 | #define NPPM_SHOWDOCSWITCHER (NPPMSG + 85) 381 | // VOID NPPM_ISDOCSWITCHERSHOWN(0, BOOL toShowOrNot) 382 | // Send this message to show or hide doc switcher. 383 | // if toShowOrNot is TRUE then show doc switcher, otherwise hide it. 384 | 385 | #define NPPM_ISDOCSWITCHERSHOWN (NPPMSG + 86) 386 | // BOOL NPPM_ISDOCSWITCHERSHOWN(0, 0) 387 | // Check to see if doc switcher is shown. 388 | 389 | #define NPPM_GETAPPDATAPLUGINSALLOWED (NPPMSG + 87) 390 | // BOOL NPPM_GETAPPDATAPLUGINSALLOWED(0, 0) 391 | // Check to see if loading plugins from "%APPDATA%\..\Local\Notepad++\plugins" is allowed. 392 | 393 | #define NPPM_GETCURRENTVIEW (NPPMSG + 88) 394 | // INT NPPM_GETCURRENTVIEW(0, 0) 395 | // Return: current edit view of Notepad++. Only 2 possible values: 0 = Main, 1 = Secondary 396 | 397 | #define NPPM_DOCSWITCHERDISABLECOLUMN (NPPMSG + 89) 398 | // VOID NPPM_DOCSWITCHERDISABLECOLUMN(0, BOOL disableOrNot) 399 | // Disable or enable extension column of doc switcher 400 | 401 | #define NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR (NPPMSG + 90) 402 | // INT NPPM_GETEDITORDEFAULTFOREGROUNDCOLOR(0, 0) 403 | // Return: current editor default foreground color. You should convert the returned value in COLORREF 404 | 405 | #define NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR (NPPMSG + 91) 406 | // INT NPPM_GETEDITORDEFAULTBACKGROUNDCOLOR(0, 0) 407 | // Return: current editor default background color. You should convert the returned value in COLORREF 408 | 409 | #define NPPM_SETSMOOTHFONT (NPPMSG + 92) 410 | // VOID NPPM_SETSMOOTHFONT(0, BOOL setSmoothFontOrNot) 411 | 412 | #define NPPM_SETEDITORBORDEREDGE (NPPMSG + 93) 413 | // VOID NPPM_SETEDITORBORDEREDGE(0, BOOL withEditorBorderEdgeOrNot) 414 | 415 | #define NPPM_SAVEFILE (NPPMSG + 94) 416 | // VOID NPPM_SAVEFILE(0, const TCHAR *fileNameToSave) 417 | 418 | #define NPPM_DISABLEAUTOUPDATE (NPPMSG + 95) // 2119 in decimal 419 | // VOID NPPM_DISABLEAUTOUPDATE(0, 0) 420 | 421 | #define NPPM_REMOVESHORTCUTBYCMDID (NPPMSG + 96) // 2120 in decimal 422 | // BOOL NPPM_REMOVESHORTCUTASSIGNMENT(int cmdID) 423 | // removes the assigned shortcut mapped to cmdID 424 | // returned value : TRUE if function call is successful, otherwise FALSE 425 | 426 | #define NPPM_GETPLUGINHOMEPATH (NPPMSG + 97) 427 | // INT NPPM_GETPLUGINHOMEPATH(size_t strLen, TCHAR *pluginRootPath) 428 | // Get plugin home root path. It's useful if plugins want to get its own path 429 | // by appending which is the name of plugin without extension part. 430 | // Returns the number of TCHAR copied/to copy. 431 | // Users should call it with pluginRootPath be NULL to get the required number of TCHAR (not including the terminating nul character), 432 | // allocate pluginRootPath buffer with the return value + 1, then call it again to get the path. 433 | 434 | #define RUNCOMMAND_USER (WM_USER + 3000) 435 | #define NPPM_GETFULLCURRENTPATH (RUNCOMMAND_USER + FULL_CURRENT_PATH) 436 | #define NPPM_GETCURRENTDIRECTORY (RUNCOMMAND_USER + CURRENT_DIRECTORY) 437 | #define NPPM_GETFILENAME (RUNCOMMAND_USER + FILE_NAME) 438 | #define NPPM_GETNAMEPART (RUNCOMMAND_USER + NAME_PART) 439 | #define NPPM_GETEXTPART (RUNCOMMAND_USER + EXT_PART) 440 | #define NPPM_GETCURRENTWORD (RUNCOMMAND_USER + CURRENT_WORD) 441 | #define NPPM_GETNPPDIRECTORY (RUNCOMMAND_USER + NPP_DIRECTORY) 442 | #define NPPM_GETFILENAMEATCURSOR (RUNCOMMAND_USER + GETFILENAMEATCURSOR) 443 | // BOOL NPPM_GETXXXXXXXXXXXXXXXX(size_t strLen, TCHAR *str) 444 | // where str is the allocated TCHAR array, 445 | // strLen is the allocated array size 446 | // The return value is TRUE when get generic_string operation success 447 | // Otherwise (allocated array size is too small) FALSE 448 | 449 | #define NPPM_GETCURRENTLINE (RUNCOMMAND_USER + CURRENT_LINE) 450 | // INT NPPM_GETCURRENTLINE(0, 0) 451 | // return the caret current position line 452 | #define NPPM_GETCURRENTCOLUMN (RUNCOMMAND_USER + CURRENT_COLUMN) 453 | // INT NPPM_GETCURRENTCOLUMN(0, 0) 454 | // return the caret current position column 455 | 456 | #define NPPM_GETNPPFULLFILEPATH (RUNCOMMAND_USER + NPP_FULL_FILE_PATH) 457 | 458 | #define VAR_NOT_RECOGNIZED 0 459 | #define FULL_CURRENT_PATH 1 460 | #define CURRENT_DIRECTORY 2 461 | #define FILE_NAME 3 462 | #define NAME_PART 4 463 | #define EXT_PART 5 464 | #define CURRENT_WORD 6 465 | #define NPP_DIRECTORY 7 466 | #define CURRENT_LINE 8 467 | #define CURRENT_COLUMN 9 468 | #define NPP_FULL_FILE_PATH 10 469 | #define GETFILENAMEATCURSOR 11 470 | 471 | 472 | // Notification code 473 | #define NPPN_FIRST 1000 474 | #define NPPN_READY (NPPN_FIRST + 1) // To notify plugins that all the procedures of launchment of notepad++ are done. 475 | //scnNotification->nmhdr.code = NPPN_READY; 476 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 477 | //scnNotification->nmhdr.idFrom = 0; 478 | 479 | #define NPPN_TBMODIFICATION (NPPN_FIRST + 2) // To notify plugins that toolbar icons can be registered 480 | //scnNotification->nmhdr.code = NPPN_TB_MODIFICATION; 481 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 482 | //scnNotification->nmhdr.idFrom = 0; 483 | 484 | #define NPPN_FILEBEFORECLOSE (NPPN_FIRST + 3) // To notify plugins that the current file is about to be closed 485 | //scnNotification->nmhdr.code = NPPN_FILEBEFORECLOSE; 486 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 487 | //scnNotification->nmhdr.idFrom = BufferID; 488 | 489 | #define NPPN_FILEOPENED (NPPN_FIRST + 4) // To notify plugins that the current file is just opened 490 | //scnNotification->nmhdr.code = NPPN_FILEOPENED; 491 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 492 | //scnNotification->nmhdr.idFrom = BufferID; 493 | 494 | #define NPPN_FILECLOSED (NPPN_FIRST + 5) // To notify plugins that the current file is just closed 495 | //scnNotification->nmhdr.code = NPPN_FILECLOSED; 496 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 497 | //scnNotification->nmhdr.idFrom = BufferID; 498 | 499 | #define NPPN_FILEBEFOREOPEN (NPPN_FIRST + 6) // To notify plugins that the current file is about to be opened 500 | //scnNotification->nmhdr.code = NPPN_FILEBEFOREOPEN; 501 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 502 | //scnNotification->nmhdr.idFrom = BufferID; 503 | 504 | #define NPPN_FILEBEFORESAVE (NPPN_FIRST + 7) // To notify plugins that the current file is about to be saved 505 | //scnNotification->nmhdr.code = NPPN_FILEBEFOREOPEN; 506 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 507 | //scnNotification->nmhdr.idFrom = BufferID; 508 | 509 | #define NPPN_FILESAVED (NPPN_FIRST + 8) // To notify plugins that the current file is just saved 510 | //scnNotification->nmhdr.code = NPPN_FILESAVED; 511 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 512 | //scnNotification->nmhdr.idFrom = BufferID; 513 | 514 | #define NPPN_SHUTDOWN (NPPN_FIRST + 9) // To notify plugins that Notepad++ is about to be shutdowned. 515 | //scnNotification->nmhdr.code = NPPN_SHUTDOWN; 516 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 517 | //scnNotification->nmhdr.idFrom = 0; 518 | 519 | #define NPPN_BUFFERACTIVATED (NPPN_FIRST + 10) // To notify plugins that a buffer was activated (put to foreground). 520 | //scnNotification->nmhdr.code = NPPN_BUFFERACTIVATED; 521 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 522 | //scnNotification->nmhdr.idFrom = activatedBufferID; 523 | 524 | #define NPPN_LANGCHANGED (NPPN_FIRST + 11) // To notify plugins that the language in the current doc is just changed. 525 | //scnNotification->nmhdr.code = NPPN_LANGCHANGED; 526 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 527 | //scnNotification->nmhdr.idFrom = currentBufferID; 528 | 529 | #define NPPN_WORDSTYLESUPDATED (NPPN_FIRST + 12) // To notify plugins that user initiated a WordStyleDlg change. 530 | //scnNotification->nmhdr.code = NPPN_WORDSTYLESUPDATED; 531 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 532 | //scnNotification->nmhdr.idFrom = currentBufferID; 533 | 534 | #define NPPN_SHORTCUTREMAPPED (NPPN_FIRST + 13) // To notify plugins that plugin command shortcut is remapped. 535 | //scnNotification->nmhdr.code = NPPN_SHORTCUTSREMAPPED; 536 | //scnNotification->nmhdr.hwndFrom = ShortcutKeyStructurePointer; 537 | //scnNotification->nmhdr.idFrom = cmdID; 538 | //where ShortcutKeyStructurePointer is pointer of struct ShortcutKey: 539 | //struct ShortcutKey { 540 | // bool _isCtrl; 541 | // bool _isAlt; 542 | // bool _isShift; 543 | // UCHAR _key; 544 | //}; 545 | 546 | #define NPPN_FILEBEFORELOAD (NPPN_FIRST + 14) // To notify plugins that the current file is about to be loaded 547 | //scnNotification->nmhdr.code = NPPN_FILEBEFOREOPEN; 548 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 549 | //scnNotification->nmhdr.idFrom = NULL; 550 | 551 | #define NPPN_FILELOADFAILED (NPPN_FIRST + 15) // To notify plugins that file open operation failed 552 | //scnNotification->nmhdr.code = NPPN_FILEOPENFAILED; 553 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 554 | //scnNotification->nmhdr.idFrom = BufferID; 555 | 556 | #define NPPN_READONLYCHANGED (NPPN_FIRST + 16) // To notify plugins that current document change the readonly status, 557 | //scnNotification->nmhdr.code = NPPN_READONLYCHANGED; 558 | //scnNotification->nmhdr.hwndFrom = bufferID; 559 | //scnNotification->nmhdr.idFrom = docStatus; 560 | // where bufferID is BufferID 561 | // docStatus can be combined by DOCSTATUS_READONLY and DOCSTATUS_BUFFERDIRTY 562 | 563 | #define DOCSTATUS_READONLY 1 564 | #define DOCSTATUS_BUFFERDIRTY 2 565 | 566 | #define NPPN_DOCORDERCHANGED (NPPN_FIRST + 17) // To notify plugins that document order is changed 567 | //scnNotification->nmhdr.code = NPPN_DOCORDERCHANGED; 568 | //scnNotification->nmhdr.hwndFrom = newIndex; 569 | //scnNotification->nmhdr.idFrom = BufferID; 570 | 571 | #define NPPN_SNAPSHOTDIRTYFILELOADED (NPPN_FIRST + 18) // To notify plugins that a snapshot dirty file is loaded on startup 572 | //scnNotification->nmhdr.code = NPPN_SNAPSHOTDIRTYFILELOADED; 573 | //scnNotification->nmhdr.hwndFrom = NULL; 574 | //scnNotification->nmhdr.idFrom = BufferID; 575 | 576 | #define NPPN_BEFORESHUTDOWN (NPPN_FIRST + 19) // To notify plugins that Npp shutdown has been triggered, files have not been closed yet 577 | //scnNotification->nmhdr.code = NPPN_BEFORESHUTDOWN; 578 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 579 | //scnNotification->nmhdr.idFrom = 0; 580 | 581 | #define NPPN_CANCELSHUTDOWN (NPPN_FIRST + 20) // To notify plugins that Npp shutdown has been cancelled 582 | //scnNotification->nmhdr.code = NPPN_CANCELSHUTDOWN; 583 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 584 | //scnNotification->nmhdr.idFrom = 0; 585 | 586 | #define NPPN_FILEBEFORERENAME (NPPN_FIRST + 21) // To notify plugins that file is to be renamed 587 | //scnNotification->nmhdr.code = NPPN_FILEBEFORERENAME; 588 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 589 | //scnNotification->nmhdr.idFrom = BufferID; 590 | 591 | #define NPPN_FILERENAMECANCEL (NPPN_FIRST + 22) // To notify plugins that file rename has been cancelled 592 | //scnNotification->nmhdr.code = NPPN_FILERENAMECANCEL; 593 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 594 | //scnNotification->nmhdr.idFrom = BufferID; 595 | 596 | #define NPPN_FILERENAMED (NPPN_FIRST + 23) // To notify plugins that file has been renamed 597 | //scnNotification->nmhdr.code = NPPN_FILERENAMED; 598 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 599 | //scnNotification->nmhdr.idFrom = BufferID; 600 | 601 | #define NPPN_FILEBEFOREDELETE (NPPN_FIRST + 24) // To notify plugins that file is to be deleted 602 | //scnNotification->nmhdr.code = NPPN_FILEBEFOREDELETE; 603 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 604 | //scnNotification->nmhdr.idFrom = BufferID; 605 | 606 | #define NPPN_FILEDELETEFAILED (NPPN_FIRST + 25) // To notify plugins that file deletion has failed 607 | //scnNotification->nmhdr.code = NPPN_FILEDELETEFAILED; 608 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 609 | //scnNotification->nmhdr.idFrom = BufferID; 610 | 611 | #define NPPN_FILEDELETED (NPPN_FIRST + 26) // To notify plugins that file has been deleted 612 | //scnNotification->nmhdr.code = NPPN_FILEDELETED; 613 | //scnNotification->nmhdr.hwndFrom = hwndNpp; 614 | //scnNotification->nmhdr.idFrom = BufferID; 615 | 616 | #endif //NOTEPAD_PLUS_MSGS_H 617 | -------------------------------------------------------------------------------- /src/Npp/PluginInterface.h: -------------------------------------------------------------------------------- 1 | // This file is part of Notepad++ project 2 | // Copyright (C)2003 Don HO 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 | // Note that the GPL places important restrictions on "derived works", yet 10 | // it does not provide a detailed definition of that term. To avoid 11 | // misunderstandings, we consider an application to constitute a 12 | // "derivative work" for the purpose of this license if it does any of the 13 | // following: 14 | // 1. Integrates source code from Notepad++. 15 | // 2. Integrates/includes/aggregates Notepad++ into a proprietary executable 16 | // installer, such as those produced by InstallShield. 17 | // 3. Links to a library or executes a program that does any of the above. 18 | // 19 | // This program is distributed in the hope that it will be useful, 20 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | // GNU General Public License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this program; if not, write to the Free Software 26 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 | 28 | 29 | #ifndef PLUGININTERFACE_H 30 | #define PLUGININTERFACE_H 31 | 32 | #ifndef SCINTILLA_H 33 | #include "Scintilla.h" 34 | #endif //SCINTILLA_H 35 | 36 | #ifndef NOTEPAD_PLUS_MSGS_H 37 | #include "Notepad_plus_msgs.h" 38 | #endif //NOTEPAD_PLUS_MSGS_H 39 | 40 | const int nbChar = 64; 41 | 42 | typedef const TCHAR * (__cdecl * PFUNCGETNAME)(); 43 | 44 | struct NppData 45 | { 46 | HWND _nppHandle; 47 | HWND _scintillaMainHandle; 48 | HWND _scintillaSecondHandle; 49 | }; 50 | 51 | typedef void (__cdecl * PFUNCSETINFO)(NppData); 52 | typedef void (__cdecl * PFUNCPLUGINCMD)(); 53 | typedef void (__cdecl * PBENOTIFIED)(SCNotification *); 54 | typedef LRESULT (__cdecl * PMESSAGEPROC)(UINT Message, WPARAM wParam, LPARAM lParam); 55 | 56 | 57 | struct ShortcutKey 58 | { 59 | bool _isCtrl; 60 | bool _isAlt; 61 | bool _isShift; 62 | UCHAR _key; 63 | }; 64 | 65 | struct FuncItem 66 | { 67 | TCHAR _itemName[nbChar]; 68 | PFUNCPLUGINCMD _pFunc; 69 | int _cmdID; 70 | bool _init2Check; 71 | ShortcutKey *_pShKey; 72 | }; 73 | 74 | typedef FuncItem * (__cdecl * PFUNCGETFUNCSARRAY)(int *); 75 | 76 | // You should implement (or define an empty function body) those functions which are called by Notepad++ plugin manager 77 | extern "C" __declspec(dllexport) void setInfo(NppData); 78 | extern "C" __declspec(dllexport) const TCHAR * getName(); 79 | extern "C" __declspec(dllexport) FuncItem * getFuncsArray(int *); 80 | extern "C" __declspec(dllexport) void beNotified(SCNotification *); 81 | extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam); 82 | 83 | // This API return always true now, since Notepad++ isn't compiled in ANSI mode anymore 84 | extern "C" __declspec(dllexport) BOOL isUnicode(); 85 | 86 | 87 | #endif //PLUGININTERFACE_H 88 | -------------------------------------------------------------------------------- /src/Npp/Sci_Position.h: -------------------------------------------------------------------------------- 1 | // Scintilla source code edit control 2 | /** @file Sci_Position.h 3 | ** Define the Sci_Position type used in Scintilla's external interfaces. 4 | ** These need to be available to clients written in C so are not in a C++ namespace. 5 | **/ 6 | // Copyright 2015 by Neil Hodgson 7 | // The License.txt file describes the conditions under which this software may be distributed. 8 | 9 | #ifndef SCI_POSITION_H 10 | #define SCI_POSITION_H 11 | 12 | #include 13 | 14 | // Basic signed type used throughout interface 15 | typedef ptrdiff_t Sci_Position; 16 | 17 | // Unsigned variant used for ILexer::Lex and ILexer::Fold 18 | typedef size_t Sci_PositionU; 19 | 20 | // For Sci_CharacterRange which is defined as long to be compatible with Win32 CHARRANGE 21 | typedef long Sci_PositionCR; 22 | 23 | #ifdef _WIN32 24 | #define SCI_METHOD __stdcall 25 | #else 26 | #define SCI_METHOD 27 | #endif 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/Parsers/C_Parser.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "Parsers.h" 20 | 21 | Keywords parse_c(const ParserSettings *ps, const char *text) 22 | { 23 | static TrRegex tr_function("(?:([\\w:]+)[*&]*\\s+(?:[*&=]*\\s+)?[*&]*)?([^\\s\\(]+)\\s*(\\([^)]*\\))"); 24 | static TrRegex tr_parameters("(\\$?\\w+|\\.\\.\\.)(\\s*=\\s*[\\\"\\w\\.']+)?\\s*[,)]"); 25 | Keywords keywords; 26 | 27 | const TRexChar *begin, *end; 28 | int chevron = 0; 29 | 30 | // HACK: Duplicate the string so it can be modified and any commas within <...> needs removed to support templates e.g. std::pair 31 | std::string dup(text); 32 | 33 | for (char &c : dup) 34 | { 35 | if (c == '<') chevron++; 36 | else if (c == '>') chevron--; 37 | else if (c == ',' && chevron > 0) c = ' '; 38 | } 39 | 40 | if (trex_search(tr_function.regex, dup.c_str(), &begin, &end)) 41 | { 42 | std::vector params; 43 | std::vector function; 44 | TRexMatch params_match, func_match; 45 | const TRexChar *cur_params; 46 | const TRexChar *p_begin, *p_end; 47 | 48 | //trex_getsubexp(tr_function, 1, &return_match); // not used for now 49 | trex_getsubexp(tr_function.regex, 2, &func_match); 50 | trex_getsubexp(tr_function.regex, 3, ¶ms_match); 51 | 52 | keywords.function = std::string(func_match.begin, func_match.len); 53 | 54 | // For each param 55 | cur_params = params_match.begin; 56 | while (trex_searchrange(tr_parameters.regex, cur_params, end, &p_begin, &p_end)) 57 | { 58 | TRexMatch param_match; 59 | trex_getsubexp(tr_parameters.regex, 1, ¶m_match); 60 | 61 | // handle "func(void)" by skipping it 62 | if (strncmp(param_match.begin, "void", 4) != 0) 63 | keywords.parameters.push_back(std::string(param_match.begin, param_match.len)); 64 | 65 | cur_params = p_end; 66 | } 67 | } 68 | 69 | return keywords; 70 | } 71 | -------------------------------------------------------------------------------- /src/Parsers/Null_Parser.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "Parsers.h" 20 | 21 | Keywords parse_null(const ParserSettings *ps, const char *text) 22 | { 23 | return Keywords(); 24 | } 25 | -------------------------------------------------------------------------------- /src/Parsers/Parsers.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "Parsers.h" 20 | #include 21 | #include 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | #define SECURITY_WIN32 25 | #include 26 | #pragma comment(lib, "Secur32.lib") 27 | 28 | const char *default_function_format = 29 | "\r\n" 30 | "$@brief $(Brief description)\r\n" 31 | "\r\n" 32 | "$@param [in] $PARAM $|$(Description for $PARAM)\r\n" 33 | "$@return $(Return description)\r\n" 34 | "\r\n" 35 | "$@details $(More details)\r\n" 36 | ; 37 | 38 | const char *default_internal_function_format = 39 | "\r\n" 40 | "$@brief $(Brief description)\r\n" 41 | "\r\n" 42 | "$@param [in] theParam $(Description)\r\n" 43 | "$@return $(Return description)\r\n" 44 | "\r\n" 45 | "$@details $(More details)\r\n" 46 | ; 47 | 48 | const char *default_file_format = 49 | "\r\n" 50 | "$@file $FILENAME\r\n" 51 | "$@brief $(Brief description)\r\n" 52 | ; 53 | 54 | 55 | 56 | const Parser *getParserByName(std::wstring name) 57 | { 58 | for(auto const &p : parsers) 59 | if(p.language_name == name) 60 | return &p; 61 | 62 | return NULL; 63 | } 64 | 65 | // 'update' causes the current parser pointer to be updated 66 | // else just return the currently cached parser 67 | const Parser *getCurrentParser(bool update) 68 | { 69 | static const Parser *current = NULL; 70 | 71 | if(update) 72 | { 73 | int lang_type; 74 | SendNpp(NPPM_GETCURRENTLANGTYPE, SCI_UNUSED, (LPARAM) &lang_type); 75 | 76 | // HACK: Keep backwards compatibility since N++ screwed up the javascript langtype 77 | if(lang_type == L_JAVASCRIPT) lang_type = L_JS; 78 | 79 | if(lang_type == L_USER /* || lang_type == L_EXTERNAL */) 80 | { 81 | wchar_t *name = NULL; 82 | size_t len = 0; 83 | 84 | len = SendNpp(NPPM_GETLANGUAGENAME, lang_type, NULL) + 1; 85 | name = (wchar_t *) malloc(sizeof(wchar_t) * len); 86 | SendNpp(NPPM_GETLANGUAGENAME, lang_type, (LPARAM) name); 87 | 88 | for(auto const &p : parsers) 89 | { 90 | // Use [6] because the name returned is "udl - mylangname" 91 | if(p.language_name == &name[6]) 92 | { 93 | current = &p; 94 | free(name); 95 | return current; 96 | } 97 | } 98 | 99 | free(name); 100 | } 101 | else 102 | { 103 | for(auto const &p : parsers) 104 | { 105 | if(p.lang_type == lang_type) 106 | { 107 | current = &p; 108 | return current; 109 | } 110 | } 111 | } 112 | 113 | wchar_t *name = NULL; 114 | size_t len = 0; 115 | 116 | len = SendNpp(NPPM_GETLANGUAGENAME, lang_type, NULL) + 1; 117 | name = (wchar_t *) malloc(sizeof(wchar_t) * len); 118 | SendNpp(NPPM_GETLANGUAGENAME, lang_type, (LPARAM) name); 119 | 120 | for(auto const &p : parsers) 121 | { 122 | // Use [0] to match any build-in language 123 | if(p.language_name == &name[0]) 124 | { 125 | current = &p; 126 | free(name); 127 | return current; 128 | } 129 | } 130 | 131 | free(name); 132 | 133 | // Parser wasn't found for current language 134 | current = nullptr; 135 | } 136 | 137 | return current; 138 | } 139 | 140 | const ParserSettings *getCurrentParserSettings(void) 141 | { 142 | const Parser *p = getCurrentParser(); 143 | return (p ? &p->ps : nullptr); 144 | } 145 | 146 | void addNewParser(std::string name, ParserSettings *ps) 147 | { 148 | parsers.emplace_back(); 149 | 150 | Parser *p = &parsers[parsers.size() - 1]; 151 | 152 | p->lang_type = L_USER; 153 | p->lang = toWideString(name); 154 | p->language_name = toWideString(name); 155 | p->external = true; 156 | 157 | if(ps == nullptr) 158 | { 159 | // Fill in default values 160 | p->ps.doc_start = "/**"; 161 | p->ps.doc_line = " * "; 162 | p->ps.doc_end = " */"; 163 | p->ps.command_prefix = "\\"; 164 | p->ps.file_format = default_file_format; 165 | p->ps.function_format = default_internal_function_format; 166 | p->ps.align = false; // not used 167 | } 168 | else 169 | { 170 | p->ps = *ps; 171 | } 172 | } 173 | 174 | // Very ugly macro 175 | #define REGISTER_PARSER(strategy, lang, language_name, doc_start, doc_line, doc_end, command_prefix, example) \ 176 | strategy, L_##lang, TEXT(#lang), TEXT(language_name), example, doc_start, doc_line, doc_end, command_prefix 177 | 178 | std::vector parsers; 179 | void InitializeParsers(void) 180 | { 181 | parsers.reserve(8); 182 | parsers.emplace_back(REGISTER_PARSER(parse_c, C, "C", "/**", " * ", " */", "\\", "int function(const char *ptr, int index)")); 183 | parsers.emplace_back(REGISTER_PARSER(parse_c, CPP, "C++", "/**", " * ", " */", "\\", "std::string function(const char *ptr, int &index)")); 184 | parsers.emplace_back(REGISTER_PARSER(parse_c, JAVA, "Java", "/**", " * ", " */", "@", "public boolean action(Event event, Object arg)")); 185 | parsers.emplace_back(REGISTER_PARSER(parse_python, PYTHON, "Python", "## ", "# ", "# ", "@", "def foo(bar, string=None)")); 186 | parsers.emplace_back(REGISTER_PARSER(parse_c, PHP, "PHP", "/**", " * ", " */", "@", "function myFunction($abc, $defg)")); 187 | parsers.emplace_back(REGISTER_PARSER(parse_c, JS, "JavaScript", "/**", " * ", " */", "@", "function myFunction(abc, defg)")); 188 | parsers.emplace_back(REGISTER_PARSER(parse_c, CS, "C#", "/// ", "/// ", "/// ", "\\", "public int Method(ref int abc, int defg)")); 189 | } 190 | 191 | void CleanUpParsers(void) 192 | { 193 | } 194 | 195 | void alignLines(std::vector &lines) 196 | { 197 | const char *flag = "$|"; 198 | unsigned int align_max = 0; 199 | 200 | // Find the max position the flag is found at 201 | for(unsigned int i = 0; i < lines.size(); ++i) 202 | { 203 | unsigned int pos = static_cast(lines[i].find(flag)); 204 | if(pos != std::string::npos) align_max = max(pos, align_max); 205 | } 206 | 207 | // Replace the flag with an appropriate number of spaces 208 | for(unsigned int i = 0; align_max != 0 && i < lines.size(); ++i) 209 | { 210 | unsigned int pos = static_cast(lines[i].find(flag)); 211 | lines[i].replace(pos, strlen(flag), align_max - pos, ' '); 212 | } 213 | } 214 | 215 | std::string FormatBlock(const ParserSettings *ps, Keywords& keywords, const std::string &format) 216 | { 217 | std::stringstream ss; 218 | std::vector lines; 219 | std::vector ¶ms = keywords.parameters; 220 | std::string format_copy(format); 221 | const char *eol = getEolStr(); 222 | 223 | stringReplace(format_copy, "$@", ps->command_prefix); 224 | 225 | // Replace keywords 226 | // Iterate the map backwards so that longer keywords are replaced first 227 | // Such as $DATE_d before $DATE 228 | for (auto iter = keywords.extras.crbegin(); iter != keywords.extras.crend(); ++iter) 229 | { 230 | stringReplace(format_copy, iter->first, iter->second); 231 | } 232 | 233 | lines = splitLines(format_copy, "\r\n"); 234 | 235 | for(unsigned int i = 0; i < lines.size(); ++i) 236 | { 237 | if(lines[i].find("$PARAM") != std::string::npos) 238 | { 239 | // Duplicate the current line for each $PARAM 240 | std::vector formatted_lines; 241 | for(unsigned int j = 0; j < params.size(); ++j) 242 | { 243 | // Make a copy of lines[i] before calling stringReplace 244 | std::string line = lines[i]; 245 | stringReplace(line, "$PARAM", params[j]); 246 | formatted_lines.push_back(line); 247 | } 248 | 249 | // If the align flag is set, align the lines, else remove all "$|" flags 250 | if(ps->align) 251 | alignLines(formatted_lines); 252 | else 253 | for(unsigned int j = 0; j < formatted_lines.size(); ++j) 254 | stringReplace(formatted_lines[j], "$|", ""); 255 | 256 | // Insert the lines 257 | for(unsigned int j = 0; j < formatted_lines.size(); ++j) 258 | { 259 | if(i == 0 && j == 0) 260 | ss << ps->doc_start << formatted_lines[j] << eol; 261 | else if(i == lines.size() - 1 && j == formatted_lines.size() - 1) 262 | ss << ps->doc_end << formatted_lines[j] << eol; 263 | else 264 | ss << ps->doc_line << formatted_lines[j] << eol; 265 | } 266 | } 267 | else 268 | { 269 | if(i == 0) 270 | ss << ps->doc_start << lines[i] << eol; 271 | else if(i == lines.size() -1) 272 | ss << ps->doc_end << lines[i]; 273 | else 274 | ss << ps->doc_line << lines[i] << eol; 275 | } 276 | } 277 | 278 | return ss.str(); 279 | } 280 | 281 | #define INFO_BUFFER_SIZE 2048 282 | 283 | void FillExtraKeywords(Keywords &kw) 284 | { 285 | wchar_t fileName[MAX_PATH]; 286 | char infoBuf[INFO_BUFFER_SIZE] = { 0 }; 287 | DWORD bufCharCount; 288 | 289 | bufCharCount = INFO_BUFFER_SIZE; 290 | if (GetComputerNameA(infoBuf, &bufCharCount)) 291 | kw.extras["$COMPUTER"] = infoBuf; 292 | 293 | bufCharCount = INFO_BUFFER_SIZE; 294 | if (GetUserNameA(infoBuf, &bufCharCount)) 295 | kw.extras["$USER"] = infoBuf; 296 | 297 | bufCharCount = INFO_BUFFER_SIZE; 298 | if (GetUserNameExA(NameDisplay, infoBuf, &bufCharCount)) 299 | kw.extras["$FULLUSER"] = infoBuf; 300 | else 301 | kw.extras["$FULLUSER"] = ""; 302 | 303 | time_t t = std::time(NULL); 304 | struct tm *ts = std::localtime(&t); 305 | const char* character = "aAbBcdHIjmMpSUwWxXyYzZ"; 306 | for (size_t uj = 0; uj < strlen(character); uj++) 307 | { 308 | char format[3] = { '%', character[uj], 0 }; 309 | char search[8] = { '$', 'D', 'A', 'T', 'E', '_', character[uj], 0 }; 310 | 311 | std::strftime(infoBuf, INFO_BUFFER_SIZE - 1, format, ts); 312 | kw.extras[search] = infoBuf; 313 | } 314 | 315 | std::strftime(infoBuf, INFO_BUFFER_SIZE - 1, "%Y-%m-%dT%H:%M:%S", ts); 316 | kw.extras["$DATE"] = infoBuf; 317 | 318 | // Make sure $FUNCTION exists even if it is just blank 319 | kw.extras["$FUNCTION"] = kw.function; 320 | 321 | SendNpp(NPPM_GETFILENAME, MAX_PATH, (LPARAM)fileName); 322 | kw.extras["$FILENAME"] = toString(fileName); 323 | } 324 | 325 | std::string FormatFileBlock(const ParserSettings *ps) 326 | { 327 | Keywords kw; 328 | 329 | FillExtraKeywords(kw); 330 | 331 | return FormatBlock(ps, kw, ps->file_format); 332 | } 333 | 334 | std::string FormatFunctionBlock(const Parser *p, const ParserSettings *ps, const char *text) 335 | { 336 | Keywords kw; 337 | 338 | if (!p->external) 339 | { 340 | kw = p->strategy(ps, text); 341 | if (kw.function.empty()) return std::string(); 342 | } 343 | 344 | FillExtraKeywords(kw); 345 | 346 | return FormatBlock(ps, kw, ps->function_format); 347 | } 348 | 349 | std::string GetFunctionToParse(void) 350 | { 351 | int found; 352 | auto p = getCurrentParser(); 353 | 354 | // External parsers are simple enough since they don't need any text to parse 355 | if (p->external) 356 | return std::string(); 357 | //return FormatFunctionBlock(p, &p->ps, nullptr); 358 | 359 | // Get the text until a closing parenthesis. Find '(' first 360 | if ((found = FindNext("(")) == INVALID_POSITION) 361 | { 362 | return std::string(); 363 | } 364 | 365 | // Do some sanity checking. Make sure curline <= found <= curline+2 366 | auto curLine = SendNpp(NPPM_GETCURRENTLINE); 367 | auto foundLine = editor.LineFromPosition(found); 368 | if (foundLine < curLine || foundLine > curLine + 2) 369 | { 370 | return std::string(); 371 | } 372 | 373 | // Find the matching closing brace 374 | if ((found = editor.BraceMatch(found, 0)) == INVALID_POSITION) 375 | { 376 | MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK | MB_ICONERROR); 377 | return std::string(); 378 | } 379 | 380 | return GetTextRange(editor.GetCurrentPos(), found + 1); 381 | } 382 | 383 | std::pair InsertDocumentationBlock(const std::string &block, const std::string &indentation) 384 | { 385 | int startLine = editor.LineFromPosition(editor.GetSelectionEnd()); 386 | 387 | int startPos = editor.GetSelectionStart(); 388 | editor.ReplaceSel(block.c_str()); 389 | int endPos = editor.GetCurrentPos(); 390 | 391 | if (!indentation.empty()) 392 | { 393 | InsertStringBeforeLines(indentation, startLine, editor.LineFromPosition(endPos) + 1); 394 | endPos = editor.GetCurrentPos(); 395 | } 396 | 397 | return std::make_pair(startPos, endPos); 398 | } 399 | -------------------------------------------------------------------------------- /src/Parsers/Parsers.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #ifndef PARSERS_H 20 | #define PARSERS_H 21 | 22 | #include "PluginDefinition.h" 23 | #include "Utils.h" 24 | #include "trex.h" 25 | #include 26 | #include 27 | 28 | // Default formats 29 | extern const char *default_function_format; 30 | extern const char *default_internal_function_format; 31 | extern const char *default_file_format; 32 | 33 | typedef struct { 34 | std::string function; 35 | std::vector parameters; 36 | std::map extras; 37 | } Keywords; 38 | 39 | // These are the settable fields in the parser 40 | // This makes it easier when changing settings in the dialog box 41 | typedef struct ParserSettings final 42 | { 43 | std::string doc_start; 44 | std::string doc_line; 45 | std::string doc_end; 46 | std::string command_prefix; 47 | std::string function_format; 48 | std::string file_format; 49 | bool align; 50 | } ParserSettings; 51 | 52 | typedef Keywords(*ParserStrategy)(const ParserSettings *ps, const char *text); 53 | 54 | class Parser final 55 | { 56 | public: 57 | int lang_type; 58 | std::wstring lang; // Short language name. Postfix of enum from lang_type 59 | std::wstring language_name; // User readable name 60 | std::string example; // Example function/method to parse for Settings Dialog 61 | bool external; // whether this is an internal or external(UDL||external lexer) 62 | 63 | ParserSettings ps; 64 | ParserStrategy strategy; 65 | 66 | // Don't judge me 67 | Parser(ParserStrategy st, int lt, std::wstring l, std::wstring ln, std::string e, std::string ds, std::string dl, std::string de, std::string cp) 68 | { 69 | strategy = st; 70 | lang_type = lt; 71 | lang = l; 72 | language_name = ln; 73 | example = e; 74 | external = false; 75 | ps.doc_start = ds; 76 | ps.doc_line = dl; 77 | ps.doc_end = de; 78 | ps.command_prefix = cp; 79 | ps.function_format = default_function_format; 80 | ps.file_format = default_file_format; 81 | ps.align = false; 82 | } 83 | 84 | Parser() {} 85 | }; 86 | 87 | extern std::vector parsers; 88 | 89 | const Parser *getParserByName(std::wstring name); 90 | const Parser *getCurrentParser(bool update=false); 91 | const ParserSettings *getCurrentParserSettings(); 92 | void addNewParser(std::string name, ParserSettings *ps = nullptr); 93 | 94 | void InitializeParsers(); 95 | void CleanUpParsers(); 96 | 97 | std::string FormatFunctionBlock(const Parser *p, const ParserSettings *ps, const char *text); 98 | std::string FormatFileBlock(const ParserSettings *ps); 99 | std::string GetFunctionToParse(void); 100 | std::pair InsertDocumentationBlock(const std::string &block, const std::string &indentation); 101 | 102 | // Simple class to make sure the regexs get cleaned up 103 | class TrRegex final { 104 | public: 105 | TRex *regex = nullptr; 106 | 107 | explicit TrRegex(const char *pattern) { 108 | const TRexChar *error = NULL; 109 | regex = trex_compile(pattern, &error); 110 | } 111 | 112 | ~TrRegex() { 113 | trex_free(regex); 114 | } 115 | }; 116 | 117 | Keywords parse_c(const ParserSettings *ps, const char *text); 118 | Keywords parse_python(const ParserSettings *ps, const char *text); 119 | Keywords parse_null(const ParserSettings *ps, const char *text); 120 | #endif 121 | -------------------------------------------------------------------------------- /src/Parsers/Python_Parser.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "Parsers.h" 20 | 21 | Keywords parse_python(const ParserSettings *ps, const char *text) 22 | { 23 | static TrRegex tr_function("def\\s+(\\w+)\\s*(\\([^)]*\\))"); 24 | static TrRegex tr_parameters("(\\w+)(\\s*=\\s*\\w+)?\\s*[,)]"); 25 | Keywords keywords; 26 | const TRexChar *begin, *end; 27 | 28 | if (trex_search(tr_function.regex, text, &begin, &end)) 29 | { 30 | //TRexMatch func_match; 31 | TRexMatch params_match, func_match; 32 | const TRexChar *cur_params; 33 | const TRexChar *p_begin, *p_end; 34 | 35 | trex_getsubexp(tr_function.regex, 1, &func_match); 36 | trex_getsubexp(tr_function.regex, 2, ¶ms_match); 37 | 38 | keywords.function = std::string(func_match.begin, func_match.len); 39 | 40 | // For each param 41 | cur_params = params_match.begin; 42 | while (trex_searchrange(tr_parameters.regex, cur_params, end, &p_begin, &p_end)) 43 | { 44 | TRexMatch param_match; 45 | trex_getsubexp(tr_parameters.regex, 1, ¶m_match); 46 | 47 | keywords.parameters.push_back(std::string(param_match.begin, param_match.len)); 48 | 49 | cur_params = p_end; 50 | } 51 | } 52 | 53 | return keywords; 54 | } 55 | -------------------------------------------------------------------------------- /src/PluginDefinition.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include 20 | #include 21 | 22 | #include "PluginDefinition.h" 23 | #include "Utils.h" 24 | #include "Parsers.h" 25 | #include "Version.h" 26 | #include "SettingsDialog.h" 27 | #include "AboutDialog.h" 28 | #include "JumpLocations.h" 29 | 30 | // --- Local variables --- 31 | static bool do_active_commenting; // active commenting - create or extend a document block 32 | //static bool do_active_wrapping; // active wrapping - wrap text inside of document blocks...todo 33 | 34 | static NppData nppData; 35 | static SettingsDialog sd; // The settings dialog 36 | static HANDLE _hModule; // For dialog initialization 37 | static HHOOK hook = NULL; 38 | static bool hasFocus = true; 39 | // --- Menu callbacks --- 40 | static void doxyItFunction(); 41 | static void doxyItFile(); 42 | static void activeCommenting(); 43 | //static void activeWrapping(); 44 | static void showSettings(); 45 | static void showAbout(); 46 | 47 | ScintillaEditor editor; 48 | 49 | // --- Global variables --- 50 | ShortcutKey sk = {true, true, true, 'D'}; 51 | FuncItem funcItem[nbFunc] = { 52 | {TEXT("Comment Function"), doxyItFunction, 0, false, &sk}, 53 | {TEXT("Comment File"), doxyItFile, 0, false, NULL}, 54 | {TEXT(""), NULL, 0, false, NULL}, // separator 55 | {TEXT("Active commenting"), activeCommenting, 0, false, NULL}, 56 | {TEXT(""), NULL, 0, false, NULL}, // separator 57 | {TEXT("Settings..."), showSettings, 0, false, NULL}, 58 | {TEXT("About..."), showAbout, 0, false, NULL} 59 | }; 60 | 61 | inline LRESULT SendNpp(UINT Msg, WPARAM wParam, LPARAM lParam) 62 | { 63 | return SendMessage(nppData._nppHandle, Msg, wParam, lParam); 64 | } 65 | 66 | static HWND getCurrentScintilla() 67 | { 68 | int which = 0; 69 | SendNpp(NPPM_GETCURRENTSCINTILLA, SCI_UNUSED, (LPARAM)&which); 70 | return (which == 0) ? nppData._scintillaMainHandle : nppData._scintillaSecondHandle; 71 | } 72 | 73 | // --- Configuration --- 74 | 75 | void getIniFilePath(wchar_t *iniPath, int size) 76 | { 77 | SendNpp(NPPM_GETPLUGINSCONFIGDIR, size, (LPARAM) iniPath); 78 | wcscat_s(iniPath, size, TEXT("\\")); 79 | wcscat_s(iniPath, size, NPP_PLUGIN_NAME); 80 | wcscat_s(iniPath, size, TEXT(".ini")); 81 | } 82 | 83 | void configSave() 84 | { 85 | wchar_t iniPath[MAX_PATH]; 86 | std::wstring ws; 87 | 88 | getIniFilePath(iniPath, MAX_PATH); 89 | 90 | // Completely delete the file 91 | DeleteFile(iniPath); 92 | 93 | // [DoxyIt] 94 | WritePrivateProfileString(NPP_PLUGIN_NAME, TEXT("active_commenting"), BOOLTOSTR(do_active_commenting), iniPath); 95 | WritePrivateProfileString(NPP_PLUGIN_NAME, TEXT("version"), VERSION_LINEAR_TEXT, iniPath); 96 | WritePrivateProfileString(NPP_PLUGIN_NAME, TEXT("version_stage"), VERSION_STAGE, iniPath); 97 | 98 | for(auto const &p : parsers) 99 | { 100 | const ParserSettings *ps = &(p.ps); 101 | 102 | // Wrap everything in quotes to preserve whitespace 103 | ws = TEXT("\"") + toWideString(ps->doc_start) + TEXT("\""); 104 | WritePrivateProfileString(p.lang.c_str(), TEXT("doc_start"), ws.c_str(), iniPath); 105 | 106 | ws = TEXT("\"") + toWideString(ps->doc_line) + TEXT("\""); 107 | WritePrivateProfileString(p.lang.c_str(), TEXT("doc_line_"), ws.c_str(), iniPath); 108 | 109 | ws = TEXT("\"") + toWideString(ps->doc_end) + TEXT("\""); 110 | WritePrivateProfileString(p.lang.c_str(), TEXT("doc_end__"), ws.c_str(), iniPath); 111 | 112 | ws = TEXT("\"") + toWideString(ps->command_prefix) + TEXT("\""); 113 | WritePrivateProfileString(p.lang.c_str(), TEXT("command_prefix"), ws.c_str(), iniPath); 114 | 115 | // Encode \r\n as literal "\r\n" in the ini file 116 | ws = TEXT("\"") + toWideString(stringReplace(std::string(ps->file_format), "\r\n", "\\r\\n")) + TEXT("\""); 117 | WritePrivateProfileString(p.lang.c_str(), TEXT("file_format"), ws.c_str(), iniPath); 118 | 119 | // Encode \r\n as literal "\r\n" in the ini file 120 | ws = TEXT("\"") + toWideString(stringReplace(std::string(ps->function_format), "\r\n", "\\r\\n")) + TEXT("\""); 121 | WritePrivateProfileString(p.lang.c_str(), TEXT("function_format"), ws.c_str(), iniPath); 122 | 123 | // Write out internal parser attributes 124 | if(!p.external) 125 | { 126 | WritePrivateProfileString(p.lang.c_str(), TEXT("align"), BOOLTOSTR(ps->align), iniPath); 127 | } 128 | else // add it to the list of external settings 129 | { 130 | WritePrivateProfileString(TEXT("External"), p.language_name.c_str(), TEXT(""), iniPath); 131 | } 132 | } 133 | } 134 | 135 | void configLoad() 136 | { 137 | wchar_t iniPath[MAX_PATH]; 138 | wchar_t tbuffer[2048]; // "relatively" large 139 | wchar_t tbuffer2[2048]; 140 | wchar_t *current; 141 | ParserSettings ps; 142 | 143 | getIniFilePath(iniPath, MAX_PATH); 144 | 145 | // [DoxyIt] 146 | GetPrivateProfileString(NPP_PLUGIN_NAME, TEXT("active_commenting"), TEXT("true"), tbuffer, MAX_PATH, iniPath); 147 | do_active_commenting = (lstrcmp(tbuffer, TEXT("true")) == 0); 148 | 149 | // NPPM_SETMENUITEMCHECK does not seem to work unless the 150 | // menu item is actually clicked, so lets do it manually 151 | if(do_active_commenting) CheckMenuItem(GetMenu(nppData._nppHandle), funcItem[3]._cmdID, MF_CHECKED); 152 | 153 | // Don't need these for now 154 | //version = GetPrivateProfileInt(NPP_PLUGIN_NAME, TEXT("version"), 0, iniPath); 155 | //version_stage = GetPrivateProfileString(NPP_PLUGIN_NAME, TEXT("version_stage"), TEXT(""), tbuffer, MAX_PATH, iniPath); 156 | 157 | for(auto &p : parsers) 158 | { 159 | // NOTE: We cant use the default value because GetPrivateProfileString strips the whitespace, 160 | // also, wrapping it in quotes doesn't seem to work either. So...use "!!!" as the default text 161 | // and if we find that the value wasn't found and we have "!!!" then use the default value in the 162 | // parser, else, use what we pulled from the file. 163 | GetPrivateProfileString(p.lang.c_str(), TEXT("doc_start"), TEXT("!!!"), tbuffer, 2048, iniPath); 164 | if(lstrcmp(tbuffer, TEXT("!!!")) != 0) p.ps.doc_start = toString(tbuffer); 165 | 166 | GetPrivateProfileString(p.lang.c_str(), TEXT("doc_line_"), TEXT("!!!"), tbuffer, 2048, iniPath); 167 | if(lstrcmp(tbuffer, TEXT("!!!")) != 0) p.ps.doc_line = toString(tbuffer); 168 | 169 | GetPrivateProfileString(p.lang.c_str(), TEXT("doc_end__"), TEXT("!!!"), tbuffer, 2048, iniPath); 170 | if(lstrcmp(tbuffer, TEXT("!!!")) != 0) p.ps.doc_end = toString(tbuffer); 171 | 172 | GetPrivateProfileString(p.lang.c_str(), TEXT("command_prefix"), TEXT("!!!"), tbuffer, 2048, iniPath); 173 | if(lstrcmp(tbuffer, TEXT("!!!")) != 0) p.ps.command_prefix = toString(tbuffer); 174 | 175 | GetPrivateProfileString(p.lang.c_str(), TEXT("function_format"), TEXT("!!!"), tbuffer, 2048, iniPath); 176 | if(lstrcmp(tbuffer, TEXT("!!!")) != 0) p.ps.function_format = stringReplace(toString(tbuffer), "\\r\\n", "\r\n"); 177 | 178 | GetPrivateProfileString(p.lang.c_str(), TEXT("file_format"), TEXT("!!!"), tbuffer, 2048, iniPath); 179 | if(lstrcmp(tbuffer, TEXT("!!!")) != 0) p.ps.file_format = stringReplace(toString(tbuffer), "\\r\\n", "\r\n"); 180 | 181 | GetPrivateProfileString(p.lang.c_str(), TEXT("align"), BOOLTOSTR(p.ps.align), tbuffer, 2048, iniPath); 182 | p.ps.align = (lstrcmp(tbuffer, TEXT("true")) == 0); 183 | } 184 | 185 | 186 | GetPrivateProfileSection(TEXT("External"), tbuffer, 2048, iniPath); 187 | current = tbuffer; 188 | while(current[0] != NULL) 189 | { 190 | wchar_t *equals = wcschr(current, TEXT('=')); 191 | 192 | // Temporarily remove the '=' that was found 193 | *equals = NULL; 194 | 195 | GetPrivateProfileString(current, TEXT("doc_start"), TEXT("/**"), tbuffer2, 2048, iniPath); 196 | ps.doc_start = toString(tbuffer2); 197 | 198 | GetPrivateProfileString(current, TEXT("doc_line_"), TEXT(" * "), tbuffer2, 2048, iniPath); 199 | ps.doc_line = toString(tbuffer2); 200 | 201 | GetPrivateProfileString(current, TEXT("doc_end__"), TEXT(" */"), tbuffer2, 2048, iniPath); 202 | ps.doc_end = toString(tbuffer2); 203 | 204 | GetPrivateProfileString(current, TEXT("command_prefix"), TEXT("\\"), tbuffer2, 2048, iniPath); 205 | ps.command_prefix = toString(tbuffer2); 206 | 207 | GetPrivateProfileString(current, TEXT("function_format"), TEXT("!!!"), tbuffer2, 2048, iniPath); 208 | if(lstrcmp(tbuffer2, TEXT("!!!")) != 0) ps.function_format = stringReplace(toString(tbuffer2), "\\r\\n", "\r\n"); 209 | else ps.function_format = default_internal_function_format; 210 | 211 | GetPrivateProfileString(current, TEXT("file_format"), TEXT("!!!"), tbuffer2, 2048, iniPath); 212 | if(lstrcmp(tbuffer2, TEXT("!!!")) != 0) ps.file_format = stringReplace(toString(tbuffer2), "\\r\\n", "\r\n"); 213 | else ps.file_format = default_file_format; 214 | 215 | addNewParser(toString(current), &ps); 216 | 217 | // add back in the equals so we can correctly calculate the length 218 | *equals = TEXT('='); 219 | 220 | current = ¤t[lstrlen(current) + 1]; 221 | } 222 | } 223 | 224 | void pluginInit(HANDLE hModule) 225 | { 226 | _hModule = hModule; 227 | } 228 | 229 | void pluginCleanUp() 230 | { 231 | } 232 | 233 | void setNppInfo(NppData notepadPlusData) 234 | { 235 | nppData = notepadPlusData; 236 | 237 | // Set this as early as possible so its in a valid state 238 | editor.SetScintillaInstance(nppData._scintillaMainHandle); 239 | 240 | sd.init((HINSTANCE) _hModule, nppData); 241 | } 242 | 243 | 244 | // --- Menu call backs --- 245 | 246 | void doxyItFunction() 247 | { 248 | const Parser *p; 249 | if (!(p = getCurrentParser())) 250 | { 251 | MessageBox(NULL, TEXT("Unrecognized language type."), NPP_PLUGIN_NAME, MB_OK | MB_ICONERROR); 252 | return; 253 | } 254 | 255 | std::string text = GetFunctionToParse(); 256 | 257 | // External parsers have no text to parse 258 | if (!p->external && text.empty()) 259 | { 260 | MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK | MB_ICONERROR); 261 | return; 262 | } 263 | 264 | std::string doc_block = FormatFunctionBlock(p, &p->ps, text.c_str()); 265 | 266 | if (doc_block.length() == 0) 267 | { 268 | MessageBox(NULL, TEXT("Error: Cannot parse function definition. Make sure the cursor is on the line directly above the function or method definition."), NPP_PLUGIN_NAME, MB_OK | MB_ICONERROR); 269 | return; 270 | } 271 | 272 | editor.BeginUndoAction(); 273 | 274 | auto indentation = GetLineIndentString(editor.LineFromPosition(editor.GetSelectionEnd()) + 1); 275 | auto range = InsertDocumentationBlock(doc_block, indentation); 276 | ProcessTextRangeForNewJumpLocations(range.first, range.second); 277 | 278 | editor.EndUndoAction(); 279 | } 280 | 281 | void doxyItFile() 282 | { 283 | std::string doc_block; 284 | const ParserSettings *ps; 285 | 286 | ps = getCurrentParserSettings(); 287 | if(!ps) 288 | { 289 | MessageBox(NULL, TEXT("Unrecognized language type."), NPP_PLUGIN_NAME, MB_OK|MB_ICONERROR); 290 | return; 291 | } 292 | 293 | doc_block = FormatFileBlock(ps); 294 | 295 | editor.BeginUndoAction(); 296 | 297 | auto range = InsertDocumentationBlock(doc_block, std::string("")); 298 | ProcessTextRangeForNewJumpLocations(range.first, range.second); 299 | 300 | editor.EndUndoAction(); 301 | } 302 | 303 | void activeCommenting() 304 | { 305 | do_active_commenting = !do_active_commenting; 306 | SendNpp(NPPM_SETMENUITEMCHECK, funcItem[3]._cmdID, (LPARAM) do_active_commenting); 307 | } 308 | 309 | void showSettings() 310 | { 311 | sd.doDialog(); 312 | } 313 | 314 | static void showAbout() { 315 | HWND hSelf = CreateDialogParam((HINSTANCE)_hModule, MAKEINTRESOURCE(IDD_ABOUTDLG), nppData._nppHandle, (DLGPROC)abtDlgProc, (LPARAM)NULL); 316 | 317 | // Go to center 318 | RECT rc; 319 | ::GetClientRect(nppData._nppHandle, &rc); 320 | POINT center; 321 | int w = rc.right - rc.left; 322 | int h = rc.bottom - rc.top; 323 | center.x = rc.left + w / 2; 324 | center.y = rc.top + h / 2; 325 | ::ClientToScreen(nppData._nppHandle, ¢er); 326 | 327 | RECT dlgRect; 328 | ::GetClientRect(hSelf, &dlgRect); 329 | int x = center.x - (dlgRect.right - dlgRect.left) / 2; 330 | int y = center.y - (dlgRect.bottom - dlgRect.top) / 2; 331 | 332 | ::SetWindowPos(hSelf, HWND_TOP, x, y, (dlgRect.right - dlgRect.left), (dlgRect.bottom - dlgRect.top), SWP_SHOWWINDOW); 333 | } 334 | 335 | // trim from start (in place) 336 | static inline void ltrim(std::string &s) { 337 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { 338 | return !std::isspace(ch); 339 | })); 340 | } 341 | 342 | // trim from end (in place) 343 | static inline void rtrim(std::string &s) { 344 | s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { 345 | return !std::isspace(ch); 346 | }).base(), s.end()); 347 | } 348 | 349 | // trim from both ends (in place) 350 | static inline void trim(std::string &s) { 351 | ltrim(s); 352 | rtrim(s); 353 | } 354 | 355 | // trim from start (copying) 356 | static inline std::string ltrim_copy(std::string s) { 357 | ltrim(s); 358 | return s; 359 | } 360 | 361 | // trim from end (copying) 362 | static inline std::string rtrim_copy(std::string s) { 363 | rtrim(s); 364 | return s; 365 | } 366 | 367 | // trim from both ends (copying) 368 | static inline std::string trim_copy(std::string s) { 369 | trim(s); 370 | return s; 371 | } 372 | 373 | 374 | // --- Notification callbacks --- 375 | 376 | void doxyItNewLine() 377 | { 378 | std::string indentation; 379 | const ParserSettings *ps; 380 | const char *eol; 381 | size_t found; 382 | int curLine; 383 | 384 | ps = getCurrentParserSettings(); 385 | if(!ps) return; 386 | 387 | eol = getEolStr(); 388 | 389 | curLine = static_cast(SendNpp(NPPM_GETCURRENTLINE)); 390 | 391 | std::string previousLine = editor.GetLine(curLine - 1); 392 | std::string nextLine = editor.GetLine(curLine + 1); 393 | 394 | // NOTE: we cannot use getLineIndentStr() because doc_start or doc_line may start with whitespace 395 | // which we don't want counted towards the indentation string. 396 | 397 | if((found = previousLine.find(ps->doc_line)) != std::string::npos) 398 | { 399 | indentation.append(previousLine.substr(0, found)); 400 | 401 | // doc_line should have only whitespace in front of it 402 | if(isWhiteSpace(indentation)) 403 | { 404 | editor.BeginUndoAction(); 405 | editor.DelLineLeft(); // Clear any automatic indentation 406 | editor.ReplaceSel(indentation.c_str()); 407 | editor.ReplaceSel(ps->doc_line.c_str()); 408 | editor.EndUndoAction(); 409 | editor.ChooseCaretX(); 410 | } 411 | 412 | } 413 | // If doc_start is relatively long we do not want the user typing the entire line, just the first 3 should suffice. 414 | // Also, if doc_end is found, this means a doc block was closed. This allows e.g. /** inline comments */ 415 | else if((found = previousLine.find(ps->doc_start.substr(0, 3))) != std::string::npos && 416 | previousLine.find(ps->doc_end.c_str()) == std::string::npos) 417 | { 418 | indentation.append(previousLine.substr(0, found)); 419 | 420 | if(isWhiteSpace(indentation)) 421 | { 422 | bool wasTriggeredAboveFunction = !GetFunctionToParse().empty(); 423 | 424 | if (wasTriggeredAboveFunction) 425 | { 426 | // The new block was triggered above a function, so do all that magic 427 | editor.DelLineLeft(); // Clear any automatic indentation 428 | editor.CharLeft(); // Back up over the new line 429 | editor.LineDelete(); // Clear the entire line 430 | doxyItFunction(); 431 | } 432 | else if (nextLine.find(ps->doc_line) != std::string::npos) 433 | { 434 | // Just extend the doc block 435 | editor.BeginUndoAction(); 436 | editor.DelLineLeft(); // Clear any automatic indentation 437 | editor.ReplaceSel(indentation.c_str()); 438 | editor.ReplaceSel(ps->doc_line.c_str()); 439 | editor.EndUndoAction(); 440 | editor.ChooseCaretX(); 441 | } 442 | else 443 | { 444 | int pos; 445 | unsigned int i = 0; 446 | 447 | // Count the characters in common so we can add the rest 448 | while (i < ps->doc_start.length() && previousLine.at(found + i) == ps->doc_start.at(i)) ++i; 449 | 450 | // Just open a blank block 451 | editor.BeginUndoAction(); 452 | editor.DelLineLeft(); // Clear any automatic indentation 453 | editor.DeleteBack(); // Clear the newline 454 | editor.ReplaceSel(&ps->doc_start.c_str()[i]); // Fill the rest of doc_start 455 | editor.ReplaceSel(eol); 456 | editor.ReplaceSel(indentation); 457 | editor.ReplaceSel(ps->doc_line); 458 | pos = editor.GetCurrentPos(); // Save this position so we can restore it 459 | editor.LineEnd(); // Skip any text the user carried to next line 460 | editor.ReplaceSel(eol); 461 | editor.ReplaceSel(indentation); 462 | editor.ReplaceSel(ps->doc_end); 463 | editor.EndUndoAction(); 464 | editor.ChooseCaretX(); 465 | 466 | // Restore the position 467 | editor.GotoPos(pos); 468 | } 469 | } 470 | } 471 | } 472 | 473 | LRESULT CALLBACK KeyboardProc(int ncode, WPARAM wparam, LPARAM lparam) 474 | { 475 | if (ncode == HC_ACTION) 476 | { 477 | if ((HIWORD(lparam) & KF_UP) == 0) 478 | { 479 | if (hasFocus) 480 | { 481 | if (!(GetKeyState(VK_SHIFT) & KF_UP) && !(GetKeyState(VK_CONTROL) & KF_UP) && !(GetKeyState(VK_MENU) & KF_UP)) 482 | { 483 | if (wparam == VK_TAB) 484 | { 485 | if (GoToNextJumpLocation(editor.GetCurrentPos())) 486 | return TRUE; // This key has been "handled" and won't propogate 487 | } 488 | else if (wparam == VK_ESCAPE) 489 | { 490 | ClearJumpLocations(); 491 | } 492 | } 493 | } 494 | } 495 | } 496 | return CallNextHookEx(hook, ncode, wparam, lparam); //pass control to next hook in the hook chain. 497 | } 498 | 499 | void handleNotification(SCNotification *notifyCode) 500 | { 501 | static bool do_newline = false; 502 | Sci_NotifyHeader nh = notifyCode->nmhdr; 503 | int ch = notifyCode->ch; 504 | 505 | switch(nh.code) 506 | { 507 | case SCN_UPDATEUI: // Now is when we can check to see if we do the commenting 508 | if (do_newline) 509 | { 510 | do_newline = false; 511 | doxyItNewLine(); 512 | } 513 | break; 514 | case SCN_CHARADDED: 515 | // Set a flag so that all line endings can trigger the commenting 516 | if((ch == '\r' || ch == '\n') && do_active_commenting) do_newline = true; 517 | break; 518 | case SCN_FOCUSIN: 519 | hasFocus = true; 520 | break; 521 | case SCN_FOCUSOUT: 522 | hasFocus = false; 523 | break; 524 | case NPPN_READY: 525 | InitializeParsers(); 526 | configLoad(); 527 | getCurrentParser(true); 528 | hook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, (HINSTANCE)_hModule, ::GetCurrentThreadId()); 529 | SendMessage(nppData._scintillaMainHandle, SCI_INDICSETSTYLE, JUMPLOCATION_INDICATOR, INDIC_DOTBOX); 530 | SendMessage(nppData._scintillaSecondHandle, SCI_INDICSETSTYLE, JUMPLOCATION_INDICATOR, INDIC_DOTBOX); 531 | SendMessage(nppData._scintillaMainHandle , SCI_INDICSETALPHA, JUMPLOCATION_INDICATOR, 30); 532 | SendMessage(nppData._scintillaSecondHandle, SCI_INDICSETALPHA, JUMPLOCATION_INDICATOR, 30); 533 | SendMessage(nppData._scintillaMainHandle , SCI_INDICSETOUTLINEALPHA, JUMPLOCATION_INDICATOR, 180); 534 | SendMessage(nppData._scintillaSecondHandle, SCI_INDICSETOUTLINEALPHA, JUMPLOCATION_INDICATOR, 180); 535 | break; 536 | case NPPN_SHUTDOWN: 537 | configSave(); 538 | CleanUpParsers(); 539 | if (hook != NULL) UnhookWindowsHookEx(hook); 540 | break; 541 | case NPPN_BUFFERACTIVATED: 542 | editor.SetScintillaInstance(getCurrentScintilla()); 543 | /* fall though */ 544 | case NPPN_LANGCHANGED: 545 | // Don't actually need the parser here, but this forces it to updates the current reference 546 | getCurrentParser(true); 547 | break; 548 | } 549 | return; 550 | } 551 | -------------------------------------------------------------------------------- /src/PluginDefinition.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #ifndef PLUGINDEFINITION_H 20 | #define PLUGINDEFINITION_H 21 | 22 | #include 23 | #include "PluginInterface.h" 24 | #include "ScintillaEditor.h" 25 | 26 | const wchar_t NPP_PLUGIN_NAME[] = TEXT("DoxyIt"); 27 | const int nbFunc = 7; 28 | 29 | // --- Helper functions --- 30 | 31 | extern ScintillaEditor editor; 32 | 33 | LRESULT SendNpp(UINT Msg, WPARAM wParam=SCI_UNUSED, LPARAM lParam=SCI_UNUSED); 34 | 35 | // Calls from DoxyIt.cpp 36 | void pluginInit(HANDLE hModule); // Called from DllMain, DLL_PROCESS_ATTACH 37 | void pluginCleanUp(); // Called from DllMain, DLL_PROCESS_DETACH 38 | void setNppInfo(NppData notepadPlusData); // Called from setInfo() 39 | void handleNotification(SCNotification *notifyCode); // Called from beNotified() 40 | 41 | #endif //PLUGINDEFINITION_H 42 | -------------------------------------------------------------------------------- /src/Utilities/Utils.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #include "PluginDefinition.h" 20 | #include "Utils.h" 21 | 22 | std::string GetTextRange(int start, int end) { 23 | if (end <= start) return std::string(); 24 | 25 | std::vector buffer(end - start + 1); 26 | Sci_TextRange tr; 27 | tr.chrg.cpMin = start; 28 | tr.chrg.cpMax = end; 29 | tr.lpstrText = buffer.data(); 30 | 31 | editor.GetTextRange(&tr); 32 | 33 | return std::string(buffer.begin(), buffer.end() - 1); // don't copy the null 34 | } 35 | 36 | // Clears the line 37 | void ClearLine(int line) 38 | { 39 | auto lineStart = editor.PositionFromLine(line); 40 | auto lineEnd = editor.GetLineEndPosition(line); 41 | 42 | editor.SetSel(lineStart, lineEnd); 43 | editor.ReplaceSel(""); 44 | } 45 | 46 | // Get the whitespace of the line, the returned value must be free'd 47 | std::string GetLineIndentString(int line) 48 | { 49 | int indentStart = editor.PositionFromLine(line); 50 | int indentEnd = editor.GetLineIndentPosition(line); 51 | 52 | return GetTextRange(indentStart, indentEnd); 53 | } 54 | 55 | // Insert str in front of each line between start and end 56 | // If the line already starts with the string it is skipped unless force = true 57 | void InsertStringBeforeLines(const std::string &str, int start, int end, bool force) 58 | { 59 | for(int i = start; i < end; ++i) 60 | { 61 | int lineStart = editor.PositionFromLine(i); 62 | 63 | // force=true will always insert the text in front of the line 64 | // force=false will only insert it if the line doesnt start with str 65 | if(force) 66 | { 67 | editor.InsertText(lineStart, str.c_str()); 68 | } 69 | else 70 | { 71 | std::string buffer = GetTextRange(lineStart, lineStart + static_cast(str.length())); 72 | if (buffer.compare(0, str.length(), str) != 0) 73 | { 74 | editor.InsertText(lineStart, str.c_str()); 75 | } 76 | } 77 | } 78 | } 79 | 80 | // Find the next instance of text 81 | int FindNext(char* text, int len, bool regExp) 82 | { 83 | int curPos = editor.GetCurrentPos(); 84 | int flags = (regExp ? SCFIND_REGEXP : 0); 85 | 86 | Sci_TextToFind ttf; 87 | ttf.chrg.cpMin = curPos; 88 | ttf.chrg.cpMax = curPos + len; 89 | ttf.lpstrText = text; 90 | 91 | return editor.FindText(flags, &ttf); 92 | } 93 | 94 | std::pair FindInRange(const char *text, int start, int stop, bool regExp) 95 | { 96 | Sci_TextToFind ttf; 97 | ttf.chrg.cpMin = start; 98 | ttf.chrg.cpMax = stop; 99 | ttf.lpstrText = text; 100 | 101 | int flags = (regExp ? SCFIND_REGEXP : 0); 102 | 103 | if (editor.FindText(flags, &ttf) != INVALID_POSITION) 104 | return std::make_pair(ttf.chrgText.cpMin, ttf.chrgText.cpMax); 105 | 106 | return std::make_pair(INVALID_POSITION, INVALID_POSITION); 107 | } 108 | 109 | // Get the end of line string for the current eol mode 110 | const char *getEolStr() 111 | { 112 | static char *eol[] = {"\r\n", "\r", "\n"}; 113 | auto eolmode = editor.GetEOLMode(); 114 | return eol[eolmode]; 115 | } 116 | 117 | std::wstring toWideString(std::string s) 118 | { 119 | return std::wstring(s.begin(), s.end()); 120 | } 121 | 122 | std::string toString(const wchar_t *w) 123 | { 124 | std::wstring wide(w); 125 | return std::string(wide.begin(), wide.end()); 126 | } 127 | 128 | bool isWhiteSpace(const std::string& str) 129 | { 130 | for(unsigned int i = 0; i < str.length(); ++i) 131 | if(!isspace(str[i])) 132 | return false; 133 | return true; 134 | } 135 | 136 | // Changes str in place and also returns it 137 | std::string& stringReplace(std::string& str, const std::string& oldStr, const std::string& newStr) 138 | { 139 | size_t pos = 0; 140 | while((pos = str.find(oldStr, pos)) != std::string::npos) 141 | { 142 | str.replace(pos, oldStr.length(), newStr); 143 | pos += newStr.length(); 144 | } 145 | return str; 146 | } 147 | 148 | std::vector splitLines(const std::string &str, const std::string &split) 149 | { 150 | std::vector lines; 151 | size_t prev_pos = 0, pos = 0; 152 | 153 | while((pos = str.find(split, pos)) != std::string::npos) 154 | { 155 | lines.push_back(str.substr(prev_pos, pos - prev_pos)); 156 | prev_pos = pos = pos + split.length(); 157 | } 158 | // Get the final line 159 | lines.push_back(str.substr(prev_pos, std::string::npos)); 160 | 161 | return lines; 162 | } 163 | -------------------------------------------------------------------------------- /src/Utilities/Utils.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #ifndef UTILS_H 20 | #define UTILS_H 21 | 22 | #include 23 | 24 | #define BOOLTOSTR(b) ((b) ? TEXT("true") : TEXT("false")) 25 | 26 | // Scintilla Utilities 27 | std::string GetTextRange(int start, int end); 28 | void ClearLine(int line); 29 | std::string GetLineIndentString(int line); 30 | void InsertStringBeforeLines(const std::string &str, int start, int end, bool force = false); 31 | int FindNext(char* text, int len=200, bool regExp=false); 32 | std::pair FindInRange(const char *text, int start, int stop, bool regExp = false); 33 | const char *getEolStr(); 34 | 35 | // Generic string utilites 36 | std::wstring toWideString(std::string s); 37 | std::string toString(const wchar_t *w); 38 | bool isWhiteSpace(const std::string& str); 39 | std::string& stringReplace(std::string& str, const std::string& oldStr, const std::string& newStr); 40 | std::vector splitLines(const std::string &str, const std::string &split); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/Utilities/trex.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************** 2 | T-Rex a tiny regular expression library 3 | 4 | Copyright (C) 2003-2006 Alberto Demichelis 5 | 6 | This software is provided 'as-is', without any express 7 | or implied warranty. In no event will the authors be held 8 | liable for any damages arising from the use of this software. 9 | 10 | Permission is granted to anyone to use this software for 11 | any purpose, including commercial applications, and to alter 12 | it and redistribute it freely, subject to the following restrictions: 13 | 14 | 1. The origin of this software must not be misrepresented; 15 | you must not claim that you wrote the original software. 16 | If you use this software in a product, an acknowledgment 17 | in the product documentation would be appreciated but 18 | is not required. 19 | 20 | 2. Altered source versions must be plainly marked as such, 21 | and must not be misrepresented as being the original software. 22 | 23 | 3. This notice may not be removed or altered from any 24 | source distribution. 25 | 26 | ****************************************************************/ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "trex.h" 33 | 34 | //#ifdef _UNICODE 35 | //#define scisprint iswprint 36 | //#define scstrlen wcslen 37 | //#define scprintf wprintf 38 | //#define _SC(x) TEXT(x) 39 | //#else 40 | #define scisprint isprint 41 | #define scstrlen strlen 42 | #define scprintf printf 43 | #define _SC(x) (x) 44 | //#endif 45 | 46 | #ifdef _DEBUG 47 | #include 48 | 49 | static const TRexChar *g_nnames[] = 50 | { 51 | _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), 52 | _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), 53 | _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), 54 | _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") 55 | }; 56 | 57 | #endif 58 | #define OP_GREEDY (MAX_CHAR+1) // * + ? {n} 59 | #define OP_OR (MAX_CHAR+2) 60 | #define OP_EXPR (MAX_CHAR+3) //parentesis () 61 | #define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) 62 | #define OP_DOT (MAX_CHAR+5) 63 | #define OP_CLASS (MAX_CHAR+6) 64 | #define OP_CCLASS (MAX_CHAR+7) 65 | #define OP_NCLASS (MAX_CHAR+8) //negates class the [^ 66 | #define OP_RANGE (MAX_CHAR+9) 67 | #define OP_CHAR (MAX_CHAR+10) 68 | #define OP_EOL (MAX_CHAR+11) 69 | #define OP_BOL (MAX_CHAR+12) 70 | #define OP_WB (MAX_CHAR+13) 71 | 72 | #define TREX_SYMBOL_ANY_CHAR ('.') 73 | #define TREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') 74 | #define TREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') 75 | #define TREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') 76 | #define TREX_SYMBOL_BRANCH ('|') 77 | #define TREX_SYMBOL_END_OF_STRING ('$') 78 | #define TREX_SYMBOL_BEGINNING_OF_STRING ('^') 79 | #define TREX_SYMBOL_ESCAPE_CHAR ('\\') 80 | 81 | 82 | typedef int TRexNodeType; 83 | 84 | typedef struct tagTRexNode{ 85 | TRexNodeType type; 86 | int left; 87 | int right; 88 | int next; 89 | }TRexNode; 90 | 91 | struct TRex{ 92 | const TRexChar *_eol; 93 | const TRexChar *_bol; 94 | const TRexChar *_p; 95 | int _first; 96 | int _op; 97 | TRexNode *_nodes; 98 | int _nallocated; 99 | int _nsize; 100 | int _nsubexpr; 101 | TRexMatch *_matches; 102 | int _currsubexp; 103 | void *_jmpbuf; 104 | const TRexChar **_error; 105 | }; 106 | 107 | static int trex_list(TRex *exp); 108 | 109 | static int trex_newnode(TRex *exp, TRexNodeType type) 110 | { 111 | TRexNode n; 112 | int newid; 113 | n.type = type; 114 | n.next = n.right = n.left = -1; 115 | if(type == OP_EXPR) 116 | n.right = exp->_nsubexpr++; 117 | if(exp->_nallocated < (exp->_nsize + 1)) { 118 | int oldsize = exp->_nallocated; 119 | exp->_nallocated *= 2; 120 | exp->_nodes = (TRexNode *)realloc(exp->_nodes, exp->_nallocated * sizeof(TRexNode)); 121 | } 122 | exp->_nodes[exp->_nsize++] = n; 123 | newid = exp->_nsize - 1; 124 | return (int)newid; 125 | } 126 | 127 | static void trex_error(TRex *exp,const TRexChar *error) 128 | { 129 | if(exp->_error) *exp->_error = error; 130 | longjmp(*((jmp_buf*)exp->_jmpbuf),-1); 131 | } 132 | 133 | static void trex_expect(TRex *exp, int n){ 134 | if((*exp->_p) != n) 135 | trex_error(exp, _SC("expected paren")); 136 | exp->_p++; 137 | } 138 | 139 | static TRexChar trex_escapechar(TRex *exp) 140 | { 141 | if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR){ 142 | exp->_p++; 143 | switch(*exp->_p) { 144 | case 'v': exp->_p++; return '\v'; 145 | case 'n': exp->_p++; return '\n'; 146 | case 't': exp->_p++; return '\t'; 147 | case 'r': exp->_p++; return '\r'; 148 | case 'f': exp->_p++; return '\f'; 149 | default: return (*exp->_p++); 150 | } 151 | } else if(!scisprint(*exp->_p)) trex_error(exp,_SC("letter expected")); 152 | return (*exp->_p++); 153 | } 154 | 155 | static int trex_charclass(TRex *exp,int classid) 156 | { 157 | int n = trex_newnode(exp,OP_CCLASS); 158 | exp->_nodes[n].left = classid; 159 | return n; 160 | } 161 | 162 | static int trex_charnode(TRex *exp,TRexBool isclass) 163 | { 164 | TRexChar t; 165 | if(*exp->_p == TREX_SYMBOL_ESCAPE_CHAR) { 166 | exp->_p++; 167 | switch(*exp->_p) { 168 | case 'n': exp->_p++; return trex_newnode(exp,'\n'); 169 | case 't': exp->_p++; return trex_newnode(exp,'\t'); 170 | case 'r': exp->_p++; return trex_newnode(exp,'\r'); 171 | case 'f': exp->_p++; return trex_newnode(exp,'\f'); 172 | case 'v': exp->_p++; return trex_newnode(exp,'\v'); 173 | case 'a': case 'A': case 'w': case 'W': case 's': case 'S': 174 | case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': 175 | case 'p': case 'P': case 'l': case 'u': 176 | { 177 | t = *exp->_p; exp->_p++; 178 | return trex_charclass(exp,t); 179 | } 180 | case 'b': 181 | case 'B': 182 | if(!isclass) { 183 | int node = trex_newnode(exp,OP_WB); 184 | exp->_nodes[node].left = *exp->_p; 185 | exp->_p++; 186 | return node; 187 | } //else default 188 | default: 189 | t = *exp->_p; exp->_p++; 190 | return trex_newnode(exp,t); 191 | } 192 | } 193 | else if(!scisprint(*exp->_p)) { 194 | 195 | trex_error(exp,_SC("letter expected")); 196 | } 197 | t = *exp->_p; exp->_p++; 198 | return trex_newnode(exp,t); 199 | } 200 | static int trex_class(TRex *exp) 201 | { 202 | int ret = -1; 203 | int first = -1,chain; 204 | if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING){ 205 | ret = trex_newnode(exp,OP_NCLASS); 206 | exp->_p++; 207 | }else ret = trex_newnode(exp,OP_CLASS); 208 | 209 | if(*exp->_p == ']') trex_error(exp,_SC("empty class")); 210 | chain = ret; 211 | while(*exp->_p != ']' && exp->_p != exp->_eol) { 212 | if(*exp->_p == '-' && first != -1){ 213 | int r,t; 214 | if(*exp->_p++ == ']') trex_error(exp,_SC("unfinished range")); 215 | r = trex_newnode(exp,OP_RANGE); 216 | if(first>*exp->_p) trex_error(exp,_SC("invalid range")); 217 | if(exp->_nodes[first].type == OP_CCLASS) trex_error(exp,_SC("cannot use character classes in ranges")); 218 | exp->_nodes[r].left = exp->_nodes[first].type; 219 | t = trex_escapechar(exp); 220 | exp->_nodes[r].right = t; 221 | exp->_nodes[chain].next = r; 222 | chain = r; 223 | first = -1; 224 | } 225 | else{ 226 | if(first!=-1){ 227 | int c = first; 228 | exp->_nodes[chain].next = c; 229 | chain = c; 230 | first = trex_charnode(exp,TRex_True); 231 | } 232 | else{ 233 | first = trex_charnode(exp,TRex_True); 234 | } 235 | } 236 | } 237 | if(first!=-1){ 238 | int c = first; 239 | exp->_nodes[chain].next = c; 240 | chain = c; 241 | first = -1; 242 | } 243 | /* hack? */ 244 | exp->_nodes[ret].left = exp->_nodes[ret].next; 245 | exp->_nodes[ret].next = -1; 246 | return ret; 247 | } 248 | 249 | static int trex_parsenumber(TRex *exp) 250 | { 251 | int ret = *exp->_p-'0'; 252 | int positions = 10; 253 | exp->_p++; 254 | while(isdigit(*exp->_p)) { 255 | ret = ret*10+(*exp->_p++-'0'); 256 | if(positions==1000000000) trex_error(exp,_SC("overflow in numeric constant")); 257 | positions *= 10; 258 | }; 259 | return ret; 260 | } 261 | 262 | static int trex_element(TRex *exp) 263 | { 264 | int ret = -1; 265 | switch(*exp->_p) 266 | { 267 | case '(': { 268 | int expr,newn; 269 | exp->_p++; 270 | 271 | 272 | if(*exp->_p =='?') { 273 | exp->_p++; 274 | trex_expect(exp,':'); 275 | expr = trex_newnode(exp,OP_NOCAPEXPR); 276 | } 277 | else 278 | expr = trex_newnode(exp,OP_EXPR); 279 | newn = trex_list(exp); 280 | exp->_nodes[expr].left = newn; 281 | ret = expr; 282 | trex_expect(exp,')'); 283 | } 284 | break; 285 | case '[': 286 | exp->_p++; 287 | ret = trex_class(exp); 288 | trex_expect(exp,']'); 289 | break; 290 | case TREX_SYMBOL_END_OF_STRING: exp->_p++; ret = trex_newnode(exp,OP_EOL);break; 291 | case TREX_SYMBOL_ANY_CHAR: exp->_p++; ret = trex_newnode(exp,OP_DOT);break; 292 | default: 293 | ret = trex_charnode(exp,TRex_False); 294 | break; 295 | } 296 | 297 | { 298 | int op; 299 | TRexBool isgreedy = TRex_False; 300 | unsigned short p0 = 0, p1 = 0; 301 | switch(*exp->_p){ 302 | case TREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break; 303 | case TREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = TRex_True; break; 304 | case TREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = TRex_True; break; 305 | case '{': 306 | exp->_p++; 307 | if(!isdigit(*exp->_p)) trex_error(exp,_SC("number expected")); 308 | p0 = (unsigned short)trex_parsenumber(exp); 309 | /*******************************/ 310 | switch(*exp->_p) { 311 | case '}': 312 | p1 = p0; exp->_p++; 313 | break; 314 | case ',': 315 | exp->_p++; 316 | p1 = 0xFFFF; 317 | if(isdigit(*exp->_p)){ 318 | p1 = (unsigned short)trex_parsenumber(exp); 319 | } 320 | trex_expect(exp,'}'); 321 | break; 322 | default: 323 | trex_error(exp,_SC(", or } expected")); 324 | } 325 | /*******************************/ 326 | isgreedy = TRex_True; 327 | break; 328 | 329 | } 330 | if(isgreedy) { 331 | int nnode = trex_newnode(exp,OP_GREEDY); 332 | op = OP_GREEDY; 333 | exp->_nodes[nnode].left = ret; 334 | exp->_nodes[nnode].right = ((p0)<<16)|p1; 335 | ret = nnode; 336 | } 337 | } 338 | if((*exp->_p != TREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != TREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != TREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { 339 | int nnode = trex_element(exp); 340 | exp->_nodes[ret].next = nnode; 341 | } 342 | 343 | return ret; 344 | } 345 | 346 | static int trex_list(TRex *exp) 347 | { 348 | int ret=-1,e; 349 | if(*exp->_p == TREX_SYMBOL_BEGINNING_OF_STRING) { 350 | exp->_p++; 351 | ret = trex_newnode(exp,OP_BOL); 352 | } 353 | e = trex_element(exp); 354 | if(ret != -1) { 355 | exp->_nodes[ret].next = e; 356 | } 357 | else ret = e; 358 | 359 | if(*exp->_p == TREX_SYMBOL_BRANCH) { 360 | int temp,tright; 361 | exp->_p++; 362 | temp = trex_newnode(exp,OP_OR); 363 | exp->_nodes[temp].left = ret; 364 | tright = trex_list(exp); 365 | exp->_nodes[temp].right = tright; 366 | ret = temp; 367 | } 368 | return ret; 369 | } 370 | 371 | static TRexBool trex_matchcclass(int cclass,TRexChar c) 372 | { 373 | switch(cclass) { 374 | case 'a': return isalpha(c)?TRex_True:TRex_False; 375 | case 'A': return !isalpha(c)?TRex_True:TRex_False; 376 | case 'w': return (isalnum(c) || c == '_')?TRex_True:TRex_False; 377 | case 'W': return (!isalnum(c) && c != '_')?TRex_True:TRex_False; 378 | case 's': return isspace(c)?TRex_True:TRex_False; 379 | case 'S': return !isspace(c)?TRex_True:TRex_False; 380 | case 'd': return isdigit(c)?TRex_True:TRex_False; 381 | case 'D': return !isdigit(c)?TRex_True:TRex_False; 382 | case 'x': return isxdigit(c)?TRex_True:TRex_False; 383 | case 'X': return !isxdigit(c)?TRex_True:TRex_False; 384 | case 'c': return iscntrl(c)?TRex_True:TRex_False; 385 | case 'C': return !iscntrl(c)?TRex_True:TRex_False; 386 | case 'p': return ispunct(c)?TRex_True:TRex_False; 387 | case 'P': return !ispunct(c)?TRex_True:TRex_False; 388 | case 'l': return islower(c)?TRex_True:TRex_False; 389 | case 'u': return isupper(c)?TRex_True:TRex_False; 390 | } 391 | return TRex_False; /*cannot happen*/ 392 | } 393 | 394 | static TRexBool trex_matchclass(TRex* exp,TRexNode *node,TRexChar c) 395 | { 396 | do { 397 | switch(node->type) { 398 | case OP_RANGE: 399 | if(c >= node->left && c <= node->right) return TRex_True; 400 | break; 401 | case OP_CCLASS: 402 | if(trex_matchcclass(node->left,c)) return TRex_True; 403 | break; 404 | default: 405 | if(c == node->type)return TRex_True; 406 | } 407 | } while((node->next != -1) && (node = &exp->_nodes[node->next])); 408 | return TRex_False; 409 | } 410 | 411 | static const TRexChar *trex_matchnode(TRex* exp,TRexNode *node,const TRexChar *str,TRexNode *next) 412 | { 413 | 414 | TRexNodeType type = node->type; 415 | switch(type) { 416 | case OP_GREEDY: { 417 | //TRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; 418 | TRexNode *greedystop = NULL; 419 | int p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; 420 | const TRexChar *s=str, *good = str; 421 | 422 | if(node->next != -1) { 423 | greedystop = &exp->_nodes[node->next]; 424 | } 425 | else { 426 | greedystop = next; 427 | } 428 | 429 | while((nmaches == 0xFFFF || nmaches < p1)) { 430 | 431 | const TRexChar *stop; 432 | if(!(s = trex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) 433 | break; 434 | nmaches++; 435 | good=s; 436 | if(greedystop) { 437 | //checks that 0 matches satisfy the expression(if so skips) 438 | //if not would always stop(for instance if is a '?') 439 | if(greedystop->type != OP_GREEDY || 440 | (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) 441 | { 442 | TRexNode *gnext = NULL; 443 | if(greedystop->next != -1) { 444 | gnext = &exp->_nodes[greedystop->next]; 445 | }else if(next && next->next != -1){ 446 | gnext = &exp->_nodes[next->next]; 447 | } 448 | stop = trex_matchnode(exp,greedystop,s,gnext); 449 | if(stop) { 450 | //if satisfied stop it 451 | if(p0 == p1 && p0 == nmaches) break; 452 | else if(nmaches >= p0 && p1 == 0xFFFF) break; 453 | else if(nmaches >= p0 && nmaches <= p1) break; 454 | } 455 | } 456 | } 457 | 458 | if(s >= exp->_eol) 459 | break; 460 | } 461 | if(p0 == p1 && p0 == nmaches) return good; 462 | else if(nmaches >= p0 && p1 == 0xFFFF) return good; 463 | else if(nmaches >= p0 && nmaches <= p1) return good; 464 | return NULL; 465 | } 466 | case OP_OR: { 467 | const TRexChar *asd = str; 468 | TRexNode *temp=&exp->_nodes[node->left]; 469 | while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) { 470 | if(temp->next != -1) 471 | temp = &exp->_nodes[temp->next]; 472 | else 473 | return asd; 474 | } 475 | asd = str; 476 | temp = &exp->_nodes[node->right]; 477 | while( (asd = trex_matchnode(exp,temp,asd,NULL)) ) { 478 | if(temp->next != -1) 479 | temp = &exp->_nodes[temp->next]; 480 | else 481 | return asd; 482 | } 483 | return NULL; 484 | break; 485 | } 486 | case OP_EXPR: 487 | case OP_NOCAPEXPR:{ 488 | TRexNode *n = &exp->_nodes[node->left]; 489 | const TRexChar *cur = str; 490 | int capture = -1; 491 | if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { 492 | capture = exp->_currsubexp; 493 | exp->_matches[capture].begin = cur; 494 | exp->_currsubexp++; 495 | } 496 | 497 | do { 498 | TRexNode *subnext = NULL; 499 | if(n->next != -1) { 500 | subnext = &exp->_nodes[n->next]; 501 | }else { 502 | subnext = next; 503 | } 504 | if(!(cur = trex_matchnode(exp,n,cur,subnext))) { 505 | if(capture != -1){ 506 | exp->_matches[capture].begin = 0; 507 | exp->_matches[capture].len = 0; 508 | } 509 | return NULL; 510 | } 511 | } while((n->next != -1) && (n = &exp->_nodes[n->next])); 512 | 513 | if(capture != -1) 514 | exp->_matches[capture].len = cur - exp->_matches[capture].begin; 515 | return cur; 516 | } 517 | case OP_WB: 518 | if(str == exp->_bol && !isspace(*str) 519 | || (str == exp->_eol && !isspace(*(str-1))) 520 | || (!isspace(*str) && isspace(*(str+1))) 521 | || (isspace(*str) && !isspace(*(str+1))) ) { 522 | return (node->left == 'b')?str:NULL; 523 | } 524 | return (node->left == 'b')?NULL:str; 525 | case OP_BOL: 526 | if(str == exp->_bol) return str; 527 | return NULL; 528 | case OP_EOL: 529 | if(str == exp->_eol) return str; 530 | return NULL; 531 | case OP_DOT:{ 532 | *str++; 533 | } 534 | return str; 535 | case OP_NCLASS: 536 | case OP_CLASS: 537 | if(trex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?TRex_True:TRex_False):(type == OP_NCLASS?TRex_True:TRex_False)) { 538 | *str++; 539 | return str; 540 | } 541 | return NULL; 542 | case OP_CCLASS: 543 | if(trex_matchcclass(node->left,*str)) { 544 | *str++; 545 | return str; 546 | } 547 | return NULL; 548 | default: /* char */ 549 | if(*str != node->type) return NULL; 550 | *str++; 551 | return str; 552 | } 553 | return NULL; 554 | } 555 | 556 | /* public api */ 557 | TRex *trex_compile(const TRexChar *pattern,const TRexChar **error) 558 | { 559 | TRex *exp = (TRex *)malloc(sizeof(TRex)); 560 | exp->_eol = exp->_bol = NULL; 561 | exp->_p = pattern; 562 | exp->_nallocated = (int)scstrlen(pattern) * sizeof(TRexChar); 563 | exp->_nodes = (TRexNode *)malloc(exp->_nallocated * sizeof(TRexNode)); 564 | exp->_nsize = 0; 565 | exp->_matches = 0; 566 | exp->_nsubexpr = 0; 567 | exp->_first = trex_newnode(exp,OP_EXPR); 568 | exp->_error = error; 569 | exp->_jmpbuf = malloc(sizeof(jmp_buf)); 570 | if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { 571 | int res = trex_list(exp); 572 | exp->_nodes[exp->_first].left = res; 573 | if(*exp->_p!='\0') 574 | trex_error(exp,_SC("unexpected character")); 575 | #ifdef _DEBUG 576 | { 577 | int nsize,i; 578 | TRexNode *t; 579 | nsize = exp->_nsize; 580 | t = &exp->_nodes[0]; 581 | scprintf(_SC("\n")); 582 | for(i = 0;i < nsize; i++) { 583 | if(exp->_nodes[i].type>MAX_CHAR) 584 | scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); 585 | else 586 | scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); 587 | scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); 588 | } 589 | scprintf(_SC("\n")); 590 | } 591 | #endif 592 | exp->_matches = (TRexMatch *) malloc(exp->_nsubexpr * sizeof(TRexMatch)); 593 | memset(exp->_matches,0,exp->_nsubexpr * sizeof(TRexMatch)); 594 | } 595 | else{ 596 | trex_free(exp); 597 | return NULL; 598 | } 599 | return exp; 600 | } 601 | 602 | void trex_free(TRex *exp) 603 | { 604 | if(exp) { 605 | if(exp->_nodes) free(exp->_nodes); 606 | if(exp->_jmpbuf) free(exp->_jmpbuf); 607 | if(exp->_matches) free(exp->_matches); 608 | free(exp); 609 | } 610 | } 611 | 612 | TRexBool trex_match(TRex* exp,const TRexChar* text) 613 | { 614 | const TRexChar* res = NULL; 615 | exp->_bol = text; 616 | exp->_eol = text + scstrlen(text); 617 | exp->_currsubexp = 0; 618 | res = trex_matchnode(exp,exp->_nodes,text,NULL); 619 | if(res == NULL || res != exp->_eol) 620 | return TRex_False; 621 | return TRex_True; 622 | } 623 | 624 | TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end) 625 | { 626 | const TRexChar *cur = NULL; 627 | int node = exp->_first; 628 | if(text_begin >= text_end) return TRex_False; 629 | exp->_bol = text_begin; 630 | exp->_eol = text_end; 631 | do { 632 | cur = text_begin; 633 | while(node != -1) { 634 | exp->_currsubexp = 0; 635 | cur = trex_matchnode(exp,&exp->_nodes[node],cur,NULL); 636 | if(!cur) 637 | break; 638 | node = exp->_nodes[node].next; 639 | } 640 | *text_begin++; 641 | } while(cur == NULL && text_begin != text_end); 642 | 643 | if(cur == NULL) 644 | return TRex_False; 645 | 646 | --text_begin; 647 | 648 | if(out_begin) *out_begin = text_begin; 649 | if(out_end) *out_end = cur; 650 | return TRex_True; 651 | } 652 | 653 | TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end) 654 | { 655 | return trex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); 656 | } 657 | 658 | int trex_getsubexpcount(TRex* exp) 659 | { 660 | return exp->_nsubexpr; 661 | } 662 | 663 | TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp) 664 | { 665 | if( n<0 || n >= exp->_nsubexpr) return TRex_False; 666 | *subexp = exp->_matches[n]; 667 | return TRex_True; 668 | } 669 | 670 | -------------------------------------------------------------------------------- /src/Utilities/trex.h: -------------------------------------------------------------------------------- 1 | #ifndef _TREX_H_ 2 | #define _TREX_H_ 3 | /*************************************************************** 4 | T-Rex a tiny regular expression library 5 | 6 | Copyright (C) 2003-2006 Alberto Demichelis 7 | 8 | This software is provided 'as-is', without any express 9 | or implied warranty. In no event will the authors be held 10 | liable for any damages arising from the use of this software. 11 | 12 | Permission is granted to anyone to use this software for 13 | any purpose, including commercial applications, and to alter 14 | it and redistribute it freely, subject to the following restrictions: 15 | 16 | 1. The origin of this software must not be misrepresented; 17 | you must not claim that you wrote the original software. 18 | If you use this software in a product, an acknowledgment 19 | in the product documentation would be appreciated but 20 | is not required. 21 | 22 | 2. Altered source versions must be plainly marked as such, 23 | and must not be misrepresented as being the original software. 24 | 25 | 3. This notice may not be removed or altered from any 26 | source distribution. 27 | 28 | ****************************************************************/ 29 | 30 | #include 31 | 32 | //#ifdef _UNICODE 33 | //#define TRexChar TCHAR 34 | //#define MAX_CHAR 0xFFFF 35 | //#define _TREXC(c) TEXT##c 36 | //#define trex_strlen wcslen 37 | //#define trex_printf wprintf 38 | //#else 39 | #define TRexChar char 40 | #define MAX_CHAR 0xFF 41 | #define _TREXC(c) (c) 42 | #define trex_strlen strlen 43 | #define trex_printf printf 44 | //#endif 45 | 46 | 47 | #define TRex_True 1 48 | #define TRex_False 0 49 | 50 | typedef unsigned int TRexBool; 51 | typedef struct TRex TRex; 52 | 53 | typedef struct { 54 | const TRexChar *begin; 55 | size_t len; 56 | } TRexMatch; 57 | 58 | TRex *trex_compile(const TRexChar *pattern,const TRexChar **error); 59 | void trex_free(TRex *exp); 60 | TRexBool trex_match(TRex* exp,const TRexChar* text); 61 | TRexBool trex_search(TRex* exp,const TRexChar* text, const TRexChar** out_begin, const TRexChar** out_end); 62 | TRexBool trex_searchrange(TRex* exp,const TRexChar* text_begin,const TRexChar* text_end,const TRexChar** out_begin, const TRexChar** out_end); 63 | int trex_getsubexpcount(TRex* exp); 64 | TRexBool trex_getsubexp(TRex* exp, int n, TRexMatch *subexp); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/Version.h: -------------------------------------------------------------------------------- 1 | // This file is part of DoxyIt. 2 | // 3 | // Copyright (C)2013 Justin Dailey 4 | // 5 | // DoxyIt is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either 8 | // version 2 of the License, or (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software 17 | // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | #define VERSION_NUM 0,4,4,0 20 | #define VERSION_LINEAR 440 21 | #define VERSION_LINEAR_TEXT TEXT("440") 22 | #define VERSION_TEXT TEXT("0.4.3") // This must match the tag pushed on the server minus the "v" 23 | #define VERSION_STAGE TEXT("") // "alpha", "beta", "" 24 | -------------------------------------------------------------------------------- /tests/test.c: -------------------------------------------------------------------------------- 1 | // --- Test function names --- 2 | 3 | void () // fail 4 | 5 | void f () 6 | 7 | void func_1(void) 8 | 9 | // --- Test return values --- 10 | 11 | int func() 12 | 13 | const char *func() 14 | 15 | const char* func() 16 | 17 | const char ** func() 18 | 19 | // --- Test parameter values --- 20 | 21 | int func(int x) 22 | 23 | float func(...) 24 | 25 | int printf( const char * format , ... ) 26 | 27 | float func(char *p, char** str, double x) 28 | 29 | // --- Test multiline functions --- 30 | 31 | const char * 32 | func( 33 | int one, 34 | double two, 35 | char three) 36 | 37 | // --- Test indentation 38 | 39 | const char* func() 40 | 41 | float func(char *p, char** str, double x) 42 | -------------------------------------------------------------------------------- /tests/test.cpp: -------------------------------------------------------------------------------- 1 | // Most of the features of the parser have been tested in test.c 2 | // Now just test c++ specific features 3 | 4 | int namespace::Class::Method() 5 | 6 | std::string& Class::Method() 7 | 8 | std::string &Class::Method() 9 | 10 | std::string && Class::Method() 11 | 12 | void Class::Method(std::string &str) 13 | 14 | void Class::Method(int x, float pi = 3.14) 15 | 16 | void Class::Method(std::mystring = std::string()) // This doesn't work, but should 17 | 18 | void function(std::pair> p, int x) 19 | 20 | Constructor(int x) // bug if space is before parenthesis 21 | 22 | ~Destructor() 23 | -------------------------------------------------------------------------------- /tests/test.cs: -------------------------------------------------------------------------------- 1 | // Most of the features of the parser have been tested in test.c 2 | // Now just test C# specific features 3 | 4 | void PassRef(ref int x) 5 | 6 | void PassOut(out int x) 7 | 8 | void PrintAll(IEnumerable objects, string! input) 9 | -------------------------------------------------------------------------------- /tests/test.java: -------------------------------------------------------------------------------- 1 | // Most of the features of the parser have been tested in test.c 2 | // Now just test Java specific features 3 | 4 | public static void main(String[] args) 5 | 6 | // Thats about it for now... 7 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | // Most of the features of the parser have been tested in test.c 2 | // Now just test Java specific features 3 | 4 | function myFunction(abc, def, ghi) 5 | 6 | a.b.c = function(jkl, mno) 7 | -------------------------------------------------------------------------------- /tests/test.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /tests/test.py: -------------------------------------------------------------------------------- 1 | # --- Test function names --- 2 | 3 | def f() 4 | 5 | deff f() # fail 6 | 7 | def f1_abc() 8 | 9 | # --- Test parameter values --- 10 | 11 | def foo(bar) 12 | 13 | def foo(bar = baz) 14 | 15 | def __init__(self, x, y, z) 16 | 17 | def f(x, *args, **kwargs) 18 | 19 | # Lots more could be added 20 | --------------------------------------------------------------------------------