Académique Documents
Professionnel Documents
Culture Documents
Professional
SlickEdit
John Hurst
Professional SlickEdit
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
41
Chapter 4: Workspaces and Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Chapter 5: Context Tagging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Chapter 6: Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 Chapter 7: Search and Replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 Chapter 8: Editing Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Chapter 9: Editing Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 Chapter 10: Editing Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 Chapter 11: Aliases and File Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 Chapter 12: Document Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 Chapter 13: Comparing and Merging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Chapter 14: Version Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
295
Chapter 15: Other Tools. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Chapter 16: Slick-C Macro Programming . . . . . . . . . . . . . . . . . . . . . . . . . . 307 Chapter 17: Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 Appendix A: Settings for Different Emulations. . . . . . . . . . . . . . . . . . . . . . . 391 Appendix B: Regular Expression Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 Appendix C: SlickEdit Callbacks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Appendix D: Whats on the CD-ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Professional
SlickEdit
Professional
SlickEdit
John Hurst
Professional SlickEdit
Published by Wiley Publishing, Inc. 10475 Crosspoint Boulevard Indianapolis, IN 46256 www.wiley.com Copyright 2008 by Wiley Publishing, Inc., Indianapolis, Indiana Published simultaneously in Canada ISBN-13: 978-0-470-12215-0 Manufactured in the United States of America 10 9 8 7 6 5 4 3 2 1 Library of Congress Cataloging-in-Publication Data is available from the publisher. No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the Legal Department, Wiley Publishing, Inc., 10475 Crosspoint Blvd., Indianapolis, IN 46256, (317) 572-3447, fax (317) 572-4355, or online at http:// www.wiley.com/go/permissions. Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties, including without limitation warranties of fitness for a particular purpose. No warranty may be created or extended by sales or promotional materials. The advice and strategies contained herein may not be suitable for every situation. This work is sold with the understanding that the publisher is not engaged in rendering legal, accounting, or other professional services. If professional assistance is required, the services of a competent professional person should be sought. Neither the publisher nor the author shall be liable for damages arising herefrom. The fact that an organization or Website is referred to in this work as a citation and/or a potential source of further information does not mean that the author or the publisher endorses the information the organization or Website may provide or recommendations it may make. Further, readers should be aware that Internet Websites listed in this work may have changed or disappeared between when this work was written and when it is read. For general information on our other products and services please contact our Customer Care Department within the United States at (800) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002. Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Wrox Programmer to Programmer, and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries, and may not be used without written permission. SlickEdit is a registered trademark of SlickEdit, Inc. All other trademarks are the property of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book. Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available in electronic books.
For Zena.
Credits
Acquisitions Editor
Chris Webb
Compositor
Kate Kaminski, Happenstance Type-O-Rama
Development Editor
Kenyon Brown
Proofreader
Nancy Carrasco
Technical Editor
Mark Berger
Indexer
Melanie Belkin
Production Editor
Debra Banninger
Copy Editor
Cate Caffrey
Editorial Manager
Mary Beth Wakefield
Production Manager
Tim Tate
Acknowledgments
Ive read that writing a book is harder than writing software. It certainly seems harder, and it is not as much fun. But, if writing is not as much fun, reviewing must be even worse. Nevertheless, my friend and colleague Mark Berger has devoted himself thoroughly to this project, checking everything carefully and pointing out many errors. If you do find errors in the book, they were added by me after Mark had finished his job. Mark has also provided stimulus throughout my career, being well informed and passionate about software development tools and practices. My thoughts about programming and software systems have been refined continuously through many discussions with Mark over the years. The team at SlickEdit should be proud to have created one of the most useful and enduring software tools ever made. They continue to refine and enhance it every year, and during 2007 their release schedule overlapped the writing of this book for the most part. All the same, they made time to support me in writing this book, by providing early builds, explaining features, and reviewing material. It was a great privilege to talk to several SlickEdit developers and discuss SlickEdit and the book with them. Most of the SlickEdit team has made a contribution to this book in one form or another, many through providing tips and assistance on the SlickEdit Community Forums. I thank Clark Maurer, Dan Henry, Dennis Brueni, Lee Baldwin, Lisa Rodwell, Matthew Etter, Mike Cohen, Rodney Bloom, Ryan Huff, Sandra Gaskin, Scott Hackett, Scott Westfall, and the other folks at SlickEdit for all their help. Scott Westfall, in particular, reviewed every chapter and contributed material on Workspaces and Projects for Chapter 4. Dan Henry, Dennis Brueni, Lisa Rodwell, Rodney Bloom, and Sandra Gaskin reviewed chapters and contributed feedback. Rodney contributed code samples. Dennis contributed code samples, and also the troubleshooting checklist for Context Tagging in Chapter 5. Hartmut Schaefer, aka hs2, is an outstanding member of the SlickEdit online community. He has posted hundreds of posts in the Community Forums, answering questions, suggesting improvements, and finding (and fixing) bugs. Several of hs2s tips appear in this book. Thanks for everything, hs2. Other community members have also provided material online that helped this book. Graeme Prentice made several useful suggestions relating to forms and GUI elements. Graeme is a frequent contributor to the online forums. Ding Zhaojie also posts bug fixes and improvements, some of which have directly assisted me in writing this book. Dierk Knig wrote Groovy in Action (Manning, 2007), from which Ive adapted his technique for illustrating code snippets using unit testing assertions. Kenyon Brown, the Development Editor for this book, put up with a lot of annoying questions from a novice author. He also moved the book through the writing process, doing what he could to keep me focused and on schedule.
Acknowledgments
Cate Caffrey, the Copy Editor, has made me realize that I ought to go back to school and learn English. I own several books on clear writing and good English usage (more awkwardly, a number of them). However, the fact of ownership has done little to improve my own usage. If any sentence of this book reads well, it is largely thanks to Cate. Id like to thank Chris Webb, Executive Editor at Wiley, for finding me and giving me this opportunity. Chris has been wonderfully supportive (and persuasive). I also thank the management at the client where I currently do most of my work, Red Energy in Melbourne, Australia. Lucy Aston and Steve Byrne have put together a great team and a great work environment, and Im grateful that they were so understanding and supportive of this project. There is never any shortage of work to do at a startup, and I hope I can catch up on all the things I have neglected the last few weeks. Unfortunately, I think Lucy will be disappointed with this book, since it is rather dry and humorless. Wait until you see the movie though. My mother bought me my first computer, many years ago. But shes pretty smart, and before she got the computer, she gave me a book about computer programming. I think I had read the whole book at least once before I got the computer. My partner, Zena, has a ThinkGeek T-shirt that says I love my geek, and I have to believe it. Shes been wonderful, always. Maybe she can write the next book, about something other than computers.
xiv
Contents
Acknowledgments Introduction xiii xxv
1
3
3 4
5 5 5 6
6 7 7
9
9
10
Key Bindings
Setting Key Bindings Listing Key Bindings
11
12 13
Macros
Recording a Macro Writing a Macro Loading a Macro Supplied Macro Source
14
14 16 17 18
Summary
18
Chapter 2: Configuration
Emulations and Key Bindings
The WROX Emulation Alt Keys
19
19
21 21
Contents
Macro Variables
Using the Set Variable Dialog Using the set-var Command
22
22 23
Common Settings
Appearance Fonts Line Behavior
24
24 25 26
Managing Configurations
Configuration Directory Reverting to the Default Configuration Working with a Different Configuration
30
30 30 31
Summary
32
33
34 34 35 35 35
36 38 40 40
Summary
40
41
43
45 46 47
49 52 53 54 60 60
61
61
xvi
Contents
Building the Project Executing the Project Adding Unit Tests Managing the Project with Ant 61 62 62 65
65
66 66 67
70 72
73
74
74 74
Listing Members
Configuring List Members
76
78
78
80
81
81 81 82 83
Finding Symbols
The Find Symbol Tool Window Using the grep-tag command
84
84 85
Browsing Definitions
The Defs Tool Window The Class Tool Window The Symbols Tool Window
85
85 86 87
88
89 90 90 92 98 102
104 105
105
xvii
Contents
Go to Reference Doesnt Work Auto-List Members Doesnt Work Auto-Parameter Information Doesnt Work Solution A: Define C/C++ Preprocessing Solution B: Add Symbol to Tag File Solution C: Configure C/C++ Extensionless Header Files Solution D: Create a File Extension Alias Solution E: Rebuild Your Tag File(s) 107 107 107 107 108 108 109 109
Performance Tuning
Tuning Maximums Tag Cache Size References Complex Code
109
110 111 111 111
Summary
112
Chapter 6: Navigation
Finding and Opening Files
Using File Open Using File and Directory Aliases Using the edit Command Using Tool Windows Using the File Manager Navigating to Header Files
113
114
114 116 117 117 119 119
Moving Around
Navigating in the buffer Positioning the Window Navigating to a Line, Column, or Byte Offset Navigating among Buffers
119
120 123 124 125
Bookmarks
Pushed Bookmarks Named Bookmarks Configuring Bookmarks
127
127 128 129
Summary
130
131
131
132 132 132
xviii
Contents
The Find and Replace Tool Window
Using Find Using Find in Files Using Replace and Replace in Files
133
134 135 137
Regular Expressions
Tagged Expressions Regular Expression Examples
137
140 141
141
143 145
Selective Display
Predefined Selective Display Custom Selective Display
146
146 148
149 150
151
152
152 152
153
153 155 157 160 161 162 163 164
165
165 168 169
Summary
171
173
173
175
Syntax Highlighting
175
xix
Contents
Indentation and Code Style
C/C++ Options Java and C# Options HTML Options Other Languages
177
178 179 180 180
180
181 182 183 184 185
186
186 188 189 190
Embedded Languages
Web Programming Here Documents in Scripts
190
190 191
192
193 194 195 195
Summary
197
199
200
200 202
202
203 203
xx
Contents
Aligning Data Large Data Files Summary 222 226 227
229
229
230 232 234 235 237 238 239 240
File Templates
Instantiating a Template Creating a Template Substitution Parameters Managing Templates Instantiating Templates in Macros
241
241 242 246 248 248
Summary
252
253
253 254 254 255 258
259
259
260 262 265 266 266
xxi
Contents
Chapter 14: Version Control
CVS
Using an Existing Working Copy Checking Out an Existing Project Reviewing Changes Adding Files Committing Changes Merge Conflicts Using Commit Sets to Group Changes Branches and Tags Browsing the History Keyboard Bindings
271
271
272 274 275 277 278 278 279 282 283 284
Subversion
Configuring SlickEdit for Subversion Creating a New Project Checking Out a Working Copy Reviewing and Committing Changes, Adding Files Merge Conflicts Branches and Tags Browsing the History Keyboard Bindings
285
287 287 288 289 289 290 291 292
Summary
293
295
297
298
299 300 301
302
304 305
305 306
307
308
309
xxii
Contents
Preprocessor Functions Properties Data Types Control Structures Declarations and Definitions 311 311 312 314 324 326
331
332 332 332 333 334
Useful Techniques
Interacting with the Buffer Searching Selections Temporary Buffers Listing Files and Directories Choosing Files Useful Macro Files Callbacks
336
337 337 339 339 340 342 342 343
Example Macros
Example: Example: Example: Example: Example: Example: Counting Duplicate Lines Inserting HTML End Tag Moving Lines Up and Down Callback Traces WROX Function Names N-Queens
346
347 348 351 353 355 357
Summary
359
361
362
362 362 363
365
365 367
372
372 375
xxiii
Contents
Programmatic Configuration
Loading Key Definitions and Code Defining Aliases General Configuration Settings Determining Programmatic Configuration
378
380 381 382 384
Summary
389
391
392
392 394 398 399 399 402 405 405 406 407
435
438
441 445
445 447 447 448 448
448 449
Troubleshooting
Customer Care
449
449
Index
451
xxiv
Introduction
I have been using SlickEdit almost every day for more than 10 years. For most of that time, it has been my editor of choice for almost every programming language Ive used. I strongly believe that a really powerful and versatile programming editor is the most important tool that a professional programmer uses. Im dismayed sometimes when I see programmers using IDEs ineffectively or producing substandard code because of limitations in their development environment. I wrote this book to help you get the most out of SlickEdit. I hope you enjoy it.
Introduction
This book is not a substitute for the online Help and other reference documentation that comes with SlickEdit. The online Help system contains detailed information organized around the features and is comprehensive and up-to-date. When we discuss features in this book, we will often give one or more examples of typical use. In some cases, well discuss options and strategies for the feature in detail, but in other cases you will be referred to the online Help for more information. I debated with myself about including so many screen shots of dialogs. In some ways theyre redundant too, since they are all covered in the online Help and you can bring up the dialogs easily enough for yourself. However, Ive found that with so many options, and so many dialogs, there are probably a few of them you wont have noticed, or wont have come across during your ordinary use of SlickEdit. Also, sometimes just seeing the options that are available in the dialogs can tell you, at a glance, something about the features available.
Conventions
To help you get the most from the text and keep track of whats happening, weve used a number of conventions throughout the book. Boxes like this one hold important, not-to-be forgotten information that is directly relevant to the surrounding text.
Tips, hints, tricks, and asides to the current discussion are offset and placed in italics like this. As for styles in the text: We highlight new terms and important words when we introduce them. We show keyboard strokes like this: Ctrl+A. We show filenames, URLs, and code within the text like so: persistence.properties. We present code in two different ways:
In code examples we highlight important code in bold
Source Code
As you work through the examples in this book, you may choose either to type in all the code manually or to use the source code files that accompany the book. All of the source code used in this book is available for download at http://www.wrox.com. Once at the site, simply locate the books title (either by using the Search box or by using one of the title lists), and click the Download Code link on the books detail page to obtain all the source code for the book. Because many books have similar titles, you may find it easiest to search by ISBN; this books ISBN is 978-0-470-12215-0.
xxvi
Introduction
Once you download the code, just decompress it with your favorite compression tool. Alternately, you can go to the main Wrox code download page at http://www.wrox.com/dynamic/books/download.aspx to see the code available for this book and all other Wrox books.
Errata
We make every effort to ensure that there are no errors in the text or in the code. However, no one is perfect, and mistakes do occur. If you find an error in one of our books, like a spelling mistake or faulty piece of code, we would be very grateful for your feedback. By sending in errata you may save another reader hours of frustration, and at the same time you will be helping us provide even higher quality information. To find the errata page for this book, go to http://www.wrox.com, and locate the title using the Search box or one of the title lists. Then, on the Book Details page, click the Book Errata link. On this page you can view all errata that have been submitted for this book and posted by Wrox editors. A complete book list including links to each books errata is also available at http://www.wrox.com/misc-pages/booklist.shtml. If you dont spot your error on the Book Errata page, go to http://www.wrox.com/contact/ techsupport.shtml, and complete the form there to send us the error you have found. Well check the information and, if appropriate, post a message to the books errata page and fix the problem in subsequent editions of the book.
p2p.wrox.com
For author and peer discussion, join the P2P forums at http://p2p.wrox.com. The forums are a Webbased system for you to post messages relating to Wrox books and related technologies and interact with other readers and technology users. The forums offer a subscription feature to e-mail you topics of interest of your choosing when new posts are made to the forums. Wrox authors, editors, other industry experts, and your fellow readers are present on these forums. At http://p2p.wrox.com, you will find several different forums that will help you not only as you read this book, but also as you develop your own applications. To join the forums, just follow these steps:
1. 2. 3. 4.
Go to http://p2p.wrox.com, and click the Register link. Read the Terms of Use, and click Agree. Complete the required information to join as well as any optional information you wish to provide, and click Submit. You will receive an e-mail with information describing how to verify your account and complete the joining process.
You can read messages in the forums without joining P2P, but in order to post your own messages, you must join.
xxvii
Introduction
Once you join, you can post new messages and respond to messages other users post. You can read messages at any time on the Web. If you would like to have new messages from a particular forum e-mailed to you, click the Subscribe to This Forum icon by the forum name in the forum listing. For more information about how to use the Wrox P2P, be sure to read the P2P FAQs for answers to questions about how the forum software works as well as many common questions specific to P2P and Wrox books. To read the FAQs, click the FAQ link on any P2P page.
xxviii
Professional
SlickEdit
Introducing SlickEdit
Welcome to SlickEdit, a text editor for programmers. In this first chapter, I start by telling you something about what makes SlickEdit so good, and why I think it is one of the best programming tools around. In the remainder of the chapter, we cover some of the central concepts of SlickEdit, which we use throughout the rest of the book.
McConnell adds, Considering some of the primitive editors still in use, you might be surprised to learn that several editors include all these capabilities. SlickEdit is one of those editors. SlickEdit provides all the features in McConnells list, to some degree, and more. However, it is not just about features. Some of these features are about the workflow of developing software: compiling, debugging, source code control, and so on. IDEs typically do these things fairly well. Where SlickEdit really comes out on top is in editing code. Most IDEs editors, although they may have a lot of fancy features such as toolbars and Class Wizards and so forth, are simply not advanced editors. They make you type and click too much. Then there is the problem that most IDEs are only good for a single programming language or environment. Many programmers need to work in a lot of different environments, and it is frustrating and inefficient to use a different editor for each one.
Multiple Platforms
SlickEdit is not tied to a particular programming platform. Most of its features are generic and apply equally well to any programming language or platform. On top of that, it does provide IDE-like tools and language-specific support for many popular programming languages. SlickEdit is also not tied to an operating system. I started using SlickEdit on OS/2, but Ive also owned copies for Windows, AIX, and GNU/Linux. Virtually all the functionality is the same. Just as importantly, the customizations and macros Ive done while using one operating system have all been carried through to other operating systems. I dont have to learn a whole new tool and create a whole new set of customizations, just because I am switching from Windows to GNU/Linux for a project.
Customizable
SlickEdit is very customizable. Out of the box, SlickEdit provides emulations for more than a dozen popular editors. These emulations provide a basic starting point for the behavior of the editor. Virtually every aspect of the editor can be customized. Dont like the way the Enter key moves to the next line? You can change it. Dont like the indentation or brace style? You can change them.
Extensible: Slick-C
You can customize and extend SlickEdit using Slick-C, a macro, or scripting language. One of the most important goals in this book is to introduce you to Slick-C and show you how easy it is to use it to customize or extend SlickEdit. Slick-C is easier to use than most plug-in systems. Slick-C is named after C and derives many of its features from C, such as control structures and declaration style. But Slick-C is really more of a scripting language. It is remarkably easy to learn and to use and is much more productive to code in than C. So if youre not a C programmer, or you dont like C, dont worry. Even if it sounds too hard for you, try it! You will be surprised. Many of SlickEdits features are implemented in Slick-C. The complete source code for those features is provided with the product, more than 750,000 lines of it at last count! Having the source code to such a major part of SlickEdits functionality makes using it a lot like using an open-source product. If youve worked with open-source libraries or tools, you probably know how useful it is to be able to dive into the source code. You can often use features more effectively if you know how they really work. You can extend or alter features if they dont fit your needs. You can write your own features. And, sometimes, you may even find a bug and see how to fix it. All of these benefits apply to SlickEdit and its supplied Slick-C source code, even though SlickEdit is a commercial product. This book aims to explain some details about macro programming and provides many useful examples you can use or adapt to your own needs. As we discover features of SlickEdit, we will often show examples of how they can be used or extended with Slick-C. The last two chapters of the book go into Slick-C in depth and show detailed examples of customization. But, as we mentioned already, the main point is to show you how easy it is and to get you started on your own macros.
This Book
SlickEdit is a powerful and versatile programming editor. Much of its power comes from its design and the large number of features that are included. Some important features are very simple, like being fast to edit and navigate even very large files. Some features are advanced and specific, such as syntax assistance for various programming languages. We will be covering a lot of these features throughout this book. However, most of these features are already covered pretty well in the User Guide and Online Help shipped with the product. This book is not a reference manual and is not intended to replace the user guide. While we will cover some details of many of the features, we will focus more on general capabilities and the versatility of SlickEdit.
SlickEdit Terminolog y
Before we start to look at SlickEdit concepts, we should get a few terms straight. When you open a file in SlickEdit, the file is loaded into a buffer. The buffer is the in-memory representation of the file. The buffer has the same name as the physical file. Changes to the buffer are saved to disk when you save the file. Sometimes the terms file and buffer are used interchangeably. The buffer is displayed in a window. The window is the GUI view of the buffer. In the default configuration, there is one window created for each buffer. We talk about managing windows in more detail in Chapter 3. In this book, while explaining certain dialogs, we use phrases such as Click OK to dismiss the Project Properties dialog. Most of the time, of course, you will not actually click OK; rather, you will simply press Enter, because OK is the default button. However, we stick to the Click terminology most of the time, because it is commonly used in help and user guides, and it makes it clear which dialog control we really mean. After all, if you tab around, the focus might change to a control where the Enter key is not the same as clicking OK.
Figure 1-1
Many computer users use the mouse a lot. The mouse is a great way to learn a program. When you first start using a program, you use the mouse to browse around. Its kind of like browsing the Web: Youre just looking around; you arent really doing anything. Once you start really using a program to do things, you tend to find youre doing some things a lot. For those things, you will do them a lot faster using the keyboard. For example, saving a file is something you do a lot. You can use the mouse to click the File menu on the menu bar, and then click Save. But thats a lot of work just to save the file. Having a toolbar with a Save icon isnt much better. Since the goal of this book is to save you work, well mostly be looking at using the keyboard, especially for things you need to do a lot. For that reason, we wont talk much about toolbars. As well as toolbars, SlickEdit also has tool windows. Tool windows tend to contain considerably more information and functionality than toolbars. They are like miniature applications within the editor. There are many tool windows, and it is not feasible to show them all on the screen at the same time. In Figure 1-1, there are several tool windows that are hidden and are only visible through their tabs, which are arranged down the left- and right-hand sides, and across the bottom (under the File Tabs toolbar). In Chapter 3, we will see how to arrange the tool windows effectively and how to invoke them using the keyboard. The most commonly used tool windows can be used quite effectively without the mouse. At the bottom of the screen, on the left, is the message area, which doubles as the command line. Well discuss commands and the command line in detail shortly.
Figure 1-2
Commands can have arguments, and these arguments can be mandatory or optional. For example, cursor-up can take an optional numeric parameter specifying how many lines to move up. When you invoke a command via a keyboard shortcut, toolbar, or menu, no arguments are provided. A command may prompt for an argument in these cases. An example of a command for which you would normally provide an argument is find.
Figure 1-3
When you enter a command on the command line, you can specify arguments. Many commands know what kinds of arguments they require, and SlickEdit can autocomplete arguments for these commands. For example, if a command requires a filename, SlickEdit can complete filenames or directories from the current directory on the command line. Figure 1-4 shows an example.
Figure 1-4
Autocompletion for command-line arguments works for several other kinds of arguments, as well as files.
10
We cover Slick-C batch macros in Chapter 16. If you want to enter an operating system command that has the same name as a SlickEdit command, use the dos command. For example, suppose you want to run the operating system find command. Since there is a SlickEdit command named find, you need to enter dos find on the command line. Although the dos command appears to be named after the DOS operating system, it actually works on all operating systems. An operating system command is run in its own window. The window closes after the command completes. You can use the dos command with the w option to keep the window open until you press a key. Alternatively, if a command has output you want to see, you can use the Build tool window instead of the command line. There are several SlickEdit commands with the same name as operating system commands. Weve seen find as one example. A few more are:
cd del dir and ls pwd
Key Bindings
You can bind commands to keys. Many commands are bound to keys already when you install SlickEdit. The set of default key bindings you select when you install SlickEdit is called an emulation. In this book, we assume that you are using the CUA emulation. We cover emulations in more detail in Chapter 2.
11
1. 2.
Enter what-is on the command line, and press Enter. SlickEdit prompts you to press a key. Press a key. If the key has a command bound to it, SlickEdit tells you what command the key runs. Otherwise, SlickEdit pops up a message box saying that the key is not defined.
If you want to find which key(s) a command is bound to, use the where-is command. For example, to find out which key the save command is bound to, enter the command where-is save. SlickEdit displays a message showing the key for the save command.
Figure 1-5
The Key Bindings dialog has several different features. Lets use it to bind a command to a key. The quick-search command is a useful shortcut for searching for the word at the current cursor position. But the command is not bound to a key in the CUA emulation. Lets bind it to Ctrl+F3 using the Key Bindings dialog. With the dialog open, follow these steps:
1. 2.
Enter quick-search in the Search by command field. SlickEdit updates the commands listed as you type. When youve typed the whole command, the list is narrowed down to just that command. This list also shows that the command is not currently bound to any key. Click in the Search by key sequence field.
12
Figure 1-6
5.
Click Bind to bind the key. If the key you have chosen is currently bound to a command, SlickEdit warns you and asks you to confirm that you wish to continue.
A given command can be bound to many different keys, but a given key or key combination can have only one command bound to it. You can use Ctrl, Alt, and Shift combinations to make key bindings unique. For example, Ctrl+Shift+F3 is distinct from Ctrl+F3. Ctrl+Alt+Shift+F3 is different again. Commands can be bound to sequences of keys. For example, you could bind a command to Alt+T followed by P. The beginning part of the sequence cannot itself have a command bound to it, because that would be ambiguous. But you can use different keys for the ending part. You could have one command bound to Alt+T followed by P, and another to Alt+T followed by F. This is one way to overcome the problem of running out of keys, if you want to bind a lot of commands. Well see a couple of applications of this idea below. You can use the Key Bindings dialog to review related commands and their key bindings. If you type search into the Search by command field, you see all commands containing the word search. The Key Bindings dialog has several other features too. You can remove key bindings, and you can export your key bindings as an HTML file. Most key bindings are done for the default mode, called the fundamental mode in SlickEdit. SlickEdit also has several other modes. Each family of programming languages has a mode, for example, C, Java, HTML. There are also specialized modes for certain SlickEdit features. Some keys have special commands bound to them per mode. For example, some keys trigger syntax assistance for certain programming languages, such as Space, (, and { in C. The Key Bindings dialog shows modes for key bindings, if they apply. Bindings with modes showing as default apply to the fundamental mode.
13
Macros
The term macro is used generically in SlickEdit to mean any of these things: Any Slick-C routine. A Slick-C command. A Slick-C batch macro.
In this section, we are referring to macros in the command sense. This section shows you how to create your own commands in SlickEdit. Well start with recorded macros and then give an introduction to writing macros in Slick-C and compiling them. After reading this section, you will be ready to compile and load the example macros presented throughout the book. We cover macro programming in more detail in Chapter 16.
Recording a Macro
The first kind of macro that most people encounter is the recorded macro. This is probably the quickest way to get started with Slick-C programming and is also a great way to see how easy it is. SlickEdit provides two commands for creating recorded macros and playing them back, shown in Table 1-1.
Table 1-1
Command
record-macro-toggle
Key Ctrl+F11
Description Start recording macro, or stop recording and save macro. Stop macro recording and execute macro.
record-macro-end-execute
Ctrl+F12
Lets record a macro to duplicate the current line. Well also bind this key to Alt+quote. It turns out that SlickEdit already has a duplicate-line command. Also, we cover line selections and copy commands in more detail in Chapter 8. For now, just follow along with the example. This example assumes that you have the CUA emulation loaded. Before you start, you also need to have a buffer open with the cursor on a line in the buffer. To record the macro, follow these steps: 1. Invoke record-macro-toggle (Ctrl+F11). SlickEdit prompts you with a message and shows the macro recording status indicator as shown in Figure 1-7.
14
Figure 1-7
2. 3. 4. 5.
Invoke select-line (Ctrl+L). SlickEdit selects the line. Invoke copy-to-clipboard (Ctrl+C). Invoke paste (Ctrl+V). SlickEdit pastes a copy of the line. Invoke record-macro-toggle. SlickEdit displays the Save Macro dialog, shown in Figure 1-8.
Figure 1-8
6. 7.
Enter wrox-dup-line as the Macro Name. This becomes the name of the command, if you should want to invoke it from the command line or from another macro. Click Save. SlickEdit displays the List Macros dialog, shown in Figure 1-9. The List Macros dialog lists user-recorded macros and allows you to manage them.
Figure 1-9
8.
Click Bind to Key. SlickEdit displays the Key Bindings dialog, with wrox-dup-line shown in the command list.
15
Congratulations! You have created a macro and bound it to a key. Try it now by pressing Alt+quote a few times. It should duplicate the line the cursor is on. The exact behavior of commands like copy-to-clipboard and paste can vary with some configuration settings. If you are not using CUA emulation, or you have altered other settings, you may need to follow a slightly different sequence of steps to duplicate a line. In particular, if the line remains selected after you invoke copy-to-clipboard, you need to invoke deselect (Ctrl+U) afterward. When you record a macro and save it with a name, SlickEdit places the source code for your macro into a file called vusrmacs.e in your configuration directory. On Windows, the default location for the configuration directory is in the My SlickEdit Config directory in My Documents. The configuration directory is named after the SlickEdit version number, for example, 12.0.2. We cover the configuration directory in more detail in Chapter 2, including how you can specify its name and location. If you record a macro and do not give it a name (e.g., by pressing Escape in the Save Macro dialog), SlickEdit names it last_recorded_macro and stores the source in lastmac.e in your configuration directory. Unnamed macros are handy for sequences of commands you want to repeat quickly a few times, but not save. You can invoke the last unnamed recorded macro using record-macro-end-execute (Ctrl+F12). If you can plan to finish recording your macro so that your cursor is already set up for the first invocation, you can use record-macro-end-execute to finish the recording and execute the macro immediately. This is very handy for doing repetitive edits on multiple lines, or at multiple search matches. We cover some more examples of unnamed macro recording and playback in Chapter 10. If you are recording a macro and wish to abort recording, press Escape. SlickEdit confirms that you have canceled recording with a message, shown in Figure 1-10.
Figure 1-10
Writing a Macro
Locate and open the vusrmacs.e file. You should find that it contains content like this:
#include slick.sh _command wrox_dup_line() name_info(,VSARG2_MACRO|VSARG2_MARK|VSARG2_REQUIRES_MDI_EDITORCTL) {
16
The macro youve recorded for duplicating a line is a nice start, but it could be somewhat better. Some of the drawbacks of the macro as it stands are: It uses selections, which means it disrupts any existing selection. It uses the clipboard.
It would be better if we had a command for duplicating a line without disrupting either the selection or the clipboard. We can do this by editing the code SlickEdit placed in vusrmacs.e. Dont worry too much about the details for now. Change the macro body of wrox_dup_line() to look like this:
#include slick.sh _command wrox_dup_line() name_info(,VSARG2_MACRO|VSARG2_MARK|VSARG2_REQUIRES_MDI_EDITORCTL) { push_bookmark(); _str the_line; get_line(the_line); insert_line(the_line); pop_bookmark(); }
Now, instead of using clipboard and selection commands, we are manipulating the buffer directly. We also added push_bookmark() and pop_bookmark() to ensure the cursor remains on the original line after duplicating it. We cover bookmarks in more detail in Chapters 5 and 6. However, simply changing the text in the source file is not enough to change the behavior of the macro in SlickEdit. SlickEdit macros are loaded (compiled), thus we need to get SlickEdit to reload our macro. (Recorded macros are automatically loaded.)
Loading a Macro
Compiling a macro and loading it into memory in SlickEdit is referred to as loading the macro. To load the macro, ensure that vusrmacs.e is in the current buffer. Then invoke the load command (F12). If there are no errors, SlickEdit reports that the module is loaded, as shown in Figure 1-11.
Figure 1-11
You can place macro code in any file you like. By convention, Slick-C code is stored in files with the extension .e. Throughout this book, we give more examples of Slick-C code. The examples are all included on the accompanying CD-ROM, in files under directories corresponding to the chapter in
17
Summar y
In this chapter, we introduced SlickEdit and explained what differentiates it from IDEs and other tools for programming. The most important things that differentiate SlickEdit are: SlickEdit is configurable. SlickEdit is extensible. SlickEdit is programmable.
We covered some central concepts in SlickEdit: the command line, key bindings, and recording and loading macros. These concepts are used throughout the rest of this book. In the next chapter, we look in detail at some general aspects of SlickEdit configuration.
18
Configuration
SlickEdit has hundreds of configuration options. It is one of the most configurable software products you will ever find. As with most configurable software, SlickEdit comes with reasonable defaults. Nevertheless, in this book, we suggest that you should consider some alternatives to the defaults. In some cases, the default settings are designed to make SlickEdit familiar to users with experience with other common programs, such as Visual Studio or Windows Notepad. But Notepad is not the most effective programming editor, and SlickEdit has alternative ways of doing things that can be more powerful. We introduce a few of these in this chapter. In the first part of this chapter, we cover some general information about configuration to give you the big picture. We discuss SlickEdits emulations, which provide behavior compatible with a selection of other editors. We introduce the WROX Emulation, which extends SlickEdits default emulation to provide more key bindings for useful commands. In the second part of the chapter, we take a look at several common settings you might consider changing in order to get the most out of SlickEdit. These include obvious things such as fonts and also some subtler points like how SlickEdit treats cursor movement and line wrapping. Finally, we explain SlickEdits configuration directory, and how you can manage SlickEdit configuration data.
Table 2-1
Emulation BBEdit (Mac) Brief CodeWarrior CodeWright Epsilon GNU Emacs ISPF SlickEdit Visual C++ 6 Vim Visual Studio CUA Xcode Source File
bbeditdef.e briefdef.e codewarriordef.e codewrightdef.e emacsdef.e gnudef.e ispfdef.e slickdef.e vcppdef.e videf.e vsnetdef.e windefs.e xcodedef.e
20
Chapter 2: Configuration
Alt Keys
One standard defined by CUA is that you can use Alt key combinations to access the main menu. Thus, for example, you can press Alt+F to open the File dropdown menu from the main menu bar. This is a convenient and intuitive way to learn the menus in an unfamiliar program. This discussion of Alt keys applies to PC-type keyboards, generally for Windows, Linux, and often for UNIX too. Because Macs use a different keyboard, much of this discussion does not apply to them. Also, the WROX emulation would need to be modified for its Alt key bindings to work on a Mac. Many programs use Alt keys for other functions besides invoking menus. Some programs split the use of Alt keys: The ones that are required for invoking main menu items such as File and Help are reserved for those, and the others are free to be mapped to other functions in the program. SlickEdit provides an option to get more use out of the Alt keys. This option is based on the premise that the menus are mainly used when learning the program, or for functions that are used infrequently. For often-used functions, direct invocation by a keyboard shortcut is faster than using the menu. (Its less keystrokes, and less screen activity.) If you bind an Alt key that is used as a menu shortcut to a command in SlickEdit, the command takes precedence. For example, Alt+F is the shortcut for the File menu in the menu bar, but the WROX emulation binds Alt+F to fill-selection. When you press Alt+F, you get fill-selection. You might be wondering how you access menu functions with the keyboard with this setting. You press and release the Alt key by itself to invoke the main menu. (This works on most Windows programs as an alternative way to invoke the main menu.) Then you press the mnemonic key for the menu item you wish to invoke, for example, F for the File menu. If you change your mind while the focus is in the menu bar and do not wish to invoke a menu item, press the Escape key to return the focus to the buffer. It should be noted that the Alt menu setting on the General tab of the General Options dialog (Tools Options General) controls this behavior. If you unselect Alt menu, you cannot use the Alt key to toggle the focus to and from the menu bar.
21
Macro Variables
Macro variables control a large number of SlickEdits configuration settings. Many settings can be changed through the configuration dialogs, but some settings can be changed only by setting the values of macro variables. For example, the def_undo_with_cursor macro variable controls whether undo steps backward through cursor movement. The setting can only be changed through the macro variable. See Chapter 8 for more details about undo in SlickEdit. It is important to understand macro variables for several reasons: Some settings have no GUI dialog to configure them and can be controlled only by setting macro variables. Macro variables provide a way to configure SlickEdit programmatically. Understanding macro variables can help you understand the behavior of many features of the editor, when viewing macro source code.
See Chapter 17 for more details about programmatic configuration using macro variables, and understanding editor behavior. In many parts of this book, when we discuss features, we mention macro variables that are used to configure options on those features. The following sections explain how to query the current value of a macro variable, and how to set a macro variable.
1.
Invoke gui-set-var (Macro Set Macro Variable). The Set Variable dialog appears, shown in Figure 2-1.
Figure 2-1
2.
Specify the name of the variable. As you type, a dropdown appears with matching names, as shown in Figure 2-2.
Figure 2-2
22
Chapter 2: Configuration
3.
When you have selected the desired variable, press Enter. The dialog displays the current value, as shown in Figure 2-3.
Figure 2-3
4.
If you wish to change the value, enter the new value and click OK. SlickEdit updates the variable.
1. 2.
Open the command line. Type the command set-var, followed by a space. The command line appears, as shown in Figure 2-4.
Figure 2-4
3.
Type part of the name of the variable. The command line prompts you for matching variables, as shown in Figure 2-5.
Figure 2-5
4.
When you have selected the desired variable, press Enter. The command line displays the current value, as shown in Figure 2-6.
Figure 2-6
5.
If you wish to change the value, enter the new value and press Enter. SlickEdit updates the variable.
23
Common Settings
In this section, we cover various common configuration settings. There are many more settings available in SlickEdit other than those covered here. The ones covered here are chosen because they are commonly needed by users but are not necessarily obvious in the interface.
Appearance
In this section, well mention a few basic things you can do with the appearance of SlickEdit that might not be obvious. Most of these settings have value beyond pure aesthetics. They are intended to provide visual clues to make you more productive.
24
Chapter 2: Configuration
Show Top of File Line
Also on the General tab of the General Options dialog is the Top of file line option. This line provides a visual cue to show you are at the top of the file. More importantly, depending on your emulation and other configuration settings, some operations that affect the line after the cursor position are not possible unless you can place the cursor before the first line. For example, in the default configuration, copying or moving an entire line places the line after the current line. If you want to copy or move a line to the start of the file, you need to be able to put the cursor before the first line. The top of file line lets you do this. We look at copying and moving lines in Chapter 8.
Special Characters
Another useful setting for visual cues is to make special characters visible. You can do this by invoking view-specialchars-toggle (View Special Characters). Special characters include: End of line. Tab. Space. Virtual Space. End of File.
You can customize how SlickEdit displays each special character on the Special Characters tab of the General Options configuration dialog.
Fonts
Fonts are a rather obvious visual setting. SlickEdit allows you to change the font for several different screen elements. Use the Font Configuration dialog (Tools Options Fonts) to configure fonts. The most important elements are: SBCS/DBCS Source Windows (Single-Byte Character Set and Double-Byte Character Set) Used for most programming work. Hex Source Windows Used mostly for displaying binary files and checking for special characters. Unicode Source Windows Used mostly for XML.
25
You need to change the font for each screen element individually. Chapter 17 shows how you can use a Slick-C script to set your fonts programmatically. There are many resources on the Web for fonts for programming. You can find a lot of fonts listed and compared at these sites:
http://keithdevens.com/wiki/ProgrammerFonts http://www.lowing.org/fonts/
The default font for SlickEdit on Windows is Courier New. While this is a widely used monospaced font, it is not specifically designed for programming. Some people find the serif look of Courier New cluttered and distracting and prefer a more open sans-serif font. Lucida Console is also available as standard with Windows and is less cluttered than Courier New. However, the spacing and relative sizes of characters are still not ideal for programming. Bitstream Vera (http://www.gnome.org/fonts/) is an example of a font that works well for programming. It is open and clear. It has a numeric 0 (zero) that is easily distinguished from a capital O (oh), and a numeric 1 (one) that is easily distinguished from a lowercase L. It also has large, easily distinguished punctuation characters such as colon, semicolon, period, and comma. SlickEdit ships BitStream Vera in its Mac installation. For other operating systems, you can download BitStream Vera from the URL above. Try it out.
Line Behavior
One fundamental choice you can make when using SlickEdit is whether you want the editor to treat the buffer as a stream of text, or a collection of lines. Most Windows and UNIX editors lean toward the stream model for text. Thus, for example, if you move the cursor to the end of a line, and then try to move to the right, the cursor comes to the beginning of the next line. This is nice for word processors, but is usually not appropriate for programming. When programming, you are typically working with lines. For most programming languages, a line represents a statement. The next line is the next statement. When you press the right arrow key, you want the cursor to move to the right, even if it is currently at the end of the line. You may be trying to add a line comment, for example. In the CUA emulation, SlickEdit follows the stream model, as that is the most familiar to many users. Some emulations, such as the SlickEdit emulation, use the line model instead. Alternatively, you can control the line behavior using several related configuration settings. Rather than having a single line behavior setting, SlickEdit allows you to change several related behaviors independently. All of the line behavior settings are found in the Redefine Common Keys dialog (Tools Options Redefine Common Keys), shown in Figure 2-7.
26
Chapter 2: Configuration
Figure 2-7
Table 2-2
Setting Cursor wrap Description When on, the cursor-left and cursor-right commands wrap when the cursor is at the beginning or end of a line. When off, the cursor commands can take the cursor beyond the end of the line. When on, the cursor stays within the text when moving up and down. When off, the cursor remains in the same column, whether or not the text extends to that column. When on, the cursor moves up and down window lines in soft wrapping mode. When off, the cursor moves up and down buffer lines. See note below.
Up/Down on text
When on, the cursor can move to column 1 regardless of margins in word wrap mode. When off, the cursor wraps at the left margin in word wrap mode. See note below. When on, the cursor jumps over tab characters in the buffer. When off, the cursor can be moved into tab characters, one space at a time. Typing inside a tab character converts the tab to the appropriate number of spaces. continued
27
The Up/Down within soft wrapped lines setting applies only in soft wrapping mode. Soft wrapping mode displays long buffer lines as multiple lines in the window, marking a continuation with a little arrow on the right-hand side. Turn on soft wrap globally or per file extension on the Word Wrap tab of the Extension Options dialog (Tools Options File Extension Setup). The Line wrap on text setting applies only in word wrap mode. When word wrap mode is on, SlickEdit wraps text you type to stay within the left and right margin columns. Turn on word wrap per file extension on the Word Wrap tab of the Extension Options dialog. A related setting concerning line wrapping is the Click past end of line checkbox on the General tab of the General Options dialog. This setting permits a mouse click to place the cursor beyond the end of a line with a mouse click. If you turn off Up/Down on text, you would probably also turn on Click past end of line. If you type something beyond the end of a line, the space in between becomes padded with spaces. If you delete the text, the trailing spaces remain. You can remove trailing spaces from a line using removetrailing-spaces (Edit Other Remove Trailing Whitespace). However, if you turn on Strip trailing spaces in the Save tab of the File Options dialog (Tools Options File Options), this is not usually necessary.
28
Chapter 2: Configuration
For the Enter key, there are three choices: nosplit-insert-line, split-insert-line, and maybesplit-insert-line. When you change the behavior of Enter using the Redefine Common Keys dialog, SlickEdit also changes Ctrl+Enter to the complementary behavior. The behaviors are shown in Table 2-3.
Table 2-3
Command for Enter
nosplit-insert-line
Description Does not split line. A new line is added below the current line. Splits line. In insert mode, splits line. In replace mode, moves cursor to first column of next line.
split-insert-line maybe-split-insert-line
nosplit-insert-line nosplit-insert-line
The pair split-insert-line and nosplit-insert-line are both commonly used while programming. Decide which you prefer as your default, and use the other with the Ctrl key. Or use maybe-splitinsert-line if that behavior works for you. All of these commands are integrated with other SlickEdit features. For example, if you are editing a source file with comments, the line splitting and joining in these commands attempt to keep the comment flow intact. Thus if you press Enter to insert a line break in a comment, SlickEdit continues the comment to the next line. If you decide to replace the standard commands with something of your own, you may need to consider whether you will lose some of this functionality. Of course, if you study the Slick-C source for commands such as split-insert-line, you can provide the same functionality in your own commands. Regardless of your settings for common keys for splitting and joining lines, you can also use split-line (WROX: Alt+S) and join-line (WROX: Alt+J) as alternatives. These commands provide more rudimentary splitting and joining, however. They dont preserve comment flow.
29
Managing Configurations
When you install SlickEdit, files are placed in two directories: The program installation directory. The user configuration directory.
The program installation directory contains the static files that dont change once they are installed. These include executable files, libraries, help system, templates, and macro source code. The default location for the program installation directory on Windows is C:\Program Files\SlickEdit 2007\. On UNIX, it is a global directory such as /opt/slickedit/. The user configuration directory contains all configuration data and other user data. The configuration data are initialized to defaults, and then may change as you use SlickEdit. We cover the content and management of the configuration directory in this section.
Configuration Directory
SlickEdit stores all your personal configuration data in the user configuration directory. By default, this directory is located under your home directory. SlickEdit creates a separate configuration directory for each update release. Thus for SlickEdit 12.0.2 on Windows, the default location for the user configuration directory is My Documents\My SlickEdit Config\12.0.2. On UNIX, the configuration directories are placed under $HOME/.slickedit/. If SlickEdit cannot find the default configuration directory when it starts, it tries to find a configuration directory for a previous version. If it finds one, SlickEdit migrates the configuration settings from the previous version to the current version. The configuration directory contains several files. The most important file is the SlickEdit state file, stored in vslick.sta on Windows and vslick.stu on UNIX. This is a binary state file that contains many of SlickEdits configuration data. It includes most of the user settings and all compiled macro code. An important thing to realize about the state file is that it is normally only saved when you exit from SlickEdit. This means that if you change your configuration, and then the editor gets terminated abnormally (e.g., because of a power outage), your changes are not saved. You can force SlickEdit to save the state file during a session using the save-config command. If you have made configuration changes that you do not wish to save, you can discard them by exiting SlickEdit using the safe-exit command. There are several other configuration files and subdirectories too. Some of these are listed in Table 2-4.
30
Chapter 2: Configuration
Table 2-4
File/Directory
tagfiles/ templates/ vsdelta/ alias.slk *.als filepos.slk uscheme.ini user.cpp vrestore.slk vusrdefs.e (UNIX: vunxdefs.e)
Description Global runtime library tag files (see Chapter 5). User-defined code templates (see Chapter 11). File backup history (see Chapter 13). Global aliases (see Chapter 11). Extension-specific aliases (see Chapter 11). Cursor positions in files opened. User-defined color schemes. User-defined C/C++ preprocessing configuration settings. GUI state, command history, file histories, etc. Slick-C representation of key bindings, user settings (see Chapter 17). Toolbar customizations.
vusrobjs.e
There are several other files in the configuration directory. Refer to the online Help for a more complete table. If you delete the directory itself, instead of just the contents, then SlickEdit will look for configuration directories for previous versions, which is probably not what you want. You can back up your entire SlickEdit configuration by making a copy of the configuration directory. If you encounter a problem with SlickEdit, it could be due to a corrupt configuration. You can try restoring a backup configuration, or reverting to the default configuration. We cover advanced ways to restore your configuration to a known state in Chapter 17.
31
These options are documented in the online Help. Both of these options override the version migration mechanism described above. If you do override the configuration directory location, be careful to remember that fact. For example, if you need to revert to the default configuration, or you receive instructions from SlickEdit Support, its important that you perform the actions in the correct directory. Another way to use different configurations without changing where SlickEdit looks for the configuration directory is to keep different copies of the directory and contents with different names, and rename the one you wish to use to the default name. For example, suppose in your My SlickEdit Config folder you have two backup copies of the 12.0.2 configuration directory: 12.0.2_safe and 12.0.2_ experimental. By copying or renaming one of these to the default name, 12.0.2, you make it the active configuration. To switch to the other, stop SlickEdit, rename the directories as desired, and restart.
Summar y
We covered a selection of the most common configuration settings in this chapter. There are many, many other settings. Some of these settings are quite obscure and do not affect most users. You are referred to the reference information in the online Help for those. For example, we dont discuss network or proxy settings. Other settings are rather obvious and do not need to be covered here. For example, you should not have much trouble figuring out how to change colors if you decide you want to. Many other configuration settings apply to specific topics that are covered elsewhere in this book, and they are covered together with those topics. In the next chapter, we take a look at using and configuring the different windows of the interface.
32
Managing Windows
When I started using the ancient ancestor of SlickEdit, the E editor on DOS in the 1980s, screens had only 25 lines and 80 columns. The editor had a command line, a status line, and a help line. I could see 22 lines of my file, and those lines were not particularly long. Figure 3-1 shows this old editor.
Figure 3-1
These days we have GUI environments and much bigger screens. Many programmers now use a monitor at a resolution of 1600 1200 or more. With that kind of screen, in full screen mode its easy to get 60 or 70 lines on the screen, with a couple of hundred columns. (And, if you dont mind a 6-point font, you can get a lot more.) This is usually enough space, because most peoples brains cant cope with more lines of code than that anyway. The thing is, our desktops and tools are a lot more sophisticated now, and they want to give us a lot more information, and give us more different ways of doing things. Some Office-style applications start up with three or four rows of toolbars. IDEs usually have extra windows on the sides and bottom, for different types of navigation. SlickEdit also has a lot of toolbars and tool windows.
Split Windows
In the default configuration, SlickEdit displays windows cascaded. Usually for programming, its more effective to maximize the Edit window. You can change the default behavior by checking the Maximize first window option on the General tab in the General Options dialog (Tools Options General). Often while programming, you need to look at two files at once. Or, you may want to look at two different parts of the same file at once. Table 3-1 shows some commands you can use for working with split windows.
Table 3-1
Command
hsplit-window
Key Ctrl+H (Window Split Horizontally) (Window Split Vertically) (Window One Window)
vsplit-window one-window
34
Full Screen
Regardless of your monitor size and resolution, there are times when you want to see as much of your buffer as possible, and nothing else. An example of this is when editing a large, badly formatted HTML file. Another example is when you are working with many columns of data, and splitting the lines is not possible because it would prevent block editing. In these cases, you may find full screen mode handy. Use the fullscreen command (View Full screen) to toggle full screen mode. When in full screen mode, SlickEdit displays the menu bar, the left margin, the scroll bars (if turned on), and the command line and status area. Nothing else is shown, and you have the maximum amount of your buffer visible.
Toolbars
I have a rather harsh view of toolbars. I think they are basically invented for and useful only for marketing purposes. Everybody seems to have one these days, whether useful or not. SlickEdits Standard toolbar has many frequently used tools. The tools are used so frequently that you will be working very slowly if you use the toolbar to invoke them. These tools include file load and save commands, clipboard and undo commands, and search-and-replace commands. You need to know the keyboard shortcuts for all of these commands to use SlickEdit effectively. There is no reason for most users to use the Standard toolbar. You can save some space by removing it and also the Current Context toolbar. Some of the more specialized toolbars are handy though, especially if they are for features that you dont use frequently. I dont use the debugger very often, so when I do use it, I use the toolbar for a lot of its commands. If I used the debugger more often, I would learn the keyboard commands. As a general rule, you should avoid using toolbars when using SlickEdit. Learn and use the keyboard bindings for commands. If you like toolbars regardless, you can adjust the size and other options for the icons on the Options tab of the Toolbar Customization dialog (View Toolbars Customize).
Tool Windows
Tool windows are different from toolbars. Tool windows provide you with different kinds of information, and different functionality, from that available in the main editing area. Depending on the work you are doing, you will use some tool windows frequently and others not at all.
35
36
Figure 3-2
You change a tool window to floating or docked mode by right-clicking on its title bar. To change a floating tool to docked, and to add it to a docking group, follow these steps:
1. 2. 3. 4.
Ensure that the docking group has auto-hide turned off and is visible. Right-click on the floating tool windows title bar. SlickEdit displays its title context menu. If the window is not already dockable, click Dockable to make it dockable. Drag the window to dock it in the desired docking group. Drag the mouse pointer to the title bar of the desired docking group. When the mouse pointer is in the title bar, the docking group pane is selected with a black rectangle. This is shown in Figure 3-3, where a tool window is being docked to a group already containing the Projects tool window.
Figure 3-3
37
You can rearrange the order of tabs in a docking group by dragging them. To change a docked tool window to floating, follow these steps:
1. 2. 3. 4. 5. 6. 7.
Ensure that the docking group has auto-hide turned off and is visible. Select the tool window you wish to make floating. Right-click on the tool windows title bar. SlickEdit displays its title context menu. Click Floating to make the tool window floating. It detaches from the docking group. Right-click on the tool windows title bar. SlickEdit displays its title context menu again. Click Dockable to make the tool window not dockable. Now, when you drag the window around to position it, SlickEdit will not accidentally dock it. Drag the tool window to the desired location, and resize it if necessary.
Whats the best arrangement for tool windows? It depends on you. If you have a large screen and dont mind SlickEdit putting its tool windows all over it, you may find floating tool windows convenient. They can be shaped more flexibly than docked tool windows. If you prefer to keep all SlickEdits tool windows within the main editor window, you will prefer docked tool windows. When docked, some tool windows work better with a horizontal layout, and some work better vertically. For example, the Build tool window works best docked at the bottom of the screen, as in the default configuration. Some tool windows can adapt themselves to either horizontal or vertical orientation. For example, the Find Symbols tool window moves its options panel to the right-hand side of the tool window when it is docked horizontally, and to the bottom if it is in a vertical arrangement. When choosing docking groups for docked tool windows, consider which combinations of tool windows you might like to have visible at the same time. Some tool windows, such as Preview, are constantly updated and can be useful while working with your code. Others are used for specific tasks and are best closed or hidden when not being used.
38
Key Alt+T, K Alt+T, B Alt+T, A Alt+T, C Alt+T, D Alt+T, H Alt+T, L Alt+T, P Alt+T, W Alt+T, F Alt+T, T Alt+T, O Alt+T, U Alt+T, V Alt+T, J Alt+T, R Alt+T, X Alt+T, S Alt+T, Y
Tool Window Bookmarks Build Slick-C Call Stack Class Defs Backup History Files: Open Files tab Files: Project Files tab Files: Workspace Files tab Find Symbol FTP Open Output Preview Projects References Regular Expression Evaluator Search Results Symbols
With this configuration in place, you can use the Alt+T keyboard sequence to activate any tool window, then Escape to dismiss it or move the focus back to the buffer. In this way, you can maximize your screen space and access any tool window functionality with a couple of key strokes. An alternative to this scheme is to use keyboard bindings to toggle tool windows, rather than only to activate them. For most of the activate-xyz commands shown in Table 3-2, there are corresponding toggle-xyz commands that toggle the tool windows. You can find all the tool window commands in the supplied Slick-C macro source, in the tbcmds.e file. By consulting that file, you can find out how
39
Summar y
The SlickEdit user interface is powerful and flexible. Learn which tool windows are useful for your work, and make sure they are quickly available. You can use the keyboard scheme presented in this chapter, or adapt it for your own needs. In the next chapter, we look at workspaces and projects, which enable many of SlickEdits advanced code editing features.
40
Tagging refers to SlickEdits ability to index the symbols in your code for navigation and smart assistance features. We go into SlickEdits tagging features in more detail in Chapter 5. To organize your work using SlickEdits workspaces and projects, you create a workspace. In the workspace you add one or more projects. SlickEdit stores the workspace details in a .vpw file, and the project details in one or more .vpj files. SlickEdit also creates a tag file (.vtg) to tag your project files and a .vpwhist file that contains state information about your workspace. A workspace contains a set of projects and retains the state of an editing session. Opening a workspace returns you to the same state you were in when you last worked on this workspace, including the set of open files. Files are added to projects, and projects are added to workspaces, thus you cannot directly add a file to a workspace. You can open files that do not belong to any of the workspaces projects, and they will be available for editing in the next session if not closed. A project can be just a set of files, but if you are using the SlickEdit build system, then a project corresponds to a build target, something that gets built. For Java, its common to have a single
44
The workspace definition contains a list of projects in the workspace, and other global parameters. The project definition defines all the files in a project, and all the tools and configuration targets for the project. These two files could be checked into version control along with the rest of your project source, if you want to share project definitions and tool configuration with other team members. The tag file contains tags for your projects. The tag file is derived from data in your source files and should not be checked into version control. It should be considered a transient file, like compilation outputs. The workspace state file saves the state so that SlickEdit can restore it when you reopen the workspace. For example, it contains the list of buffers open and the file history. The workspace state file should not be checked into version control, as it is transient and specific to each developer. When you add files to a project, you have three choices: Add files. Add tree. Add wildcard.
Add tree is really just an alternative form of add files. They both result in the same information in the project file: Each file is explicitly listed in the project. Add wildcard is different. It stores the wildcard pattern in the project, rather than the specific files. Each of these approaches has its advantages and disadvantages. Storing each specific file gives more precision and can give better performance. Storing wildcards gives more convenience. Which you choose depends on the nature of your project and what other tools you and your other developers are using. If you are all using SlickEdit, and no other tool to create files in your project, you may find that storing specific files in your project works best. If a team member adds a file and commits his project definition file, other team members will pick up the changes next time they update from the repository. On the other hand, if you often have new files added to the project from outside of SlickEdit, you may find that it is too labor-intensive and error-prone to keep the SlickEdit project file up-to-date with the correct project source files. In this case, you may find that wildcards are better. Generally speaking, wildcards are more convenient than specific files. Once you have them set up correctly, you can pretty much forget about them, and SlickEdit will always be up-to-date with the source files in your project.
45
The Example
For our example projects, well create a simple console application that uses only a few files. Well see how to: Organize the source files. Compile or build the application. Run automated unit tests, and then review the results. Run the application itself.
Well see how SlickEdit integrates with popular build tools such as Make and Ant. Well also see how SlickEdit can interpret output from compilers and tests to help you navigate to errors. Our simple console application solves the n-queens problem. This is a nice programming puzzle where you have to find an arrangement of n queens on an n n chessboard so that none of the queens attacks any other. The smallest board that its possible to do this on is a 4 4 board. A 4 4 solution is shown in Figure 4-1.
Figure 4-1
To show how to set up SlickEdit projects for different languages and compilers, well work through the example in three different languages: GNU C/C++. Java. Ruby.
The source code for each project is included on the accompanying CD-ROM, under Author/Chapter04/
projects.
46
On my system these files are in the directory Z:\ProfessionalSlickEdit\projects\gnu_queens. The code for this project is included on the accompanying CD-ROM. The listing for board.h follows:
#include <vector> class Board { public: Board(int size); int size(); void place(int row, int col); int unplace(int row); bool is_ok(int row, int col); bool solve(); int col(int row); private: int size_; std::vector<int> pos_; std::vector<bool> col_; std::vector<bool> diag1_; std::vector<bool> diag2_; };
47
48
The driver program creates a Board of the required size, asks the Board to solve itself, and then outputs the Board and the elapsed time to solve.
1.
Open the New Project dialog (Project New). The dialog is shown in Figure 4-2.
Figure 4-2
SlickEdit supports several project types. Some of the project types provide wizards to set up the project configuration. Some project types provide template files. You can also create your own custom project types with your own configurations. We look at custom project types later in the chapter. For now well continue with the GNU C/C++ project.
49
5. 6.
Figure 4-3
7.
Click Next. SlickEdit displays the second page of the wizard, shown in Figure 4-4. Here we can request that SlickEdit add a file containing one of two very simple main() templates. For the queens project, we have a main() function already in queens.cpp; thus well leave the An empty project option selected.
Figure 4-4
50
Figure 4-5
9. 10.
Click Finish. SlickEdit completes the wizard and displays the New Project Information dialog, summarizing our choices. Click OK to dismiss the dialog. SlickEdit opens the Project Properties dialog, as shown in Figure 4-6. The Project Properties dialog is where you configure most of the important options for your project. You can open this dialog at any time via Project Project Properties. For the purposes of the queens application, all well do for now is add the source files to the project.
Figure 4-6
51
We have now concluded the basic steps for setting up a project. We are now ready to compile, execute, or debug it. Some compiler projects may require a little more configuration to get everything working.
Figure 4-7
If you hide the Build tool window, SlickEdit shows the message for the current compiler error in the message area, as shown in Figure 4-8.
52
Figure 4-8
You can navigate among errors in the buffer using prev-error (Ctrl+Shift+Up) and next-error (Ctrl+Shift+Down). When the last error in one buffer is reached, next-error takes you to the next buffer containing errors.
53
1. 2. 3.
Write CxxTest test suites. Generate a CxxTest test runner to run the test suites. Execute the test runner to run the tests.
54
0)); 1)); 2)); 3)); 0)); 1)); 2)); 3)); 0)); 1)); 2)); 3)); 0)); 1)); 2)); 3));
55
Refer to the online user guide at http://cxxtest.sourceforge.net/guide.html to find out more about writing tests with CxxTest. We wont make board_tests.h part of our main project. Instead, well create a second project specifically for building and running the unit tests. This project will include the board.h and board.cpp files defining our Board class, as well as the board_tests.h file containing the test suite. It will also include the test runner, which well create below. It wont include the queens.cpp file with the main() function of our application. Follow these steps to set up a new project:
1. 56
You now have a project for building and running the tests. You can switch between the tests and the main application using Project Set Active Project. You cant actually build or run the tests yet, because we still need to generate the test runner.
Well add a tool to our project to generate the test runner. Follow these steps:
1.
57
Figure 4-9
4. 5.
Enter Generate Test Runner for the New Tool Name. Click OK. SlickEdit adds the tool to the tool list and shows you its properties. Enter the command line:
The command line should be all one line. You may need to adjust the paths for your own installation of Perl and CxxTest.
6.
You now have a new item on the Build menu: Generate Test Runner. Try it now. If everything was configured correctly, a file runner.cpp should be generated in your project working directory. The contents of runner.cpp are not particularly important. You can take a look if you want to find out more about how CxxTest works. For our purposes, the important point is that it contains a main() function and thus can be used to run an application. The runner.cpp file does include other header files from the CxxTest distribution. For it to compile without errors, we need to add the CxxTest distribution directory to our projects include directories. To do this, follow these steps:
1. 2. 3. 4. 5.
Open the Project Properties dialog. Select the Directories tab. Double-click on the bottom line in the Includes list to add a new directory. Enter the directory where CxxTest is installed, for example, C:\cygwin\usr\local\cxxtest. Click OK to close the Project Properties dialog.
Well now add runner.cpp to our project, so that it will be included in the compilation step, and well be ready to run.
1. 2. 3. 4. 58
Open the Project Properties dialog. Select the Files tab. Click Add Files, and add runner.cpp. Click OK to close the Project Properties dialog.
Figure 4-10
Lets introduce a bug in the code and see what happens when we run the tests. Well change the last assignment in Board::unplace() from false to true, as shown below:
int Board::unplace(int row) { int col = pos_[row]; pos_[row] = -1; col_[col] = false; diag1_[col-row+size_] = false; diag2_[col+row] = true; return col; }
After making this change, we execute the tests again. This time, we get a bunch of failures, as shown in Figure 4-11. You can use SlickEdits error navigation commands prev-error (Ctrl+Shift+Up) and next-error (Ctrl+Shift+Down) to navigate among the test failures. This works because the CxxTest output looks like compiler output, with line numbers of errors. For this to work properly with SlickEdit, its important that you have Capture output and Output to build window checked in the configuration for the Execute tool in your project properties.
59
Figure 4-11
Target Configurations
SlickEdit supports multiple target configurations. The default configurations for a new project are Debug and Release, familiar to developers who have used Microsoft Visual C++ products. The configurations allow you to store compiler options in a named configuration.
Build Systems
SlickEdit supports three different build system alternatives for C/C++ projects: Build without a makefile (dependencies automatically checked). Build with a user-maintained makefile or custom build command. Build with an auto-generated, auto-maintained makefile.
For experimenting or for small projects, you can use SlickEdits automatic dependency checking, as we did in our example. For large professional projects, you will probably have additional artifacts and other steps in the build process, and you will probably use your own makefile.
60
Ive placed these files in Z:\ProfessionalSlickEdit\projects\java_queens on my system. The code for this project is also included on the accompanying CD-ROM, and we wont use space by listing it here. Its very similar to the C++ code already presented.
1. 2. 3. 4. 5. 6. 7. 8. 9.
Open the New Project dialog (Project New). Select project type Java Empty Project. There are many other Java project types, but most of them are more for demonstration purposes than for real programs. Usually for Java projects you will use the Java Empty Project project type. Enter java_queens for the Project name. Enter the Location for the SlickEdit project files. On my system, I put the project files in the root of the source tree, in Z:\ProfessionalSlickEdit\projects\java_queens. Enter Queens as the Executable name. For Java programs, the executable name is the class containing the main() function. Click OK. SlickEdit opens the Project Properties dialog. Click Add Files. SlickEdit displays the Add Source Files dialog. Select the two files Board.java and Queens.java, and click OK. SlickEdit shows the two Project files. Were done setting up the project. Click OK to close the Project Properties dialog.
We now have the Java project set up. We can use SlickEdit to build it.
61
Figure 4-12
As with C/C++, you can use prev-error (Ctrl+Shift+Up) and next-error (Ctrl+Shift+Down) to navigate among your compilation errors.
1. 2. 3. 4.
Open the Java Options dialog (Build Java Options). This dialog has several tabs to configure all aspects of compiling, running, and debugging Java programs. Select the JRE tab. Enter a number (such as 4) in the Arguments field. Click OK to dismiss the Java Options dialog.
62
We need to add this source file to the project. Use Add Files on the Files tab of the Project Properties dialog to do that. We also need to add junit.jar to the classpath, for compilation and execution of the unit tests. To do that:
1. 2. 3. 4. 5. 6.
Invoke javaoptions (Build Java Options). The Java Options dialog appears. Select the Classpath tab. Click Add Jar File. The Open dialog appears with the title Add Jar File. Navigate to and select junit.jar. Click OK to close the Add Jar File dialog. Click OK to close the Java Options dialog.
63
1. 2. 3.
Activate the Projects tool window. (Click its tab or use View Toolbars Projects.) Expand the project root to display the package or test case you wish to run. In this case, the files are all in the default package (i.e., they are not in a package); thus we select that. Right-click on the package, and select Unit Test Run from the context menu. SlickEdit displays the Unit Testing tool window and runs the tests. The results are shown in the tool window.
If there are test failures, they are shown in the Unit Testing tool window, along with stack traces. Lets experiment with a test failure. Again, we change the last assignment in the unplace() method from false to true:
public int unplace(int row) { int col = pos[row]; pos[row] = -1; this.col[col] = false; diag1[col - row + size] = false; diag2[col + row] = true; return col; }
Run the tests again from the Unit Testing tool window:
1. 2.
Activate the Unit Testing tool window if it is not displayed (View Toolbars Unit Testing). Right-click BoardTest, and select Run Test from the context menu. SlickEdit runs the tests again. This time, there are failures, as shown in Figure 4-13.
You can double-click in the Tests pane or the stack traces to navigate to the failure locations in the source files.
Figure 4-13
64
To manage the project with Ant, add the build.xml file to the projects files. Once you have done this, SlickEdits Build menu should include a menu entry called Execute Ant Target, which cascades down to the targets in your build.xml file.
65
Ive placed these files in Z:\ProfessionalSlickEdit\projects\ruby_queens on my system. The code for this project is also included on the accompanying CD-ROM. The class uses the same algorithm as the C++ and Java versions.
1. 2. 3. 4. 5. 6. 7. 8. 9.
Open the New Project dialog (Project New). Select the project type (Generic). This is the project type you use for all projects that dont use specific compilers and tools. For example, you would use Generic for an ASP or PHP Web project, or a PL/SQL database project. Enter ruby_queens for the Project name. Enter the Location for the SlickEdit project files. On my system, I put the project files in the root of the source tree, in Z:\ProfessionalSlickEdit\projects\ruby_queens. Enter queens.rb as the Executable name. Click OK. SlickEdit opens the Project Properties dialog. Click Add Files. SlickEdit displays the Add Source Files dialog. Select the two files board.rb and queens.rb, and click OK. SlickEdit shows the two Project files. Were done setting up the project. Click OK to close the Project Properties dialog.
We now have the Ruby project set up. We can use SlickEdit to run it.
1. 2. 3. 4. 5. 6. 66
Open the Project Properties dialog. Select the Tools tab. Select the Execute tool. Change the Command line to ruby queens.rb 4. This will run the script with the argument 4. Select the Capture output and Output to build window options. This will cause the program output to appear in the Build tool window. Click OK to close the Project Properties dialog.
If we now run this using project-execute, we see the following error output in the Build tool window:
queens.rb:14: unterminated string meets end of file queens.rb:14: parse error, unexpected $, expecting kEND
Because these look like compiler error messages, SlickEdit can navigate among the errors using prev-error (Ctrl+Shift+Up) and next-error (Ctrl+Shift+Down).
67
1. 2. 3. 4. 5. 6. 7. 8.
Open the Project Properties dialog. Select the Tools tab. Click New. SlickEdit shows the New Project Tool dialog. Enter Run Tests for the New Tool Name. Click OK. Enter ruby test_board.rb for the Command line. Select the Capture output and Output to build window options. This will cause the program output to appear in the Build tool window. Click OK to close the Project Properties dialog.
SlickEdit adds a new item called Run Tests in the Build menu. You can use this item to run the tests. Lets try this with the same bug weve used before in the C++ and Java versions. We change the last assignment of the unplace! method from false to true:
def unplace!(row) col = @pos[row] @pos[row] = nil @col[col] = false @diag1[col-row+size] = false @diag2[col+row] = true col end
Now run the tests using Build Run Tests. SlickEdit shows the test results in the Build tool window, as shown in Figure 4-14. However, this time there is no error navigation. This is because SlickEdit doesnt know how to parse the error messages from the Ruby interpreter.
Error Parsing
The error messages from the tests look like this:
1) Failure: test_solve_true(TestBoard) [test_board.rb:88]: <false> is not true. 2) Failure: test_unplace(TestBoard) [test_board.rb:52]: <false> is not true.
We can set up SlickEdit to recognize these error messages, using Error Regular Expressions configuration.
68
Figure 4-14
This procedure makes use of SlickEdit regular expressions. In particular, to understand the procedure completely, you need to understand match groups in regular expressions. For more detail about SlickEdit regular expressions, see Chapter 7. Follow these steps:
1.
Open the Error Regular Expressions dialog (Build Configure Error Parsing). SlickEdit displays the dialog shown in Figure 4-15.
Figure 4-15
69
{#3[^\[]+}\[{#0:p}\:{#1:i}\]\:
This matches the middle line of a Ruby unit test error message. SlickEdits Error Regular Expression cannot match error messages that span more than one line. The expression is made up of three tagged expressions. The first one, {#3[^\[]+}, matches the test method and class at the beginning of the line, for example, test_solve_true(TestBoard). This match is assigned to match group 3. The second group is {#0:p}, which matches the filename and is assigned to group 0. The last group is {#1:i}, which matches the line number and is assigned to group 1. Ruby unit test error messages dont include a column number. If they did, we could assign another match to group 2 for the column number. SlickEdit uses the filename and line and column numbers for error navigation. See the online Help for more detail.
Type or paste the error message lines into the Test Case text area. Click Validate to test the regular expression. If it is correct, SlickEdit displays a Matched Error Expression window containing details of the match. Click OK to close the Matched Error Expression dialog. Click OK to close the Edit Expression dialog. Click OK to close the Error Regular Expressions dialog.
Run the tests again using Build Run Tests. You can now navigate among the errors using prev-error (Ctrl+Shift+Up) and next-error (Ctrl+Shift+Down).
Custom Projects
SlickEdit includes several preconfigured project types. You can create new customized project types based on these, and change default configuration settings. This is useful if you want to change the default compilation settings or any other tool settings predefined by SlickEdit. If you want to do further customization in your custom project type, you can write a SlickEdit macro that is run when the project type is instantiated. For example, suppose all of your projects use a certain directory structure. This is a common feature in Java projects, which often have a structure similar to that shown in Figure 4-16.
70
Figure 4-16
SlickEdits custom projects dont support adding folders to the project upon initialization. Well create a Slick-C macro to do the job, and combine this with a new custom Java project type. The macro will also add a wildcard to the project for all files under the src/ directory. To create the new project type, follow these steps:
1. 2. 3. 4. 5.
Invoke workspace-new (Project New). SlickEdit displays the New Project dialog. Click Customize. SlickEdit displays the Customize Packages dialog. Click New to create a new project type. SlickEdit displays the New Package dialog. Enter Java WROX for the Name. Select Java Empty Project to copy settings from. Select Generic if you do not wish to begin with any specific compiler support. SlickEdit displays a dialog titled Project Package for Java WROX. The dialog is very similar to the Project Properties dialog, but you cannot add files. Click OK to save the new project type, and close the Project Package dialog. Click OK to close the Customize Packages dialog. The new project type should now appear in the project types in the New Project dialog. Click Cancel to close the New Project dialog.
6. 7. 8.
Custom project definitions are stored in the usrprjtemplates.vpt file in your SlickEdit configuration directory. The SlickEdit GUI for custom project types does not allow you to specify the macro to run when a project is instantiated. To do that, well edit the XML file directly. Follow these steps:
1. 2. 3. 4.
Open the usrprjtemplates.vpt file in your SlickEdit configuration directory. Locate the XML element <Template Name=Java - WROX>. Add an InitMacro attribute to the element, so that it reads as follows:
The macro source for wrox_create_java_dirs.e is shown below. (The source is also on the CD-ROM.) You need to load the module to proceed with this example.
#pragma option(strict, on) #include slick.sh
71
FILESEP :+ :+ wrox;
FILESEP :+ :+ wrox;
// add wildcard for src/*, recursive, excluding SVN files _ProjectAdd_Wildcard(_ProjectHandle(), src\*, *\.svn\*, true); }
As well as running a macro when a project type is instantiated, SlickEdit allows you to run macros at other points in the project/build cycle. You can configure your project to run one or more commands when the project is open, and before and after a build. These commands are supported through the GUI for predefined and custom project types, in the Open and Build tabs. We could add various other features to the new project. One idea would be to add a starting build.xml Ant file. This could be done in a Slick-C macro, but would involve a lot of ugly code like this:
_insert_text( _insert_text( _insert_text( <target name=\clean\>); <delete dir=\build\/>); </target>);
As well as being ugly, this code is difficult to maintain. A better solution for inserting boilerplate template code into projects with SlickEdit is to use file templates. In Chapter 11, we have a look at templates and show how you can programmatically instantiate a template in a custom project type to initialize common files.
Summar y
SlickEdits workspace and project features are important for getting the most out of SlickEdit. Several useful features depend on you setting up a project for your source files. Tagging is probably the most important of these. We cover tagging in detail in the next chapter. Some navigational and other features also require projects to be set up. By adding custom tools to projects, you can add support for your own workflow in SlickEdit. An example of this is in unit testing, which has become a software development best practice. You can also automate the creation and setting up of new projects using custom project types. By providing your own InitMacro for your custom project type, you get the full power of Slick-C programming to customize your project on creation.
72
Context Tagging
A lot of SlickEdits power comes from a feature called Context Tagging. Many of SlickEdits advanced navigation, editing, and browsing features depend on Context Tagging: Navigating to definitions and references. Automatic completions of functions, members, and parameters. Browsing definitions and references.
Context Tagging creates databases of symbols in your projects and libraries, and uses those databases to provide symbol-based navigation, editing, and browsing. The process of creating a tag database for a set of source files or a library is called tagging. When tagging a set of files, SlickEdit scans the files for symbols and updates the tag database with the symbol information. This information includes various properties about the symbol: The symbols category (class, structure, function, variable, etc.). The name of the symbol (owning class, short name, qualified name, etc.). The location of the symbol (file, line and column numbers, offsets, etc.). Associated data for the symbol (return type, arguments, exceptions, etc.).
SlickEdit uses the symbol information to provide a range of useful features. In this chapter we describe how to ensure that your project is tagged correctly. We cover some of the features that Context Tagging provides. We also go into some detail about how to manage tag databases effectively and some issues that arise with tagging.
In the following section, we explain a little bit about tagging the files in your projects, and also the standard libraries for the languages youre using. Below, in Managing Tag Files, we talk about ways to tag additional runtime libraries used in your projects.
74
SlickEdit tries to find installation paths for each of these languages and displays them in the Create Tag Files for Run-Time Libraries dialog, shown in Figure 5-1. You can amend any of the installation paths, or disable tagging for any language by unchecking its box. Once you have specified all the details, click Create tag file(s), and SlickEdit initializes the tag databases.
Figure 5-1
You can run the auto-tagging again at any point later by invoking autotag. This command is also available via the Auto-Tag button on the Context Tagging Tag Files dialog (Tools Tag Files). Auto-tagging is available for C/C++, Java, and .NET only, but SlickEdit also can tag several other languages automatically as soon as you start using them. For example, Slick-C itself is tagged. Once you invoke any tagging-related feature in a Slick-C file, SlickEdit automatically creates the Slick-C tag database from the installed macro source. SlickEdit automatically creates tag databases for several dynamic languages too, such as Perl, Python, and JavaScript. We cover procedures for tagging in more depth below in this chapter, in the section Managing Tag Files. For now, lets take a look at some of the benefits of tagging.
75
Listing Members
When you are using classes or structures, SlickEdit can list members for you if it knows the type of the variable you are working with. This is useful because it can remind you of the name of a method, or inform you about an unfamiliar API. It also saves a lot of typing. Suppose you are working with the class shown in Figure 5-2.
Figure 5-2
If we declare a variable foo of type FooBase, and then type a dot after foo, SlickEdits List Members feature activates. Figure 5-3 shows the list that appears. In the figure, the list extends below the cursor position. If you want to see the code below, you can press Shift+Up to move the list to above the cursor. Shift+Down moves it back to below the cursor.
Figure 5-3
The feature works the same if the variable is declared as a pointer, and we use the C/C++ pointer operator ->. Figure 5-4 shows the example with the declaration changed to a pointer.
Figure 5-4
You can use the arrow keys to navigate the list. If you type part of the name of a member, the selection is moved to the first matching item. Press Enter to select a member, or Escape to dismiss list members.
76
Figure 5-5
If a method is overloaded, SlickEdit shows the variations as in Figure 5-6. You can click the blue arrows or use Ctrl+PgUp and Ctrl+PgDn to cycle through the variations.
Figure 5-6
If a member has a comment, SlickEdit shows this as documentation for the member. Figure 5-7 shows an example for the cancel() method.
Figure 5-7
If a member has JavaDoc comments, SlickEdit shows them as documentation for the member. Figure 5-8 shows an example for the start() method. You can page through the documentation comment using Shift+PgUp and Shift+PgDn.
Figure 5-8
77
Figure 5-9
List members is normally invoked automatically when you type a dot or -> operator. You can turn off automatic list members in the configuration dialog, by unchecking Auto-list members. You can always invoke list members manually with the list-symbols command (Alt+dot).
Figure 5-10
78
Figure 5-11
For some languages, SlickEdit can determine valid completions for parameters based on variables in the current scope. In Figure 5-11, there are no int variables in scope, and the only thing SlickEdit can suggest is a sizeof() expression. In Figure 5-12 we show an example in which there are some int variables in scope: sp and identifier. When SlickEdit shows the parameters for the start() method, it provides a list of suggested completions including these two variables.
Figure 5-12
If a variable exists in scope that matches a parameter in both name and type, SlickEdit goes further. The editor assumes that there is a very good chance that you will want to type in that variable name, thus it does it for you. Figure 5-13 shows this with our start() method again. This time, there is an int variable in scope with the same name as the savepoints parameter, thus immediately after we type the opening parenthesis, SlickEdit suggests that variable for the first parameter. Because the variable is selected, you can easily overtype it if you want something else. You can still use the arrow keys to select from the list of suggestions. Or, you can type a comma and move on to the next parameter.
79
Figure 5-13
Figure 5-14 shows what happens after typing a comma. The second parameter is a char* named name. Because there is a matching variable in scope, SlickEdit prompts with that. If this is the variable we want to pass for the parameter, all we need to do now is press the closing parenthesis. We didnt have to type any parts of the parameter names!
Figure 5-14
80
Figure 5-15
In this C++ example, the Preview tool window shows information about the solve() method in the Board class. The top-left pane shows the symbol itself, along with an icon to indicate the type of symbol. It also lists different locations if a symbol is overloaded or if it has a separate declaration and definition. The top-right pane shows documentation about the symbol. SlickEdit can parse and format documentation comments for various languages. The bottom pane shows the source file itself in which the symbol is defined. In this case, the source file is a C++ header file. When you are typing code or navigating around your source files, the Preview tool window is automatically refreshed to display information about the symbol the cursor is on. The Preview tool window is also shown during certain other operations, to provide help when choosing among symbols. The Preview tool window is also synchronized with other tool windows, like Defs, Class, Reference, and Symbols. When you select an item in these tool windows, the Preview window displays information about the selected item. We cover these tool windows below in this chapter.
Navigating to Definitions
To navigate to the definition of the symbol the cursor is on, invoke push-tag (Ctrl+dot). If there is a single definition, SlickEdit navigates to it. Otherwise, SlickEdit displays a list of matching symbols, such as that shown in Figure 5-16.
81
Figure 5-16
In Figure 5-16, there are two different overloads of the same method, each with a declaration and a definition. You can navigate to one of the choices by double-clicking it with the mouse, or using the arrow keys to pick it and pressing Enter. While navigating in the Select a tag window, SlickEdit also opens the Preview tool window and refreshes it to show the preview of the currently highlighted item. Sometimes the information in the Preview tool window is all you need, and there is no need to open the definition in the main editor window. In C and C++, functions usually have a separate declaration and definition. The declaration is often just the prototype for the function, while the definition contains the full body. If you invoke push-tag on a function with a declaration and a definition, SlickEdit displays the Select a tag dialog. You can make push-tag a little faster for this situation by choosing always to navigate first to either the declaration or the definition. You can set this up using the checkboxes on the Select a tag. This can also be configured (e.g., if you change your mind) in the Context Tagging tab of the File Extension options (Tools Options File Extension Setup). If you configure push-tag to go to the definition or declaration first, you can invoke it multiple times to cycle between them. This provides a very fast way to navigate among the declarations and definitions of C/C++ symbols.
Navigating to References
The complement of push-tag is push-ref (Ctrl+slash), which is used to navigate to references to the symbol at the cursor. While a symbol may have a single definition, symbols generally have multiple references. For this reason, SlickEdit provides the References tool window for browsing references. The References tool window is shown in Figure 5-17. In the WROX emulation, you can show the References tool window with Alt+T followed by R.
Figure 5-17
82
Pushed Bookmarks
When you navigate to a definition or a reference using push-tag or push-ref, SlickEdit creates a pushed bookmark at your original location. You can return to the original location quickly by invoking pop-bookmark (Ctrl+comma). Pushed bookmarks form a stack, thus you can navigate repeatedly from one symbol to another and return in the reverse order by popping the bookmarks. If you have been navigating around a lot using push-tag and push-ref, without necessarily popping all of the bookmarks, you can end up with several of them in the bookmark stack. This doesnt cause any problems normally, but it can be annoying if you switch to doing something else, because you can find that popping too many bookmarks takes you back to an unexpected place. You can clear all the pushed bookmarks with the pop-all-bookmarks command. If you find you are popping bookmarks and ending up in files from a previously opened workspace, you might like to load this callback macro, which uses a Slick-C callback to ensure that all pushed bookmarks are popped when you close a workspace:
void _wkspace_close_popallbkms() { pop_all_bookmarks(); }
Thanks to Hartmut Schaefer (hs2) for this tip. The callback is called whenever SlickEdit closes a bookmark. We cover further details of bookmark usage and configuration in Chapter 6. We cover callbacks in more detail in Chapter 16.
83
F inding Symbols
If you are already at a location where a symbol is used, its easy to navigate to it using push-tag. Sometimes you want to find a symbol, but you dont know the complete name of the symbol. It may be a long class name that you cant remember exactly. Or, you might want to find all symbols containing a certain word. SlickEdit 2007 provides a powerful GUI tool for searching for symbols, in the Find Symbol tool window. You can also perform searches for symbols from the command line.
Figure 5-18
Usually it is enough simply to enter part of the symbol name and press Enter. If you have a large project, you can use the options to refine your search in various ways. The options are well documented in the online Help. In particular, you can use the Look in dropdown to specify the scope of the search. Usually you use Context Tagging, which searches in all tag files currently associated with the workspace. Alternatively, you can specify to search only in the current file, project, or workspace. You can also search in a specific tag database. If Match case is checked, the symbol search is case-sensitive. If it is unchecked, the search is not casesensitive. In Figure 5-18 the checkbox is in its default state, which is actually the indeterminate state: neither checked nor unchecked. In this case SlickEdit first performs a case-sensitive search. If no items are found using a case-sensitive search, SlickEdit performs a case-insensitive search. You can use the filters to specify if you are interested only in symbols of a particular type, for example, classes.
84
The options for grep-tag are shown in Table 5-1. The grep-tag command also has a shorter alias, gt, which is handy for using on the command line.
Table 5-1
Option
E I R U B A P
Description Case-sensitive match. Case-insensitive match. SlickEdit regular expressions. UNIX regular expressions. Brief regular expressions. Search all tag files, rather than just the workspace tag file. Search the current project only.
The regular expression options are the same as those for the find command, which is described in Chapter 7.
Browsing Definitions
SlickEdit includes several tool windows that provide different ways to browse your code and view definitions. Most of these tool windows are driven by Context Tagging.
85
Figure 5-19
The tool window shows all open files, with the current file expanded. The expanded file synchronizes automatically with the current edit buffer. If you have too many files open and dont wish to see them in the Defs tool window, uncheck the Display Files option in the tool windows context menu. The icons indicate the type of each symbol. Float the mouse over the icon to see bubble Help on what the icon means. You can also filter the list based on symbol type and visibility by checking or unchecking options in the context menu. You can double-click on an entry to navigate to it. Within the tool window, you can also move the focus in the list using the arrow keys or by typing part of an identifier. Press Enter to navigate to the symbol in the editor. If you have the Preview tool window showing, it is synchronized automatically with selections in the Defs tool window.
Figure 5-20
86
Figure 5-21
As with other browsing tool windows, the Preview tool window is automatically synchronized with selections in the Symbols tool window. The Symbols tool window supports advanced filtering. Right-click in the Symbols tool window to show the Context menu, and choose Filters Filtering Options. SlickEdit displays the Symbol Browser Filter Options dialog, shown in Figure 5-22. Using the options, you can filter what is displayed. For example, using the filtering options and the Class or Member search fields, you could filter the window to show Non-Const Public Data members in classes matching a certain regular expression.
87
Figure 5-22
Figure 5-23
88
There is only one workspace tag file, and it always contains exactly the files in the projects in your workspace. If you add or remove files in the workspace tag file, they are added or removed from your workspace also, and vice versa. The auto-updated and global library categories can each contain any number of tag databases. Use the auto-updated tag files to manage tag databases that are project-specific. Use a global library category to manage libraries that are common to all projects using that language. The auto-updated tag file feature is designed so that a group of users can share one centrally updated tag file. However, it is also useful for a single user with different projects, as described here. For most languages, tag databases for standard libraries and other global libraries are created in the same category for the specific language. For C/C++, tag databases for compiler libraries are created in C Compiler Configuration Tag Files, while other global libraries are created in C/C++ Tag Files. As of SlickEdit 12.0.2, Java also has a separate configuration for compiler libraries and for other global libraries.
89
90
1. 2.
Invoke gui-make-tags (Tools Tag Files). SlickEdit shows the Context Tagging Tag Files dialog. There is no Ruby category at this stage. Click Add Tag File. SlickEdit displays the Add Tag File dialog, shown in Figure 5-24.
Figure 5-24
3. 4. 5. 6. 7. 8.
Select the Ruby source type. Click OK. SlickEdit displays the Add Tags Database dialog. Type ruby.vtg for the tag file name. Click Open. SlickEdit displays the Add Tree dialog, prompting you for the location of the Ruby source files. Navigate to the location of your Ruby library files. On my system, they are in C:\ruby\lib. Click OK to add the files. The tag database has the source files added, as shown in Figure 5-25.
Figure 5-25
91
1. 2. 3. 4. 5.
Invoke gui-make-tags (Tools Tag Files). SlickEdit shows the Context Tagging Tag Files dialog. Click Add Tag File. SlickEdit shows the Add Tag File dialog. Select C/C++. Click OK. SlickEdit prompts for the directory and filename for the new tag database. The default location is in the tagfiles/ subdirectory under your SlickEdit configuration directory. Give the tag database a suitable name. A good idea is to name the tag database with a name corresponding to the library being tagged; thus for wxWidgets, we might use wxWidgets.vtg, or wxWidgets-2.8.3.vtg. Note that if you include dot characters in the filename, you will need to add the .vtg extension also. Otherwise, SlickEdit misinterprets the filename. Specify the location for the tag database. The default location is the easiest, because that is where SlickEdit looks for tag databases by default. Click OK. SlickEdit displays the Add Tree dialog. Specify the file types to add to the tag database. For a C/C++ runtime library, choose the item from the dropdown that includes all the C/C++ file types: *.c;, *.cc;, *.cpp, and so forth. Specify the path to the library Include files. In my system, it is C:\lib\wxWidgets2.8.3\include. Click OK. SlickEdit builds the tag database. At this point, we have the tag database defined as a global runtime library.
6. 7. 8. 9. 10.
After following these steps, we have tagging set up for the runtime library, and all Context Tagging features should be available. A quick way to test whether tagging has worked correctly is to type the start of a line of code into a new .cpp file in the project:
wxDialogBase
92
1. 2. 3. 4. 5.
Invoke gui-make-tags (Tools Tag Files). SlickEdit shows the Context Tagging Tag Files dialog. Select Auto-Updated Tag Files. This step is important! Click Add Tag File. SlickEdit prompts for the tag file to add. The default location is the tagfiles/ subdirectory under your SlickEdit configuration directory. Select the tag database. In my case, it is wxWidget-2.8.3.vtg. Click OK. SlickEdit adds the tag database to the auto-updated tag files for the workspace. The tag database is now both referenced as a global tag database and linked from the auto-updated tag database. To eliminate duplicate symbols, we need to remove it from the list of global tag files. Select the tag database under the global C/C++ Tag Files category. Click Remove Tag File. SlickEdit prompts you to confirm that you wish to remove the file from your tag file list. Click Yes. SlickEdit prompts you whether you wish to permanently delete the file. Click No. The file is removed from the global tag file list but is still attached to the workspace. Click Done.
6. 7. 8. 9. 10.
After completing this procedure, Context Tagging features should still work with the workspace. But the tag database is now specific to the workspace. You can test Context Tagging using push-tag on a symbol from the wxWidgets library again. Auto-updated tag databases are linked to shared tag databases and are updated automatically from them. In this case, the shared tag database is wxWidgets-2.8.3.vtg in the tagfiles/ subdirectory of the SlickEdit configuration directory, because thats where we created the global tag database originally. The auto-updated tag database is wxWidgets-2.8.3.vtg in the workspace directory.
93
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Invoke workspace-new (Project New). SlickEdit displays the New Project dialog. Choose Generic C/C++ for the project type. Enter wxWidgets-2.8.3 for the Project name. Specify the location of the wxWidgets Include directory as the Location. On my system, it is C:\lib\wxWidgets-2.8.3\include. Click OK to create the workspace. SlickEdit displays the Project Properties. Click Add Wildcard to add files. SlickEdit displays the Add Tree dialog. Enter *.* for the Filespec. Ensure that Recurse is checked. All the source files in the include/ directory and subdirectories will be included in the tag database. Click OK to close the Add Wildcard dialog. Click OK to close the Project Properties dialog. SlickEdit scans the files and creates the tag database. Close the workspace (workspace-close, or Project Close Workspace).
At this point, you have the tag database created. You can link an auto-updated tag database in the real project to this tag database using the same procedure as we used above to link one to a global tag database. After creating the auto-updated tag database, you can test tagging by invoking push-tag on a symbol defined in the wxWidgets library. Similarly to before, you should now have a shared tag database in the wxWidgets include/ directory (C:\lib\wxWidgets-2.8.3\include\wxWidgets-2.8.3.vtg) and an auto-updated tag database in your project. Whenever you open your project, SlickEdit checks the shared tag database to see if it has changed. If it has, SlickEdit refreshes the auto-updated tag database. For this method, we have created a separate workspace for the wxWidgets library. If we were doing this to make a tag database for a common project within the organization, this would be quite natural. Whenever you open the wxWidgets project, SlickEdit scans the source files and updates the workspace tag database. This is one way you can keep the tag database up to date.
94
where workspaces are the filenames of the workspaces to update. Run vsmktags with no arguments to get a list of options supported. The vsmktags command scans all the source files in the workspace and updates the workspace tag database. This is why we used Add Wildcard, rather than Add Tree, to specify the files in the project. (If we used Add Tree, new files would not be automatically added to the workspace tag database.) The design of the auto-updated tag database mechanism is for you to use the mechanism for common subprojects within your organization. You can set up nightly jobs to refresh shared copies of workspace tag databases, and then in your personal workspaces, use auto-updated tag databases linked to the shared copies. This reduces the impact on individual developers of rescanning large common code bases that change slowly.
1.
Change the working directory to the include/ directory of the wxWidgets distribution. On my system, this is C:\lib\wxWidgets-2.8.3\include. This is where we will create the tag database. You can create it anywhere you like, and because it is not frequently refreshed, there is less concern about whether you create it on a network drive. Enter this command on the SlickEdit command line:
2.
3.
SlickEdit scans the source files and creates the tag database. When it has finished, it displays a message in the status area giving the full path of the newly created tag database.
In this example, we used the t option, which scans a tree for files. You can also use L to specify a file containing a list of source files to scan. Other options are described in the macro source in maketags.e.
95
The entire command should be entered on one line. Note that you should use absolute paths, otherwise SlickEdit may not behave reliably if it tries to restore its working directory when launching. The single quotes in the command are for a bash shell in Windows such as in Cygwin. For the CMD shell, remove the quotes. On UNIX, use UNIX paths.
1. 2. 3.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Click Auto-Tag. SlickEdit displays the Create Tag Files for Run-Time Libraries dialog. The Compiler dropdown list contains C/C++ compilers found on your system. On my system, I have a couple of options from Cygwin, and the Microsoft VC++ compiler, as shown in Figure 5-26. Choose the compiler for which to create a configuration. If your compiler is not in the list, you need to create a new compiler definition, as described below.
Figure 5-26
96
You can repeat this process for each compiler on your system. To associate your C/C++ project with a compiler configuration, follow these steps, with your project open:
1. 2. 3. 4.
Invoke project-edit (Project Project Properties). SlickEdit displays the Project Properties dialog. Select the Compile/Link tab. Select the Compiler from the dropdown list. Click OK.
If SlickEdit doesnt list your compiler in its list, you need to create a compiler definition for it. The compiler definition specifies the locations of header files, so that SlickEdit can create a tag database. Suppose we have downloaded the Digital Mars C/C++ compiler from http://www.digitalmars.com and installed it under C:\dm. To add a new custom C/C++ compiler definition for Digital Mars, open a C/C++ file and follow these steps:
1.
Invoke refactor-options. SlickEdit displays the C/C++ Compiler Properties dialog, shown in Figure 5-27. This dialog can also be reached via the GUI. You can find it in the menu under Tools C++ Refactoring C/C++ Compiler Options, but only if you have a C/C++ project open. You can also open it via the Browse button in the C/C++ section on the Create Tag Files for Run-Time Libraries dialog.
Figure 5-27
97
You now have the Digital Mars compiler available for your C/C++ projects. If you select this compiler in a project, the Context Tagging system will use symbol data from the Digital Mars header files.
You can tag Java source files for a library, if you have them available. This is certainly desirable, because you will get all the benefits the Context Tagging system can provide. Many Java libraries these days are open source, and it is often useful to download and install the source on your system. As well as enabling more Context Tagging features, you will also be able to learn a lot about a library by reading its source code! Whether you tag JARs or source files for your additional libraries, you need to decide for each one whether to tag it in your workspace or tag it globally in the Java Tag Files category. Usually you will want the option of tagging different versions of runtime libraries for different projects, thus you need to tag them per workspace.
98
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select the Java category. Click Add Tag File. SlickEdit displays the Add Tag File dialog. Select the Java language. Click OK. SlickEdit displays the Add Tags Database dialog, prompting you for the name of your global tag database. Enter java_libs for the File name. Click OK. SlickEdit displays the Add Tree dialog. Change the File types to *.jar. Navigate to your projects lib directory, and select it. Click OK. SlickEdit builds the tag database, containing symbol information for commonslogging.jar and spring.jar. You can see these two files listed in the right-hand pane when you select the java_libs.vtg tag database. Click Done.
The global tag database is created. Many Context Tagging features work, but not all of them. You can confirm this by typing code into an empty .java file:
class Tryme { void foo() { JdbcTemplate } }
When you type JdbcTemplate and press space, SlickEdit adds an import for the org.springframework .jdbc.core.JdbcTemplate class at the top of the source file. But if you place the cursor on
99
based on source files, not symbol information; thus SlickEdit cannot preview a class from a JAR. To get better Context Tagging support for Java libraries, well use Java source files.
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select the java_libs.vtg tag database in the Java category. Select the spring.jar file in the right-hand pane. Click Remove Src File. SlickEdit prompts you to confirm that you wish to remove the selected files from the tag database. Click Yes. SlickEdit removes the source file. Click Add Tree. SlickEdit displays the Add Tree dialog. Ensure that the File type is *.java. Navigate to the src directory in the Spring distribution. Click OK. SlickEdit adds the source files and tags them in the tag database. Click Done.
You can verify that Context Tagging is working for the Spring library now by opening the Preview tool window when your cursor is on a symbol from the library, such as JdbcTemplate. In these two examples weve placed two separate libraries into a single global Java tag database: Spring and commons-logging. In practice, you would probably want to tag separate libraries into separate tag databases. A library such as commons-logging is relatively static, and you may find that a global tag database is appropriate for it even if you have more than one Java project using it. Other libraries, such as Spring, have more frequent changes. You may find that different projects need different versions. In this case, you will be better off associating the tag database with your workspace.
1. 2.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select the java_libs.vtg tag database in the Java category.
100
Now, well create a workspace for the Spring framework source distribution. Follow these steps:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Invoke workspace-new (Project New). SlickEdit displays the New Project dialog. Select Java Empty Project. Enter spring-framework-2.0.2 for the Project name. Specify the location as the directory containing the Spring distribution (C:\lib\springframework-2.0.2). Click OK. SlickEdit displays the Project Properties for the new project. Click Add Wildcard. SlickEdit displays the Add Wildcard dialog. Enter src\*.java for the Filespec. Check the Recurse checkbox. Click OK. SlickEdit adds the wildcard. Click OK. SlickEdit scans the src directory for .java files and tags them in the workspace tag database.
We now have a workspace for the Spring library, and all the source files tagged. To use this tag database in our project, well link an auto-updated tag database to it. Reopen the main project (java_spring), and follow these steps:
1. 2. 3. 4. 5. 6. 7.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select the Auto-Updated Tag Files category. Click Add Tag File. SlickEdit displays the Add Tags Database dialog. Navigate to the location of the tag file for the Spring framework workspace (C:\lib\springframework-2.0.2). Select the tag database (spring-framework-2.0.2.vtg). Click OK. SlickEdit creates the auto-updated tag database and updates it with the source files from the shared tag database. Click Done.
At this point you have the library tagged in your project via an auto-updated tag database. You can confirm that its working by opening the Preview tool window when your cursor is on a symbol from the Spring library, such as JdbcTemplate.
101
1. 2.
SlickEdit scans the source files and creates the tag database. When it has finished, it displays a message in the status area giving the full path of the newly created tag database. You can now link an auto-updated tag database in the workspace to this tag database, as described above.
102
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select the C# category. Click Add Tag File. SlickEdit displays the Add Tag File dialog. Ensure that C# is selected. Click OK. SlickEdit displays the Add Tags Database dialog. Enter springnet for the File name. Click OK. Spring displays the Add Tree dialog. Enter *.dll for the File types. Navigate to the location of the Spring.NET DLLs appropriate for your .NET version in the distribution directory (e.g., C:\lib\Spring.NET-1.1.0 Preview 3\bin\net\1.1\release). Click OK. SlickEdit scans the DLLs and creates the tag database. Click Done.
The global tag database is now created. You can verify that it is working by typing this code into an empty C# file:
class Tryme { void foo() { AdoTemplate template; template. } }
Open the Preview tool window with the cursor on AdoTemplate. You should see some class and method names in the top-left pane, but no other information. As with Java JAR files, DLL assemblies provide only a limited amount of symbol information for Context Tagging. However, if you also add *.xml (assuming there are xmldoc documentation files), SlickEdit will also scan those and correlate the definitions in the DLL with the documentation in the XML. It will then be able to display documentation comments in List Members and the Preview window. Alternatively, to get better support, you can tag the source files themselves.
103
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select the springnet.vtg tag database in the C# category. Select the DLL files in the right-hand pane. Click Remove Src File. SlickEdit prompts you to confirm that you wish to remove the selected files from the tag database. Click Yes. SlickEdit removes the source file. Click Add Tree. SlickEdit displays the Add Tree dialog. Ensure that the File types is *.cs. Navigate to the src directory in the Spring.NET distribution. Click OK. SlickEdit adds the source files and tags them in the tag database. Click Done.
You can verify that Context Tagging is working for the Spring.NET library now by opening the Preview tool window when your cursor is on a symbol from the library, such as AdoTemplate.
104
1. 2. 3. 4. 5.
Open the Extension Options dialog (Tools Options File Extension Setup). Select extension cpp. Click C/C++ Options. SlickEdit shows the C/C++ Formatting Options dialog. Click the Other tab. Click C/C++ Preprocessing. SlickEdit displays the C/C++ Preprocessing dialog.
For more information about C/C++ Preprocessing setup, see the online Help.
Troubleshooting Tagging
The many tagging-related features presented in this chapter all depend on an accurate tag database in order to work correctly. Several conditions can result in the tag database being inaccurate, from invalid code to incorrect configuration. This section contains a checklist with some tips you can use when trying to diagnose tagging problems. These tips are adapted from a troubleshooting checklist provided by Dennis Brueni of SlickEdit.
1.
Where is x defined or declared? Is it a local variable or function parameter? Does it show up if you invoke list-symbols (Alt+dot)? If not, look at its definition. Is it correct (would the code compile)? In C/C++, is it declared using preprocessing? If yes, see Solution A below. Is it in the same file? Does the symbol show up in the Defs tool window? (You may have to turn off filtering options.) Is the symbol information correct? (Check the symbols name, class scope, and protection flags.) If not, look at its definition. Is it correct? (Would the code compile?) In C/C++, is it declared using preprocessing? If yes, see Solution A below. Is it in a different file? Is that file tagged? Is it in your workspace? Is it in an extensionspecific tag file? If not, see Solution B below.
105
1. 2.
Try list-symbols (Alt+dot). Does a list of items show up? Is it the correct list of items? Is it the correct class? Is x in the list? If not, do you get an error message in the message bar? Does the error message help you figure out the problem? Move your cursor to the left of the member access operator, and invoke push-tag (Ctrl+dot) to go to the definition. Does it take you to the correct symbol? Is the symbol tagged correctly? (Check the symbols name, class scope, and protection flags.) If not, follow the guidelines for Go to Definition to determine why you cant jump to the last symbol in expr. If yes, then look at the type of the symbol. Try to jump to the definition of the symbols type using push-tag (Ctrl+dot). Does it take you to the correct symbol? Is the symbol tagged correctly? (Check the symbols name, class scope, and protection flags.) Is the type name a typedef? Can you navigate to the typedefd type?
3.
Evaluate expr to determine if it is recognized correctly. For a simple example: Assume expr is a local variable of type MyClass. Follow the guidelines for Go to Definition to determine if expr is correctly tagged. Follow the guidelines again to determine if MyClass is correctly tagged. For longer prefix expressions such as a[i].getIterator()->currentItem()->x, you may need to follow this procedure iteratively to determine where the missing link is.
4.
Assuming that youve found the actual type of expr by now: Is x correctly seen as a member of the type? Follow the procedure in Case 1, Step 2 to verify if the symbol is tagged correctly.
106
1. 2.
Does Go to Definition (Ctrl+dot) work? Follow the Go to Definition procedure to determine that the symbol you are searching for references to is correctly tagged itself. Are references missing? Are all the files you are expecting to find references in tagged correctly? (See above.) Is the tag file they are in built with cross-referencing enabled? Put your cursor on a reference that is skipped. Go to Definition (push-tag) should take you to the definition of the symbol you are looking for. If not, this is why the reference was skipped. Follow the Go to Definition debugging procedure.
3.
Are there too many references found? Are the references displayed with a ? icon? This indicates that SlickEdit was unsure about the reference. Put your cursor on an extra reference. Follow the Go to Definition debugging procedure. When symbol information is incomplete, References falls back on a philosophy that it is better to show too many items than miss items. This means that it will only eliminate an occurrence of the symbol if it can prove that it is another symbol. Otherwise, it is regarded as a correct reference or a miscellaneous reference.
1. 2.
Does Go to Definition (push-tag, Ctrl+dot) work on the function name? Follow the Go to Definition procedure to determine that the function about which you are looking for parameter information is correctly tagged itself. Is the incorrect prototype displayed? Try hitting Alt+comma again to cycle to the next prototype. If there is only one prototype, make sure your tag file is up to date. See Solution E below.
1. 2.
Open the Extension Options dialog (Tools Options File Extension Setup). Select extension cpp.
107
For more information about C/C++ Preprocessing setup, see the online Help.
1. 2. 3. 4.
Invoke project-edit (Project Project Properties). SlickEdit displays the Project Properties dialog. Select the Files tab. Use Add Files, Add Tree, or Add Wildcard as appropriate to add the file to the workspace. Click OK when done to close the Project Properties dialog.
If the file is part of a third-party library of files, you might want to create a library project for them and add that to your workspace. If the file is part of a large library of files that you use in all your projects, you may want to create a global tag file.
1. 2. 3. 4. 5. 6. 7. 8. 108
Open the Extension Options dialog (Tools Options File Extension Setup). Select extension cpp. Click C/C++ Options. SlickEdit shows the C/C++ Formatting Options dialog. Click the Other tab. Verify the Extensionless C++ File Path Regular Expression. The file/path where your files are needs to match this expression. Click Extensionless C++ Files. SlickEdit displays the Extensionless C++ Files dialog. Add the names of your extensionless header files. Click OK to close the Extensionless C++ Files dialog.
See Chapter 9 and the online Help for more information about extensionless header files. Close and reopen the file, and it should come up as C/C++ now. You may have to rebuild your tag file after doing this step.
1. 2. 3. 4. 5. 6.
Open the Extension Options dialog (Tools Options File Extension Setup). Click New. SlickEdit displays the New Extension dialog. Enter the file extension of the file you need to add (without the dot). Select the language/extension to refer to (e.g., cpp). Click OK to close the New Extension dialog. Click OK to close the Extension Options dialog.
Close and reopen the file, and it should come up in the correct language mode now. You may have to rebuild your tag file after doing this step.
1. 2. 3. 4. 5. 6.
Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files dialog. Select your workspace tag file. Click Rebuild Tag File. SlickEdit displays the Rebuild Tag File confirmation dialog. Turn off Retag modified files only. Click OK. SlickEdit rebuilds the tag file. Click Done to close the Context Tagging Tag Files dialog.
Performance Tuning
The Context Tagging engine is designed to work as well as possible for typical projects. As with all things in SlickEdit, it is highly configurable, and if you find that tagging features are not working for your project, or arent working fast enough, you can fine-tune several parameters to improve performance. In this section, we give an overview of some common performance tuning options. However, unless your projects are exceptionally large or unusual, you probably wont need to do any performance tuning. SlickEdits default configuration works just fine for most projects, even some of a substantial size.
109
You can configure the Context Tagging engine in the Context Tagging Options dialog (Tools Options Tagging Options). The dialog is shown in Figure 5-28.
Figure 5-28
Tuning Maximums
The Maximums section lists the maximum number of items found or listed in different categories. Most well-designed programs should not have more than 1,000 members in a single class or structure. However, if you are working with a complex library with a deep inheritance structure, for example, you may find that some subclasses do, in fact, exceed this limit. When this happens, you will not see all members listed in tool windows. To fix this, you can increase these parameters as needed.
110
References
If you are working on a project in which you have many symbols sharing the same name, you may find that the performance of push-ref and the References tool window are not acceptable. You can change a couple of parameters to improve the performance of References. Normally, when you use the References tool window to find references for a symbol, SlickEdit updates the window in two steps: First it uses the tag database to find all files that contain a symbol with the given name. Then it scans each file to determine whether the file truly contains references to that particular symbol, or merely to another synonymous symbol. For example, many C++ classes may contain a method named init(), but References should refer only to occurrences in one specific class (and its subclasses). With this default behavior, files not containing true references are removed from the list after they are scanned, and the remaining files are expanded to show the references. If you check the Find references incrementally option, SlickEdit displays files without expanding them and defers scanning until you expand the node for a file. The advantage of this is that there is far less file scanning required to initialize the window. The down side is that you may get files that dont really contain the symbol youre looking for.
Complex Code
Some kinds of code make a lot of work for the tagging engine. If you have a large (or extremely difficult) code base and are experiencing delays like this, you can try turning off the following items in the Context Tagging tab of the Extension Options dialog: Auto-list compatible values. Auto-list compatible parameters.
In this case, SlickEdit is trying to use the tag database information to obtain context-sensitive static-type information about the current object in your source code. This can be difficult in code that makes heavy
111
Summar y
Context Tagging is vital for many of SlickEdits advanced features. Particularly for languages with statictype information, Context Tagging provides information that SlickEdit can use to help you browse, navigate, and edit your code effectively. Tagging your own source files is easy Just make sure you have a workspace and that all your source files are included in the workspace, either by adding them individually or using appropriate wildcards. Tagging runtime libraries is also important, because it extends SlickEdits features to work with them as well as with your own source code. Depending on whether you want your runtime libraries tagged globally or per project, there are various approaches possible. We reviewed several methods you can use for tagging C/C++, Java, .NET, and dynamic languages. Occasionally you may need to troubleshoot tagging, or tune the performance, although this should only happen if you have a very large or exotic project. Because problems and performance vary enormously between scenarios, a complete description of all options is beyond the scope of this book. Weve provided a few common tips. Tagging enables many of SlickEdits navigational features. For strongly typed languages, you may not need much else in the way of navigation tools, because you can use push-tag and push-ref to navigate around your code a lot of the time. For other kinds of files, such as dynamic languages, SQL, data files, and others, you need more general-purpose navigation tools. In the next chapter, we cover these other navigation tools.
112
Navigation
Large software projects contain thousands of source files. Often those source files are spread over dozens or even hundreds of directories. And those files can contain thousands of lines. You need to be able to open the file you want as quickly as possible. Once you are in the file, you need to be able to navigate quickly to any place in that file. You need to be able to jump from one place to another, then back, perhaps several times. In Chapter 5, we saw how Context Tagging enables several powerful navigation features, along with other things. In particular, push-tag and push-ref are the preferred way to navigate a large base of source code in SlickEdit. There are also other ways of opening files in SlickEdit. Depending on the nature of your project and the way you prefer to work, some methods will suit you better than others. Some methods are obvious, such as File Open. Others are not so obvious but can be far more effective. SlickEdit allows you to open many different files at once. When you have only one or two files open, you can switch between them easily. If you have a dozen or more files open, SlickEdit offers several nice ways to get quickly to the one you want. Most editors support a standard set of navigation commands for getting around inside a file. You have the arrow keys for moving a character or a line at a time. You have keystrokes for moving a word or a page at a time. SlickEdit has a rich set of commands for navigating around the buffer. Its well worth becoming familiar with these commands, because they can save you a lot of time and keystrokes. If you find yourself returning to the same location in a file frequently, a bookmark can save a lot of time. Bookmarks also let you return quickly to where you were editing after jumping to a definition or a reference.
Figure 6-1
On GNU/Linux, UNIX, and Mac, a different Open dialog is used. Figure 6-2 shows this dialog on GNU/Linux. The dialog is shown with the Advanced button clicked, to show the additional advanced options. Windows users can optionally use a dialog similar to the dialog used on other platforms. On Windows, it is called the Fast Open Dialog, or the Windows 3.1 Style Open Dialog. Figure 6-3 shows this dialog on Windows. As before, the dialog is shown with the Advanced button clicked, so that all the advanced options are shown. Windows users can configure SlickEdit to use the fast Open dialog by selecting the Windows 3.1 style open dialog in the More tab of the General Options dialog (Tools Options General) or by setting the macro variable def_fast_open to 1.
114
Chapter 6: Navigation
Figure 6-2
Figure 6-3
The fast Open dialog can be more effective than the default Windows dialog, because it supports some additional features. The file name combo box lists files recently opened in SlickEdit. Also, you can type a pattern and press Enter to filter the list displayed. This is very useful if you wish to open a set of files
115
Figure 6-4
116
Chapter 6: Navigation
Aliases are particularly useful for frequently edited files that are not necessarily part of any project. Examples of such files are: System Configuration Files such as /etc/hosts. On Windows, the hosts file is in C:\WINDOWS\system32\drivers\etc\hosts. You might alias this to hosts. Product Configuration Files such as C:\oraclexe\app\oracle\product\10.2.0\ server\NETWORK\ADMIN\tnsnames.ora. You might alias this to tnsnames. User Configuration Files such as ~/.bashrc. On Windows, the home directory is longer than on UNIX, something like C:\Documents and Settings\jhurst. You might alias your home directory.
You can use a file or directory alias anywhere in SlickEdit where a filename can be entered. See Chapter 11 for more details on file and directory aliases.
117
1. 2. 3.
Invoke activate-files-project [Project Open Files from Project or Alt+T, P (WROX)]. The Files tool window appears with the View Files in the Current Project button selected. Type part of the file name. The list of files is filtered to match what you type. You can use * as a wildcard in the name. Use the arrow keys to select a file from the list, and press Enter to open the file.
Figure 6-5
You can use * as a wildcard in the Files tool window, but you often dont have to. As shown in Figure 6-5, you can type any part of the name of the file, and all files containing that string in their names are shown. Suppose you have a lot of SQL DDL scripts, where each script is named according to the definition it performs. The scripts might be called:
create_table_account.sql create_table_customer.sql create_table_order.sql (etc) create_view_customer_orders.sql (etc) create_package_customer.sql (etc)
By typing in cust*sql in the Files tool window, you can see all SQL files relating to customers. This is a very effective way to search for and open files in large projects. The View Files in Current Project is the option you will use most often to open files in your project. The Files tool window can also be used with View Files in Current Workspace to expand the search to include all projects in the workspace. You can switch among modes using the buttons at the top of the tool window. Alternatively, if you know what you are after and prefer to use the keyboard, invoke the tool window in workspace mode using activate-files-workspace [Project Open Files from Workspace or Alt+T, W (WROX)].
118
Chapter 6: Navigation
The main limitation of the Files tool window is that you can only use it to open files that are in your project or workspace. You cant use it to open arbitrary files. But when you are working on a project that has been set up properly, the Files tool window is usually the fastest way to open a file.
1. 2.
Place the cursor anywhere on the line containing the #include directive. Invoke cursor-error (Alt+1). SlickEdit opens the file.
As you might guess from the name of this command, its use is not restricted to opening header files, although it is particularly good at that. The same command is used to jump to compiler errors. You can also use the cursor-error command to open files whose names are in your source files for other reasons. For example, you might have a master database script, which calls separate other scripts for creating each table and index. It might look like this:
START create_table_account.sql; START create_table_customer.sql; START create_table_order.sql; -- (etc) START create_view_customer_orders.sql; -- (etc) START create_package_customer.sql; -- (etc)
If you have this script loaded into your editor and the other scripts are in the working directory, you can open them by placing the cursor on the appropriate line and invoking cursor-error.
Moving Around
SlickEdit provides many basic commands for moving around. By mastering these commands and their key bindings, you can get to where you want to be quickly and with the least number of keystrokes.
119
Table 6-1
Command
cursor-up cursor-down cursor-left cursor-right prev-word next-word wrox-prev-word
Key Up arrow Down arrow Left arrow Right arrow Alt+Left (WROX) Alt+Right (WROX) Ctrl+Left (WROX)
Description Move the cursor up. Move the cursor down. Move the cursor left. Move the cursor right. Move the cursor left one word. Move the cursor right one word. Move the cursor left one word (alternative). Move the cursor right one word (alternative). Move to previous function or class definition. Move to next function or class definition. Move up one page. Move down one page. Move the cursor to the top of the window. Move the cursor to the bottom of the window. Move the cursor to the top of the buffer. Move the cursor to the bottom of the buffer. Move the cursor to the matching brace, parenthesis, etc. Move to next higher-level block or definition.
wrox-next-word
Ctrl+Right (WROX)
prev-tag
Ctrl+Up
goto-parent
(none)
120
Chapter 6: Navigation
Several of these commands deserve further explanation. By default, the top-of-buffer command moves the cursor to the first column of the first line, and the bottom-of-buffer command moves it to the last position of the last line. You can change this behavior to preserve the column on the top and bottom by selecting Preserve column on top/bottom on the More tab of the General Options dialog (Tools Options General), or by setting the macro variable def_top_bottom_style to 1. Often you might use top-of-buffer to jump to the top of a file to check a definition. Then you can use undo to return to the point where you were editing. Sometimes you might change something at the top of the file, such as a header comment, an #include directive, or a Java import statement. In such a case, you cannot use undo to go back to where you were without undoing your changes. For this reason, as of SlickEdit 2007, there is an optional behavior for top-of-buffer and bottom-of-buffer to make them push a bookmark before moving the cursor. Then, you can pop the bookmark to return, even if you have done edits in between. This behavior can be turned on by setting the macro variable def_top_bottom_ push_bookmark to 1. Pushing and popping bookmarks is discussed further below in this chapter. You might have noticed that there are two sets of commands in Table 6-1 for moving to the previous or next word: prev-word/next-word and wrox-prev-word/wrox-next-word. There is a reason for this. The SlickEdit default commands prev-word and next-word navigate by words as defined by the current source language. Also, prev-word moves to the beginning of the previous word, while next-word by default navigates to the end of the next word. If you prefer, you can change the behavior of next-word by choosing Next word style as Begin or End on the More tab of the General Options dialog (Tools Options General), or by setting the macro variable def_next_word_style to B for Begin and E for End. However, it turns out to be useful to have it set to End, the default setting. The WROX commands wrox-prev-word and wrox-next-word work slightly differently. Firstly, they move between words that are delimited by white space. Their definition of a word has nothing to do with the source language of the file only white space matters. Secondly, they always move to the beginnings of words, whether moving backward or forward. The wrox-prev-word and wrox-next-word commands behave more like Ctrl+Left and Ctrl+Right in most word processing programs. Suppose you have some code like this:
for (i=0; i<size-1; i++) { sum += arr[i]; }
If we start with the cursor on for and invoke next-word repeatedly, the cursor will move through the positions shown in Figure 6-6.
1 2 3 4 5 6 7
9 10
Figure 6-6
121
6 7
Figure 6-7
The point is that both of these schemes are useful at different times. SlickEdits next-word is good for getting to specific identifiers inside expressions with no spaces in them, such as i<size-1. The End style for next-word is useful for recording and playing back macros because with it you have a reliable way of getting to the beginning or the ending of an identifier something that is frequently needed when recording a macro. On the other hand, wrox-next-word is quicker when you want to skip over expressions such as i<size-1, and additionally is useful if you do want to get to punctuation characters such as { and operators such as += in the example above. I find that I use wrox-next-word most often, but also use SlickEdits next-word a lot too. The following listing shows the source code for wrox-prev-word and wrox-next-word:
/** * Moves to beginning of next whitespace-delimited word. * This command is an alternative to SlickEdits next_word command. * Its useful to have them both mapped, since they work * differently but are both useful. * * @return typeless */ _command void wrox_next_whitespace_word() name_info(,VSARG2_READ_ONLY|VSARG2_TEXT_BOX|VSARG2_REQUIRES_EDITORCTL) { init_command_op(); _str current_char = get_text(); if (current_char != && current_char != \t && current_char != \n) { search([ \t\n]|$, @U<); } search([^ \t\n], @U<); retrieve_command_results(); } /** * Moves to beginning of previous whitespace-delimited word. * This command is an alternative to SlickEdits prev_word command. * Its useful to have them both mapped, since they work * differently but are both useful. * * @return typeless */ _command void wrox_prev_whitespace_word() name_info(,VSARG2_READ_ONLY|VSARG2_TEXT_BOX|VSARG2_REQUIRES_EDITORCTL) { init_command_op(); if (p_col > 1) { left();
122
Chapter 6: Navigation
} else { up(); end_line(); } _str current_char = get_text(); if (current_char == || current_char == \t || p_col == 1) { search([^ \t\n], -@U<); } search([ \t\n]|^, -@U>); retrieve_command_results(); } // remap the standard SlickEdit prev-word/next-word to Alt-Left/Alt-Right, // and the WROX ones to Ctrl-Left/Ctrl-Right. defeventtab default_keys def C-RIGHT= wrox_next_word def A-RIGHT= next_word def C-LEFT= wrox_prev_word def A-LEFT= prev_word
Table 6-2
Command
line-to-top
Description Reposition the window so that the current line is at top. Reposition the window so that the current line is at bottom. Reposition the window so that the current line is in the middle. Scroll buffer up one line. Scroll buffer down one line. Scroll buffer left one character. Scroll buffer right one character.
line-to-bottom
Alt+PgDn (WROX)
center-line
Alt+Home (WROX)
None of these commands has key bindings in the CUA emulation; thus its easy to miss them.
123
Table 6-3
Command
goto-line n n cursor-up n -n cursor-down n +n goto-col n cursor-left n cursor-right n seek n seek n seek +n
Description Go to line n. Go to line n (shorthand form). Go up n lines. Go up n lines (shorthand form). Go down n lines. Go down n lines (shorthand form). Go to column n. Go left n columns. Go right n columns. Go to character n in file. Go backward n characters. Go forward n characters.
You can also use the seek command with no arguments to show the current character offset in the file in the message line. An example of this is shown in Figure 6-8, where the cursor is at character 270 in the file (hex 0x10E).
Figure 6-8
The seek command works with characters, not bytes. The behavior for some files depends on the encoding used to open the file. For an ASCII file, each character corresponds exactly to a byte. For a Unicode file, a character can correspond to more than one byte. Also, there may be a byte order mark (BOM) of two or more bytes at the beginning of the file. If a Unicode file is opened with the correct encoding, seek works with Unicode characters. If a Unicode file is opened with a binary encoding, seek effectively works with bytes. We cover more details about file encodings in Chapter 12.
124
Chapter 6: Navigation
Table 6-4
Command
next-buffer prev-buffer next-buff-tab prev-buff-tab next-window prev-window list-buffers
Key Ctrl+N Ctrl+P (none) (none) Ctrl+Tab, Ctrl+F6 Ctrl+Shift+Tab, Ctrl+Shift+F6 Ctrl+Shift+B
Description Move to the next buffer. Move to the previous buffer. Move to the next buffer tab. Move to the previous buffer tab. Move to the next window. Move to the previous window. List the buffers so you can choose.
Recall from Chapter 3 that buffers are not the same as windows, and relationships among them are controlled by configuration settings. Thus, whats the difference between all of these commands? It has to do with the order in which the buffers or windows are traversed. The next-buff-tab command simply traverses the buffers in alphabetical order. That is the same order in which the buffers appear in the File Tabs tool window. The prev-buff-tab command traverses the buffers in the reverse order. These commands are not particularly useful normally. The next-buffer command follows the order of the buffer ring. When you load files into buffers, the buffers form a ring. The buffers have a fixed order in the ring. When you invoke next-buffer, you go to the next buffer in the ring. When you reach the last buffer in the ring, the command cycles back to the first buffer. Similarly, prev-buffer takes you to the previous buffer in the ring, until you get to the first buffer, after which it cycles to the last buffer. The order of the buffers in the ring is determined by how files are loaded. When you load a file, it is inserted into the ring after the current buffer. This can be illustrated by an example:
1. 2.
We edit file A. The ring now contains only file A, and prev-buffer and next-buffer do nothing. We edit file C. The ring is now A, C.
125
In this example, I deliberately loaded the files in such a way as to result with them in the ring in alphabetical order. Its important to realize that the ring itself does not sort them alphabetically, but by which position in the ring each file is loaded into. The prev-buffer and next-buffer commands are nice for getting around your files in a fixed order. If you take care in the order you load files, you can keep track of where they are in the ring and navigate to them quickly using prev-buffer and next-buffer. However, its often inconvenient to have to keep track of the order of the files as they are loaded, especially if you are working with a lot of different files, and opening and closing them a lot. In these cases, the window commands work better. With the default configuration, the next-window command takes you through the windows in the order of most recent use. The command is bound to Ctrl+Tab in CUA, and behaves like Ctrl+Tab in many other Windows applications. Its also similar to the way Alt+Tab works to switch among applications in Windows and other operating systems. Similarly, prev-window goes through windows in the order of least recent use. The next-window command is very convenient if you have a lot of files open and are switching among just two or three of them. You can toggle between two windows with Ctrl+Tab, and toggle among more windows by holding Ctrl and pressing Tab more than once. The behavior of next-window and prev-window is controlled by a configuration setting found on the More tab of the General Options dialog (Tools Options General). There is an unlabeled combo box containing these options: No window reordering. Smart next window. Reorder windows.
(These configuration settings do not have a corresponding macro variable.) The default setting is Smart next window, which is the behavior just described. With the No window reordering setting, the next-window command cycles through the windows in the reverse of the order in which they are created. This is similar to, but not the same as, the order of buffers in the ring. With the Reorder windows setting, when you activate a window, SlickEdit places it after the current window in the window list. The prev-window and next-window commands do not reorder the window list.
126
Chapter 6: Navigation
You can also select among windows using the Window menu. The Window menu displays the windows in window order. The list-buffers command invokes the Files tool window, in the View Open Files mode. This is the same tool window you can use to open files from the project or workspace. When used in View Open Files mode, it allows you to navigate to, close, or save open files. The list-buffers command is bound to Ctrl+Shift+B in CUA. Alternatively, you can use the activate-files-files command, which is bound to the Alt+T, L sequence in the WROX extension. (The Files tool window is new in SlickEdit 2007 and replaces the old List Buffers dialog. The CUA emulation doesnt include key bindings for activating tool windows.) The Files tool window is useful if you have many files open, because it allows you to navigate to a particular one relatively quickly. Its also a handy way to review just what files you actually do have open, because the File Tabs tool window cannot show a large number of files effectively.
Bookmar ks
SlickEdits bookmarks are a powerful way of returning to a previous location in a source file. There are two types of bookmarks. We have already seen pushed bookmarks in Chapter 5, where we used them with push-tag and push-ref. The other kind of bookmark is the named bookmark.
Pushed Bookmarks
Pushed bookmarks are invaluable for jumping to and returning from definitions and references. They can also be useful in other situations. Sometimes you may want to push a bookmark yourself before jumping to another location. To push a bookmark explicitly, use push-bookmark (WROX: Ctrl+semicolon). Table 6-5 lists the important commands for working with pushed bookmarks.
Table 6-5
Command
push-bookmark push-tag push-ref pop-bookmark pop-all-bookmarks
Description Push a bookmark explicitly. Push a bookmark and go to definition. Push a bookmark and go to reference. Pop last bookmark. Pop all bookmarks.
Note that when you push a bookmark using push-bookmark, it uses the same bookmark stack as push-tag and push-ref.
127
Named Bookmarks
Pushed bookmarks are use once. Once you pop the bookmark, its gone. If you want to be able to return to a location many times, use a named bookmark instead. Named bookmarks are also referred to as set bookmarks. Table 6-6 shows some commands that work with named bookmarks.
Table 6-6
Command
set-bookmark delete-bookmark goto-bookmark toggle-bookmark
Menu or Key Search Set bookmark (none) Search Go to bookmark Search Toggle bookmark or Ctrl+Shift+J Search Bookmarks or Ctrl+Shift+N Search Next bookmark Search Previous bookmark Ctrl+Shift+number key (WROX) Ctrl+number key (WROX) (none)
Description Sets a named bookmark. Deletes current or named bookmark. Go to a named bookmark. Toggle a named bookmark on the current line. Show the Bookmarks tool window.
activate-bookmarks
alt-gtbookmark clear-bookmarks
There are three ways to use named bookmarks: You can give a bookmark a meaningful name that you choose, using set-bookmark. This is the most effective option for bookmarks you want to use for a long time. You can have an automatically generated name, when you use toggle-bookmark. SlickEdit generates a name using the file or symbol name and the line number. You can use a key binding for a name, when you use alt-bookmark. The bookmark is given the name of the key used to set it. See below.
128
Chapter 6: Navigation
You can delete the named bookmark on the current line with the delete-bookmark command. Alternatively, you can use delete-bookmark with a name argument to delete a specific named bookmark. The alt-bookmark command is used to create a quick temporary bookmark with a keyboard shortcut. In the CUA emulation, the alt-bookmark command is bound to Ctrl+0 through Ctrl+9, and the alt-gtbookmark command is bound to Ctrl+Shift+0 through Ctrl+Shift+9. Because jumping to a bookmark is usually done more often than setting a bookmark, the WROX emulation reverses the key bindings, to make it easier to jump to bookmarks.
Configuring Bookmarks
There are several configuration options controlling bookmarks. They can be found in the Search tab of the General Options dialog (Tools Options General), in the group titled Bookmarks. The search configuration dialog is shown in Figure 6-9, with the default settings for bookmarks.
Figure 6-9
Select Use workspace bookmarks to make named bookmarks local to your workspace, rather than global. When Show set bookmarks is checked, named bookmarks show as a green icon in the margin. When Show pushed bookmarks is checked, pushed bookmarks show as a blue icon in the margin. The Close deletes pushed bookmarks setting causes pushed bookmarks to be dropped when you close the files containing them. This can be a helpful setting if you like to return from a reference lookup by
129
Summar y
In this chapter, we tried to do justice to SlickEdits great set of features for navigation. We saw several ways to open files with a minimum of navigation and typing required. We covered many of SlickEdits commands and their key bindings for moving around in the buffer, and we saw effective ways to switch buffers quickly, even if many files are open. We looked at bookmarks, another powerful navigation tool. In the next chapter, we continue the theme of navigation by looking in detail at SlickEdits search-andreplace capabilities.
130
Keyboard Searching
Table 7-1 is a summary of search and replace commands with keyboard shortcuts. We cover command-line searching below in this chapter.
Table 7-1
Command
quick-search
Description Quick search for selection or word at cursor. Quick search backward for selection or word at cursor. Incremental search forward. Incremental search backward. continued
quick-reverse-search
Ctrl+Shift+F3 (WROX)
i-search reverse-i-search
Ctrl+I Ctrl+Shift+I
Description Show Find dialog. Show Find in Files dialog. Show Replace dialog. Show Replace in Files dialog. Find next match. Find previous match.
Quick Search
The fastest way to search for the word at the cursor is to use quick-search (WROX: Ctrl+F3). If you have a normal character selection, that is used for the search. Otherwise, the entire word at the cursor is used. You can also search backward with quick-reverse-search (WROX: Ctrl+Shift+F3). You can use find-next (Ctrl+G) and find-prev (Ctrl+Shift+G) to repeat your quick search after the first match. The find-next and find-prev commands can be used to repeat searches started in different ways. When you invoke them, they display the current search conditions in the message area.
Incremental Search
Incremental search is a quick way to search without having to type too much. To use incremental search:
1.
Invoke i-search (Ctrl+I). SlickEdit prompts you in the command-line area with Exact I-Search, as shown in Figure 7-1.
Figure 7-1
2. 3. 4.
Type the first character of your search expression. SlickEdit advances the cursor to the next match for that character. Type more characters to narrow the search. SlickEdit advances to matching text in the buffer. Use backspace to back up if you make a mistake.
132
The procedure for using reverse-i-search is the same (except you press a different key to start it). SlickEdit remembers your search string until your next search, thus you can continue to use find-next and find-prev after you have terminated the incremental search. In this example, the incremental search was exact, which meant a literal case-sensitive search. Incremental search uses default search options from the Search tab of the General Options dialog (Tools Options General). You can change default options there. You can also change search options and behavior during incremental search by pressing the keys shown in Table 7-2.
Table 7-2
Key Ctrl+C Description Toggles case sensitivity. The key bound to the BRIEF emulation command case_toggle will also toggle the case sensitivity. Toggles searching within mark. Toggles incremental search mode. Quotes the next character typed. Searches in reverse for the next occurrence of the search string. Searches forward for the next occurrence of the search string. Toggles regular expression pattern matching on/off. The key bound to the BRIEF emulation command re_toggle will also toggle regular expression pattern matching. Toggles word searching on/off.
Ctrl+W
133
Using Find
Figure 7-2 shows the Find and Replace tool window, with the Find tab selected.
Figure 7-2
There are many options, but most of them are self-explanatory. We discuss some of the more complex options in the sections below. As always, full details are in the online Help. Enter your search string into the Search for combo box. The combo box remembers previous searches. These can be recalled using the down arrow key. The arrow button to the right of the Search for combo is a helper for building regular expressions. Use the Look in selection box to define the scope of your search. The options are: Current Buffer Searches to the end (or beginning) of the buffer. Current Selection Searches to the end (or beginning) of the selection. Current Procedure Searches to the end (or beginning) of the current procedure. This option is available only in modes where SlickEdit can recognize procedures or functions. All Buffers Searches all open buffers.
Use the Match case and Match whole word options to control the precision of the match. Use one of the regular expression types to specify a search pattern rather than an exact string. Regular expression searches are explained below. Use the Color button to specify a color-syntax scope for your search. The Color Coding Search Options dialog is shown in Figure 7-3. These options correspond to the syntax elements defined by SlickEdits programming language lexers. Lexers are explained further in Chapter 9, and also in Chapter 17. The checkboxes are three-valued, with the three values having these meanings: Checked means Restrict the search to include this element. Unchecked means Exclude this element. Neither checked nor unchecked means This element does not affect the search.
134
Figure 7-3
To clarify this a little, consider two typical cases: To search only in comments, check the Comment box, and leave the others in the middle (neither checked nor unchecked) state. To search everywhere except comments, uncheck the Comment box, and leave the others in the middle state.
We give some more examples of color syntax searching when we cover command-line searching below. We also cover regular expression searching and replacing in more detail below.
Figure 7-4
135
Figure 7-5
The Search Results buffer is a special kind of editor buffer that supports commands and actions to review the search results and navigate to them. You can press Enter or double-click a file to open that file, or a match to open the file at that line. Its interesting to note that while you cannot invoke command-line commands or the Find tool window on the Search Results buffer itself, you can use incremental search while the focus is in Search Results. The + and bitmaps indicate regions that can be expanded or collapsed. You can click the and + buttons, or invoke plusminus (Ctrl+backslash) to expand or collapse results from particular files. When you do multiple searches with Find in Files, the default behavior is to replace the Search<0> buffer in the Search Results tool window with the new results each time. You can change this by selecting from the choices under the Search Results window. The choices include: Search<0> Search<n> The buffers are already created. <New> Creates a new buffer. <Auto Increment> Cycles through existing search buffers.
These choices allow you to keep results from a given search for as long as you need them. Multiple search results appear as different tabs in the Search Results tool window.
136
Regular Expressions
One of the more powerful ways of searching or replacing with SlickEdit is to use regular expressions. A regular expression specifies a pattern of text to search for, rather than the exact text. You can use patterns in a conventional way as you might use a search tool such as the UNIX grep command. You can also use them in combination with SlickEdits other search options, such as the ability to limit searches to comments or keywords. Because most programmers are probably familiar with regular expressions, we dont present an entire tutorial on them in this book. Besides, they are a book-sized subject in their own right! If you would like to learn more about regular expressions, a definitive treatment is given in Mastering Regular Expressions by Jeffrey Friedl (3rd edition, 2006, OReilly). SlickEdit supports three variants of regular expressions, described below: UNIX Regular Expressions These are closest to UNIX tools like egrep. SlickEdit Regular Expressions These are unique to SlickEdit and are designed to be more concise for some patterns. Brief Regular Expressions These are based on those in the Brief editor, popular in the DOS days.
These three regular expression languages offer almost exactly the same set of features. Choose the language that suits your background and preference. Table 7-3 lists common regular expression features. Appendix B contains a complete listing of regular expression features for each variant.
Table 7-3
Definition Match beginning of line. Match end of line. Match any character except newline. Maximal match of zero or more occurrences of X. Maximal match of one or more occurrences of X. UNIX
^
SlickEdit
^
Brief
% < $ > ? X\:@ X\:+
. X* X+
? X@ X#
continued
137
SlickEdit
X:0,1 X:n1
Brief
X\:0,1 X\:n1 X\:n1? X\:n1, X\:,n2
X:n1, X:0,n2
X{n1,n2}
X:n1,n2
X\:n1,n2
[charset]
[charset]
[charset]
[^charset]
[~charset]
\xhh
\xhh
\dnnn \d
\nnn \gd
\dnnn \d
\c \n
\c \n
\c \n
\r \t
\r \t
\r \t
138
SlickEdit
\om
Brief
\om
\ol
\ol
\ol
\char \:char
\char :char
\char \:char
The \c regular expression feature is particularly useful, and is specific to the context of a text editor. It allows you to control the position of the cursor after a match is found. You may find this option a reason to use a regular expression search, even if you are not otherwise searching for a pattern. The last feature (\:char) in Table 7-3 provides a shorthand for a set of common patterns. The patterns are more fully documented in the online Help, but are summarized in Table 7-4. The \:f and \:p patterns, for searching for a filename part and a path, respectively, are operating-system-specific. Thus if you are running on Windows, \:f will match a Windows-style filename part. Its worth noting that \:f and \:p also match anything that can be a part of a filename. But they dont do paths or files that contain spaces. Many regular expression features use the backslash (\) character. If you type regular expressions into the Find dialog or use them on the command line, you can use the backslash normally. If you use regular expressions with the search() function in a macro, you need to keep in mind that backslashes are interpreted specially in double-quoted strings in Slick-C. Usually, this means you need to escape the backslashes in your Slick-C expressions. For example, the following UNIX-style regular expression matches an ISO date (yyyy-mm-dd):
\:d{4}-\:d{2}-\:d{2}
You can use that expression in the Find dialog. If you are programming a macro and using the search() function, you need to escape the backslashes, like this:
search(\\:d{4}-\\:d{2}-\\:d{2}, U);
139
Description Matches an alphanumeric character. Matches blanks. Matches an alphabetic character. Matches a digit. Matches a filename part. Matches a hex number. Matches an integer. Matches a floating number. Matches a path. Matches a quoted string. Matches a C variable. Matches a word.
Tagged Expressions
Regular expressions can specify tagged expressions, which can be used to replace or extract parts of the match. For example, using UNIX-style regular expressions again, we could give the above expression as:
(\:d{4})-(\:d{2})-(\:d{2})
In UNIX-style regular expressions, parentheses are used for forming tagged expressions. In this regular expression, there are three tagged expressions, one each for the year, month, and day parts of the ISOformatted date. In replacement strings, matches to tagged expressions are given as a backslash followed by the number of the tagged expression. Thus for this regular expression, the year part would be specifed by \1 in a replacement string, and so on. A replacement string that converts the given ISO-formatted date into USA format (mm/dd/yyyy) would look like this:
\2/\3/\1
In this replacement string, the ordinary slashes are date separators, and the backslashes are for identifying tagged expressions. Tagged expressions are also referred to as match groups or capturing groups.
140
Table 7-5
Expression
\:d{4}-\:d{2}-\:d{2} \:d{1,2}/\:d{1,2}/\:d{4}
Description Match an ISO date (yyyy-mm-dd). Match a USA date (mm/dd/yyyy), with months and days being one or two digits. Match a USA date, with grouping expressions to capture the resulting fields. Search for an #include directive using quotes, with a group to capture the #included file. HTML/XML start or end tag, with attributes.
(\:d{1,2})/(\:d{1,2})/(\:d{4})
#include\:b+([^]+)
<(/?(\:c|[0-9]|-|_|:)+)([^>]*)>
Table 7-6
Command
find/expr[/options] /expr[/options] l/expr[/options] replace/exp1/exp2[/options] c/exp1/exp2[/options] all/expr[/options] allnot/expr[/options] show-all
Description Find command. Find command (shorthand form). Find command (alternative shorthand form). Replace command. Replace command (shorthand form). Selective display show matches. Selective display hide matches. Cancel selective display.
141
where
expr is the string or pattern to search for; and options are the search options.
The command can be shortened to just a slash, and the closing slash is not required if there are no options. The short form of the find command looks like this:
/expr
If you are searching for a string that contains slashes, you can escape them with a backslash. Alternatively, you can use the find command or the shorthand l (letter L, for locate) command with a different delimiter. For example, to search for the date 3/9/2007, we could use either of these commands:
/3\/9\/2007 l|3/9/2007
The second one is easier to understand. The syntax of the command-line replace is:
change /exp1/exp2[/options]
where:
exp1 is the string or pattern to search for; exp2 is the replacement string; and options are the search and replace options.
Once again, the command can be shortened to just c, and the closing slash is not required if there are no options. Thus the short form of the change command looks like this:
c/exp1/exp2[/options]
Just as with the find command, you can use different delimiters with the change command. For example, to change the literal date 3/9/2007 to 2007-03-09, we could use the command:
c|3/9/2007|2007-03-09
142
Command-Line Options
The command-line find and change commands have many options. Table 7-7, showing the options, is taken directly from the online documentation. The options are not case-sensitive. Consult the online documentation for more details about these options.
Table 7-7
Option
E I + M < > R U B & @ H # N P W W:P W:PS
Description Exact case. Ignore case. Forward search. Reverse search. Limit search to marked area. If found, place cursor at beginning of word. If found, place cursor at end of word. Interpret search string as a SlickEdit regular expression. Interpret search string as a UNIX regular expression. Interpret string as a Brief regular expression. Interpret string as a wildcard regular expression. No error message if string not found. Search through hidden lines. Highlight matched occurrences with highlight color. Do not interpret the string as a regular expression. Wrap to beginning/end when string not found. Limits search to whole words. Limits search to word prefix. Limits search to strict word prefix. continued
143
Description Limits search to word suffix. Limits search to strict word suffix. Binary search. Delimiter to separate ambiguous options. Requires the first character of the match to be one of the color coding elements specified by letters. Requires the first character of the match to be not one of the color coding elements specified by letters. Preserve case. Highlight replaced text with modified line color.
Xletters
V $
Some of these options are particularly useful in macro programming. Its often important to specify options explicitly in macros so that the macros operation is not confounded by an unexpected user setting. The < and > options, for example, allow you precise control over cursor placement during a macro execution, regardless of the users default search options. The C and X options specify color coding elements. Table 7-8 shows the letters that can be used.
Table 7-8
Letter
O K N S C P L 1 2
Color Coding Element Other Keyword Number String Comment Preprocessing Line number Symbol 1 Symbol 2
144
Table 7-9
Command
/ERROR/e all/ERROR/e allnot/DEBUG/e /def_ /def_//def_/xc all/def_/xc /_command/ck l|\:d{1,2}/\:d{1,2}/\:d{4 }|u l|\:d{1,2}/\:d{1,2}/\:d{4 }|u> l|\:d{1,2}/\:d{1,2}/\c\:d {4}|u c|(\:d{2})/(\:d{2})/(\:d{ 4})|\3-\1-\2|u
Description Search for ERROR, matching exact case. Show only lines containing ERROR, exact case. Show only lines not containing DEBUG, exact case. Search for next occurrence of def_. Search for previous occurrence of def_. Search for next occurrence of def_, outside comments. Show only lines containing def_, outside comments. Search for _command as a keyword. Search for US style date (mm/dd/yyyy). Search for US style date, place cursor at end. Search for US style date, place cursor at beginning of year. Change US style date to ISO (yyyy-mm-dd) (doesnt handle single-digit days or months). continued
145
Description Change SQL semicolon terminator to a slash on its own line (excludes commented lines). Change line endings DOS to UNIX (includes hidden lines). Change line endings UNIX to DOS (includes hidden lines).
c/\x0d\x0a/\x0a/uh* c/\x0a/\x0d\x0a/uh*
Selective Display
SlickEdits selective display feature is like having grep built into the editor. It allows you to show only certain lines, or to omit certain lines. In some situations, this can make it much easier to focus on what you want to see and edit.
Table 7-10
Command
hide-all-comments hide-code-block hide-selection hide-dotnet-regions show-procs toggle-all-outlining
Menu View Hide All Comments View Hide Code Block View Hide Selection View Hide #region Blocks View Function Headings (none) View Expand/Collapse Block (Ctrl+backslash) View Copy Visible View Show All
Description Hides all comments. Hides block containing cursor. Hides lines containing selected text. Hides .NET #region blocks. Shows only function headings. Toggles selective display of function bodies and comments. Expand or collapse a hidden block.
plusminus
copy-selective-display
show-all
146
Figure 7-6
When you are finished with selective display and wish to see the entire buffer again, invoke show-all. If you wish to copy only the visible lines to the clipboard, you can use copy-selective-display:
1. 2.
Make a selection that includes the lines you wish to copy. Invoke copy-selective-display (View Copy Visible). The visible lines in the selection are copied to the clipboard.
The hide-dotnet-regions command is intended for .NET programming, where Visual Studio inserts foldable regions into the code. There are region markers defined in SlickEdit for the standard Visual Studio comment markers for these regions, depending on the language of the source file. The region markers are shown in Table 7-11. The #region and #endregion markers also work in Slick-C files.
147
End Region
#endregion #pragma endregion #endregion #End Region
Figure 7-7
The Selective Display dialog operates in several different modes, selected by the radio buttons near the top. The default is Search text, which you use to specify your own search criteria. Using Function definitions is an alternative way to invoke selective display to make all your function definitions expandable and collapsible. The Preprocessor directives mode lets you use selective display to filter your source file according to preprocessor conditional directives such as #ifdef. You can use this to see which lines of your source file are actually seen by the compiler.
148
Figure 7-8
The custom selective display capability available with the Selective Display dialog is nice, but it does not allow you to use some of the features available for searching in general with selective display. For example, it does not support searching in color syntax regions as the Find and Replace tool window does. Command-line selective display is faster to use and sometimes more powerful than the GUI interface. Its also very simple.
149
Figure 7-9
Command-line find is smart enough to leave the selection alone when using the m option (Search in selection), even if Leave selected is on. The GUI Find is not, however. (Did you need another reason to prefer the command line?)
Summar y
Search and replace is a fundamental aspect of any text editor. SlickEdit offers a variety of search and replace tools to cover all situations, from the fast and simple to the complex. SlickEdits regular expression support is extensive, including three different syntax variants. Color-coded searching is an enhancement specifically for programming, which can often make searches much more selective than they would be otherwise. Simple search features such as quick-search and i-search are invoked directly using the keyboard for maximum speed. Complex searches can be configured using many options in either the GUI dialogs or a range of commands on the command line. The GUI dialogs are great for learning what options are available and experimenting with them. The command line can be faster for experts, and makes searches more repeatable and programmable. Macro programming often invokes searches similarly to the commandline searches. In the next chapter, we start looking at advanced features and techniques with SlickEdit for actually editing text.
150
Editing Text
While Ive spent a lot of time writing code throughout my programming career, it seems that I spend just as much time in the editor working with other kinds of files. Some examples are: Scripts or sets of commands. Test data (and sometimes production data too!). Log files. Configuration files. Stack traces. Dumps. Notes.
Sometimes I am merely searching and browsing. Sometimes I am moving things around and deleting unwanted data to analyze the content of a file. Other times I am actively editing, adding new data. SlickEdits speed and advanced features make it ideal for all of these tasks. Many of SlickEdits features are generic to the job of editing text and are not specific to programming, much less to a particular programming language. This chapter covers some of SlickEdits general-purpose text editing features. The topics are important in any task you are doing with SlickEdit. They include: Using basic editing. Using selections and clipboards to move, copy, and manipulate text. Using word completion to save typing.
Chapter 9 follows this with detailed information specific to editing code. Chapter 10 focuses on data-oriented editing.
Table 8-1
Command
undo undo-cursor redo
Description Undo last change or cursor movement. Undo all cursor movement to last change. Redo last undone change.
The way that cursor movement is undone is controlled by a configuration setting. By default, the undo command undoes all cursor movement back to the last change. With this setting, there is no need for undo-cursor. If you prefer to undo cursor movements individually, you can set the macro variable def_undo_ with_cursor to 1. With this setting, each press of undo undoes just one cursor movement, and undo-cursor undoes all cursor movement to the last change. In many cases, pushed bookmarks are the most effective way to get back to where you were after navigation. They are the standard way to return from push-tag or push-ref. They can be used to return after top-of-buffer or bottom-of-buffer, if def_top_bottom_push_bookmark is set to 1. For arbitrary navigation within the buffer, such as paging up and down or moving around among routines, pushed bookmarks only work if you remember to push them first. For these cases, its advantageous to have def_undo_with_cursor set to 1 so that you have flexibility in undoing cursor movement.
Line Commands
When programming, and in other programming-related tasks, its very common to work with lines of text. SlickEdit provides several useful shortcut commands for common operations on lines. These are summarized in Table 8-2.
152
Description Delete from cursor to end of line. Delete current line. Duplicate current line.
The cut- commands both place the deleted text into the clipboard. Well see a lot more ways of working with the clipboard, and with lines, in the next section.
They are also used for defining the scope of some operations, for example: Searching and replacing. Formatting and manipulating. Filling with data.
SlickEdit is all about text. As we see in Chapter 9, SlickEdit has quite a lot of understanding of the structure of programs, at least for some programming languages. But there is no Drag n Drop, no WYSIWYG, and there are no hidden fields or symbols when you are working with a file. Everything is text. When you make a selection, you are selecting characters of text. The standard character sequence model of selection works in SlickEdit. But it is designed for word processing and is often not the most effective kind of selection in typical programming work. SlickEdit offers a couple of other selection models that reflect more closely the kind of work programmers do. Several configuration options affect the way selections work. Some of these options are discussed in the Configuring Selection Options section.
153
Description Delete text and place a copy in the clipboard. Copy text to the clipboard. Paste text from clipboard to buffer. Delete text and append it to the current clipboard. Copy text and append it to the current clipboard. Display multiple clipboards to paste from.
These commands work pretty well for quick edits with small selections of a single word or a few words. Note that you can also use the cut and copy-to-clipboard commands with no selection, in which case they operate on the current line. For larger jobs, SlickEdit has powerful commands that work with locked selections, explained below.
Multiple Clipboards
When you copy text to the clipboard in SlickEdit, the editor actually creates and remembers a set of clipboards. When you wish to paste from the clipboard into SlickEdit, you can select which clipboard to paste from. The default paste command always pastes from the current or most recent clipboard. If you want to paste from another clipboard, use the list-clipboards command (Ctrl+Shift+V) instead. (Although the name of the command is quite different from paste, its function is similar; thus the keyboard shortcut is chosen to make it easy to remember as an enhanced version of paste.) SlickEdit displays the Select Text to Paste dialog, shown in Figure 8-1. The dialog shows you, for each clipboard, the type of selection stored in it and a preview of the selection. You can select a clipboard to paste, or cancel. The number of clipboards SlickEdit remembers is configured in Max clipboards in the More tab of the General Options dialog (Tools Options General), or by setting the def_clipboards macro variable.
154
Figure 8-1
Appending to a Clipboard
Sometimes you want to collect multiple chunks of text together and move or copy them all to a new location. An example is when you are refactoring a class and moving a selection of its methods to another file. You could move each function separately, one by one. Or, you could cut each function individually to a clipboard, and then paste each of those clipboards in turn into the new file. A better alternative is provided by SlickEdits clipboard append commands: Use append-cut (Ctrl+Shift+X) to cut text and append it to the current clipboard. Use append-to-clipboard (Ctrl+Shift+C) to append text to the current clipboard.
The keyboard shortcuts of these commands are designed to be easy to remember, because they simply add the Shift key to the familiar shortcuts for cut and copy.
Locked Selections
If you make a selection with the mouse, or by holding down Shift and using cursor movement keys, the selection is regular, and behaves like selections in most word processors. You need to copy or cut the text before moving the cursor again, because moving the cursor loses the selection. With SlickEdit, you can also make locked selections. Locked selections are much more flexible than regular selections, because you can move the cursor away, type text, and do many other things without losing the selection. Locked selections can be extended any number of times. Many SlickEdit features are designed to work with locked selections. Table 8-4 is a summary of SlickEdit commands for locked selections. Many of the select- commands are available under the Edit Select cascading menu.
Table 8-4
Command
select-char select-line
Description Start or extend a character selection. Start or extend a line selection. continued
155
Description Start or extend a block selection. Make a character selection from the cursor to the end of the current word. Make or extend a character selection from the cursor to the end of the current word. Make a character selection for the whole word under the cursor. Make a line selection for the entire buffer. Make a selection for the code at the current scope. Make a line selection for a group of lines bounded at the top and bottom by a blank line. Make a character selection for the next block of code bounded by parentheses, brackets, or braces. Make a line selection for the entire procedure, function, or method the cursor is in. Move the selection to the current cursor position. Copy the selection to the current cursor position. Move to the beginning of the selection. Move to the end of the selection. Turn off existing selection. Convert all words in selection to uppercase. Convert all words in selection to lowercase. Shift text in selection one character to the left.
select-next-word
(none)
select-whole-word
(none)
select-all select-code-block
Ctrl+A (none)
select-paragraph
(none)
select-paren-block
(none)
select-proc
(none)
move-to-cursor
WROX: Alt+M
copy-to-cursor
WROX: Alt+C
WROX: Alt+Y WROX: Alt+E Ctrl+U, WROX: Alt+U Ctrl+Shift+U Ctrl+Shift+L Shift+F7
156
Key Shift+F8
Description Shift text in selection one character to the right. Remove trailing spaces from lines in selection. Pass selection as input to external command.
remove-trailingspaces filter-command
(none)
(none)
There are some configuration options that affect the behavior of regular selections, but for the most part they behave the same way they do in many other programs; thus we will not go into them in much detail here. Unless otherwise noted, what follows applies to locked selections.
Selection Models
SlickEdit supports three different selection models: Character selection. Line selection. Block selection.
The following sections explain each of these models, and how to make them.
Character Selection
A character selection is defined by a starting character and an ending character. The selection includes the start, end, and all characters between, as shown in Figure 8-2.
Figure 8-2
When a character selection spans more than one line, as does the one in Figure 8-2, SlickEdit displays the number of lines selected in the status line, as shown in Figure 8-3.
Figure 8-3
157
Figure 8-4
Character selection should be familiar from programs such as Notepad and most word processors. Character selection is the most useful kind of selection when you are working with plain text, such as notes or documentation. Character selection can also be used to select small chunks of characters within a single line. To make a (locked) character selection:
1. 2. 3. 4.
Move the cursor to the first character. Press select-char (F8) to begin the selection. Move the cursor to the character after the last character you wish to select. The selection grows as you move the cursor. Press select-char (F8) to lock the selection.
Once the selection is locked, you can move the cursor to another location. In the WROX emulation, select-char is also bound to Alt+Z.
Line Selection
A line selection is defined by a starting line and an ending line. The selection includes all the characters of the starting line, the ending line, and all lines between, as shown in Figure 8-5.
Figure 8-5
When you make a line selection, SlickEdit displays the number of lines selected in the status line, as shown in Figure 8-6.
Figure 8-6
158
1. 2. 3. 4.
Move the cursor to anywhere on the first line. Press select-line (Ctrl+L) to begin the selection. Move the cursor to anywhere on the last line. The selection grows as you move the cursor. Press select-line (Ctrl+L) to lock the selection.
Once the selection is locked, you can move the cursor to another line. In the WROX emulation, select-line is also bound to Alt+L.
Block Selection
A block selection is defined by an upper-left position and a lower-right position. The selection includes all the characters in the rectangle bounded by the upper-left and lower-right characters, as shown in Figure 8-7.
Figure 8-7
When you make a block selection, SlickEdit displays the number of rows and columns selected in the status line, as shown in Figure 8-8.
Figure 8-8
Block selection is the most useful kind of selection when you are working with data in columns, such as CSV files, SQL updates, and some XML files.
159
1. 2. 3. 4.
Move the cursor to the top-left character. Press select-block (Ctrl+B) to begin the selection. Move the cursor to the bottom-right character. The selection grows as you move the cursor. Press select-block (Ctrl+B) to lock the selection.
Once the selection is locked, you can move the cursor to another location. In the WROX emulation, select-block is also bound to Alt+B.
Selecting Words
There are several commands providing convenient ways to select individual words. These commands work well for variables and other identifiers in programming: Use select-word to make a character selection from the cursor to the end of the current word. The cursor is moved to the end of the selection. Use select-next-word to make or extend a character selection from the cursor to the end of the current word. The cursor is moved to the end of the selection. You can use this command to extend the selection a word at a time. Use select-whole-word to make a character selection for the whole word under the cursor. The cursor is moved to the end of the selection.
160
These commands are not bound to keys in the default CUA emulation. Note that only one selection may be active at a time, throughout the editor. This means that you cannot have different selections active simultaneously in different buffers. It allows you to use move-to-cursor and copy-to-cursor to move and copy text between buffers unambiguously.
These commands are also not bound to keys in the default CUA emulation.
Deselecting
Moving the cursor does not deselect a locked selection. To turn off an existing locked selection, use the deselect command (Ctrl+U). In the WROX emulation, deselect is also bound to Alt+U. Usually you dont have to deselect explicitly. You can also deselect by any of the following: Deleting the selection. Starting a new selection of a different kind. Starting a new selection in a different buffer.
161
These commands can all be found under the Edit Other menu. You can also create your own commands and have those commands operate on selections. We see how to write macros that operate on selections in Chapter 16.
Searching in Selections
An important use of selections is to limit the scope of Find or Search and Replace. This can be particularly useful using block selections, as it allows you to find or replace in a column. To limit a Find or Replace command to the selection, use the m option. For example, to find the next occurrence of the word edit in the selection, use the command:
find /edit/m
162
163
To restore the line selection later, provided the bookmarks have not been cleared, enter the command:
wrox-restore-line-sel SET1
To make these commands handier to use, you may want to rename them to something shorter.
Figure 8-9
Most of these options are self-explanatory or are well explained in the online Help. When Extend selection as cursor moves is checked, the procedure for making a locked selection is as described above, that is:
1. 2. 3. 4.
Move the cursor to the start. Use a selection command (select-char, select-line, or select-block) to start the selection. Move the cursor to the end of the selection. The selection grows as you move the cursor. Use the selection command again to lock the selection.
164
1. 2. 3. 4.
Move the cursor to the start. Use a selection command (select-char, select-line, or select-block) to start the selection. Move the cursor to the end of the selection. The selection does not change as you move the cursor. Use the selection command again to extend the selection to the current cursor position and lock the selection.
This approach has some advantages over the default setting: You can move the cursor around wherever you want after starting the selection, before you finish it. The selection is not affected. You can extend the selection again any number of times after locking it, by invoking the selection command again.
In addition, with Extend selection as cursor moves unchecked, the regular selections made by the special selection commands such as select-word and select-code-block can be locked if you choose. This gives them a bit more flexibility. As with most configuration settings, it is a personal preference, but I recommend unchecking the Extend selection as cursor moves option.
165
You want to review each log file and add a note about it next to the file name in the list of log files. Suppose that the notes you want to add look like this:
batch_job_run-20070101.log batch_job_run-20070102.log batch_job_run-20070103.log batch_job_run-20070104.log batch_job_run-20070105.log batch_job_run-20070106.log passes passes fails: missing fails: missing followup: user fails: missing
We can use word completion to save a lot of typing when entering these notes. First, you add passes as a comment for the first file. Then, move the cursor to the end of the second line. Figure 8-10 shows the data on the screen at this point.
Figure 8-10
Next, type in p. Now invoke the complete-prev command (Ctrl+Shift+comma). SlickEdit finds the previous string in the file beginning with p and completes your current word to match that. Figure 8-11 shows the result. The matched word is selected.
Figure 8-11
Next, we need to add the comment fails: missing data to the third and fourth lines. Type the complete comment on the third line. Then, move the cursor to the comment position on the fourth line. Type the f to start fails. Invoke complete-prev. SlickEdit completes fails, as shown in Figure 8-12.
166
Figure 8-12
The message line contains the prompt Press Ctrl+Shift+Space for more: : missing data. This is shown in Figure 8-13. The prompt is useful if the match is off the screen.
Figure 8-13
Invoke complete-more (Ctrl+Shift+Space). The next word (missing) is completed. Invoke complete-more once again to get data. The entire matching comment is selected, as shown in Figure 8-14.
Figure 8-14
Next, add the comment followup: user review required to the fifth line. Now, the sixth line needs fails: missing data again. Move the cursor to the comment position on the sixth line. Type the first f of fails. Invoke complete-prev twice. The first time matches f with followup on the line above. The second time continues searching backward, to fails, which is on line 4 of Figure 8-15.
Figure 8-15
Alternatively, instead of typing just f and using complete-prev twice, you could type fa to make the search more precise. You can search forward instead of backward using complete-next (Ctrl+Shift+dot). You can also use complete-next if you accidentally overshoot while searching backward with complete-prev, and vice versa.
167
In such a situation, we can use word completion to complete more than half of each statement, after the first statement. That is, the text:
INSERT INTO network_category (id, description, header, active_yn) VALUES
needs to be typed in only once. Following the first time, it can be repeated very quickly. Even with programming languages that have special syntax support, word completion is often the most effective way to save typing. Java, for example, has a lot of syntax support from SlickEdit. But even so, lets see how word completion works for Java in a typical example. This time we are entering the code for the following JUnit test method:
public void testFirstOrChangedToAnyOf() { Condition aaaCondition = aaa.firstOrChangedToAnyOf(a1, a3); Condition bbbCondition = bbb.firstOrChangedToAnyOf(b1, b3); Condition cccCondition = ccc.firstOrChangedToAnyOf(c1, c3); Condition dddCondition = ddd.firstOrChangedToAnyOf(d1, d3); assertTrue(aaaCondition, bbbCondition, cccCondition); assertFalse(dddCondition); next(); assertFalse(aaaCondition, bbbCondition, cccCondition, dddCondition); next(); assertTrue(aaaCondition, bbbCondition, cccCondition); assertFalse(dddCondition); next(); assertFalse(aaaCondition, bbbCondition, cccCondition, dddCondition); next(); assertFalse(aaaCondition, bbbCondition, cccCondition, dddCondition); }
168
Figure 8-16
If any of the identifiers Condition, firstOrChangedToAnyOf, assertTrue, or assertFalse already existed in the buffer before starting, the savings would be even more. Because word completion is simple, it is very fast. You may find that because of tagging or other reasons, the advanced expansion features in SlickEdit can suffer from delays. If the editor delays, it interrupts your flow. Word completion almost never suffers from delays; thus it lets you write code quickly and smoothly. Get into the habit of using word completion. Although it is disarmingly simple, you will find it among the most powerful and useful features in any editor.
169
The default value of def_complete_flags is 5, which corresponds to both COMPLETE_REVERSE_AT_CURSOR and COMPLETE_ALLOW_DUP_MATCHES being set. The meanings of these flags are explained below. The flag COMPLETE_REVERSE_AT_CURSOR controls what happens when you reverse direction while searching. The default is to reverse direction at the current search position. This setting is useful because you can use it to reverse your search if you accidentally overshoot the match you intended. Also, if matches are off screen, you can search alternately backward and forward, observing the matched lines in the message area. If the COMPLETE_REVERSE_AT_CURSOR flag is not included, then reversing a search causes the search location to revert to the current editing location. The flag COMPLETE_CHECK_SCOPE can be used to indicate that the search has extended outside of the current scope. If you include this flag and the search extends out of the current scope, the message line showing the match is prepended with *** Outside current proc *** as a warning. The flag COMPLETE_ALLOW_DUP_MATCHES controls whether duplicate matches are included in searches. If the flag is not included, duplicate matches are skipped. It might appear that duplicate matches are a bad thing, and that this flag should be excluded. If you are searching for a match for just one word, this is true. If you intend to complete more text after the match, however, it often turns out you need to allow duplicates to match so that you can navigate to the correct line. To continue our example above, suppose you need to extend the file commentary like this:
batch_job_run-20070101.log batch_job_run-20070102.log batch_job_run-20070103.log batch_job_run-20070104.log batch_job_run-20070105.log batch_job_run-20070106.log batch_job_run-20070107.log batch_job_run-20070108.log batch_job_run-20070109.log passes passes fails: missing data fails: missing data followup: user review required fails: missing data fails: incorrect dates fails: incorrect dates fails: missing data
170
If the COMPLETE_LOOK_FOR_ANYTHING flag is included, then matches in comments and strings are always included. The behavior concerning comments and strings can be further customized by the def_complete_vars macro variable. This variable contains two values separated by a space. The default value is 1 2. The first of the two values controls whether comments and strings are skipped. This setting actually affects the same behavior as the COMPLETE_LOOK_FOR_ANYTHING flag above: If either the flag is included, or this first value is not set to 1, then comments and strings are not skipped. (This redundancy is a legacy effect of the SlickEdit macro code.) The second of the two values is a number of lines. This is a rather fine point: Comments and strings within this number of lines of the edit position are not skipped. The idea of this setting is that it can be useful to match comments and/or strings in close proximity to where you are currently editing, but generally you dont want to match them further away. How far away is further away is controlled by this macro variable. The default value of the second value in def_complete_vars is 2, meaning that comments and strings within two lines of the edit line are actually included in matches, while comments and strings farther away are not. Having said all this, I have to admit that configuring word completion is currently rather esoteric and is quite likely to be overhauled in a forthcoming release. Besides, because the default configuration works just fine for most users, you may be happy not to mess with it.
Summar y
This chapter introduced several topics around the general needs of editing text. We started with standard editing features, touching on a few useful features beyond the basics found in Notepad. Then we covered SlickEdits support for clipboards and powerful selection models. We use selections in many places in the book, particularly in Chapter 10. Finally, we introduced word completion, a simple but powerful feature that saves a lot of typing. The next chapter goes into more detailed specifics about editing code and shows several features specific to different types of source files.
171
Editing Code
Editing code is SlickEdits primary function. Many features of the editor apply to text editing in general. Some of them apply to editing data. But the most specialized features deal with specific tasks encountered while editing code. In Chapter 5, we cover Context Tagging, which is an important set of features that provide assistance when editing code. In this chapter, we cover a variety of additional features for editing code. The most basic and obvious code-specific feature is color syntax highlighting. SlickEdit has color syntax highlighting for numerous programming languages, and you can easily add support for a new language. SlickEdit also supports a range of other options per programming language, such as indentation preferences and comment formatting. SlickEdit provides syntax assistance for common constructs in various languages. For example, SlickEdit expands control structures automatically. When you type in starting elements in code, SlickEdit often adds the ending elements automatically. This happens with braces and multiline comments, for example. One reason for this is to save you time. Another reason is that it helps keep the file structure valid, and that is very useful because when SlickEdit can parse the file structure correctly, it can provide the best contextual assistance.
The default mode, for plain text files or files with an unknown extension, is fundamental mode. To switch a buffer to fundamental mode, use the fundamental-mode command. Some of the settings defined in a mode are: Tab or indentation settings. Language-specific key bindings. A lexer name.
To view and edit the settings for a file extension, use Tools Options File Extension Setup. For an example of setting up a new file extension, see Chapter 17. Some of the modes supplied with SlickEdit are: C/C++. Java. Slick-C.
There are many others, more than 70 in total. A file extension defined in SlickEdit either defines a named mode or refers to another file extension and inherits the mode of that extension. For example, the file extensions cpp, cxx, h, hpp, and hxx all refer to the c extension, and are thus all associated with the C/C++ mode. A lexer is a collection of settings that define syntax coloring rules for a programming language. Some of the settings that define a lexer are: The keywords of the programming language. Whether or not the language is case-sensitive. How comments are defined. How strings are delimited.
To view and edit the color settings for a lexer, use Tools Options Color Coding. We cover lexers in more detail in Chapter 17.
174
Extensionless Files
Most programming source files have an extension, but some dont. UNIX shell scripts, for example, commonly do not have an extension. SlickEdit deals with shell scripts by examining the first line of the file for the UNIX shebang comment like this:
#!/bin/sh
If SlickEdit finds a shebang comment that it recognizes, it applies the appropriate mode. Another group of files that have no extension is the set of header files for the C++ standard library. SlickEdit has special rules to recognize these files when opening them, and applies the correct mode. You can define additional extensionless header files for libraries you are using:
1. 2. 3. 4. 5.
Open the Extensions Options dialog (Tools Options File Extension Setup). Select extension C. Click C/C++ Options to open the C/C++ Options dialog. Click the Other tab. Click Extensionless C++ Files. SlickEdit displays the Extensionless C++ Files dialog, as shown in Figure 9-1. Use this dialog to specify names of extensionless files you want to be opened as C++ files.
Figure 9-1
Syntax Highlighting
SlickEdits color syntax highlighting is powered by its lexers. If a language has a lexer set up for it, SlickEdit can display different program elements in different colors and styles. There are many program elements. Some of them are: Identifiers. Keywords.
175
In addition to program elements, there are many other screen elements that SlickEdit can color specially to make them more distinctive. Some of these other elements are: The cursor. Hex mode. Selection. Block matching. Search match.
There are more than 30 screen elements in total. You can define the foreground and background color for any screen element, as well as whether to display the element in normal font, bold, italic, or underlined. The settings are done separately for whether the language is the main language of the file or embedded within another language. See Embedded Languages below in this chapter. You can save a collection of color settings in a named color scheme. SlickEdit provides several color schemes, and you can create as many more as you like. The Color Coding Setup dialog (Tools Options Color Coding) is used to define the characteristics of lexers. From that dialog, you can click the Colors button to open the Color Settings dialog, where you can customize the colors of screen elements. Figure 9-2 shows the Color Settings dialog.
Figure 9-2
176
Figure 9-3
This dialog allows you to customize various aspects of tab use and indentation. From the Extension Options dialog, you can click on an Options button to open an options dialog specific to the programming language associated with the selected extension.
177
C/C++ Options
By far the most options are available for the C/C++ languages. These languages have three tabs of options available, shown in Figures 9-4, 9-5, and 9-6. Figure 9-4 shows the C/C++ style options concerning braces. Note that the function brace style can be set differently from the control structure brace style in C/C++, as many C/C++ coding standards require this.
Figure 9-4
Figure 9-5 shows some additional indentation settings that are specific to C/C++. This tab also allows you to specify your preferred style for declaring pointers.
Figure 9-5
Figure 9-6 shows other settings specific to C/C++. The Main style setting selects a template to use when you define the C/C++ main() function.
178
Figure 9-6
The C/C++ Preprocessing button opens the C/C++ Preprocessing dialog, which is used to control the preprocessor for C/C++ files. This is important for SlickEdit to be able to parse C/C++ files correctly. The Extensionless C++ Files button opens the dialog of that name, which we have covered above.
Figure 9-7
179
HTML Options
HTML options are completely different from those of other programming languages. Figure 9-8 shows the options for HTML. You can specify the case for different HTML elements. You can specify the language for embedded ASP. And you can specify a number of settings that affect how SlickEdit inserts HTML content.
Figure 9-8
Other Languages
SlickEdit has language-specific options for several other programming languages. Click the Options button on the Extension Options dialog to see options specific to the selected extension. The Options button dynamically changes label depending on the language and is enabled only if there are language-specific options available.
180
Syntax Expansion
When you are typing code, SlickEdit can automatically expand control structures and other statements in the language. For example, suppose you are editing a C file as shown in Figure 9-9.
Figure 9-9
Lets use syntax expansion to insert an if() test for the number of arguments passed in to the program:
1.
Type if and press Space. SlickEdit expands the if control structure as shown in Figure 9-10.
Figure 9-10
2.
Figure 9-11
3.
Invoke next-hotspot (Ctrl+[) to move the cursor out of the condition and on to the next place where you want to edit. The screen now appears as in Figure 9-12. SlickEdit also prompts you to continue pressing Ctrl+[ to go to the next part of the statement, as shown in Figure 9-13.
Figure 9-12
Figure 9-13
The if() statement has two hotspots: one in the condition, and one after the opening brace. Invoke next-hotspot (Ctrl+[) and prev-hotspot (Ctrl+Shift+[) to cycle through the hotspots. Syntax expansion is triggered by mode-specific key bindings. For example, in C/C++ mode, the Space key invokes the command c-space, which is defined in c.e in the supplied macro source. The logic for
181
This template is entered verbatim. It does not honor the brace preference settings. One way to fix this would be to edit the Slick-C code in the slick_expand_space() macro function. However, messing with the macros provided with SlickEdit is usually not a good idea. For one thing, you might mess things up! For another, your changes will be lost when you upgrade. Fortunately, there is a much better way to override the templates provided, using extension-specific aliases. We look at aliases in detail in Chapter 11.
Figure 9-14
One way you can do this is using the surround-with command. To add the test with surround-with:
1.
Select the lines you want to surround. The screen should appear as shown in Figure 9-15.
Figure 9-15
2.
Invoke surround-with. SlickEdit displays the Surround With dialog, as shown in Figure 9-16. There is no key binding for surround-with in the CUA emulation, but it is available in the context menu. (Open the context menu by right-clicking with the mouse.)
182
Figure 9-16
3.
Choose if and press Enter. SlickEdit surrounds the selection with an if() statement, as shown in Figure 9-17.
Figure 9-17
4.
The surround-with templates are specific for each mode. The templates are implemented by way of extension-specific aliases. In Chapter 11, we look at an example of how to add your own surround-with template.
Dynamic Surround
In SlickEdit 2007, there is a new feature for surrounding code with control structures, called dynamic surround. Dynamic surround does basically the same thing as surround-with, but it is generally quicker and more intuitive. To add the same test as before, but with dynamic surround, start again with the file as shown in Figure 9-14. Then:
1. 2.
Add a new line for the if() statement, above the first printf(). Type if, and press Space. SlickEdit goes into dynamic surround mode, as shown in Figure 9-18. SlickEdit prompts you to surround lines of code using the arrow keys, as shown in Figure 9-19.
Figure 9-18
183
Figure 9-19
3.
Press the down arrow three times, to surround the three printf() statements. As you extend the surround, the closing brace moves down, and the printf() statements are re-indented to the enclosing block. The screen appears as shown in Figure 9-20.
Figure 9-20
4.
Type argc == 0 for the condition. Dynamic surround mode ends when you start typing code. You can also end dynamic surround by pressing Escape.
Dynamic surround is particularly nice for dealing with heavily nested files such as HTML. You can wrap an element such as a <div> or a <p> around other content quickly and intuitively. Alternatively, you may find that having dynamic surround invoked automatically gets in your way, since it sometimes interrupts normal typing. If thats the case, you can disable it in the Indent tab or the Extension Options dialog (Tools Options File Extension Setup). This setting is per mode; thus you can have dynamic surround run automatically for some file types and not for others.
Figure 9-21
1. 2. 3.
Move the cursor to the if() statement. Invoke delete-code-block (Ctrl+Del). SlickEdit displays the Delete Code Block dialog, shown in Figure 9-22. SlickEdit also selects the whole block, as shown in Figure 9-23. If you wish to delete the whole block, including the printf() statements, you can click Delete the entire block. If you wish to remove the if() statement and unsurround the printf() statements, you can click Unsurround the block.
184
Figure 9-22
Figure 9-23
If you prefer to delete code blocks without prompting, check the Always just delete block checkbox. This setting is also controlled by the def_prompt_for_delete_code_block macro variable. If you turn off prompting for delete-code-block, you cannot use the command for unsurrounding blocks. You can use the unsurround command (Ctrl+Shift+Del) instead. This command also displays a confirmation prompt, as shown in Figure 9-24. You can turn off this prompt too by setting the macro variable def_prompt_for unsurround_block to 0.
Figure 9-24
185
Introduction to Auto-Complete
In contrast to word completion, which is invoked explicitly, Auto-Complete is usually invoked automatically by SlickEdit when you pause briefly in your typing. The default timeout is 250 milliseconds, but this can be configured, as can many Auto-Complete settings. Lets compare Auto-Complete with word completion for the data-editing job given in Chapter 8. Suppose we start again with the original file, which looks like this:
batch_job_run-20070101.log batch_job_run-20070102.log batch_job_run-20070103.log batch_job_run-20070104.log batch_job_run-20070105.log batch_job_run-20070106.log
First, you add passes as a comment for the first file. Then, move the cursor to the end of the second line. Figure 9-25 shows the data on the screen at this point.
Figure 9-25
Next, type in p. After a short delay, Auto-Complete activates and finds the previous string in the file beginning with p, as shown in Figure 9-26.
186
Figure 9-26
Move the cursor down to the passes entry (the only entry) in the list. Auto-Complete displays information about the match, as shown in Figure 9-27.
Figure 9-27
Press Enter to accept the match. SlickEdit updates the buffer with the completed word, and the AutoComplete dropdown disappears. Next, we need to add the comment fails: missing data to the third and fourth lines. As with word completion, type the complete comment on the third line. Then, move the cursor to the comment position on the fourth line. Type the f to start fails. After a short delay, Auto-Complete activates and finds the previous word starting with f. Move the cursor down to the fails entry. Auto-Complete indicates on which line the match was found and the text following the match. Figure 9-28 illustrates Auto-Complete, showing the match for fails.
Figure 9-28
Press Enter to accept the match. The message line contains the prompt Press Ctrl+Shift+Space for more: : missing data, just as with word completion. This is shown in Figure 9-29.
Figure 9-29
187
Figure 9-30
Next, add the comment followup: user review required to the fifth line. Now, the sixth line needs fails: missing data again. Move the cursor to the comment position on the sixth line. Type the first f of fails. After a short delay, Auto-Complete activates and shows matches for f, as shown in Figure 9-31.
Figure 9-31
At this point, you can use the arrow keys to select the desired match, or type more of the word to narrow the search.
Auto-Complete in Programming
Many Auto-Complete features are specific to programming. In this section, we take a brief look at how Auto-Complete unifies word completion with other features on the programming example we looked at above. The first thing to notice about Auto-Complete is that it can complete things that word completion cannot. For example, word completion cannot complete a word that is not already in the buffer. Auto-Complete, thanks to its advanced searches, can often complete words that are not in the buffer, and it can do it intelligently based on the context. Figure 9-32 shows how Auto-Complete can complete the first word in a Java class definition. The category Syntax Expansion shows which search found the match public for the text pu.
Figure 9-32
188
Figure 9-33
If a symbol has some associated documentation such as JavaDoc, Auto-Complete shows that documentation, as shown in Figure 9-34. This is the same information we saw with list members and parameter information.
Figure 9-34
Configuring Auto-Complete
You can configure Auto-Complete for a particular file extension on the Auto Complete tab of the Extension Options dialog (Tools Options File Extension Setup). The tab is shown in Figure 9-35.
Figure 9-35
189
Embedded Languages
In some programming environments, it is common to embed one language inside another. There are many examples in web programming, where files frequently contain a mixture of code and formatting. Its also common in UNIX shell scripts and other scripting languages to use here documents to output chunks of code. SlickEdit supports embedded languages very well, providing color syntax highlighting, and often other editing features too, for the embedded code.
Web Programming
There is a huge variety of web programming environments these days. On the one hand, there is serverside web programming such as PHP, ASP, and JSP. On the other hand, many web sites use client-side
190
Figure 9-36
Client-side JavaScript is often placed into its own .js file, which SlickEdit treats just like any other source file. JavaScript may also be embedded within HTML files, within the <script> tag. In this case, SlickEdit supports the embedded syntax between the <script> tag and its closing </script> tag. Figure 9-37 shows an example of JavaScript embedded in an HTML file. Again, the main file is treated as HTML. The text within the <script> and </script> tags is treated as JavaScript, getting syntax coloring and other language-specific assistance.
Figure 9-37
191
Figure 9-38
Note that for SlickEdits embedded language features to work with here documents, you must use the name of the lexer (HTML in the example above) in the string terminating the here document.
Multiline comments are also known as block comments. These comments typically use a sequence of characters to mark the beginning and another to mark the end. Examples are:
/* and */ in C, C++, Java, and many other languages. <!-- and --> in HTML and XML.
Comments are used for two main purposes in coding. The intended purpose of comments is to document the code. However, they are also commonly used to exclude code from the compiler (or interpreter), whether temporarily or permanently. In C/C++, the preprocessor is also used to selectively omit sections of code. In many other languages, there is no preprocessor, and comments are the standard technique for selectively omitting code. SlickEdit has several features that assist when using line comments or multiline comments for either of these purposes.
192
Line Comments
Single-line comments can be added to document small pieces of code. Line comments are also frequently appended to the ends of lines to document declarations or logic. Perhaps less frequently, longer comments can be made with line comments that run over more than one line. For these comments, SlickEdit can provide assistance by wrapping lines as you type. One single-line comment is treated as a special case. Wrapping features dont start until you have more than one contiguous line comment. Wrapping for line comments is off by default. See Configuring Comments below. In many programming languages, including the C/C++ family, block comments do not nest. For this reason, they are often inappropriate for commenting-out code. Line comments do not have this problem and can be safely used to comment-out any code, even code that already has line or block comments. With help from the editor, you can apply or remove line comments on a range of lines easily. You can apply line comments to a selection or the current line like this:
1. 2.
If you want to apply line comments to multiple lines, select them first. Invoke comment (Document Comment Lines).
You can use comment-erase (Document Uncomment lines) in a similar way to remove line comments. These commands are not bound to keys in the CUA or WROX emulations. You could bind them to keys if you want to. But rather than use up two keys for applying and removing line comments, how about using a single key to toggle them instead? The macro code below defines a utility function wrox_in_comment(), which returns True if the cursor is currently on a commented line. After that, it defines a command, wrox-toggle-comment, and a binding for that command to Ctrl+Shift+slash.
boolean wrox_in_comment() { push_bookmark(); p_col = 1; begin_line_text_toggle(); int orig_col = p_col; int orig_line = p_line; int status = search(., U,CC); boolean result = (!status && orig_col == p_col && orig_line == p_line); pop_bookmark(); return result; } _command void wrox_toggle_comment() name_info(,VSARG2_REQUIRES_EDITORCTL) { boolean selection = _select_type() != ; if (wrox_in_comment()) { comment_erase(); } else { comment();
193
You can use wrox-toggle-comment instead of comment and comment-erase. The wrox-toggle-comment command determines whether the cursor is currently on a commented line or not. If the cursor is on a commented line, the command invokes comment-erase, otherwise it invokes comment. If there is no selection, wrox-toggle-comment also moves the cursor down one line. This makes it quick and easy to toggle the line comments on a few lines.
Multiline Comments
Multiline comments, oddly enough, often span more than one line. SlickEdit wraps multiline comments automatically, according to margin rules that you can configure. See Configuring Comments below. When you start a multiline comment by typing /*, SlickEdit automatically inserts the closing */ after the cursor. This is shown in Figure 9-39. This has the advantage that it keeps your file structure valid, so that syntax coloring and other assistance work correctly.
Figure 9-39
If you intended the multiline comment to end somewhere else, you can simply move to that location and insert the */ yourself. SlickEdit removes the */ that it inserted. This is shown in Figure 9-40. However, usually you simply type in your comment.
Figure 9-40
194
JavaDoc Comments
A special form of multiline comment is the JavaDoc comment, which originated in its current form with the Java programming language. JavaDoc is a very useful idea because it provides a standard format for documentation comments in source code. This allows tools to extract and process the documentation reliably. On the Java platform, the javadoc tool generates HTML documentation from Java source code. There are other tools for Java too, and also for other programming languages. C/C++ programmers often use JavaDoc comments with tools such as Doxygen. Doxygen is a kind of uber-javadoc. It can generate HTML documentation, but also LaTeX, RTF, PDF, and UNIX man pages. It supports Java, and also C/C++, Objective-C, Python, IDL, and to some extent other languages too. See http://www.stack.nl/~dimitri/doxygen/ for more information about Doxygen. As it happens, Slick-C itself also uses a documentation system based on JavaDoc, which enables a lot of SlickEdits online help to be generated automatically from the Slick-C source code. And, as we expect from Microsoft, C# also has its own incompatible version of the same idea, called an XMLDoc comment. SlickEdit supports JavaDoc comments for Java, C/C++, and Slick-C, and XMLDoc comments for C#. To add a JavaDoc comment to a member:
1. 2. 3. 4.
Insert a line above the member. Type /*. SlickEdit adds the closing */. Type a second *. This indicates to SlickEdit that the comment is a JavaDoc comment. Press Enter to split the line. SlickEdit fills in a JavaDoc comment template, with relevant information from the signature of the member. An example is shown in Figure 9-41. The cursor is placed at the start of the JavaDoc description, ready for you to start typing.
Figure 9-41
Configuring Comments
Comment behavior is configured per extension, in the Extension Options dialog. There are two tabs. The first tab, Comments, shown in Figure 9-42, defines several different configuration options for comments. There is also a string editing option hidden away in this tab, which controls whether strings are split when you press Enter.
195
Figure 9-42
The second tab, Comment Wrap, is shown in Figure 9-43. This tab controls which types of comments have wrapping enabled and what margins to use. Again, the online Help has a lot of documentation about these options.
Figure 9-43
196
Summar y
In this chapter, we covered several of SlickEdits features for editing code in specific programming languages. SlickEdits support for programming languages ranges from simple color syntax highlighting, which works with virtually any programming language, through to advanced features specific for major languages that SlickEdit targets, such as C/C++ and Java. The advanced features in SlickEdit in many areas match or rival those found in IDEs. Combined with SlickEdits superior text editing and navigation, this is what makes SlickEdit a compelling generalpurpose programming editor. Code is not the only part of a programmers life. Most programmers also spend much time dealing with data in one form or another. In the next chapter, we look in detail at SlickEdits perhaps surprising capabilities for dealing with data.
197
Editing Data
Programmers frequently have to deal with data. Much of your programming job may be concerned with manipulating data, whether the data are in a corporate database, read from an instrument, or generated to describe a 3D world in a game. Of course, if a certain task is within the scope of the main project youre working on, you will write code for the task in your main programming language it will be a feature of the application youre building. Often, though, you find you need to do something quick and ad hoc with some data. Someone sends you a spreadsheet with some test data that need to be entered in the database. You might need to sort a log file and count the number of error messages in it. You might want to take a directory listing and generate a one-off script from it. These are just some of many different scenarios that seem to arise daily in many programming or IT jobs. Different programmers have different preferences for dealing with these situations. UNIX gurus are usually proficient with tools such as sed and awk, not to mention more powerful scripting languages, such as Perl, Python, or Ruby, all of which are well suited for quick data hacks. Windows programmers might prefer a more interactive environment such as Microsoft Excel for manipulating data that are in rows and columns. SlickEdit provides several features that help out with ad hoc or one-off data manipulation. Using SlickEdit for one-off data jobs can provide an appealing mix of interactivity and scripted automation. This chapter describes some of SlickEdits features that are useful for data, and also covers some techniques you can use to make ad hoc data manipulation as quick and easy as possible. We start by discussing more of what you can do with block selections, which are one of SlickEdits most fundamental tools for working with data. Next, we cover several tools that SlickEdit provides for working with data, for filling in data, sorting data, generating data, and calculating with data. Finally, we present three techniques in detail that can be used for working with data generally. This chapter presents some further Slick-C code as examples. It also relies on the code in
wrox_next_prev_word.e from Chapter 6.
Block Selection
The most fundamental tool for dealing with data is the block selection. Using block selections, you can: Reorder columns of data by moving blocks left or right. Remove unwanted columns. Add data in columns, such as commas and quote marks. Sort data. Generate sequences. Search and replace within columns.
Using combinations of features with block selections, you can perform an unlimited variety of editing tasks in an intuitive, interactive way.
Figure 10-1
Use move-to-cursor (WROX: Alt+M) to move the selected block to the cursor position, moving existing text to the right. Figure 10-2 shows the result of a move.
Figure 10-2
200
Figure 10-3
Use cut (Ctrl+X or WROX: Alt+D) to delete the selected block. Figure 10-4 shows the result of a cut. The deleted block is placed in the clipboard. If you paste from the clipboard back into SlickEdit, the paste is treated as a block.
Figure 10-4
Just as they are with line or character selections, the move-to-cursor and copy-to-cursor commands with block selections are nondestructive, in that they do not delete any existing text. Instead, these commands move existing text to the right. There are corresponding commands that overwrite the existing text. Again, starting from Figure 10-1: Use adjust-block-selection (WROX: Alt+A) to move the selected block to the cursor position, overlaying existing text and filling in the original position with spaces. Figure 10-5 shows the result of a block adjustment.
Figure 10-5
Use overlay-block-selection (WROX: Alt+O) to copy the selected block to the cursor position, overlaying existing text. Figure 10-6 shows the result of a block overlay.
201
Figure 10-6
The Preserve column on the top/bottom setting controls the position of the cursor when using these commands. The setting is found in the More tab of the General Options dialog (Tools Options General). The default value of this setting is off, which means that the cursor will go to the first column of the first line when you use top-of-buffer, and to the last column of the last line when you use bottom-of-buffer. Its usually better to turn this setting on, especially if you are editing columns of data. This configuration setting can also be changed by setting the macro variable def_top_bottom_ style to 1. On the other hand, the data are often only a part of the buffer. There may be multiple chunks of data within a single buffer. In this case, these selection navigation commands are useful: Use begin-select (WROX: Alt+Y) to move the cursor to the top-left of a selected block. Use end-select (WROX: Alt+E) to move the cursor to the bottom-right of a selected block.
Bookmarks can also be useful if you are editing a large amount of data. See Chapter 6 for more information about bookmarks.
202
Filling Data
The fill-selection command offers a simple way to fill a block with a single character. Usually the block is a single column, and the character is some kind of punctuation, such as a comma or quotation mark. The command can also handle blocks that are more than one column, and occasionally this is useful. To fill a region with a character:
1. 2. 3.
Make a block selection. Invoke fill-selection (WROX: Alt+F). SlickEdit prompts you, Type a key to fill mark with. Type a key. The selection is filled.
You can use fill-selection to type words or other text into columns. The procedure is like this:
1. 2. 3. 4.
Make a block selection. Invoke fill-selection to type in the last character of the word. Invoke shift-selection-right (Shift+F8) to move the text, including the character you typed. Repeat Steps 2 and 3 with each character, typing from the end of the word to the beginning.
This is not a very convenient procedure, because you need to type the word backward. Usually its much easier to use block insert mode.
1. 2. 3.
Make a block selection. Invoke block-insert-mode (Edit Other Block Insert Mode). SlickEdit prompts you with Block/column insert mode active. Press ESC when done. Type characters to insert them in the column. The selection moves as you type.
While in block insert mode, you can move the selection left and right using cursor-left and cursorright (the left and right arrow keys). You can use Delete and Backspace to delete characters. You can also use undo to undo mistakes. You can quit the block insert mode using the Escape key, or by deselecting the block.
203
The most useful of these commands for data is sort-on-selection. Use sort-on-selection to sort data in a particular column. SlickEdits sorting algorithm is stable, which means that lines that have equal sort keys remain in the same relative order after a sort. Its also worth remembering that undo works fine after sorting. There are several options that can be used with any of the sorting commands. They are fully documented in the online documentation. There is also a GUI interface to the sorting commands, shown in Figure 10-7. You can invoke the GUI interface with the command gui-sort, or via Tools Sort.
Figure 10-7
204
Generating Data
When dealing with data, it is often necessary to generate a sequence of numbers. Here are some examples: Generating a sequence of primary keys for some test data. Generating a sequence of years. Generating a sequence of dates.
SlickEdits enumerate command helps with these tasks. To use enumerate to generate a sequence of data, follow these steps:
1. 2.
Make a block selection where you want the data generated. Use the enumerate command to generate the data.
zeros. Figure 10-8 shows the result of the command enumerate 100 5 3, with a 10 3 block selection.
Figure 10-8
The enumerate command has some additional options supporting hex output and flags for C/C++ programs. Consult the online Help for the full list. In SlickEdit 11, there is a bug in SlickEdits enumerate command, that causes the padding option of enumerate not to work properly. This bug has been fixed in version 12, but is easy to patch for version 11. See http://community.slickedit.com/index.php?topic=1058.msg4491#msg4491 for details. There is also a GUI interface to enumerate, shown in Figure 10-9. You can invoke the GUI interface with the command gui-enumerate (Edit Other Enumerate).
205
Figure 10-9
Figure 10-10
1. 2. 3.
Make a block selection that includes the shipping charge column and nothing else. Move the cursor to the line after the shipping charges, under the shipping charge column. Invoke the add command on the command line. SlickEdit adds up the numbers and places the sum into the buffer at the cursor position. The result is shown in Figure 10-11.
Figure 10-11
206
1. 2. 3. 4. 5. 6. 7.
Make a block selection one column wide between the price and quantity columns. Invoke the fill-selection command (WROX: Alt+F). SlickEdit prompts you for a character. Type an * to fill the selection with the multiplication symbol. Invoke deselect to drop the selection. Make a new block selection that includes all the data. Move the cursor to the line after the data, under the price column. Invoke the add command on the command line. SlickEdit adds up the numbers, multiplying the prices by the quantities, and places the sum into the buffer at the cursor position. The result is shown in Figure 10-12.
Figure 10-12
The operators supported by the add command are those of the Slick-C programming language. See the online Help for more details. Usually you will not use SlickEdit as a spreadsheet. However, the ability to add up a column of numbers without leaving the editor is sometimes useful.
Manipulating Data
In this section, we look at several techniques for manipulating data in columns, beyond the basics weve covered so far. These represent ways in which you can add, change, and restructure data. The techniques fall into three basic categories: Using SlickEdits block selections to manipulate columns of data interactively and to type into columns. Using keyboard macro record/playback to repeat operations on data. Using search and replace to manipulate data.
207
These data may have been extracted from a database, pasted from a spreadsheet, or sent in an e-mail. Notice that the dates are in the format widely used in the United States, which is not a useful format for storing in a computer. For our examples, we are going to transform these data into XML elements, like this:
<code <code <code <code <code <code <code <code <code <code id=GBA7 id=GBX2 id=GBX6 id=GBY3 id=GBY6 id=GBY7 id=GBY8 id=GBZ2 id=GBZS id=GCB5 start_date=2007-02-12/> start_date=2007-02-14/> start_date=2007-04-01/> start_date=2007-03-07/> start_date=2007-03-17/> start_date=2007-02-14/> start_date=2007-02-09/> start_date=2007-02-15/> start_date=2007-04-03/> start_date=2007-05-06/>
We need to reformat the dates into ISO format, and add XML markup: punctuation, elements, and attributes. For the purpose of the example, were working with only 10 lines of data. In practice, the techniques can be used for many more lines. Some techniques work well with dozens or even hundreds of lines. Other techniques can be used with thousands of lines. In our example, we are converting space-delimited data to XML, but this is just one of an unlimited variety of conversions we could do. The same techniques work equally well for many other cases.
Block Editing
SlickEdits block editing feature is the most straightforward, intuitive way of dealing with columns of data. With block editing, you manipulate columns of data by: Using move, copy, and delete commands to rearrange columns. Using block fill and block insert to add or remove delimiters and other text.
208
Block editing is intuitive and interactive because you see the changes on the screen as you edit. You manipulate columns directly. You can use undo if you make a mistake. Often you need to add or move column data in conjunction with other changes, such as sorting, generating sequence numbers, or changing tabs to commas. In these cases, you may find it easiest to use block selections for all the editing, rather than mixing techniques. Block commands are reasonably fast even with thousands of lines. For larger files, you may find that block commands are too slow. See Large Data Files below for some information on performance with large files. The main disadvantages of the block editing technique are: It doesnt work if the data are not aligned. It is not automatically repeatable.
If data are not aligned, you cannot select the columns. Examples of cases where this happens are: A variable number of tabs are used to indent tabular data. Columns are variable length, so that the delimiters do not line up in the same columns.
You may be able to align the data before editing, which can make it a lot easier to use block selections. We discuss one way of doing this, with SlickEdit macros, in the section Aligning Data below. Block edits, being interactive, are not as repeatable as commands. In fact, because of the way in which block insert mode is implemented, it is not able to be used in conjunction with macros. In practice, this is not a serious limitation, since block insert mode is interactive by nature. If macros need to work with blocks, they can use many other block commands, including select-block and fill-selection, thus achieving all the same things that are done with block insert mode.
Example
In this example, we go through the steps to transform our test file to XML data using block editing. We begin with the data, as shown in Figure 10-13. Well do the job in two parts. The first part is to use block selection and movement commands to reorder the fields of the date column into ISO format. The second part is to use block insert mode to add the XML markup around the data. Here are the steps for the first part:
1. 2.
Move the cursor to the beginning of the 02 on the first line. Invoke select-block (WROX: Alt+B) to start a block selection for the month column.
209
Figure 10-13
3. 4. 5.
Invoke bottom-of-buffer (Ctrl+End) to move the cursor to the bottom of the file. Move the cursor to the 5 in the 05 on the last line. Invoke select-block to lock the selection. The month column is selected, as shown in Figure 10-14.
Figure 10-14
6. 7. 8.
Invoke top-of-buffer to return to the first line. Invoke end-line to move the cursor to the end of the line. Invoke move-to-cursor (WROX: Alt+M) to move the month column to the end. Figure 10-15 shows the result.
Figure 10-15
Invoke deselect (WROX: Alt+U) to drop the selection, since were going to start another one. Move the cursor back to the beginning of the 12 on the first line. Invoke select-block to start a block selection for the day column. Invoke bottom-of-buffer to move the cursor to the bottom of the file. Move the cursor to the 6 in the 06 on the last line. Invoke select-block to lock the selection. The day column is selected, as shown in Figure 10-16.
210
Figure 10-16
Invoke top-of-buffer to return to the first line. Invoke end-line to move the cursor to the end of the line. Invoke move-to-cursor to move the day column to the end. Figure 10-17 shows the result.
Figure 10-17
We have now moved the date fields into the correct order. What remains is to remove the left-behind slash characters, and add the XML markup and hyphen (-) separators. Well use block insertion mode to do all that. Make sure you still have a block selection on the day column, and then follow these steps:
1.
Invoke Edit Other Block Insertion Mode. SlickEdit switches to block insertion mode, as shown in Figure 10-18. The status bar also indicates that block insertion mode is active, as shown in Figure 10-19.
Figure 10-18
Figure 10-19
2.
Invoke cursor-left (left arrow key) repeatedly to move the block to the left, until it is in the first column, as shown in Figure 10-20.
211
Figure 10-20
3.
Type <code id=. Block insertion adds the text to all lines, as shown in Figure 10-21.
Figure 10-21
4.
Invoke cursor-right (right arrow key) repeatedly to move the block over until it is after the code field, as shown in Figure 10-22.
Figure 10-22
5. 6.
Invoke delete-char (Delete key) three times to delete the space and the two unwanted slash characters. Type start_date=. Block insertion adds the text to all lines, as shown in Figure 10-23.
Figure 10-23
7. 8.
Invoke cursor-right four times to move the cursor past the year field. Type the hyphen date separator.
212
Figure 10-24
Discussion
We can see that block selections, combined with the block movement and fill commands and block insertion mode, make an easy and appealing way to edit small-to-medium amounts of data.
Because you get to see every step as its done for the first line, macro recording is intuitive. Even if you make a mistake, you can often correct it without aborting recording the macro. For example, the undo command can be recorded as part of a macro. You do need to take care that the steps you record will work correctly for all lines, not just the first line. For example, if data are not aligned, you cannot rely on a certain number of left or right cursor movements to move the cursor to a given field the field may start in a different column on different lines. Instead, you can use commands such as prev-word and next-word to move among columns flexibly. Doing this requires a clear understanding of how these commands work.
213
If you record a new macro without saving your current one, you have to re-record all the commands over again. See Chapter 1 for an introduction to saving recorded macros.
Example
In this example, we go through the steps to transform our test file to XML data using macro record and playback. We begin with the same data again that were shown in Figure 10-13. To use the macro record and playback technique, we begin by recording the necessary operations on the first line:
1.
Invoke record-macro-toggle (Ctrl+F11). SlickEdit shows the message Recording macro in the message area and the macro recording indicator in the status bar, as shown in Figure 10-25.
Figure 10-25
2.
Type the first part of the text: <code id=. This is shown in Figure 10-26.
Figure 10-26
3. 4.
Invoke cursor-right (right arrow) to move the cursor past the code. Type the next part of the text: start_date=. This is shown in Figure 10-27.
Figure 10-27
214
Figure 10-28
9. 10.
Invoke cursor-left to move the cursor back to the character after the quote mark for the XML date attribute. Invoke move-to-cursor to move the year field to the correct place, as shown in Figure 10-29.
Figure 10-29
Invoke deselect (WROX: Alt+U) to drop the selection. Invoke insert-toggle (Insert key) to switch to overwrite mode. The cursor should change to a block cursor. Use delete, cursor-right and overtype the slashes with hyphens, to change the rest of the date to ISO format, and complete the XML element. The completed line is shown in Figure 10-30.
Figure 10-30
Invoke insert-toggle to switch back to insert mode. Invoke begin-line-text-toggle (Home) to move the cursor back to the start of the line. Invoke cursor-down (down arrow) to move the cursor to the start of the second line.
215
Figure 10-31
18.
Press Escape to save the macro as the last macro. We dont need to give this macro a name, since we are not keeping it permanently.
At this point, weve done all the edits we need to on the first line. Figure 10-32 shows the buffer, with the cursor at the beginning of the second line.
Figure 10-32
Its important that we moved the cursor to the correct position on the second line before we finished recording the macro. This is so that we can now invoke the macro repeatedly to edit the rest of the file:
19. 20.
Invoke record-macro-end-execute (Ctrl+F12) to run the macro. The same edits are done for the second line, as shown in Figure 10-33. Invoke record-macro-end-execute eight more times to complete the file. The finished file is the same as with block editing.
Figure 10-33
216
See Chapter 16 for more information about macros and several more examples of macros that are useful for working with data. Using record-macro-end-execute is fine if you only have a few dozen lines or so. If you have more lines, you can automate the repetition of the recorded macro. The following code is a simple command, wrox-repeat-n, that executes a given command n times:
_command void wrox_repeat_n(_str args = null) name_info(,VSARG2_EDITORCTL) { if (args == null) { message(Specify number of times and command to run.); return; } _str n; _str command; parse args with n command; if (n <= 0 || command == null) { message(Specify number of times and command to run.); return; }
217
Using this command, we can write this command, wrox-repeat-n-last-macro, to execute the last recorded macro n times:
_command void wrox_repeat_n_last_macro(_str args = null) name_info(,VSARG2_EDITORCTL) { wrox_repeat_n(args :+ last_macro); }
SlickEdits syntax assistance can sometimes get in the way when you are using macro record and playback, particularly if you are doing data-oriented operations on a lot of lines. For example, suppose you have the following data in a Java file:
SBL1 SJP1 VATS VBAT VBE2 35.87 34.39 36.17 37.57 38.80
Suppose you want to convert these lines into Java statements like this:
result.add(energy(tni(SBL1), result.add(energy(tni(SJP1), result.add(energy(tni(VATS), result.add(energy(tni(VBAT), result.add(energy(tni(VBE2), ma(35.87))); ma(34.39))); ma(36.17))); ma(37.57))); ma(38.80)));
If you record a macro to add the code to the data for a single line, it comes out something like this:
_command last_recorded_macro() name_info(,VSARG2_MARK|VSARG2_REQUIRES_EDITORCTL) { _macro(R,1); keyin(result); last_event(name2event(.));java_auto_codehelp_key(); keyin(add); last_event(name2event(());c_paren(); keyin(energy); last_event(name2event(());c_paren(); keyin(tni); last_event(name2event(());c_paren(); keyin(\); next_word(); keyin(\); last_event(name2event()));keyin_match_paren(); last_event(name2event(,));java_comma(); cursor_right(); keyin(ma); last_event(name2event(());c_paren();
218
The calls to routines such as java_auto_codehelp_key(), c_paren(), and java_comma() implement SlickEdits syntax assistance. For a recorded macro, the syntax assistance is not required. In fact, it can sometimes cause a macro to behave incorrectly. In addition, the syntax assistance uses a lot of processing power and can slow down macro playback noticeably. To avoid these issues, switch the buffer to fundamental mode using the fundamental-mode command before recording the macro. Recorded in fundamental mode, the macro for the data operation above becomes:
_command last_recorded_macro() name_info(,VSARG2_MARK|VSARG2_REQUIRES_EDITORCTL) { _macro(R,1); keyin(result.add(energy(tni(\); next_word(); keyin(\); last_event(name2event()));keyin_match_paren(); keyin(,); cursor_right(); keyin(ma(\); end_line(); keyin(\); last_event(name2event()));keyin_match_paren(); last_event(name2event()));keyin_match_paren(); last_event(name2event()));keyin_match_paren(); keyin(;); begin_line_text_toggle(); cursor_down(); }
This is significantly faster to execute. Once you are finished working with recorded macros, you can switch back to whichever mode the file was in previously. For example, to switch back to Java mode, use the java-mode command. There is also another opportunity for improvement in avoiding the calls to keyin_match_paren(). This feature provides visual assistance while you are typing. Again, it is not required in a recorded macro. To avoid generating these calls when recording, use the quote-key command (Ctrl+Q). Using quote-key for the closing parentheses, the recorded macro comes out like this:
_command last_recorded_macro() name_info(,VSARG2_MARK|VSARG2_REQUIRES_EDITORCTL) { _macro(R,1); keyin(result.add(energy(tni(\);
219
This macro code is much more efficient to execute. In general, when you are using recorded macros and they are not running fast enough, or perhaps do odd things, you should check the generated macro source in lastmac.e. You may find that SlickEdit features are being invoked inadvertently. You can avoid many features if necessary by using the quote-key command.
You can use regular expressions to do a surprising amount of manipulation on a line. Users of UNIX tools such as sed and awk and users of dynamic languages such as Perl are aware of this. Once you master the arcane details of regular expressions, they are a very powerful tool. Regular expression search and replace is usually faster than other techniques for large files. If you use the command line for entering your Search and Replace command, it is stored there until it falls out of the command-line history. This makes it very easy to retrieve even complicated regular expression commands. You can change a command if necessary, and re-use it. The main disadvantages are: It is not interactive. It is relatively complex and unintuitive.
220
This command does not deal with situations in which the day or month might be only one digit, rather than two. Nevertheless, if you are comfortable with regular expressions, they are a powerful way to manipulate data. SlickEdits Regex Evaluator tool window can help with figuring out regular expressions. We cover it in Chapter 15. Search and replace is probably the most complex way of dealing with data. Once you get beyond the capabilities of search and replace, you are probably beyond using the editor itself. Instead, you may need to write a custom program for data manipulation.
Example
In this example, we will use search and replace to transform our test file into XML data. We will do it in two steps. The first step will be to change the date into ISO format. The second step will be to add the XML markup. To use the search and replace technique to transform the file:
1. 2.
Move the cursor to the top of the file. Invoke the following command to change the dates from the U.S. format into ISO format:
c |(\:d\:d)/(\:d\:d)/(\:d\:d\:d\:d)|\3\-\1-\2|u
SlickEdit asks you to confirm the search and replace, as shown in Figure 10-34.
Figure 10-34
3.
Press g to confirm all changes. SlickEdit replaces all the dates with ISO-formatted dates, as shown in Figure 10-35.
221
Figure 10-35
4. 5.
Move the cursor back to the top of the file. Invoke the following command to add the XML markup:
6.
Discussion
Regular expressions can quickly become unwieldy when used for complex data edits. Here are a few techniques that can help you manage them: If a job is complex, use several search and replace commands rather than combining all edits into a single command. Store the commands in a temporary file while you work, so that you can edit them and re-use them. Remember that undo can be used to roll back search and replace changes. The Regex Evaluator tool can be helpful. See Chapter 15 for more details.
Aligning Data
Frequently data are not properly aligned for using block editing. Usually this occurs when fields are not all the same length. Consider the following data:
GBA07 02/12/2007 279.77 35080.13 125.39 GBX002 02/14/2007 280.98 36381.8 129.48 GBX6 04/01/2007 0.1 21.45 129.48 GBY13 03/07/2007 15.23 1829.22 120.09 GBY16 03/17/2007 69.59 10058.89 144.55 GBY7 02/14/2007 0.21 25.76 120.36 GBY008 02/09/2007 0.64 90.6 141.39 GBZ02 02/15/2007 25 3542.64 140.49 GBZS 04/03/2007 30.48 4338.75 142.37 GCB15 05/06/2007 42.67 6094.2 142.81
222
If you load the code, these commands will be bound to Alt+Shift+L and Alt+Shift+R.
_command wrox_align_left_with_field_above() name_info(,MACRO_ARG2|MARK_ARG2) { if (p_line < 2) { message(This function does not work on line zero or one.); return 0; } // save current position etc push_bookmark(); int cur_line = p_line; _str cur_char = get_text(); // move forward to non-whitespace on current line if (cur_char == || cur_char == \t || cur_char == \n) { wrox_next_whitespace_word(); } // remember column of stuff to move int cur_col = p_col; // go to next field on line above cursor_up(); wrox_next_whitespace_word(); // if we stayed on the same line when moving forward by a field ... if (p_line == cur_line-1) { // shift the text, returning to the original position afterward int diff = p_col - cur_col; pop_bookmark(); push_bookmark(); _insert_text(substr(, 1, diff, )); pop_bookmark(); } else { // return to the original position pop_bookmark(); } } _command wrox_align_right_with_field_above() name_info(,MACRO_ARG2|MARK_ARG2) {
223
In this example, well also use the supplied word-movement command wrox-next-whitespace-word, since its easier to use than SlickEdits own next-word for moving among space-delimited fields. We could use SlickEdits next-word command, but wed have to type more keystrokes because it navigates punctuation characters within fields, in this case the slash characters in the date fields and the decimal points in the numeric fields.
224
1.
Insert some spaces to space out the data in the top column, as shown in Figure 10-36. We choose the spacing so that each field in the following lines will move to the right to become aligned.
Figure 10-36
2. 3. 4. 5.
Place the cursor at the start of the second line. Invoke record-macro-toggle (Ctrl+F11). SlickEdit shows the message Recording macro in the message area and the macro recording indicator in the status bar. Invoke wrox-next-whitespace-word (Ctrl+Right), to move the cursor to the beginning of the date field. Invoke wrox-align-left-with-field-above (Alt+Shift+L), to align the date field with the one above, as shown in Figure 10-37.
Figure 10-37
6. 7.
Invoke wrox-next-whitespace-word twice more, to move the cursor to the beginning of the first numeric field. Invoke wrox-align-right-with-field-above (Alt+Shift+R), to align the numeric field with the one above. The field, being numeric, is aligned on the right-hand side, before the decimal point. The result is shown in Figure 10-38.
Figure 10-38
225
Figure 10-39
12.
Invoke record-macro-end-execute seven more times to align the rest of the lines. Figure 10-40 shows the finished result.
Figure 10-40
The alignment commands always move text to the right. Afterward, we may end up with extra white space in columns, as is shown in Figure 10-40. We can now use block selection and deletion to get rid of this white space if necessary. Following alignment, we can use block editing to manipulate the data further. Alternatively, the alignment commands can be combined with other commands during macro recording and playback to perform combinations of edits.
226
Undo is available after any of these edits, and typically takes a similar amount of time as the edit itself. Interestingly, disabling undo seems to make little difference to the performance of these edits, at least for these examples.
Summar y
In this chapter, we have taken a detailed look at SlickEdits capabilities for editing data. Editing data is characterized by data in columns or fields, and repetitive editing over a number of lines. We looked at some of the basic tools SlickEdit provides, most of which are used in conjunction with block selections. Then we studied three distinct techniques for manipulating data with SlickEdit: block editing, macro record and playback, and search and replace. Each of these techniques is useful for repetitive edits on a number of lines. We also saw how macros can be used to align data to make them more amenable to block editing. This concludes our three chapters on general editing features. The next chapter covers the more specific topics of aliases and templates.
227
Aside from the loop counter and the bound, and, of course, the body, a lot of the loop construct is boilerplate. Built-in syntax assistance in a programming tool such as SlickEdit can go a long way to reduce the amount of typing you have to do for these constructs, but there are always other constructs that you use that the tool doesnt know about. There are many examples of repetitive chunks of text other than programming constructs. In some cases, whole files follow a particular pattern, at least to begin with. Aliases and file templates are a couple of SlickEdit features that assist with repetitive text. The alias feature expands short abbreviations into larger chunks of text, and can be used for a wide variety of purposes. File templates allow you to define standard boilerplates for often-used file structures, in one or more files, and create new items based on them at any time. In this chapter, we look at the alias and template features, and see various applications of them.
Aliases
Aliases provide a powerful feature for expanding a shortcut or abbreviation into a larger string. Aliases work within the editor, but also work in many dialogs, such as the Open dialog. Things that aliases can be used for include: Frequently accessed directories and filenames. Frequently entered snippets of text, for example, copyright notices.
You can define global aliases that work everywhere in SlickEdit. You can also define aliases specific to file extensions. Aliases are basically a substitution mechanism. They also support features that allow you to customize the substituted text and control the cursor placement and movement after expanding them.
File Aliases
There are several configuration files I have to edit on my system quite often. A couple of examples are: The TCP/IP hosts file, located in C:\Windows\system32\drivers\etc\hosts. The Oracle lookup file tnsnames.ora, located on my system in C:\oraclexe\app\ oracle\product\10.2.0\server\NETWORK\ADMIN\tnsnames.ora.
These files are not part of any particular project; thus I cant get at them quickly using the Files tool window. And, as you can see, because the paths to these files are rather long (under Windows anyway), it can be frustrating to open them with the normal Open dialog. Aliases are ideal for this. To define an alias to the hosts file on Windows, follow these steps:
1.
Invoke alias (Tools Options Aliases). SlickEdit displays the Select Alias File dialog, shown in Figure 11-1.
Figure 11-1
2.
Select alias.slk and click OK. This is the file for global aliases; the other files define extension-specific aliases. SlickEdit displays the Alias Editor, shown in Figure 11-2. Several global aliases are predefined by SlickEdit.
230
Figure 11-2
3. 4. 5. 6.
Click New. SlickEdit displays the Enter New Alias Name dialog. Enter hosts for the Alias Name. Click OK to close the Enter New Alias Name dialog. Enter C:\Windows\system32\drivers\etc\hosts in the text area for the alias text.
Its important to remember to click New and type in a new alias name before you type in the alias text. Its quite easy to type the new alias name into the filter field by mistake and overwrite the alias text of an existing alias.
7.
The alias is added to the global aliases. To try it, open the hosts file using the Open dialog:
1. 2. 3. 4.
Invoke gui-open (Ctrl+O). Type hosts into the File name field. Invoke codehelp-complete (Ctrl+Space). SlickEdit expands the alias. Press Enter. SlickEdit opens the file.
Using aliases for directories like this is useful because it saves you having to navigate manually. It also prevents you from changing your working directory to the location of the file, which you might do inadvertently otherwise, while navigating to it.
231
The config and ma aliases are frequently handy in the daily use of SlickEdit. When defining an alias for a directory, end the substitution value with the path-separator character (\ on Windows, / on UNIX or GNU/Linux). That gives the smoothest use in the Open dialog. After expanding the alias, you can start typing a further directory name or file name, or simply press Enter to have SlickEdit refresh the directory listing. When using aliases for directories or filenames containing spaces, it helps to start the substitution value with a double quote. That will help SlickEdit expand file names that you type in the Open dialog after expanding the alias. (If you dont use a double quote, SlickEdit thinks the space separates two different filenames.) Combining these tips, you might want to define a handy alias for your home directory on Windows. (On UNIX or GNU/Linux, you probably dont need this.) Call the alias home, and define its expansion as:
C:\Documents and Settings\username\
where username is your Windows username. You can use %USERNAME% instead for more flexibility if you wish, as we see below. Now if you expand the alias in the File name textbox of the fast Open dialog, SlickEdit refreshes the completions list immediately with matching files in your home directory.
You can save typing when entering the copyright notice by defining an alias for it. Use the Alias Editor to define an alias cpr for Copyright 2007 Acme Inc. The obvious problem with this alias is that it has the year hard-coded. Change the 2007 in the substitution value to %\d, like this:
Copyright %\d Acme Inc
Now, when you expand the alias, you get something like this:
Copyright 2007-04-05 Acme Inc
232
Table 11-1
Escape Sequence
%EnvVar% %\d %\e %\t %\f %\i %\b %\c %\l %\s %\n %\o %(ParamName) %\m macro % %\xcol %\x+col %\x-col %%
Description Insert the value of the EnvVar environment variable. Insert the date (locale preference format). Insert the date (MMDDYY). Insert the time. Insert the filename. Indent. Unindent. Place cursor. Preserves leading spaces at beginning of line. Preserves trailing spaces at end of line. Inserts current function name. Inserts current function name with signature. Argument replacement. Execute macro in-place. Moves the cursor to the specified column. Increment column by amount. Decrement column by amount. Inserts a percent character.
The %\m sequence is especially powerful. Because you can execute any macro, it opens up virtually unlimited possibilities. The macro can be a command, in which case it is executed in place in the buffer. The macro can also be a Slick-C function, in which case, its result is inserted into the buffer.
233
Now try expanding the alias again. If the current year is still 2007 when you try it, you should get:
Copyright 2007 Acme Inc
The %\c escape sequence places the cursor by creating a hotspot. You can use this escape sequence multiple times to create multiple hotspots. You then use next-hotspot (Ctrl+[) to jump through the hotspots after expanding the alias. Well see more of this below.
234
Use these aliases when opening files, on the command line, or in the Open dialog. Sometimes you might want to have a directory alias relative to another directory alias. For example, you might like to create an hf alias for your hotfixes directory. The hotfixes directory is under the SlickEdit configuration directory, which is referenced by the config alias. You can use the expand-alias command inline to nest one alias in another, like this:
config%\m expand_alias%hotfixes
This alias works like this: The text config is entered into the buffer. The expand-alias command is invoked, which expands the config alias. The text hotfixes is inserted afterward.
Unfortunately, this doesnt quite work. The expand-alias command is defined to return an int, which is inserted into the buffer, giving a result like this:
C:\jhurst\My SlickEdit Config\12.0.2\0hotfixes
The wrapper command returns void and therefore inserts nothing extra into the buffer. We can now define the hf alias with this expansion:
config%\m wrox_expand_alias_inline%hotfixes
Extension-Specific Aliases
Sometimes you might want the same alias to have different meanings depending on the current file extension. An example of this is an hdr alias that expands into a file header. For Java or C++ files, the alias should expand to:
// // // // $Id$ Copyright 2007 Acme Inc username date
235
1. 2. 3. 4. 5. 6.
// // // //
Invoke alias (Tools Options Aliases). SlickEdit displays the Select Alias File dialog. Select the java.als file for Java-specific aliases, and click OK. SlickEdit displays the Alias Editor. Click New to add a new Java alias. SlickEdit displays the Enter New Alias Name dialog. Enter hdr for the alias name. Click OK to close the Enter New Alias Name dialog. Enter the following text for the substitution value:
$Id$ Copyright %\m wrox_year% Acme Inc %USERNAME% %\d
7.
Now if you open a new file with extension .java, type in hdr, and invoke codehelp-complete (Ctrl+Space), you should get results similar to this:
// // // // $Id$ Copyright 2007 Acme Inc jhurst 2007-04-05
There is no sql.als file set up by default when you install SlickEdit. To create a new alias file for SQL files, follow these steps:
1. 2. 3. 4. 5.
Open the Extension Options dialog (Tools Options File Extension Setup). Select the sql extension. Select the General tab. Enter sql.als for the Alias filename. Click OK to close the Extension Options dialog. SlickEdit adds sql.als to its list of alias files.
Now you can add the SQL-specific hdr alias using steps similar to those for Java.
236
C++ aliases are in c.als. The %\c places the cursor in the position for typing in the classs name when you expand the alias. You can expand the class alias by pressing space, rather than invoking codehelp-complete (Ctrl+Space). SlickEdits syntax expansion knows about aliases and checks to see whether an alias overrides a particular syntax expansion before performing it. Thus, you can use aliases to override any standard syntax expansion. If you want to create a class forward declaration (and not expand the alias), use keyin-space (Shift+Space) instead of pressing Space. The keyin-space command bypasses syntax expansion. Heres another C++ example, using the for statement. The default syntax expansion produces:
for () { }
If you prefer, you can add a C-specific alias called for, with this expansion:
for (%\c ; %\c ; %\c) { %\c%\m sur_text% }
This alias adds the semicolons and has several hotspots you can move the cursor through. The alias also supports the dynamic surround feature, by including the %\c%\m sur_text% sequence. Heres an example of an extension-specific alias using Slick-C. The syntax expansion for the _command keyword in Slick-C files does not honor brace style preferences. If, in a Slick-C file, you type _command and press Space, you get the following code:
_command void () name_info(,) { }
This occurs even if you have set your brace preference to put opening braces at the ends of lines. You can correct this by defining a Slick-C-specific alias called _command, with this substitution:
_command void %\c(%\c) name_info(%\c,%\c) { %\c }
237
This is a great opportunity for an easymock alias. There is a really quick technique for creating an extension-specific alias from existing code. Just select the code, right-click, and select Create Alias. You will be prompted for an alias name and then be placed in the Alias editor to fine-tune the alias.
Surround Aliases
An extension-specific alias can support dynamic surround by including the special sequence %\c%\m sur_text% in the appropriate place, as shown above in the for loop example. SlickEdits surround-with feature, which we looked at in Chapter 9, makes use of special surround-with aliases. You can modify the supplied surround-with aliases or add your own. Surround-with aliases are extension-specific and are accessed by checking the Surround With box in the Alias Editor. For example, the supplied HTML surround-with aliases include many HTML tags, but not <div>. Lets add a surround-with alias for <div>. Follow these steps:
1. 2. 3. 4. 5. 6. 7.
Invoke alias (Tools Options Aliases). SlickEdit displays the Select Alias File dialog. Select the html.als alias file for HTML aliases, and click OK. SlickEdit displays the Alias Editor. Click the Surround With box. SlickEdit displays the surround-with aliases for HTML files. Click New to add a new surround-with alias. SlickEdit displays the Enter New Alias Name dialog. Enter div for the Alias Name, and click OK to close the dialog. Enter the following for the substitution value:
You can now use <div> with surround-with. As with dynamic surround, surround-with aliases use the special macro function sur_text. This macro inserts the surrounded text into the expansion at the desired position. The sur_text function can take several different options. See the online Help for full details. Note that if you want your alias to support both surround-with and dynamic surround, you need to enter it twice: once as a regular alias and again as a surround-with alias.
238
Lets create an extension-specific lookup alias that will save typing when creating these scripts. Well put a hotspot after the description column, to allow other columns to be added, and another hotspot after the inserted text. Follow these steps:
1. 2. 3. 4. 5.
Invoke alias (Tools Options Aliases). SlickEdit displays the Select Alias File dialog. Select the sql.als file for SQL-specific aliases, and click OK. SlickEdit displays the Alias Editor. Click New to add a new SQL alias. SlickEdit displays the Enter New Alias Name dialog. Enter lookup for the alias name. Enter the following text for the substitution value:
CREATE TABLE %(NAME) ( id INTEGER NOT NULL, description VARCHAR(50) NOT NULL,%\c active_yn CHAR(1) CONSTRAINT %(NAME)_active CHECK (active_yn IN (Y, N)) ); ALTER TABLE %(NAME) ADD CONSTRAINT %(NAME)_pk PRIMARY KEY (id); %\c
In this alias, were using a parameter (NAME) for the table name.
6.
Click Add under the Parameters list. SlickEdit displays the Enter Alias Parameter dialog, shown in Figure 11-3.
Figure 11-3
239
You can use this alias in SQL files whenever you need to create a skeleton lookup table. To use the alias to create a customer_type table, follow these steps:
1. 2.
Create a new file called create_table_customer_type.sql. In the new file, type lookup, then invoke codehelp-complete (Ctrl+Space). SlickEdit prompts for the alias parameters, as shown in Figure 11-4.
Figure 11-4
3.
Enter customer_type for the Table Name, and click OK. SlickEdit expands the alias and inserts the following text:
CREATE TABLE customer_type ( id INTEGER NOT NULL, description VARCHAR(50) NOT NULL, active_yn CHAR(1) CONSTRAINT customer_type_active CHECK (active_yn IN (Y, N)) ); ALTER TABLE customer_type ADD CONSTRAINT customer_type_pk PRIMARY KEY (id);
The cursor is at the hotspot at the end of the description line, where you can add more column definitions if you want to.
4.
Invoke next-hotspot (Ctrl+[) to move the cursor to the hot spot at the end of the inserted text.
240
F ile Templates
File templates extend the concept of predefined chunks of text or code to multiple files. You can use file templates to instantiate constructs quickly in a single file, or in multiple files. A classic example of a template is for a C++ class, where you have to create a header (.h) file and a corresponding implementation (.cpp) file. SlickEdit comes with several predefined templates that you can use right away. You can also customize them, or add your own.
Instantiating a Template
Lets instantiate a template for a C++ class. Follow these steps:
1.
Invoke add-item (File New Item from Template). SlickEdit displays the Add New Item dialog, shown in Figure 11-5. The templates are organized into categories, which are arranged in a hierarchy.
Figure 11-5
2. 3. 4. 5.
Expand the C++ category. Subcategories are displayed under C++. Select the Class category under C++. The C++ Class category includes templates for C++ Basic Class, C++ Derived Class, and C++ Header File. Select C++ Basic Class. Enter MyNewClass for the Name.
241
Creating a Template
Now well add a template of our own. SlickEdit doesnt come with any templates for PL/SQL programming. Lets add a template for creating an Oracle PL/SQL package. Like C++ classes, PL/SQL packages have two parts: The Package Definition created with the CREATE PACKAGE statement. The Package Body created with the CREATE PACKAGE BODY statement.
We will make a template that places each of these statements in its own file. Before we start creating the template in SlickEdit, we need to create the two files that will be in the template. Create a file called create_package_template.sql, containing the following code:
----$$Id$ $copyright$ $username$ $localdate$
CREATE OR REPLACE PACKAGE pkg_$itemname$ AS -- add members here ... PROCEDURE test; END; / GRANT EXECUTE ON pkg_$itemname$ TO $granted_user$;
The identifiers between $ characters are substitution parameters. They will be substituted when the template is instantiated. Some of the substitution parameters are predefined by SlickEdit, such as $username$ and $localtime$. Other substitution parameters are user-defined, and some of these are global, while others are defined at the time the template is instantiated. Well explain the substitution parameters in more detail shortly. The instantiated file will contain a version-control keyword $Id$ on the first line. The double $ in $$Id$ prevents SlickEdit from interpreting Id as a substitution parameter. Create another file called create_package_body_template.sql, containing the following code:
-- $$Id$ -- $copyright$ -- $username$
242
Now were ready to define the template in SlickEdit. Follow these steps:
1.
Invoke template-manager (File Template Manager). SlickEdit displays the Template Manager, shown in Figure 11-6.
Figure 11-6
2. 3. 4.
Right-click on the User Templates category, and select New Category from the context menu. SlickEdit displays the New Category dialog. Enter PLSQL for the Category name. Click OK to close the New Category dialog.
243
Figure 11-7
244
That was a lot of steps, but the result is quite powerful. Lets instantiate the template. Follow these steps:
1. 2. 3. 4. 5. 6. 7.
Invoke add-item (File New Item from Template). SlickEdit displays the Add New Item dialog. Select the PLSQL category under User Templates if it is not already selected. Select the create_package template if it is not already selected. Enter customer for the Name of the new item. Click Add. SlickEdit displays the Parameter Entry dialog. Enter ADMIN for the User to grant EXECUTE to. Click OK to close the Parameter Entry dialog and instantiate the template. SlickEdit creates two files and opens create_pkg_customer.sql.
CREATE OR REPLACE PACKAGE pkg_customer AS -- add members here ... PROCEDURE test; END; / GRANT EXECUTE ON pkg_customer TO ADMIN;
CREATE OR REPLACE PACKAGE BODY pkg_customer AS -- complete definitions of members here ... PROCEDURE test IS
245
Usually when you are using templates you will add the instantiated files to your project. The Add New Item dialog has a checkbox to control whether this happens automatically. If there is no current project, the option is disabled. If there is a current project, then new items are added to it unless the checkbox is unchecked. When invoked from the Project menu (Project Add New Item From Template), the Add to current project checkbox is on by default. For this example, we chose not to copy the source file to the template directory.
Substitution Parameters
We saw several different kinds of substitution parameters in the example. SlickEdits built-in substitution parameters are described in the online Help. They are repeated in Table 11-2, but you should check the online Help in case new ones have been added since this book went to print.
Table 11-2
Parameter
$itemname$ $fileinputname$
Description Name of item entered, as on the Add New Item dialog. Name of item entered, as on the Add New Item dialog, without file extension. Name of item entered, as on the Add New Item dialog, with all unsafe characters replaced with safe characters. Same as $safeitemname$ with all characters uppercased. Same as $safeitemname$ with all characters lowercased. Location of operating system temp directory. No trailing file separator. Root namespace or package for the current project. Time of day in the form hh:mm[am|pm]. Example: 11:34pm. Time of day in locale-specific format. Time of day in the form hh:mm:ss.
$safeitemname$
246
Description Current date in locale-specific format. Current date in the form mm/dd/yyyy. Current project name (no path, no extension). Current project name (no path, no extension), with all unsafe characters replaced with safe characters. Current workspace name (no path, no extension). Current workspace name (no path, no extension), with all unsafe characters replaced with safe characters. Current project working directory. No trailing file separator. Current project build (output) directory. No trailing file separator. Current project configuration name. Current workspace configuration name. This will be the same as $projectconfigname$ except for MS Visual Studio workspace, which will have a separate workspace/solution configuration name. Location of current project file. No trailing file separator. Location of current workspace file. No trailing file separator. Operating system login name.
$workspacename$ $safeworkspacename$
Unfortunately, the template feature has no equivalent of the alias features %\m escape sequence. This limits its flexibility somewhat. For some uses of %\m, such as our use for the current year to insert into a copyright notice, the global substitution parameters can be used effectively. In the case of the current year, you only have to change the substitution value once per year, and it would apply to all projects. For other uses of %\m, there is no suitable alternative in the template feature. Per-template substitution parameters can be used to customize the content of your template. In the example above, we used this for the GRANT EXECUTE statement. Again, if we want to instantiate the template and have no GRANT EXECUTE statements, or more than one, we cant configure the template to do that. However, once the template is instantiated, its easy enough to edit the file and make the necessary changes. In fact, an alias would help with this.
247
This alias, along with word completion (for the package name), would make it pretty quick to add GRANT EXECUTE statements.
Managing Templates
When you create a file template, you have the choice of copying the source files into the template directory or linking to them in their original location. Usually in a professional environment, the template source files should be checked into version control, probably in a special VCS project for templates. With that setup, you can check out a local copy wherever you want and point the SlickEdit template entries at the source files.
1.
<!-$$Id$ $copyright$ $username$ $localdate$ --> <project name=$projectname$ basedir=. default=compile-java > <tstamp>
248
249
This is a simple build script, including basic steps for compiling production and test code and running tests. In a real environment, you would also include standard targets for packaging and possibly distributing your application, and other targets too. Note that the template uses substitution parameters for the copyright, user, and local date as before. We also use the predefined substitution parameter $projectname$ to set the Ant project name from the name given to the project in SlickEdit. This can, of course, be changed after the template is instantiated.
2.
# # # #
project.name = $projectname$ build.version.number = ${version.number}.${release.number}.${build.number} build.version.string = ${build.version.number} built on ${build.date} # compiler options compile.debug = false compile.optimize = true compile.source = 1.5 compile.target = 1.5 # paths lib = lib lib.test = ${lib}/test build = build build.classes = ${build}/classes build.javadoc = ${build}/javadoc src.java = src/java src.test = src/test
3.
250
Now that we have the template, the next step is to cause the custom project type to instantiate it when creating a new project. We will extend the custom project created in Chapter 4, with the InitMacro named wrox_create_java_dirs(). In the Author/Chapter11 directory on the CD-ROM is an updated version of that macro, called wrox_create_java_project(). The code is shown below:
_command int wrox_create_java_project() name_info(,) { // create src/java/com/wrox/ _str java_path = _file_path(_project_name) :+ src :+ java :+ FILESEP :+ com :+ FILESEP make_path(java_path); // create src/test/com/wrox/ _str test_path = _file_path(_project_name) :+ src :+ test :+ FILESEP :+ com :+ FILESEP make_path(test_path);
FILESEP :+ :+ wrox;
FILESEP :+ :+ wrox;
// add wildcard for src/*, recursive, excluding SVN files _ProjectAdd_Wildcard(_ProjectHandle(), src\\*, *\\.svn\\*, true); add_item(%VSLICKCONFIG%\\templates\\ItemTemplates\\Java\\Ant build file\\Ant build file.setemplate, build.xml, , true, false); return 0; }
The new statement, containing the add_item() call, should all be on one line. The function call instantiates the Ant build file template from the user templates directory and adds the files to the current project. Note that the add_item() macro function detects the environment variable %VSLICKCONFIG% and replaces it with your SlickEdit configuration directory. Load this code, and change the InitMacro to refer to the new name. The next time you create a new project of type Java Project WROX, you should get it initialized with the standard build scripts, as well as the source directories. The add_item() macro used here is the same command that is invoked from the menu via File Add New Item from Template. When invoked from the menu, the macro displays the Add New Item dialog. If you use the macro from Slick-C code, you can provide parameters, as weve done here, to bypass the dialog. As with a number of SlickEdit macro/commands, the parameters are not documented in the Help system, but they are not difficult to figure out by reading the source code. Reading the Slick-C source code is essential for making significant extensions and customizations. Sometimes when browsing the Slick-C macro source code you will find that a command works by calling some other, simpler macro function. Or, you may discover the internal workings of some mechanism, such as the XML structure of configuration files. You can use this knowledge in your own programming
251
Summar y
In this chapter, we looked at two related features that allow you to add your own customized time-savers to SlickEdit. Aliases are useful for a wide variety of situations, from shorthands for commonly used files and directories, to full-sized coding constructs, including overriding the built-in syntax expansion. The inline macro execution capability of aliases is particularly powerful for advanced uses. File templates are useful when you want to define a standard boilerplate layout for one or more files. The difference comes down to a matter of granularity. Aliases are pieces of code; templates are one or more files. In the next chapter, we cover several topics relating to document types.
252
Document Types
When you open a file in SlickEdit, the editor determines several things about it. Weve already seen the importance of the extension in determining the document mode. (The mode is basically the programming language family; see Chapter 9.) Most programming language source files are simple ASCII files (or nearly enough), and that is all that matters. SlickEdit can also edit files of other types. Sometimes there is more involved in determining how to read them or display them. SlickEdit can open binary files. For binary files, its usually more useful to view them in hex mode as bytes rather than as text characters. Sometimes hex mode is useful for text files too. SlickEdit supports XML files as well. XML files are Unicode rather than ASCII and can be represented on disk in a variety of encodings. Unicode is a massive character set (~100,000 characters). This introduces some challenges, because most fonts are not capable of displaying the entire set. When dealing with XML documents, SlickEdits default behavior is to try to provide as much assistance as it can by downloading referenced DTDs and schemas from the Internet. I use a laptop for almost all my work, and because Im on the road a lot, not always connected to the Internet, sometimes I dont want this behavior. Sometimes I need to prevent SlickEdit from fetching documents from the Internet. An even better option is to store local copies of required resources and get SlickEdit to use them instead. In this chapter, we cover a variety of topics concerning types of files and ways to view and edit them.
Document Mode
When you open a source file with a known extension, SlickEdit places the document into the mode associated with the extension. If SlickEdit does not recognize the extension, the editor goes into Fundamental mode. Usually the automatically selected mode is just what you want, because it enables all the features associated with the programming language.
Binar y F iles
When you open a binary file, SlickEdit attempts to display it as text by default. For binary files, this is usually meaningless. To view a binary file, switch to hex mode using the hex command (View Hex or Ctrl+Shift+H). SlickEdit displays the file as 16-byte chunks as shown in Figure 12-1. You can still edit the text part on the right-hand side, or you can edit the hexadecimal representation by clicking in the lefthand side. To switch back to text mode, invoke hex again.
Figure 12-1 SlickEdit also supports Line Hex mode via the linehex command (View Line Hex). Line hex mode shows each line of the source file on a separate line in the editor, showing both ASCII characters and hex bytes. This mode is useful if you have a file that has line structure but binary data. An example might be a PDF file. Hex mode can be useful for text mode too, occasionally. For example, you can use it to check line endings in a file when you are not sure if the file has UNIX or DOS line endings (or might have both). You can use it to check tab characters in makefiles.
254
SlickEdit normally determines the encoding and thus the character set automatically, based on the file extension and content. If the file extension is associated with XML, the file is loaded as Unicode. If the file contains a Unicode Byte Order Mark (BOM), also known as a signature, the BOM determines the encoding, and the file is loaded as Unicode. Otherwise, the file is loaded as SBCS/DBCS. You can override the encoding on the Open dialog. Most of the encodings require your files text to be converted to UTF-8, but some are for SBCS/DBCS mode. The Windows Fast Open dialog, or Windows 3.1 style Open dialog, does not have an option to override the encoding. If you need to override the encoding when opening a file on Windows, you need to switch to the standard Open dialog. It is important to understand the distinction between Unicode and SBCS/DBCS when working with XML files, because some features are not fully supported for the Unicode representation. For example, hex mode is not supported for XML files in encodings other than UTF-8, because the disk representation is different from the in-memory representation. If you need to view a UTF-16 XML document in hex, for example, you need to open it using an SBCS/DBCS encoding, such as Binary. Several other features, mainly concerning limitations of fonts, are also not supported for Unicode. These are documented in the online Help. You can use the encoding option in the Open dialog to create a new file in a specific encoding. For example, you can create a text file using UTF-16 encoding. When you save the file, SlickEdit stores a UTF-16 BOM at the beginning, and writes two bytes per character.
255
1.
Open the URL Mappings dialog (Tools Options URL Mappings). SlickEdit displays the dialog, shown in Figure 12-2.
Figure 12-2
2. 3. 4. 5.
Click Add. SlickEdit adds a new empty entry. Enter http://www.springframework.org/dtd/spring-beans-2.0.dtd for From. Enter C:\lib\spring-framework-2.0.2\dist\resources\spring-beans-2.0.dtd for To. Click OK. SlickEdit adds the URL mapping.
After adding this URL mapping, SlickEdit retrieves the DTD from the local disk instead of over the network. Locally mapped URLs are stored in options.xml in your SlickEdit configuration directory. When setting up URL mappings, SlickEdits support for multiple clipboards is helpful. You can copy the From and To parts into the clipboard in turn, then use list-clipboards (Ctrl+Shift+V) to paste them selectively into the URL Mappings dialog.
256
This command disables automatic download of DTDs and schemas for syntax expansion for all XML and XSD files. You can enable syntax expansion and color highlighting for a specific file you have open by invoking apply-dtd-changes. You can also invoke this command by right-clicking in the window and clicking Apply DTD, TLD, or Schema Changes. For the best editing experience with XML files, I recommend that you download all DTDs and schemas referred to by your documents and store local copies on your hard drive. Use the URL mapping configuration to prevent SlickEdit from downloading them from the Internet every time it opens a file. Here is a macro and function you can use to automate downloading URL resources and creating local mappings for them:
_command void wrox_make_url_mapping(url) name_info(,) { edit(url); // Note: SlickEdit knows how to fetch http:// addresses _str resourcename = wrox_make_local_resource_filename(); save(resourcename); quit(); typeless handle=_cfg_get_useroptions(); int index = _xmlcfg_set_path(handle,/Options/URLMappings); int new_index = _xmlcfg_add(handle, index, MapURL, VSXMLCFG_NODE_ELEMENT_START, VSXMLCFG_ADD_AS_CHILD); _xmlcfg_set_attribute(handle, new_index, From, url); _xmlcfg_set_attribute(handle, new_index, To, resourcename); _cfg_save_useroptions(); } _str wrox_make_local_resource_filename() { int i = 0; _str basename = _config_path() :+ resource; while (file_exists(basename :+ i)) { i++; } return basename :+ i; }
257
The macro uses a function, wrox_make_local_resource_filename(), which returns an unused filename in the SlickEdit configuration directory. The function uses the SlickEdit-provided function _config_path() to get the configuration directory. It then works by simply appending numbers to the prefix resource until it finds a name that does not currently exist as a file in the configuration directory. The macro uses SlickEdits ability to fetch HTTP resources when passed to the edit command. You dont need to do anything else to load an HTTP resource into SlickEdit. Its not industrial strength: Theres no error-handling, so you wont use it for building your next Web Services infrastructure, but for automating some manual tasks in the editor, it will do just fine. After loading the resource, the macro saves it to the new file. Finally, it uses some of SlickEdits XML handling functions to open the options.xml configuration file and add the URL mapping.
Summar y
In this chapter, we have covered several areas loosely gathered under the topic of document types. Firstly, the document mode determines much of the appearance and behavior of the editor, particularly for files having syntax highlighting and assistance. In Chapter 17, some examples of defining new document modes for your own languages are demonstrated. SlickEdit can open files in a variety of character sets and encodings, including binary files. Finally, most of the chapter was concerned with XML document types and effective ways to manage DTDs and XML schemas for working with these. In the next chapter, we take a look at SlickEdits Compare and Merge tools, which are used for managing and comparing different versions of files and directories.
258
1.
Invoke diff (Ctrl+equals). SlickEdit displays the DIFFzilla setup dialog, shown in Figure 13-1. You use this dialog to set up the files or directories you wish to compare.
Figure 13-1
2. 3. 4.
Enter the path and filename of the old version of board.h in Path 1. You can use the button labeled to select the file from the file system. You can use the button labeled B to select an open buffer. Enter the path and filename of the new version of board.h in Path 2. Click OK. SlickEdit displays the Diff window, shown in Figure 13-2.
The differences in the file are indicated graphically. You can navigate backward and forward among the differences using the Next Diff and Prev Diff buttons. The most common use of DIFFzilla is simply to compare two versions of a file. However, you can also use DIFFzilla to resynchronize files by eliminating differences. The first row of buttons in the Diff window provides operations for copying lines or blocks from either side to the other. You can save either side at any time while you are working in the Diff window, and you can undo changes. In fact, the two buffer panes act like the regular SlickEdit editor pane in most ways, so you can type and make use of a limited set of SlickEdit editing features, such as cursor movement and syntax assistance. Not all commands work by default in the Diff window. If you try to use a command that is not supported in Diff, you will receive a message box stating Command xxx currently not allowed in Diff mode. For example, you cannot use selections to copy lines directly from one pane to the other, or within a pane. You can use the clipboard to copy selections, however.
260
Figure 13-2
The Diff window uses its own command dispatch mechanism. The commands that are supported are listed in the diffedit.e macro file supplied in the macros directory under the SlickEdit installation. If you want to add additional commands, you can add them there. Use caution when making changes to supplied macros. Changes to the supplied macros can affect the behavior of the editor. For example, while the standard prev-word and next-word commands are supported in DIFFzilla, the WROX alternatives wrox-prev-whitespace-word and wrox-next-whitespace-word are not. To add them, follow these steps:
1. 2.
Edit diffedit.e. Add these lines near the top of the file, to declare prototypes for the commands:
3.
4.
Invoke load. You should now be able to use wrox-prev-whitespace-word and wrox-next-whitespace-word in DIFFzilla editor panes.
This tip can work for your own commands and for many standard SlickEdit commands that have been omitted from DiffCommands, for whatever reason. Thanks to Hartmut Schaefer (hs2) for this tip.
261
262
To limit the comparison to a range of lines, click the More button under Path 1 in the DIFFzilla setup dialog. Like most of SlickEdit, the DIFFzilla functionality is available via a macro function. The diff command invokes DIFFzilla and has many options. Most of the options are documented in the online Help, and the rest, corresponding to options available in the setup dialog, can be discovered by looking at the source code in diff.e. Heres an example of using DIFFzilla from a macro to save work. When comparing ranges of lines, it is rather tedious to note the line numbers for the starts and ends of the ranges and enter them into the DIFFzilla setup dialog. This macro can make comparing ranges of lines a bit easier:
_command void wrox_diff_lines(_str bookmarks = 1 2 3 4) name_info(BOOKMARK_ARG*,VSARG2_REQUIRES_EDITORCTL) { _str bookmark1; _str bookmark2; _str bookmark3; _str bookmark4; parse bookmarks with bookmark1 bookmark2 bookmark3 bookmark4; push_bookmark(); goto_bookmark(bookmark1); _str filename1 = p_buf_name; int start_line1 = p_line; goto_bookmark(bookmark2); if (p_buf_name != filename1) { message(Bookmark 2 must be in same file as bookmark 1.); pop_bookmark(); return; } int end_line1 = p_line; if (end_line1 <= start_line1) { message(Bookmark 2 must be after bookmark 1 in file.); pop_bookmark(); return;
263
This macro defines a command, wrox-diff-lines, which invokes DIFFzilla for a pair of ranges in a pair of files. The ranges are defined by the four bookmarks, named by default 1 through 4. To use this macro to compare two ranges, follow these steps:
1. 2. 3. 4. 5. 6. 7. 8. 9.
Navigate to the start of the first range. Invoke alt-bookmark with bookmark 1 (WROX: Ctrl+Shift+1). This marks the start of the first range for the macro. Navigate to the end of the first range. The end of the first range should be after the start, and in the same file. Invoke alt-bookmark with bookmark 2 (WROX: Ctrl+Shift+2). Navigate to the start of the second range. This can be in the same file as the first range, or in a different file. Invoke alt-bookmark with bookmark 3 (WROX: Ctrl+Shift+3). Navigate to the end of the second range. The end of the second range should be after the start, and in the same file. Invoke alt-bookmark with bookmark 4 (WROX: Ctrl+Shift+4). Invoke wrox-diff-lines. The macro loads DIFFzilla to compare the ranges specified by the bookmarks.
If you wish, you can use different names for the bookmarks, in which case you must specify them on the command line when you invoke the command.
264
Comparing Directories
You can use DIFFzilla to compare whole directory trees, as well as individual files. To compare directories, check the Multi-File radio button in the DIFFzilla setup dialog. To compare entire directory trees, check the Recurse into subdirectories checkbox. Figure 13-3 shows an example of a Multi-File Diff. You can select any pair of files and compare them with DIFFzilla.
Figure 13-3
In Figure 13-3, some of the subdirectories showing differences are Subversion admin directories (the .svn subdirectories). When comparing directories, you sometimes want to exclude such items from the comparison. To exclude the .svn subdirectories, add .svn\ to the Exclude Filespecs. When the Multi-File Diff Output window is displayed, you can right-click in the results windows to get a context menu. This menu is shown in Figure 13-4.
Figure 13-4
On the context menu, you can filter the results by a variety of criteria. You can also click Hide to hide subtrees you are not interested in. These options can rapidly make a large list of differences more manageable.
265
DIFFzilla Options
The options tab of the DIFFzilla setup dialog has many options for fine-tuning the comparison. You can select from several ways of comparing or ignoring white space, line endings, and case. You can skip comments at the beginning of the file, which is handy if your files have version control information on the first few lines.
Merging Changes
DIFFzilla is most often used for comparing files or directories. As weve seen, you can also edit files while you are comparing them, and DIFFzilla has tools for reconciling differences by copying lines or blocks from one side to the other. SlickEdit includes another tool that is sometimes more useful for another kind of change reconciliation: 3 Way Merge. Use 3 Way Merge when you have an original file and two independent changed versions. This scenario is illustrated in Figure 13-5. The 3 Way Merge tool displays data from all three files and allows you to merge them selectively into the output.
Base File
Rev 1
Rev 2
3 Way Merge
Base File
Figure 13-5
266
This is a file used to demonstrate 3 way merging. This is the line in the base file. Here is line 1 of 3. Here is line 2 of 3. Here is line 3 of 3. Here is line 1 to be deleted. Here is line 2 to be deleted.
This is a file used to demonstrate 3 way merging. This is the line in the diff1 file. Here This Here Here is line line is is line is line 1 of 3. added in diff1. 2 of 3. 3 of 3.
This is a file used to demonstrate 3 way merging. This is the line in the diff2 file. Here Here This Here is line is line line is is line 1 of 3. 2 of 3. added in diff2. 3 of 3.
Lets run 3 Way Merge on these files, placing the result in a new file, output.txt:
1. 2. 3. 4.
Invoke merge (Tools File Merge). SlickEdit displays the 3 Way Merge Setup dialog, shown in Figure 13-6. Enter base_file.txt for the Base file Filename. Enter rev1.txt for the Revision 1 Filename. Enter rev2.txt for the Revision 2 Filename.
267
Figure 13-6
5. 6.
Enter output.txt for the Output file Filename. Click OK to invoke 3 Way Merge. SlickEdit displays 3 Way Merge, as shown in Figure 13-7. The output file starts with the contents from base_file.txt.
Figure 13-7
7.
Use the buttons to navigate the merge, and apply changes from either of the revisions to the output file as desired.
268
The 3 Way Merge tool can be particularly useful in combining multiple independent revisions from version control.
Backup Histor y
As weve mentioned, the diff and merge tools are often used in conjunction with version control. SlickEdit also provides a fine-grained change-tracking tool for changes made between commits into version control, or for changes made to files not in version control. Every time you save a file, SlickEdit stores the changes youve made since the last save. You can review these snapshots using the Backup History tool window. View this tool window via View Toolbars Backup History, or by invoking activate_deltasave (WROX: Alt+T, followed by H). The tool window is shown in Figure 13-8.
Figure 13-8
The tool window reflects the changes made to the current buffer. The list shows the date and time of each save. You can select a pair of saves, as shown in Figure 13-8, and use DIFFzilla to compare the file versions. The DIFFzilla headings for the panes display the version numbers you are comparing. You can also select a single save in the list and use DIFFzilla to compare it to the current buffer contents. This provides an easy way to find out exactly what you have changed in the file since your last save. The first time you edit a file with SlickEdit, there is no backup history for it until you save it at least once. If you make some changes, you cannot use the Backup History tool window to see them until the first save. (This limitation may be removed in a future version of SlickEdit.) For this situation, to see what changes you have made, use DIFFzilla directly to compare the on-disk version of the file with the buffer version. You can do this very quickly in the DIFFzilla setup dialog using keyin-buf-name (Alt+N):
1. 2. 3. 4. 5.
Invoke diff (Ctrl+=). SlickEdit displays the DIFFzilla setup dialog. Invoke keyin-buf-name (Alt+N). SlickEdit enters the buffer name in Path 1. Press Alt+2 to move the focus to Path 2. Invoke keyin-buf-name (Alt+N). SlickEdit enters the buffer name in Path 2. Press Enter to run DIFFzilla.
269
Summar y
Comparing and managing differences between multiple versions of files is an inevitable part of a programmers job. Good version control practices can reduce the pain involved considerably, but you will still find that there are plenty of times you need to compare file versions, whether in your version control system or out of it. SlickEdit provides tools for comparing files and directories. DIFFzilla can be used within SlickEdit, or as a standalone tool in its own right. SlickEdits 3 Way Merge tool can be used to reconcile changes from different sources. Finally, SlickEdits Backup History tool window is a great way to see changes youve recently made to a file, independent of your version control system. Backup history is a valuable feature, but it is no substitute for proper version control. In the next chapter, we look at some of SlickEdits integration with two popular version control systems, CVS and Subversion. We will find that SlickEdit uses DIFFzilla extensively within its version control integration also.
270
Version Control
Version control should be a key part of any programmers workflow. (Every file involved in the writing of this book was checked into and versioned in a Subversion repository.) Whether you work in a large distributed team, or are coding alone on a personal project, version control tools are very useful in helping you manage changes and versions of your code base. Most programmers have been through a phase of using what I call ZIP file archive version control, which is pretty much what its name implies. If youre using ZIP files or other ad hoc copies of your source code for version control, you are probably spending a lot of time using the diff tool and scratching your head. You may also have some trouble explaining why you cannot reproduce the behavior found in released versions of your product, because you cannot reliably reproduce those versions! Do yourself (and your customers) a favor, and start using version control. SlickEdit provides support for several version control systems. In this chapter, we look at the two main popular open source version control systems: CVS and Subversion. As usual, we wont be studying these version control systems in minute detail. You should refer to the appropriate documentation for each version control system for more detail. The main point of this chapter is to show how SlickEdit uses Slick-C and macro commands to interact with version control. You can use macros within the SlickEdit environment to add your own preferred key bindings and valueadded commands. We show a set of possible key bindings for working with each of CVS and Subversion, and some sample macros that make these version control systems quicker and easier to use with SlickEdit. This should give you a start for building on your own requirements.
CVS
CVS, or the Concurrent Version System, is the venerable de facto standard open source version control system. It was developed in the 1980s and is widely used today, although its use may be declining, with many developers switching to Subversion.
Your details will obviously be different. CVS supports several other authentication schemes besides pserver, but we wont be covering those in this book. With the pserver authentication scheme, you can start a CVS session using the cvs login command. The CVS client stores your password in an encrypted form in the file .cvspass in your home directory during your session. This saves you from having to type the password for every command. You can make the client clear the password using the cvs logout command. In the setup examples below, we assume you are not logged in to CVS to start with.
1.
Invoke vcsetup (Tool Version Control Setup). SlickEdit displays the Version Control Setup dialog, shown in Figure 14-1. This dialog allows you to select your version control system and configure its options. The dialog shown in Figure 14-1 is for Windows. The UNIX version is slightly different. (The UNIX version does not have SCC providers.) Check the Command-line systems box. CVS is a command-line system. Some version control systems provide API integration, but SlickEdit integrates with CVS via command-line commands. Select CVS in the list of Version Control Systems. Click Setup. SlickEdit displays the CVS Setup dialog, containing setup options specific to CVS. The dialog is shown in Figure 14-2. Ensure that the CVS executable is correct for your system. SlickEdit needs to be able to find the CVS executable in order to issue CVS commands.
2. 3. 4. 5.
272
Figure 14-1
Figure 14-2
6. 7.
Change other options according to your preferences. Click Login. SlickEdit displays the CVS Login dialog, shown in Figure 14-3. This dialog allows you to specify your repository and login details. In Figure 14-3, SlickEdit has filled in the User Id, Host, Repository, and Authentication type correctly from the CVS/Root file in the working copy.
Figure 14-3
273
Click OK. SlickEdit prompts you whether you wish to set CVSROOT in vslick.ini. Click No. SlickEdit runs the cvs login command in a console to log in to your CVS server. The login command prompts you for your CVS password. Type your password, and press Enter. The console prompts you to Hit any key to continue. Press a key. The console closes. Click OK to dismiss the CVS Setup dialog. Click OK to dismiss the Version Control Setup dialog.
SlickEdit updates the project definition in the .vpj file to indicate that the CVS version control system is used with the project. You are now ready to start working with your files with version control.
1. 2.
Change to the directory under which you want to place the working copy. Invoke cvs-checkout-module (Tools Version Control Check Out Module). SlickEdit displays the first page of the Check Out CVS module wizard, shown in Figure 14-4. The page shows projects available on your CVS server.
Figure 14-4
3. 4.
Select the module you want to check out. Enter the path where you want the new working copy to be created.
274
Figure 14-5
6. 7. 8.
Select the branch or tag you want to check out. Click Finish. SlickEdit displays the Checkout workspace dialog, summarizing your options for checking out the module. Click OK to close the Checkout workspace dialog. SlickEdit invokes CVS to check out the module. CVS output is shown in the Output tool window. If everything worked correctly, you now have a new working copy.
Checking out a module does not change your working directory. If you checked out the module to another location, you still need to change directory to that location. Checking out a module also does nothing to create a SlickEdit project. If your SlickEdit project files are version controlled, you can now open the project in the working copy. Otherwise, you will need to create a new SlickEdit project for the files in the fresh working copy.
Reviewing Changes
When you are working with version control, you regularly need to review the local changes you have made and refresh your working copy with changes others have made. CVS achieves this with the cvs update command. In SlickEdits version control menu, there are several update variants available. Most of these update variants are implemented (for CVS) using the cvs-gui-mfupdate command. For example, to update your current project, you can use this command:
cvs-gui-mfupdate project_dir
If you want to update directories recursively under the project, add the r option. This macro uses our wrox_project_dir() function to update the current project, and all subdirectories:
_command void wrox_cvs_update_project() name_info(,) { cvs_gui_mfupdate(-r wrox_project_dir()); }
275
Figure 14-6
The window reflects the output of the cvs update command, using visual cues to indicate the status of files. You can move the mouse over the status icons to find out what they mean. In Figure 14-6, we see that:
board.cpp has local changes.
The SlickEdit workspace and project files gnu_queens.vpj and so on have not been added to version control. The file LICENCE.txt has been changed by another user. The file README.txt has been added by another user. The directory doc/ has been added by another user.
SlickEdit invokes cvs update with the n option, which causes CVS to report updated files on the server, but not to refresh them on the local disk. Use the Update or Update All button to accept refreshes of new or changed files from the server. For the local changes and the refreshed files, you can use the History or Diff buttons to find out more about changes. When you use the Diff button to compare revisions against other revisions or the local copy, SlickEdit fetches the necessary versions from CVS and then invokes the SlickEdit DIFFzilla tool to show the comparison. Figure 14-7 shows DIFFzilla in action, comparing the local changes in a file to the latest version in the repository. The headings above the panes indicate which revision is in each pane. Other buttons appear, such as Revert, when you select a file for which the action is valid. Right-click on a file, and use the context menu for other commands.
276
Figure 14-7
Adding Files
Its often easiest to add new files to CVS from the CVS Update Directory window. For example, lets add the SlickEdit project and workspace files in the sample project to CVS:
1. 2.
Select gnu_queens.vpj and gnu_queens.vpw in the CVS Update Directory window. Right-click on one of the files, and choose Add Files from the context menu. SlickEdit displays the Options for CVS Add dialog, shown in Figure 14-8. You can specify options for adding the file here, such as -kb for a binary file.
Figure 14-8
3.
Click OK to close the Options for CVS Add dialog. SlickEdit schedules the files for adding. The CVS Update Directory window updates the icons to indicate that the files are pending being added.
If you are in a new file and you wish to add it to CVS, you can do it with the cvs-add command (WROX: Alt+V, A). This approach can be quicker if you already have the file open in a buffer, but it does not give you the opportunity to use options such as -kb when adding a file. However, its unlikely you would add a binary file by having it open in a buffer. Adding files in CVS is a two-step process. After marking files to be added, they still need to be committed.
277
Committing Changes
As with adding, you will usually commit changes from the CVS Update Directory window. Lets commit the newly added project and workspace files to CVS:
1. 2.
Select gnu_queens.vpj and gnu_queens.vpw in the CVS Update Directory window. Right-click on one of the files, and choose Commit selected files from the context menu. SlickEdit displays the Comment window, as shown in Figure 14-9.
Figure 14-9
3. 4. 5.
Enter Adding SlickEdit project and workspaces for the comment. Check the Apply to all checkbox to apply your comment to both files. Click OK. SlickEdit commits the files, and they are removed from the CVS Update Directory window.
Merge Conflicts
If you have made local changes to a file and another user commits changes on the same lines to the server, CVS reports a merge conflict when you update your local copy. Figure 14-10 shows the CVS Update Directory window showing board.cpp with a merge conflict.
Figure 14-10
278
Figure 14-11
These choices reflect the different revisions involved in the merge conflict: The older repository version (1.2 in the example). The new changes committed by another user (1.3 in the example). Your own local changes.
You can choose any pair and use DIFFzilla to compare them. Once you have decided which changes you would like to keep, you have two basic choices: You can click Revert to throw away your own changes and revert to the latest repository version. You can click Update to cause CVS to insert its merge markers into the file. You then edit the merged lines until you have resolved all the conflicts, and then commit the file.
279
1.
Invoke commit-sets (Tools Version Control Commit sets). SlickEdit displays the CVS Commit Sets dialog, shown in Figure 14-12. This dialog allows you to manage your commit sets.
Figure 14-12
2. 3. 4. 5.
Click Add. SlickEdit displays the New Commit Set dialog. Enter Project administration for the New Commit Set Name. Click OK to close the New Commit Set dialog. SlickEdit adds the commit set to Current commit sets. Repeat Steps 24 to add a commit set called Documentation.
The first commit set added is Project administration. Its shown in bold because it is the default commit set. When you add files to commit sets in the CVS Update Directory window, they are added to the default commit set.
280
1. 2. 3. 4. 5.
Select the Documentation commit set on the CVS Commit Sets dialog. Click Edit. SlickEdit displays the editing dialog for the commit set. Click Add files. SlickEdit displays an Open dialog for selecting files for adding. Select board.cpp and board.h. Click OK to close the Open dialog. SlickEdit adds the files to the commit set. The result is shown in Figure 14-13.
Figure 14-13
6. 7.
Enter Added some documentation comments as the Comment for all files. Click OK to close the CVS Commit Sets editing dialog.
SlickEdit allows you to specify a different comment per file in a commit set. However, this runs contrary to the idea of a change set. With CVS, theres no technical reason why you cant use a different comment for different files, because each file is committed separately to the repository, even when using a commit set feature such as SlickEdits. With other version control systems, such as Subversion, change sets are atomic, and all files in the change set must share the same comment. Also, even with CVS, many tools rely on files committed together sharing the same comment in order to group them and reconstruct change sets retrospectively. For example, the FishEye CVS repository browser (http://www.atlassian.com/software/fisheye/) constructs synthetic change sets for CVS commits using the check-in comments. Also, the cvs2svn tool (http://cvs2svn.tigris.org), used to convert CVS repositories to Subversion, creates true Subversion change sets from groups of CVS
281
1. 2. 3.
Invoke wrox-cvs-update-project. SlickEdit displays the CVS Update Directory window. Select .cvsignore and README.txt. Right-click on one of the files, and select Add to commit set from the context menu. SlickEdit adds the files to the default commit set.
As of this writing, SlickEdit allows you to add files to more than one commit set. Thats probably not what you want to do; thus its up to you to make sure your files are only in the commit sets you intend. Once you have all your changes done and all your files in the correct commit sets with the check-in comments entered, you can commit your commit sets. To commit the Documentation commit set, follow these steps:
1. 2. 3.
Invoke commit-sets (Tools Version Control Commit sets). SlickEdit displays the CVS Commit Sets dialog. Select the Documentation commit set. Click Commit. SlickEdit verifies that all files have check-in comments and then commits the files. If any file does not have a check-in comment, SlickEdit displays a warning message in a confirmation dialog.
After you commit a commit set, it is moved from the Current commit sets group to the Past commit sets group.
Figure 14-14 shows the command as executed in the Build tool window.
282
Figure 14-14
After creating a release branch, you typically need to check out a working copy of that branch, complete final changes, and then tag the release. Lets do that within SlickEdit:
1. 2. 3. 4.
Invoke workspace-close (Project Close Workspace) to close the current workspace. Invoke activate-build (WROX: Alt+T, B) to activate the Build tool window. Enter the command cd .. to change your local directory to the parent of your project. (This is assuming that you were in the project directory to start with.) Enter this command to check out the 1.1 release branch of the gnu_queens project:
SlickEdit shows the output of the CVS command in the Build tool window. If the command worked correctly, you now have the 1.1 release branch checked out in the gnu_queens_01_01/ subdirectory.
5.
Invoke workspace-open (Project Open Workspace), and navigate to and open the gnu_queens.vpw workspace in the release branch subdirectory. You are now working with the project in the release branch.
You can do final release preparation and testing in the release branch, while the rest of the team works in the tip. Once you have built and released the release, you can tag it, so that you can get back to the exact source code revisions for the release at any future time. Enter this command in SlickEdits Build tool window, to create a tag for release 1.1.0 of the gnu_queens project:
cvs tag REL_01_01_00
For the tasks involved in branching and tagging, SlickEdits Build tool window works very well with regular CVS commands. SlickEdit also provide a powerful graphical history browser that you can use to browse branches and tags in your project.
1. 2.
Open the file you want to browse. Invoke cvs-history (Tools Version Control History for <filename>). SlickEdit displays the Log info window, shown in Figure 14-15.
283
Figure 14-15
In this window, you get a view of all the revisions made to the file, across all the branches. You can click on any revision to examine the date and comment for the revision. You can compare a revision to the tip, or to any other revision.
Keyboard Bindings
In SlickEdits default configuration, the user interface for CVS operations is accessed through menus. Most of the commands are available in at least three different ways: From the main menu, under Tools Version Control. From the context menu in a file. From the context menu in the Projects tool window.
The context menu approaches require the mouse and thus are not very suitable for commonly used operations. The Tools Version Control menu is the fastest way to access the version control features in the default configuration. However, all the SlickEdit CVS functionality is also available in the form of SlickEdit commands. Therefore, its easy to set up convenient keyboard shortcuts for the commonly used commands. In the file wrox_cvs.e on the CD-ROM, you will find one possible keyboard binding scheme for CVS commands. This scheme uses the same technique as the WROX emulation uses for accessing tool windows. Because there are quite a few CVS commands and only so many keystrokes available, the scheme uses a prefix key for CVS commands. All the shortcuts begin with Alt+V, which is followed by a mnemonic for the command. Thus, for example, the command to update the current project (wrox-cvs-update-project) has the shortcut Alt+V followed by U. Table 14-1 shows a subset of the SlickEdit CVS-related commands. Commands that work on the current file will prompt for a file if none is open. The WROX keyboard shortcuts are shown, as well as a
284
Table 14-1
Command
commit-set-add commit-sets cvs-add cvs-checkout-module cvs-commit cvs-diff-with-tip cvs-history cvs-login cvs-query cvs-remove cvs-review-and-commit
Description Adds the current file to the default commit set. Shows the commit sets. Adds the current file to CVS version control. Checks out working copy of module from repository. Commits the current file. Shows the local changes. Shows the Log info window for the current file. Invokes CVS login.
Invokes the CVS query facility. Removes the current file from version control. Displays DIFFzilla showing local changes, allowing revision. Then follows with commit dialog. Displays the CVS Setup dialog. Updates the current file. Updates the current directory. Updates the current project.
Subversion
Subversion was designed in the early part of this decade to be a replacement for CVS and to address its shortcomings. Some of the significant advantages of Subversion over CVS are: It supports the history of renames and moves. It supports transactional commits of multiple files. When committing a set of files together, all of them are committed, or none of them is. The repository structure and communication protocols are designed to minimize network use. Subversion can perform many operations without using the network.
285
To make the environment variable available in SlickEdit, I put the following line in vslick.ini:
SVN=svn+ssh://jhurst@vcs/var/svn/slickedit
Make the appropriate changes for your environment. Usually when you are working with Subversion, you dont want to see the hidden admin files that it places in its .svn/ directories. For example, when you are defining projects, you dont want to include those files in the project for tagging. When you are navigating the directory tree with the Open dialog, its usually easier if the .svn/ directories do not appear. The exception to this is, of course, when you are using SlickEdit to examine a Subversion admin file when you are experiencing problems with Subversion itself. But thats an unusual circumstance; thus most of the time you want the .svn/ directories to be invisible. On Windows, one easy way to do this is to choose Do not show hidden files and folders in the Windows Explorer Folder Options. SlickEdit honors the value this setting has at the time SlickEdit starts. (Thus, if you change the setting, you need to restart SlickEdit to pick it up.) If you prefer to use Show hidden files and folders on Windows, you have to take steps to prevent SlickEdit from including .svn/ files in projects. If you are defining a project and adding a tree or a wildcard, you can enter *\.svn\* in the Exclude or Exclude filespecs text field.
286
1. 2. 3. 4.
Invoke vcsetup (Tools Version Control Setup). SlickEdit displays the Version Control Setup dialog. Check the Command-line systems box. Subversion is a command-line system. Select Subversion in the list of Version Control Systems. Click Setup. SlickEdit displays the Subversion Setup dialog, containing setup options specific to Subversion. The dialog is shown in Figure 14-16.
Figure 14-16
5. 6. 7.
Ensure that the Subversion executable is correct for your system. Click OK to close the Subversion Setup dialog. Click OK to close the Version Control Setup dialog.
(If youre using Cygwin or UNIX, you need to use $SVN instead of %SVN%.) In these examples, well follow the normal Subversion convention that the main trunk, where most of the project changes occur, is in the trunk/ subdirectory. Branches and tags will be in the branches/ and tags/ subdirectories, respectively. Lets create the branches/ and tags/ subdirectories for the project too:
svn mkdir %SVN%/gnu_queens/branches -mCreated gnu_queens/branches directory. svn mkdir %SVN%/gnu_queens/tags -mCreated gnu_queens/tags directory.
In order to add files to the project, you need to get a working copy.
287
1. 2. 3. 4.
Invoke svn-browse (Tools Version Control Check Out). SlickEdit displays the Subversion Browser. Before you can browse repositories, you need to define them in the browser. Click Add to List. SlickEdit displays the Add Subversion Repository dialog. Enter the repository URL. Click OK to close the Add Subversion Repository dialog. SlickEdit refreshes the Subversion Browser with the new repository and the directories found under it.
When SlickEdit executes Subversion commands, you may see one or more console windows appear on your screen. This is because SlickEdit executes Subversion commands by shelling out to a console process. The windows should disappear when the commands finish.
5.
Expand the tree for gnu_queens. SlickEdit shows the trunk/, branches/, and tags/ subdirectories under the gnu_queens project. The window is shown in Figure 14-17.
Figure 14-17
6. 7.
Select the trunk/ entry under gnu_queens. Click Checkout. SlickEdit displays the Checkout from Subversion dialog, shown in Figure 14-18.
Figure 14-18
8. 9.
Enter the desired location for the project to be checked out to. Click OK. SlickEdit checks out the project.
288
This command opens the Subversion Update Directory window, showing all the changes in your project. The wrox_svn.e file supplied with this book includes this macro, with a keyboard binding so that you can invoke it with Alt+V followed by U. Figure 14-19 shows the window, with the same set of changes we saw for the CVS example. The format is slightly different, because the Subversion support is able to tell us more about the new directory (doc/) that was added to the repository.
Figure 14-19
With CVS, you can review and update files changed on the server into your working copy individually. That is because with CVS, every file is committed separately. With Subversion, change sets are committed atomically; thus you cannot update just one file from a change set into your working copy. If you try to use the Update button to update an individual file, SlickEdit prompts with a confirmation box, to check that you want to update the entire directory. Adding files and committing changes with Subversion are the same as for CVS.
Merge Conflicts
If you have local changes in a file when you update from the repository, and there is a new version of the same file with changes on the same lines, it creates a merge conflict. When this happens, Subversion creates four files in your working copy, to allow you to resolve the conflict. For example, I created a merge conflict on board.cpp. I had been working on revision 3 in my working copy, but revision 7 was checked in with changes to the same line. When I ran svn update, I got these files in my directory:
board.cpp The working copy file, now with merge conflict markers in it on the conflict lines. board.cpp.mine The file with the local changes as they were before running svn up.
289
You can use the four files to decide what you want to do with each merge conflict. Make your edits on the file with the original name, that is, board.cpp in this example. Use the others for reference to see what youre doing, or in case you make a mistake. When you have resolved all the conflicts, you should have removed all the merge conflict markers from the file. At that point, issue this command on the command line or in the Build tool window:
svn resolved board.cpp
Subversion reports:
Resolved conflicted state of board.cpp
After you have created a release branch, you need to switch to it to do the final testing and preparation for a release. To switch to a branch with Subversion, you can check it out as a separate working copy if you prefer. Or you can use the svn switch command. For example, to switch to the RB-01.01 release branch, use this command in the Build tool window:
svn switch %SVN%/gnu_queens/branches/RB-01.01
The switch command switches your working copy to the desired branch. The advantages of using svn switch are: It is simple. It is usually far quicker than checking out a whole extra copy of the project, especially if there are many files with relatively few changes. You dont have lots of different copies of the code on your system. You dont have to switch projects in your editor.
290
As you follow this convention for branches and tags, you will find it very easy to navigate to and check out particular branches and tags using SlickEdits Subversion Browser. Figure 14-20 shows the browser now that we have added a branch and a tag.
Figure 14-20
1. 2.
Open the file you want to browse. Invoke svn-history (Tools Version Control History for <filename>). SlickEdit displays the Subversion info window, shown in Figure 14-21.
In this window, you get a view of all the revisions made to the file, from its start to the latest revision. Subversion tracks changes across copies, moves, and renames, so you can see the history across these operations. Because branches and tags are done using svn copy, you can see the history across any branches or tags in the sequence from the current revision back to the start. Changes that occur on a branch other than the current one, including copies, moves, and renames as well as normal changes, cannot be seen. Thus, if the working copy is the 1.1 release branch, we cant see changes made to the trunk after the release branch was created. Similarly, if the working copy is the trunk, we cant see changes made in any other branch. You can, of course, use the command line to do arbitrary svn log or svn diff commands.
291
Figure 14-21
Keyboard Bindings
As with CVS, we can improve the workflow with Subversion a little bit by adding some custom key bindings. The file wrox_svn.e supplies an example for Subversion. Table 14-2 shows common SlickEdit Subversion commands, as well as key bindings from wrox_svn.e.
Table 14-2
Command
commit-set-add commit-sets svn-add svn-browse svn-commit svn-diff-with-tip svn-history svn-remove svn-revert
Key (none) (none) Alt+V, A Alt+V, B Alt+V, C Alt+V, D Alt+V, L Alt+V, R Alt+V, T
Description Adds the current file to the default commit set. Shows the commit sets. Adds the current file to Subversion. Opens the Subversion Browser. Commits the current file. Shows the local changes. Shows the Log info window for the current file. Removes the current file from version control. Reverts the local changes on the current file.
292
Key Alt+V, V
Description Displays DIFFzilla, showing local changes, allowing revision. Then follows with commit dialog. Displays the Subversion Setup dialog. Updates the current file. (This command is not really meaningful for Subversion.) Updates the current directory. Shows Update Directory window for the current project.
svn-setup svn-update
(none) (none)
svn-update-directory wrox-svn-update-project
(none) Alt+V, U
You will notice that the commands for Subversion are mostly different from those for CVS (with the exception of commands for commit sets), but the keyboard shortcuts are the same. The keyboard shortcuts are provided as examples, to allow you to customize them to your own workflow. If you are using both CVS and Subversion, you need to come up with a different scheme, allowing use of both sets of commands. One approach would be to use a different prefix key for CVS and Subversion. Another approach might be to create a macro to load the appropriate CVS/Subversion key bindings when you switch projects. Or, you might be happy simply to load the key bindings you prefer manually when you need them.
Summar y
In this chapter, we looked in detail at SlickEdits support for CVS and Subversion, two popular opensource version control systems. SlickEdit also supports several other proprietary systems. If your company is using a particular system, thats great, and hopefully SlickEdit supports it. (If SlickEdit doesnt support it, ask them to!) If you are looking for a great system that costs nothing, download Subversion. It has all the features most people need, its quite fast and very reliable, and it is used widely both in open-source and commercial environments. In the next chapter, we move on to some other tools SlickEdit provides, which can also be used as standalone tools in their own right.
293
Other Tools
As weve seen, SlickEdits DIFFzilla program is a useful program that is integrated in the editor but can also be used standalone, for comparing files or directories. SlickEdit includes several other tools that you can also use within the editor, but may find useful in their own right. SlickEdits remote ancestor was an IBM internal-use DOS editor in the 1980s. Along with the DOS editor, IBM also developed various PC productivity applications. One of the most popular of these was a file manager called FileMan. Other similar products existed in the DOS days outside IBM, such as XTree Gold. One idea that reoccurred a few times in text-mode computing was combining the text editor with the file manager, often by implementing the file manager in the text editor. This happened on the IBM VM/CMS mainframe operating system, for example, with the XEDIT text editor and FILELIST file manager. SlickEdit contains a text-based file manager implemented in Slick-C. You can use the file manager to browse and manage your files and directories and, of course, to open files. You can also use Slick-C in conjunction with the file manager to automate tasks involving both the files and the editor. The file manager is intended for use on file systems visible on your machine, that is, local file systems or network attached ones. Using the FTP tool window, you can also open and edit files on remote hosts via the FTP or SFTP/SSH protocols. Finally, SlickEdits Regex Evaluator tool window can be used to test regular expressions in any of SlickEdits supported regex styles. In this chapter, we take a brief look at each of these tools.
1.
Invoke the fileman command (File File Manager New File List). SlickEdit displays the List Files dialog, as shown in Figure 15-1.
Figure 15-1
2. 3.
Enter the path for the directory you want to work with. Click OK. SlickEdit opens a file manager buffer with the files in the given directory, as shown in Figure 15-2.
Figure 15-2 To add more files to the list, use the fileman command with the append option (File File Manager Append File List). The file manager can mix file listings from multiple directories. Instead of using the menu to list files in the file manager, you might find it quicker to invoke the list or dir command on the SlickEdit command line. Specify the directory for the list as a command-line argument, or list the working directory by default. With list or dir, you can also use some options, which are shown in Table 15-1. The list and dir commands are almost identical. With list, Tree File List is on by default; with dir, it is off. With dir, directory files are included by default, and directories are sorted to the top. With list, directory files are excluded by default, but if they are included, they are sorted with the other files in the list. This makes dir more suitable for working with a single directory at a time and navigating directories, and list more suitable for working with an entire subtree in one list. The ls command is also available, as an alias for dir.
298
Description Exclude/include directory files. Exclude/include hidden files. Ignored on UNIX; on Windows the default follows the Windows Explorer Show all files setting. Append path. Default is on. Exclude/include system files. Ignored on UNIX; on Windows the default follows the Windows Explorer Show all files setting. Tree file list. (Includes subdirectories.)
-|+P -|+S
-|+T
Table 15-2
Command
fileman-space fileman-enter select-all fileman-backup fileman-copy fileman-delete fileman-edit fileman-find fileman-replace fileman-move fsort
Key Space Enter Alt+Shift+A Alt+Shift+B Alt+Shift+C Alt+Shift+D Alt+Shift+E Alt+Shift+F Alt+Shift+G Alt+Shift+M Alt+Shift+O
Description Toggles select if file cursor is on. Edit file at cursor, or insert directory list. Select all files. Back up (copies) selected files to a directory. Copy selected files. Delete selected files. Edit selected files. Run multifile search in selected files. Run multifile search and replace in selected files. Move selected files. Sort list. continued
299
Description Set DOS attributes. Repeat a command on each selected file. Deselect all selected files. Reverse selected files. Select files based on DOS attributes. Select files based on given extension. Select files based on extension. Select files marked with a (character or line or block) selection. Deselect files marked with a selection. Empty the list. Unlist the selected files. Unlist files based on given extension. Unlist files based on extension. Unlist files based on DOS attributes. Unlist files based on filename matching a search string. Read a list of filenames from a file. Write the list of selected filenames to a file.
read-list write-list
(none) (none)
Most GUI file managers use a tree on the left-hand side to navigate the directory structure, and a file list pane on the right-hand side to show files. The file list pane contains only files for the currently selected directory. The neat thing about text-based file managers is that you can list arbitrary combinations of files from different directories. Using fsort, you can group similar files together by name or extension.
Selecting Files
In order to do things with files in the file manager, you need to select files to operate on. You can toggle selection on the file on the current line by pressing Space. You can also use the various select and deselect commands to turn many selections off and on quickly.
300
You can combine these commands into new shortcut commands. For example, the macro below defines the command wrox-retain-exts. You can use this command to unlist all files in the list apart from the extensions provided as arguments to the command:
_command void wrox_fileman_retain_exts(_str exts=) name_info(,VSARG2_REQUIRES_FILEMAN_MODE) { exts = prompt(exts, Extensions to retain); deselect_all(); select_ext(exts); select_reverse(); unlist_select(); }
Automating Tasks
You can use the file manager to automate tasks in SlickEdit. Heres an example from Hartmut Schaefer (hs2). SlickEdit usually recognizes files as C++ header files by the extension being associated with C mode. But some libraries, such as the standard C++ library and some third-party libraries, use extensionless header files. SlickEdit recognizes an extensionless file as a C++ header file if both of the following conditions are true: The path of the file matches the regular expression in the macro variable
def_cpp_include_path_re.
Both of these macro variables are normally managed from the GUI configuration on the Other tab of the C/C++ Formatting Options dialog (Tools Options File Extension Setup, C/C++ Options button). However, if you have a lot of header files to add to the list, it can be rather tedious to add them using the GUI. Instead, you can make use of the file managers ability to run arbitrary commands for selected files. Define this simple macro:
_command void wrox_addextlessfile(_str file = ) { message(file=[ :+ file :+ ]); int idx = find_index(def_user_langext_files, VAR_TYPE); _str val = _get_var(idx); strappend(val, file); _set_var(idx, val); }
301
1. 2. 3.
Invoke list to open a file manager buffer with the directory containing the extensionless header files. Select all the extensionless header files. Invoke for-select (Alt+Shift+R). SlickEdit displays the Repeat Command on Selected dialog, shown in Figure 15-3.
Figure 15-3
4. 5.
Enter wrox_addextlessfile %n for the command. Click OK. SlickEdit applies the command for each selected file, passing the name of the file (without extension or path) to the command. The macro adds the filenames to the spacedelimited list.
If you use this technique, remember to configure your Extensionless C++ File Path Regular Expression too; the macro as shown deals with the files only. You should be able to adapt this technique for your own needs when you need to do operations in SlickEdit on several files.
1. 2.
Open the FTP tool window. (Using the WROX emulation, you can do this with Alt+T followed by T.) The FTP tool window is shown in Figure 15-4. There are currently no connections. Click the icon with the green plus sign to create a new connection. SlickEdit displays the Connect dialog, shown in Figure 15-5. There are currently no connection profiles.
302
Figure 15-4
Figure 15-5
3.
Click Add. SlickEdit displays the Add FTP Profile dialog, shown in Figure 15-6.
Figure 15-6
303
You can install OpenSSH as part of the free Cygwin UNIX emulation package. See http://www.cygwin.com. You cannot use PuTTY. OpenSSH is required.
5. 6. 7.
Click OK to close the Add FTP Profile dialog. SlickEdit adds the profile to the list available in the Connect dialog. Click Connect. If you are using SFTP/SSH on Windows, SlickEdit confirms the location of your ssh executable. The FTP tool window shows connection progress and then the directory and directory listing for the connection.
You can now navigate the directory tree on the remote host and edit files, provided you have appropriate permissions via your authentication credentials. You can create and open multiple FTP or SSH host connections at the same time. Select between connections in the top dropdown box in the FTP tool window. This makes SlickEdit a useful tool for browsing and analyzing server configurations and logs.
Figure 15-7
304
305
Figure 15-8
Summar y
SlickEdits built-in additional tools are well integrated with the editor and, in some cases, are useful in their own right. In this chapter, we had a look at the file manager, which can be an effective way to manage and edit files. The file manager is also important because of its ability to automate tasks in the editor using Slick-C. We also looked at SlickEdits support for editing files on remote hosts using FTP and SSH. Finally, we had a quick intro to the regular expression evaluator, which you can use when developing and testing regular expressions for use in your macros. As in most of the chapters in this book, we provide some Slick-C code to illustrate how you can customize and extend SlickEdit in relation to the topics weve been discussing. By now you should have a good feel for what its like to work with Slick-C. In the next chapter, we finally get into Slick-C in detail, presenting the background and reference information that you can use to extend your Slick-C skills further.
306
For examples in this chapter, well use a few more functions to extend the basic _assert() for a few common cases:
void wrox_assert_false(boolean condition, _str msg = null) { _assert(!condition, msg); } void wrox_assert_equals_message(typeless expected, typeless actual, _str msg) { if (expected._varformat() == VF_LSTR && actual._varformat() == VF_LSTR) { _assert(expected :== actual, msg); // exact match for strings } else { _assert(expected == actual, msg); } } void wrox_assert_equals(typeless expected, typeless actual) { wrox_assert_equals_message(expected, actual, expected=[expected], actual=[actual]); }
The code snippets demonstrating Slick-C features this way are all contained in files with names beginning with wrox_try_ in the Author/Chapter16/ directory of the CD-ROM.
308
Slick-C Engine
Builtins
SlickEdit executable
Operating System
Figure 16-1
309
Module Initialization
There are two special module initialization sections you can place into a Slick-C module, indicated by the keywords defload and definit. These sections look like this:
defload() { // code ... } definit() { // code ... }
The defload routine is run when the module has been compiled and loaded. It is not run again unless the module is compiled again. You can place one-time tasks in defload that need to be run when your module is set up. For example, if your module needs a special subdirectory to work, you can create it in defload. The definit routine is run when the module is compiled and loaded (before defload), and also whenever SlickEdit starts. You can place code in definit if it needs to be run every time the Slick-C environment is initialized. For example, you might place initialization for global variables in definit. If you have a choice, you should prefer to place code in defload rather than definit, because it will have less impact on the performance of the SlickEdit startup. You can distinguish between the load case and the init case in definit by calling the special function arg(), like this:
if (arg(1) == L ) { // load case }
Batch Macros
If you need to run some Slick-C code as a one-time job, rather than have it loaded as part of the editor environment for use all the time, you can run it as a Slick-C batch macro. A batch macro contains a block of code in a defmain section like this:
defmain() { // code ... }
310
Preprocessor
The Slick-C compiler includes a preprocessing step much the same as that for C. Most of the classic C preprocessor directives are supported, such as #include, #define, #if, #else, and #endif. To get the best error checking from the compiler, you should place these two lines at the top of every Slick-C file:
#pragma option(strict, on) #include slick.sh
The #pragma option(strict, on) line turns on several compile-time checks, such as variable declarations. It also enforces stricter syntax rules, making it less likely for your code to do something other than what you intend. Slick-C header or include files have the extension .sh. The standard slick.sh header file contains the most commonly used declarations, shared by most Slick-C code. Some supplied Slick-C macro files make use of additional header files, and, of course, you are free to create your own for your own macros. You can use the preprocessor to write conditional code the same way you would with C. For example, to make part of your macro code specific to UNIX, you can use:
#if __UNIX__ // UNIX code #else // non-UNIX code #endif
Similarly, you can use the __NT__ special macro to make code dependent on Windows.
Functions
Most of the code you write for SlickEdit is in the form of Slick-C functions. Slick-C functions are of several basic types: Commands are special functions that can be invoked from the command line or bound to keys or menu items. Commands are declared by preceding the function definition with the _command keyword. Ordinary functions cannot be invoked from the command line or bound to keys or menu
311
We refer to ordinary functions simply as functions in this chapter. It is also possible to write functions in Windows DLLs that can be called from Slick-C. These functions are not covered in this book. The online Help contains reference information for many supplied macro functions. If the Slick-C declaration or definition has a JavaDoc comment preceding it, this documentation is extracted and included in the online Help. There is a master list at the end of the online Help contents called Macro Functions by Category. The @categories documentation tag indicates which function categories list a given function. For example, several functions are listed in the category String Functions. There are also many supplied Slick-C macro functions that dont have JavaDoc documentation. These macro functions do not appear in the online Help. In order to find out about these functions, you need to become familiar with the Slick-C source code.
Properties
Properties are special global pseudovariables. Like built-in functions, they are intrinsic to the Slick-C runtime environment and are declared in builtins.e. Properties are an important part of the interface between the Slick-C environment and the editor. Properties exist for a great many editor attributes. Reading a property accesses the value of the attribute. Writing a property updates the attribute, which may have various visible effects in the editor. For example, two very simple and useful properties are p_line and p_col, which reflect the cursor line and column in the current buffer. Macro code can read these properties, save their values in variables, and update them. If macro code changes the value of p_line or p_col, the cursor position in the buffer is updated accordingly. The following macro defines a command, wrox-goto-line-col, that can be used to navigate to a given line and column:
_command void wrox_goto_line_col(_str command = ) name_info(,) { if (command == ) { return; } _str line, col; parse command with line col; p_line = (int) line; p_col = (int) col; }
The command gets its job done simply by setting the properties p_line and p_col. You will find that a lot of Slick-C code works by reading and setting properties.
312
Table 16-1
Property
p_buf_id p_buf_name p_buf_size p_caps p_col p_DocumentName
Description Determines buffer displayed in current window. Determines buffer name. Returns number of bytes in buffer. Returns True if capitalization mode is on. Determines the character column position. Determines the document name. If not blank, the document name is displayed instead of the buffer name. It doesnt need to be a valid filename. Determines embedded language context mode. Determines embedded language lexer name. Determines the default encoding that the buffer will be saved in. Set to the encoding chosen if the user overrode automatic encoding processing. Determines extension file type support. When in hex mode, determines whether cursor is displayed in hex nibbles (True) or ASCII data (False). Determines whether text is displayed in hex or ASCII lines. (Use hex function to switch.) Buffer time stamp. Determines lexer name, which defines the language coloring elements for a buffer. Determines the current line number. Determines the mode name for the current buffer. continued
p_extension p_hex_field
p_hex_mode
p_LastModified p_lexer_name
p_line p_mode_name
313
Description Determines whether the current buffer is modified. Returns the new line characters used for the current buffer. Returns the total number of hidden lines in the current buffer. Returns the number of lines in the current buffer. Determines the length of a selection in bytes. Determines the position of the left-most character of a selection. Determines whether the buffers data are UTF-8. Determines the current object/window.
Data Types
Slick-C provides a fairly typical set of data types, including basic types for numbers and strings, and data structures for dynamic arrays, hash tables, and user-defined structs. Slick-C also has a generic, or dynamic, typeless type.
Numbers
Slick-C supports three kinds of numbers:
ints are regular 32-bit signed integers. longs hold larger values, with precision up to 32 decimal digits. doubles are floating point numbers.
Most Slick-C programming uses integers. Note that all Slick-C numbers are signed. There is no unsigned modifier.
int i1 = 0x7fffffff; // 2^31 - 1 int i2 = i1 + 2; // - 2^31 + 1) int i3 = i1 + i2 - 1; // - 1 wrox_assert_equals(0x7FFFFFFF, dec2hex(i1)); wrox_assert_equals(2147483647, i1); wrox_assert_equals(-0x7FFFFFFF, dec2hex(i2)); wrox_assert_equals(-2147483647, i2); wrox_assert_equals(-1, i3);
314
Notice that once a long value gets bigger than 32 digits, it loses precision. For example, adding 1 to 1032 has no effect. This is unlikely to be a limitation for editor macros! Floating point numbers provide a large range of values:
double d1 = 9.9999999999999999999999999999999e999999999; double d2 = 0.1e-999999997; wrox_assert_equals(9.9999999999999999999999999999999E+999999999, d1/1.0); wrox_assert_equals(1.1E-999999998, d2*1.1);
Again, floating point numbers are not used in most editor macros.
Strings
Strings are represented in Slick-C using the built-in type _str. There is no such thing as a char in Slick-C. Elements of strings are also strings. You can get the length of a string using the length() built-in function:
wrox_assert_equals(13, length(Hello, World.));
Strings can be delimited with single quotes or double quotes. If you use double quotes, you need to use backslashes to escape double quotes and backslashes in the string. If you use single quotes, then
315
You can concatenate strings using the :+ operator. The + operator is restricted to numeric addition only, and cannot be used for concatenation. Most of the time the :+ operator is not necessary. You can simply abut strings as shown in the example below. It is often good practice to use the operator anyway, because it improves clarity.
wrox_assert_equals(Hello, World., Hello, World.); wrox_assert_equals(Hello, World., Hello, World.); _str a = Hello,; _str b = World.; wrox_assert_equals(Hello, World., a :+ b); wrox_assert_equals(Hello, World., a b); _str result = ; strappend(result, Hello, ); strappend(result, World.); // faster than result = result :+ ... wrox_assert_equals(Hello, World., result);
Another difference from C is that Slick-C strings are 1-indexed, rather than 0-indexed:
_str a = 0123456789ABCDEF; wrox_assert_equals(0, substr(a, 1, 1)); wrox_assert_equals(1, substr(a, 2, 1));
The strip() function strips unwanted leading and/or trailing characters from a string:
_str s = space string ; _str q = quoted string; wrox_assert_equals(space string, strip(s)); wrox_assert_equals(space string , strip(s, L)); // leading wrox_assert_equals( space string, strip(s, T)); // trailing wrox_assert_equals(quoted string, strip(q, B, )); // both, strip quotes
316
Despite the many string functions included with Slick-C, you will occasionally need to write your own. For example, there are no functions to extract the left-hand or right-hand part of a string. Here are some:
_str wrox_leftstr(_str string, int len, _str pad= ) { _str result = ; if (length(string) > len) { result = substr(string, 1, len); } else { result = string :+ translate(indent_string(len - length(string)), pad, ); } return result; } _str wrox_rightstr(_str string, int len, _str pad= ) { _str result = ; if (length(string) > len) { result = substr(string, length(string) - len + 1, len); } else { result = translate(indent_string(len - length(string)), pad, ) :+ string; } return result; }
317
The parse with construct uses a template or pattern to parse a string, placing matches or parts into variables. The parse with construct can be used for many situations in which you have to parse a string into parts according to a pattern. One of the most common cases is parsing command arguments. If you write a function that takes two string parameters, you would declare it like this:
void foo(_str a, _str b) { // ... }
However, this is not necessarily the best way to declare a command that takes two string parameters. When invoking functions, arguments are separated by commas. With commands, arguments are usually separated by spaces. Its friendlier to the user of a command if it is declared like this:
_command void wrox_try_parse_command(_str s=) name_info(,) { _str a, b; parse s with a b; // ... }
If the arguments can contain spaces, you will need to do something more elaborate to parse them, because SlickEdit does not automatically parse quotation marks in command-line arguments. A common technique is to use parse with to extract repeated items from a string:
_str s = 1,2,3; _str head, rest; int i = 0; parse s with head,rest; while (head != ) { wrox_assert_equals(++i, head); parse rest with head,rest; } wrox_assert_equals(3, i);
318
Table 16-2
Item
variable_name
Description Output variable. Null output variable (match ignored). New parse column. Parse column increment. Parse column decrement. String constant or pattern to search for. String expression to search for.
.
nnn +nnn -nnn text[,search_options] (expression)[,search_options]
The numeric offsets let you control the character positioning of parsing. The parenthesized expression feature allows you to use a variable in the template, including a variable that has been set earlier in the template. For example:
_str date1 = 2007/5/19; _str yyyy, mm, dd, delim; parse date1 with yyyy +4 delim +1 mm (delim) dd; wrox_assert_equals(2007, yyyy); wrox_assert_equals(5, mm); wrox_assert_equals(19, dd); _str date2 = 2008-12-01; parse date2 with yyyy +4 delim +1 mm (delim) dd; wrox_assert_equals(2008, yyyy); wrox_assert_equals(12, mm); wrox_assert_equals(1, dd);
The search options allow you to use regular expressions for parts of the template. The search options can be one or more of the characters in Table 16-3. Heres an example of parsing with a regular expression:
_str url = http://www.skepticalhumorist.co.nz/index.html; _str host; _str file; parse url with (http|ftp),U :// host / file; wrox_assert_equals(www.skepticalhumorist.co.nz, host); wrox_assert_equals(index.html, file);
319
Description Brief-style regular expression. Case-insensitive match. SlickEdit-style regular expression. UNIX-style regular expression. Binary value for DBCS searches (see online Help).
Using regular expressions with parse with is useful up to a point. But theres no way to use regular expressions in conjunction with storing a result in an output variable. Suppose you want to parse a date and ensure that its components are numeric. The example above does not check this and thus would parse 20XX/may/twentieth, for example, possibly giving a type conversion error later in the macro. The pos() function can be used for more complex parsing scenarios. The ordinary use of pos() is the familiar string function that returns the position of a substring in a search string:
wrox_assert_equals(6, pos(th, The other ones)); wrox_assert_equals(1, pos(th, The other ones, 1, I)); // case-insensitive wrox_assert_equals(6, pos(th, The other ones, 3, I)); // with start pos
The fourth argument to pos() is a set of options, which includes the options available for patterns in parse with. You can call pos() with a single argument to find the positions and lengths of matched subexpressions when using regular expressions. Call pos(S1) to get the start position of the first matched subexpression and pos(1) to get its length:
_str date = 2007-05-20; wrox_assert_equals(1, pos((\:d{4})([-/])(\:d{1,2})\2(\:d{1,2}), date, 1, U)); wrox_assert_equals(2007, substr(date, pos(S1), pos(1))); wrox_assert_equals(5, substr(date, pos(S3), pos(3))); wrox_assert_equals(20, substr(date, pos(S4), pos(4)));
A new utility function is planned for SlickEdit 2008 to simplify this idiom: get_match_substr(). As well as the pos() function, Slick-C also provides the lastpos() function, which has the same arguments but works backward from the end rather than forward from the start:
wrox_assert_equals(6, lastpos(th, The other ones, , I));
Arrays
Slick-C arrays look like C arrays, but, in fact, they are dynamic, which is much more convenient for a scripting language. Whenever you set an element of an array, Slick-C ensures that the array is long enough. For example, you can append items to an array like this:
_str a[]; a[a._length()] = one;
320
Arrays have several built-in member functions defined for them, which are declared in builtins.e. For example, you can sort an array like this:
a._sort(); wrox_assert_equals(four, a[0]); wrox_assert_equals(one, a[1]); wrox_assert_equals(three, a[2]); wrox_assert_equals(two, a[3]);
There are several other functions that also take arrays as arguments. For example, there are the join() and split() functions, borrowed from Perl:
_str a[]; a[a._length()] = one; a[a._length()] = two; a[a._length()] = three; a[a._length()] = four; wrox_assert_equals(one,two,three,four, join(a, ,)); _str b[]; split(five,six,seven,eight, ,, b); wrox_assert_equals(five, b[0]); wrox_assert_equals(six, b[1]); wrox_assert_equals(seven, b[2]); wrox_assert_equals(eight, b[3]);
Note that Slick-Cs split() function only works with exact strings for splitting, not regular expressions.
Hash Tables
Hash tables are also known in other languages as dictionaries, maps, or associative arrays. They let you store keys and values. You can also use a hash table as a simple set by storing a dummy value against each key. The Slick-C syntax for declaring and accessing hash tables is similar to that for arrays:
_str h:[]; h:[first] = one; h:[second] = two; h:[third] = three; wrox_assert_equals(one, h:[first]); wrox_assert_equals(two, h:[second]); wrox_assert_equals(three, h:[third]);
321
If youre like me, you probably find this idiom for iterating through items in a hash table a little weirdlooking. At the very least, its a little verbose. Future versions of Slick-C may provide a more natural way of iterating through hash tables. In fact, a foreach statement is tentatively planned for SlickEdit 2008. In the meantime, you can make things a little bit nicer for your own code by adding a function to return the keys as an array:
typeless wrox_hash_keys(typeless h:[], boolean sorted = true) { typeless k; typeless result[]; for (k._makeempty();;) { h._nextel(k); if (k._isempty()) { break; } result[result._length()] = k; } if (sorted) { result._sort(); } return result; }
Using this function, you can iterate through the items of a hash table by looping over its keys. The snippet below shows the function in action. Note that hash table keys are not sorted normally. (This is normal for hash data structures.) The convenience function wrox_hash_keys() sorts the result by default before returning it.
_str b[] = wrox_hash_keys(h); wrox_assert_equals(first, b[0]); wrox_assert_equals(second, b[1]); wrox_assert_equals(third, b[2]);
322
As with arrays and hash tables, you can declare and initialize structs globally:
NAMES name = { John, Hurst };
However, be aware that in Slick-C, assignment is a deep copy (not a shallow reference copy such as in languages like Java). This example would therefore be a very inefficient way to implement a linked list, because adding an item would copy the whole list, unless the code is careful to traverse to the end of the list using pointers and then add the new item.
323
The documentation for _varformat() warns that its behavior is likely to change in a future version of SlickEdit, thus you should be wary of using it. SlickEdit 2008 adds classes and changes the implementation of structs. In SlickEdit 2008, there is a new _varformat(), VF_OBJECT, which represents a struct or class instance.
Control Structures
Slick-C control structures are basically the same as in C, with a few minor enhancements because of the more dynamic nature of Slick-C. Whenever you create a block, it creates a new scope for local variables. This is the same as most modern C-style languages. This does allow you to re-use the same name for a new variable in a new scope:
int x = 1; { int x; x = 3; } wrox_assert_equals(1, x);
However, such usage is confusing and is not recommended. Its treated as a compilation error if you are using #pragma option(strict, on). The if() statement is straightforward:
int i = random(0, 10); if (i < 5) { wrox_assert(i < 5); } else { wrox_assert(i >= 5); }
324
Some people also like to use the for() loop for an unknown number of iterations:
for (;;) { // loop forever if (random(0, 10) < 1) { break; } }
The while() statement is more commonly used for loops with an unknown number of iterations, when the loop condition should be tested before executing the first iteration:
_str head, rest = 1,2,3; int i = 0; parse rest with head,rest; while (head != ) { wrox_assert_equals(++i, head); parse rest with head,rest; } wrox_assert_equals(3, i);
If the loop always should be executed at least once, the do() statement places the condition test at the end:
_str head, rest = 1,2,3; int i = 0; do { parse rest with head,rest; if (head != ) { wrox_assert_equals(++i, head); } } while (head != ); wrox_assert_equals(3, i);
Unlike most compiled languages, the Slick-C switch() statement can use strings as case targets, which is a great convenience:
_str month = May; int mm; switch (upcase(month)) { case JANUARY: mm = 1; break; case FEBRUARY: mm = 2; break; case MARCH: mm = 3; break;
325
You should note that switch() using strings is really a syntactic convenience. The Slick-C compiler currently does not generate a jump table for switch statements.
Functions
Weve already seen many examples of function definitions in this book. A definition includes the full function body. You can also write function declarations. A declaration includes the name, arguments, and return type of the function. Declarations are also known as prototypes and are commonly placed in header files. The purpose of declarations is to give the compiler more information about functions so that it can catch more errors at compile time. By default, Slick-C resolves function references at run time; thus it is legal to make use of any Slick-C function in code without declaring it. There is no check at compile time whether the function actually exists. While this is convenient and typical in dynamic languages, it does mean that you can accidentally mistype a function name and the compiler will not inform you of your error. Instead, the error will manifest itself at run time when Slick-C attempts to invoke the function. As of SlickEdit 12.0.2, you can enforce declaration checks using this #pragma at the top of your file:
#pragma option(strictprotos, on)
With this option, a prototype declaration or full definition is required before any use of a function.
326
If you specify a default for any argument, all the arguments after that must also have default arguments. Specify variable arguments with in the function signature, like this:
void wrox_multimessage(_str m, ...) { _str messages = m; int i; for (i = 2; i < arg(); i++) { messages = messages \n arg(i); } _message_box(messages); }
When you use variable arguments, access them using the arg() function. Call the arg() function with no arguments to get the total number of arguments to the current routine. Call arg() with an argument number to retrieve that argument. Default arguments are a newer feature in Slick-C than variable arguments. In older code, you may find variable arguments being used when defaults would be more appropriate. For example, an alternative way to implement wrox_leftstr() using variable arguments is shown here:
_str wrox_leftstr(_str string, int len, ...) { _str pad = ; _str result = ; if (arg() >= 3) { pad = arg(3); } if (length(string) > len) { result = substr(string, 1, len); } else { result = string :+ translate(indent_string(len - length(string)), pad, ); } return result; }
In this case, the previous implementation using default arguments is clearer, and there is no need for variable arguments in defining wrox_leftstr(). Use variable arguments when you have a truly variable number of arguments, rather than simply optional arguments, which are better handled with default values.
327
Thus, L and the slash are valid alternative names for the command. The same feature applies in a similar way to the goto-line command (the shorthand is simply typing the desired line number as a command), and commands for moving up or down a given number of lines (the shorthands are - and +). However, this feature is not something you are likely to use in your own commands. The underscore character is commonly used in Slick-C identifiers. Commands containing underscores are displayed with the underscores changed to hyphens and can be entered that way too. Commands are defined the same way as functions, with some differences. Command definitions are preceded by the _command keyword, and they optionally have a name_info() expression after the argument list. The _command keyword simply indicates that the definition is a command. The optional name_info() expression specifies types of arguments accepted by the command, and the valid context for it. The name_info() expression is a string consisting of two parts, separated by a comma. The first part specifies the type of argument for the command, which is used on the command line to provide argument completion. It should be an _ARG value from slick.sh. Some of the most useful argument values are shown in Table 16-4.
Table 16-4
Argument Value
COMMAND_ARG BOOKMARK_ARG FILE_ARG DIR_ARG TAG_ARG
Description The command takes a SlickEdit command name as an argument. The command takes a bookmark name as an argument. The command takes a filename. The command takes a directory. The command takes a tagged procedure.
SlickEdit uses the argument information to provide completion for command arguments. For example, if you specify FILE_ARG for your command, SlickEdit can complete filenames on the command line for
328
If the user types the command name, presses Space, and starts typing a filename, SlickEdits completion features help the user complete the filename. If the user types just the command name and presses Enter, SlickEdit prompts on the command line for the Filename parameter. Because of the name_info() specifying a file argument, prompt() supplies auto-completion for the filename. SlickEdit commands such as name and edit use this facility. If your command takes a command-name argument, you can write it like this:
_command void wrox_try_prompt_command(_str command=) name_info(COMMAND_ARG,) { command = prompt(command, Command); // ... rest of command }
This time prompt() auto-completes command names, because name_info() specifies a command argument. The second part of the name_info() expression specifies the valid context for the command and should be a combination of VSARG2_ values from slick.sh. Some of the common ones are shown in Table 16-5.
Table 16-5
Argument Value
VSARG2_CMDLINE VSARG2_EDITORCTL VSARG2_READ_ONLY VSARG2_REQUIRES_EDITORCTL VSARG2_REQUIRES_AB_SELECTION VSARG2_REQUIRES_SELECTION
Description The command is supported on the command line. The command is supported in an editor control. The command is allowed in read-only mode. The command requires an editor control. The command requires a selection in the active buffer. The command requires a selection.
329
The second part of the name_info() expression is VSARG2_REQUIRES_AB_SELECTION, which indicates that the command requires a selection in the active buffer. If you have a buffer open, but no selection, SlickEdit displays the message Command is disabled for this object. Only when the conditions are valid will SlickEdit execute the command. Both parts of the name_info() expression are optional, as is the whole expression. If you leave either part out, it simply means that SlickEdit is less able to provide help with the arguments and context of your command. This is often not a big deal for user-written macros, but it is certainly a good feature for many of the SlickEdit-provided commands. The VSARG2_ constants cover a variety of standard contexts for commands. For scenarios that arent covered by these standard contexts, you can write a callback function to determine whether a command is valid. The callback functions name should be the commands name prefixed by _OnUpdate_. For example, a callback for wrox-save-line-sel would be declared:
int _OnUpdate_wrox_save_line_sel() { // ... }
The callback should return MF_ENABLED if the command is allowed and MF_GRAYED if the command is not allowed. (These constants are declared in slick.sh.)
Global Variables
If you declare a variable outside any function, it is global and is shared across the entire Slick-C environment. If you want to share a global variable across multiple Slick-C modules, its best to declare it in a header file, then #include that header file in any module that needs to reference the global variable. You still need to define and initialize the global variable in a specific module. That module owns the global variable.
Static Variables
If you declare a variable outside a function but use the static keyword in the declaration, the variable is static but not global. A static variable is visible to any code in the module (i.e., the current .e file). If you declare a static variable with the same name in two different files, each has its own copy of the variable. Use static variables for global data within a module, and use global variables for global data that need to be shared across different modules.
Macro Variables
Macro variables refer to Slick-C variables containing configuration settings to control SlickEdit features. Most of the macro variables names start with def_.
330
Event Tables
Event tables are special declarations that are used primarily to bind commands to shortcut keys. There is a default event table, called default_keys. There is also an event table for each language mode, such as c_keys, java_keys, and xml_keys. Definitions for specific modes override the defaults in default_keys. There are also event tables for certain special modes in the editor, shown in Table 16-6.
Table 16-6
Event Table Name
argument_completion_keys auto_complete_keys fileman_keys grep_keys process_keys
Description Argument completion. When Auto-Complete active. File Manager. Search Results tool window. Process Buffer.
To specify key bindings for an event table, first specify the desired event table using defeventtab. Then define key bindings using def:
defeventtab html_keys; def A-/= wrox_insert_html_ending_tag;
You should always specify an event table using defeventtab, but if you dont, the default is default_keys. We cover programmatic key binding with event tables more in Chapter 17. More information on event tables can also be found in the Slick-C Macro Programming Guide.
331
If you bind this command to a key, you can execute the Slick-C command you are editing at any time. For example, I have it bound to Alt+Shift+equals, which is easy to remember because it is similar to Alt+equals (the default binding for execute-selection). This works well for commands that have no arguments.
Terminating a Macro
If your macro goes into an endless loop or is running for too long for any other reason, you can halt it by pressing the macro break key combination: Ctrl+Alt+Shift+F2. For some reason, I found this key combination really hard to remember for years. You might want to write it down somewhere just in case, because if you need it, you really need it.
Writing Messages
A fundamental technique for debugging in all programming languages is outputting debug messages from your code. Slick-C provides several built-in ways to display debug messages. You can display a message in the message area of the editor using the message() function:
message(Hello, World.);
This function can be used in debugging but is also commonly used for ordinary status messages. Be aware that as soon as another routine calls message(), the previous message will be replaced. Therefore, message() is not suitable for complex debugging with a lot of messages. It can be quite handy for simple debugging though.
332
This function is very useful for debugging because it causes a refresh so that you can see where the cursor is and what changes have been made to the file at each point where you call messageNwait(). If you want to display a message more dramatically, you can use _message_box() instead. This pops up a message box with the given message. The user must dismiss the message box by clicking OK before the calling macro continues.
_message_box(Hello, World.);
These functions for displaying a message are occasionally useful for debugging but are also quite valid for normal use in macros. Finally, there is the say() function, which really is just for debugging:
say(Hello, World.);
This function also takes its name from the REXX equivalent. The say() function outputs its messages to the vsapi.dll output window on Windows, as shown in Figure 16-2. On UNIX, it writes to stdout, and on Mac OS X, output is written to a console log, for example, /Library/Logs/Console/501/ console.log.
Figure 16-2
If you see the vsapi.dll window appear while using SlickEdit and you havent put any debug code into macro files yourself, it usually means youve hit some debug code of the SlickEdit team. There are plenty of references to say() in the supplied sources, but most of them are intended to be invoked only in debugging scenarios.
Stack Traces
Consider the command wrox-makestacktrace, shown below. The command calls the wrox_ stacktrace1() function, and this function calls the wrox_stacktrace2() function. The wrox_stacktrace2() function contains an illegal expression, where it attempts to add 1 to a null value. This results in SlickEdit aborting the function and displaying a stack trace.
_command void wrox_makestacktrace() name_info(,) { wrox_stacktrace1(); } void wrox_stacktrace1() { wrox_stacktrace2();
333
SlickEdit displays the stack trace in the Slick-C Stack tool window, shown in Figure 16-3.
Figure 16-3
You can programmatically update the Slick-C Stack tool window by calling _UpdateSlickCStack() in your code. You can dump the stack to the console debug output (vsapi.dll, stdout, etc.) at any time by calling _StackDump(). Finally, if you get a stack dump due to an error, the stack dump is also written to a log file (vs.log in your configuration directory). You can navigate to any frame of the stack trace in the Slick-C Stack tool window by moving the cursor to the line and pressing Enter, or by double-clicking. If you note the offset reported in the stack trace, you can also navigate to it directly in the module using the st command with the f option. For example, in Figure 16-3, the first stack frame is in wrox_stacktrace.ex at offset 67. To navigate to the corresponding source line, you can open wrox_stacktrace.e and invoke this command:
st -f 67
Usually the cause of a stack trace is pretty clear from the source code combined with the error message.
334
You can find objects matching a given name prefix using the name_match() function. The function takes a prefix for the names you want to match, a flag to indicate first match or next match, and flags to indicate the kinds of objects you are interested in. It returns an index into the global names table, or 0 if nothing is found. You can then use the name_name() and name_type() functions to find out about the symbol given its index. For example, you can use this function to obtain an array of name indexes of objects matching given criteria:
typedef int INTARRAY[]; INTARRAY wrox_find_matching_name_indexes(_str prefix, int name_type_flags) { int result[]; int index = name_match(prefix, 1, name_type_flags); while (index) { result[result._length()] = index; index = name_match(prefix, 0, name_type_flags); } return result; }
The names table holds information about objects other than commands and functions. For example, it holds all the global variables too. You can query the value of an integer or string global variable with a given name like this:
int index = find_index(varname, VAR_TYPE); if (!index) { message(Variable varname not found.); return; } if (index) { typeless value = _get_var(index); message(varname=[value]); // integer or string only! }
335
Table 16-7
Type
PROC_TYPE VAR_TYPE EVENTTAB_TYPE COMMAND_TYPE MODULE_TYPE PICTURE_TYPE BUFFER_TYPE OBJECT_TYPE MISC_TYPE IGNORECASE_TYPE
Description Matches global function. Matches global variable. Matches event table. Matches command. Matches module. Matches picture. Matches buffer. Matches object. Matches miscellaneous. Matches case-insensitive search.
You can use the name_match() function with these types to find out more about objects in the Slick-C environment. For example, you can list all loaded modules using this command:
_command void wrox_try_list_modules() name_info(,) { int index = name_match(, 1, MODULE_TYPE); while (index) { insert_line(name_name(index)); index = name_match(, 0, MODULE_TYPE); } }
The commands output includes all modules: user-defined and SlickEdit-supplied. If you want to know the names of all the modules you have loaded, you can get them from the macro variable def_macfiles. This contains a space-delimited list of filenames of all .ex files loaded by the user.
Useful Techniques
The previous section concerned techniques for working with macros themselves: various ways of executing and debugging them. Now we turn our attention to how you can actually put macros to use to perform useful tasks in SlickEdit. In this section, we cover several common techniques for using macros to do things in the editor.
336
The default value for the seek position is a special negative value, which causes the function to use the current cursor position. The default value for the character count is 1. Thus, get_text() with no arguments returns the character at the current cursor position. The get_text() function is particularly useful when combined with search(), as explained below. A macro can also retrieve the current line from the buffer using the get_line() function. The function retrieves the line into the variable given as an argument:
_str the_line; get_line(the_line); // retrieves current line into var
Alternatively, macros can insert whole lines using the insert_line() function:
insert_line(end;); // adds line after current line
A macro can also delete text from the buffer using the _delete_text() function:
_delete_text(10); _delete_text(-1); _delete_text(-2); // deletes 10 characters // deletes to end of line // deletes to end of buffer
You can also delete the entire current line with _delete_line(). There is also a delete_line() command (no leading underscore), but this is not usually appropriate for general macro use because it is hooked into the auto-unsurround feature.
Searching
Its frequently useful in a macro to search for text in the buffer. You can invoke the find command, which is the same as the slash (/) command on the command line. However, this command is intended for interactive use and is not generally used internally by macro code. If you invoke find in your macro, it
337
Many of the same options you would use with find on the command line are also useful with search() in macro code, such as + and to search forward and backward, m to search in the selection, and so forth. A couple of options you should consider using with search() specifically in macro code are h and @. The h option causes search() to find text in hidden lines as well as visible lines. This can make your macros more robust, in case selective display happens to be active when the macro is running. The @ option prevents search() from displaying an error message if nothing is found. If you are testing the result of search() in your macro code, you can decide in the macro whether it is an error if nothing is found. Usually it is not an error, but just another possible scenario for the macro to deal with. If your search uses a regular expression with tagged subexpressions, you can extract the text matching the subexpressions from the editor using get_text() with match_length(), as shown in this example:
int status = search(created date.*(\\:d{4}-\\:d{1,2}-\\:d{1,2}), UI); if (!status) { message(Created date = get_text(match_length(1), match_length(S1))); }
This example code searches for the text created date, followed by a date in ISO format (yyyy-mm-dd). If a match is found, the macro shows the date in the message area. The U option indicates that the search is for a UNIX-style regular expression, and the I option makes it case-insensitive. The macro extracts the date from the editor using the get_text() function. The match_length() function returns character counts and seek positions suitable for get_text(). When match_length() is called with a string representing a tagged subexpression group number, for example, 1, it returns the length of the match on that subexpression. When match_length() is called with an S followed by a group number, it returns the seek position for the match on that subexpression. Thus get_ text(match_length(1), match_length(S1)) means the text in the buffer matched by the first tagged subexpression. Similarly, you can use 2 and S2 for the second subexpression, and so forth. If you specify 0 and S0, you get the entire matched text.
338
You can use save_search() and restore_search() to save and restore the current search data. This allows you to write functions that use search but do not disturb existing searches, so that you can nest one search in another search. Here is an example from the save_search() documentation:
search(test); save_search(string, options, word_re); status = search(xyz); if (status) { messageNwait(Cant find xyz); } restore_search(string, options, word_re); // Repeats search for test repeat_search();
Selections
Macros can allocate and use multiple selections, activating them as required. Several primitive functions exist for managing selections. They are well documented in the online Help, under the category Selection Functions. To get the selection type of the active selection, use the _select_type() function with no arguments. The result is BLOCK, CHAR, or LINE according to the selection type, or a null string if no selection is active. To iterate over a line selection, use the filter_init(), filter_get_string(), and filter_restore_pos() functions like this:
filter_init(); for (;;) { _str line; int status = filter_get_string(line); // fetch next line into variable if (status) { break; // status is non-zero when no more lines } // do something with the line } filter_restore_pos();
Temporary Buffers
A common requirement in more elaborate macros is to have a scratch pad buffer to place results while the macro is working. Well see one application of this in the next section, where we find out how to work with lists of files and directories. The situation arises often in the supplied macro source code, and SlickEdit supplies some functions specifically for creating and managing temporary buffers.
339
You can open an existing file in a temporary buffer with _open_temp_view(). The advantage of this in a macro, rather than opening the file normally using edit(), is that the buffer is hidden. This lets you open a file, do something, and close it, without the user seeing the activity on screen.
Table 16-8
Option
H
Description Includes hidden files (Windows only). Default is ON in Windows if Explorer is set to show all files. Includes system files. Default is ON in Windows if Explorer is set to show all files. Includes archive files. Default is OFF. Includes directories. Default is OFF. Appends path to filenames. Default is OFF.
S A D P
340
Description Recursive: includes files in subdirectories. Default is OFF. Includes UNIX dot files. Default is ON. Verbose output with size, date, attributes. Default is ON.
By default, files are listed with their sizes, dates, and attributes, as with the DOS dir command. You can omit the extra information and list the file names only with V. For example, to list macro source files into the buffer, including their paths but excluding other attributes, you could use this code:
_str macro_filespec = maybe_quote_filename(get_env(VSLICKMACROS) :+ *.e); insert_file_list( +P -V -D macro_filespec);
Often when dealing with lists of files and directories, the desired end result is not to see them listed in a buffer but to actually do something with them. The following simple function lists files and returns them in an array, rather than leaving them in a buffer. This makes it a little more natural for calling macro code to iterate through the list of files. The function takes a single argument, almost identical to that for insert_file_list().
STRARRAY wrox_list_files(_str command) { int filelist_view_id; int orig_view_id = _create_temp_view(filelist_view_id); _str result[]; insert_file_list(-V command); top(); up(); while (!down()) { _str filename; get_line(filename); filename = strip(filename); if (filename == ) { break; } result[result._length()] = maybe_quote_filename(filename); } _delete_temp_view(filelist_view_id); activate_window(orig_view_id); return result; }
This function uses a couple of the techniques weve looked at. First, it creates a temporary buffer. Then it lists files into the temporary buffer using the supplied criteria. Notice that it adds V to the criteria, to limit the output to filenames only, suppressing other attributes. This function is not intended to list other attributes.
341
Choosing Files
When you want to allow the user to choose one or more files for your macro to process, you can present a customized File Open dialog using the Slick-C _OpenDialog() function. The function takes several arguments, documented in the online Help. Heres an example:
_command void wrox_try_open_dialog() name_info(,) { _str files = _OpenDialog( -modal _open_form, // form and mode Choose files to list, // title *.e;*.sh, // initial exts All Files (*.*),C/C++ Files (*.c;*.cpp;*.h),Slick-C Files (*.e;*.sh), OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST, // flags , // default ext , // initial filename // initial directory ); while (files != ) { _str file; parse files with file files; insert_line(file); } }
This command shows some of the options to _OpenDialog() in action. It prompts the user to select one or more files, and then lists their names in the buffer. By using different arguments, you can specify defaults and limit the types of files to be selected. You can also specify a callback that the _OpenDialog() function will call before presenting a list, so that you can screen the files being offered to the user. There are many examples of _OpenDialog() in the supplied macro source.
342
Description Built-in functions and properties. Includes operations for arrays and hashes, some basic window and menu functions, global properties, and low-level (primitive) functions. All of these functions and properties are implemented natively. The builtins.e file only declares them: There is no Slick-C implementation. Declares many macro variables, provides default values. Defines many standard commands, e.g., undo, redo, nosplit-insert-line, begin-line, top-of-buffer. Defines many standard functions, e.g., abs(), strip_filename(), maybe_quote_filename(), path_exists(), _create_temp_view(), _delete_temp_view(). Defines more standard commands, e.g., scroll-up, scroll-down, center-line, sort-on-selection, asc, chr, execute-selection, goto-line, select-mode, block-insert-mode. Quite useful for seeing how these work.
main.e stdcmds.e
stdprocs.e
util.e
Callbacks
Callbacks are Slick-C functions you write that SlickEdit will call whenever certain events occur. For example, you can have a callback that is invoked whenever a project is opened. You create callbacks by writing Slick-C functions following a certain naming convention. Callback functions are named _event_name(), where: _event_ is the name of the callback event, and
name is a name you give to the function to make it unique and to indicate its purpose.
Callback event names start with an underscore, and almost always end with one too. For example, here is a callback function from Chapter 5, which pops all bookmarks whenever a workspace is closed:
void _wkspace_close_popallbkms() { pop_all_bookmarks(); }
The event name for this callback is _wkspace_close_, and what the callback does is indicated by the popallbkms part of the function name. The _wkspace_close_ callback takes no arguments. Some callbacks can be provided with arguments giving more information about the event. For example, there is a _buffer_renamed_ event that occurs when a buffer is renamed. Callbacks for _buffer_renamed_ are provided with four arguments: Buffer ID. Old name.
343
You can write a callback to be called whenever a buffer is renamed, using this signature:
void _buffer_renamed_wrox_example(buf_id, old_name, new_name, buf_flags) { // your code here ... }
Table 16-10 shows some of the callback events available in SlickEdit 12.0.2, with a description for each and a list of the arguments provided to the callback. A more complete listing is in Appendix C.
Table 16-10
Name
_actapp_
_buffer_add_
Buffer ID, buffer name, buffer flags. Buffer ID, buffer name, new name, buffer flags. Buffer ID, buffer name, filename, buffer flags. Buffer ID, buffer name, filename, buffer flags. (none) (none) New directory. (none) (none) Buffer ID, old name, new name, buffer flags. Key binding table, key. (none) (none)
_buffer_renamed_
Buffer renamed.
_cbquit_
_cbquit2_
File saved. Stopping build. Directory changed. End of DIFFzilla operation. Start of DIFFzilla operation. Document name changed.
344
_prjclose_
Closing project (but fired only if not saving state during auto restore see source in wkspace.e). Active configuration changed. Project properties edited. Opening project. Project saved. Closing project. File added to project. Switching buffer.
(none)
(none) (none) (none) (none) Project name. Project name, filename. Old buffer name, option, old pos, old buffer ID. (none) Project name, filename. (none)
SlickEdit looks up and invokes callbacks using the call_list() function defined in files.e in the supplied macro source. By examining references to call_list(), you can find all the places in SlickEdit where callbacks are invoked, what they are called, and what arguments are supplied. For example, when you use the name command to rename a buffer, eventually during the execution of this command, the name_file2() function is called, defined in files.e. The name_file2() function looks like this:
int name_file2(_str new_name) { call_list(_buffer_renamed_,p_buf_id,p_buf_name,new_name,p_buf_flags); p_buf_name= new_name; docname(); return(0); }
345
If you want to understand the context and parameters of a particular callback better, you need to study the Slick-C code invoking the callback. You can search for a callback identifier from Table 16-10 using Find in Files, or you can search references to the call_list() function to find all places where callback events are dispatched. One interesting way to study the behavior of callbacks is to set up tracing for them. For example, if you load this code, it will output a message to the vsapi.dll window whenever the _switch_buffer event occurs:
void _switchbuf__trace() { say(_switchbuf_ called); }
You can generate similar trace code for other events. In the Example Macros section below, we give a macro that can generate trace calls like this for all callbacks defined in SlickEdit.
Example Macros
This chapter has contained a small amount of definitions and theory about Slick-C, but most of the focus has been on practical use of Slick-C for macro programming. In this section, we give several examples of more elaborate macros. These examples put the techniques together to make complete applications. As with the rest of this book, these examples are supposed to be practical and useful. (Well, most of them.) But the main point of them is to show how you can customize and extend SlickEdit for your own needs. In years of using SlickEdit, Ive written many macros specifically for work I was doing at the time. In some jobs, Ive worked with obscure scripting file formats with no tool support. I wrote SlickEdit macros to provide the support I needed. In another job, I worked for a client whose C++ coding style standard was, I believe, unique in the world. I created SlickEdit macros to beautify my code into his style. Any time you find yourself doing repetitive editing, consider whether it can be automated with Slick-C. You will often find that writing a Slick-C macro takes less time than editing the tedious way. Its more fun, too. And, as with everything, the more you do of it, the faster and better you become. SlickEdit is the kind of tool that really rewards long-time use and investment. As with other source code presented in this book, the full source for these examples is on the accompanying CD-ROM, under /Author/Chapter16. Updates and bug fixes are also available online.
346
347
This macro uses the filter_selection() functions to iterate through the selection. It stores the lines themselves in the key[] array and the counts in the data[] array. When outputting the revised lines, it uses the wrox_leftstr() and wrox_rightstr() functions from above in this chapter to pad the results. Another nice feature is that if there are no duplicate lines, then the macro adds no counts it effectively leaves the data unchanged. Suppose you run this command with a selection containing these data:
one two two three three three ten ten ten ten ten ten ten ten ten ten
Like SlickEdits remove-duplicates command, this command takes an optional string parameter which, if I, causes the macro to compare lines case-insensitively.
348
349
The macro tries to insert the appropriate closing tag at the current location. It searches backward for opening and closing tags, keeping a stack of tags it has found. When it encounters a closing tag, it pushes it on the stack. When it encounters an opening tag, it pops the stack and matches it with the top of the stack. If it finds an unexpected opening tag, it reports an error. When it encounters an opening tag and theres nothing left to pop, thats the tag that needs to be ended. The macro inserts a closing tag in the buffer. If the start tag is on the same line as the cursor position, the macro inserts the closing tag at the cursor position. Otherwise, it adds a new line and inserts the ending tag indented to the same level as the start tag. XML rules are very strict: In XML, all opening tags must be matched with closing tags. HTML, particularly older HTML, is more lax. Some tags are often specified as opening tags with no closing tags. Common examples of tags like this are <br> and <img>. The macro has special processing to be tolerant of these tags if they are not closed. Suppose you start with a file like this:
<html> <head> <title>Title</title>
350
If your cursor is after the one on the last line and you invoke wrox-insert-html-ending-tag eight times, the macro will fill in the ending tags, indented correctly, like this:
<html> <head> <title>Title</title> </head> <body> <p>Paragraph.</p> <p>Paragraph. <img src=xxx>xxx <table > <tr> <td> <ul> <li>one</li> </ul> </td> </tr> </table> </p> </body> </html>
To be effective, this macro should be bound to a key. I usually have it bound to Alt+slash, in HTML and XML modes.
351
352
The commands work very similarly. First they test to see if there is a character selection. If there is, they convert it to a line selection. Then there are two cases, one for a line selection and the other to work with the current line. In each case, there is logic to move the cursor to the appropriate new location and move the line(s) there. The commands each take an optional number argument, which can be used to say how far to move the lines. The default is to move only one line up or down. You can bind the commands to keys for convenient use. The keys Alt+Up and Alt+Down are bound to prev-paragraph and next-paragraph in the CUA emulation. If you prefer, you can use those keys for wrox-move-line-up and wrox-move-line-down:
defeventtab default_keys; def A-Up=wrox_move_line_up; def A-Down=wrox_move_line_down;
Alternatively, select some key combinations that are not already used.
You can use a SlickEdit macro to generate this code for all SlickEdit macros by scanning the supplied macro source for callback invocations. First, define a function wrox_list_callbacks() like this:
#define CALL_LIST_PATTERN call_list\(([])(\:v)\1 STRARRAY wrox_list_callbacks() { _str macro_filespec = maybe_quote_filename(get_env(VSLICKMACROS)*.e); // NOTE: on Mac OS X VSLICKMACROS may not include a trailing slash ... (!) _str files[] = wrox_list_files(+P -D macro_filespec); int i; _str callbacks:[]; for (i = 0; i < files._length(); i++) { _str filename = files[i]; int temp_view_id; int orig_view_id = _create_temp_view(temp_view_id); get(filename); // loads file contents into temp buffer top(); int status = search(CALL_LIST_PATTERN, U@>); while (!status) { _str callback = get_text(match_length(2), match_length(S2));
353
The function first lists all macro source files into an array, using the wrox_list_files() function from above in this chapter. Then, it loads a copy of each macro source file into a temporary buffer created by the _create_temp_view() function. The real work is in the loop, which uses a simple regular expression to search for each invocation of call_list(). For each invocation, the function adds the prefix pattern [the first argument to call_list()] to the set stored in the callbacks hash table. After the loop, the function returns the keys of the callbacks hash table. The result of the function is an array with all the callback event names. With this function in place, you can proceed to define a couple of commands to generate the trace functions:
_command void wrox_make_callback_trace(_str callback=) name_info(,VSARG2_REQUIRES_EDITORCTL) { insert_line(void callback_trace() {); insert_line( say(\callback called\);); insert_line(}); insert_line(); } _command void wrox_foreach_callback(_str command=) name_info(COMMAND_ARG,VSARG2_REQUIRES_EDITORCTL) { command = prompt(command, Command); _str callbacks[] = wrox_list_callbacks(); int i; for (i = 0; i < callbacks._length(); i++) { execute(command callbacks[i]); } }
To generate macro source for callback trace functions using this code:
1. 2.
Open a new empty buffer. Invoke this command on the command line:
wrox-foreach-callback wrox-make-callback-trace
The wrox-foreach-callback command obtains the list of callbacks using the wrox_list_callbacks() function, then invokes the given command for each callback event. The wrox-make-callback-trace command prints out a simple trace function like that shown above for each callback event. You can easily modify the wrox-make-callback-trace command to customize the trace function generated. For example, you could have the trace function print the arguments passed to the callback. The ideas in this set of macros can be easily extended to very specific searches and edits over your own code base. This can be a great way to automate some large sets of simple changes.
354
explained above, if you inadvertently load a macro file named the same as an existing Slick-C module, or containing definitions with the same name as existing commands or functions, you can alter SlickEdit functionality in ways you did not intend. However, it is not particularly convenient to have a large number of commands beginning with wrox_. The advantage is that you know where the commands came from (and whom to blame if they dont work). The disadvantages are that the commands are unnecessarily long to type, and auto-complete is not as effective. If you decide to incorporate some or all of the commands presented in this book into your own installation of SlickEdit, you may wish to consider dropping the wrox_ prefix, in order to make the commands easier to use. Of course, you wouldnt want to have to edit all the source files by hand to do this. Also, you need to be careful that none of the shortened command names actually do conflict with supplied SlickEdit definitions. The macro in this section can automate this conversion task:
#define WROX_FUNCTION_NAME wrox_(\:v)\( #define WROX_DEF def (.*)= *wrox_(\:v); #define WROX_TYPES (PROC_TYPE | VAR_TYPE | COMMAND_TYPE) _command void wrox_convert_wrox_names(_str path = ) name_info(DIR_ARG,VSARG2_REQUIRES_EDITORCTL) { path = prompt(path, Path to WROX source files); push_bookmark(); insert_line(#include slick.sh); _str macro_filespec = path/*.e; _str files[] = wrox_list_files(+P +T -D macro_filespec); int i; int file_count = 0; for (i = 0; i < files._length(); i++) { _str filename = files[i]; if (pos(wrox_try, filename) > 0) { continue; // skip wrox_try files: theyre for testing/demo purposes only } int temp_view_id; int orig_view_id = _create_temp_view(temp_view_id); get(filename); // loads file contents into temp buffer top(); if (!search(defmain)) { // skip Slick-C batch macro files pop_bookmark(); _delete_temp_view(temp_view_id); continue; } file_count++; int status = search(WROX_FUNCTION_NAME, U@>); while (!status) {
355
The command takes a directory argument. It searches for .e files under that directory using the wrox_list_files() function. It skips any file containing a defmain(). These are Slick-C batch macros and are not to be converted. For each of the remaining files, it first checks that it is OK to remove the wrox_ prefix from all of the commands and functions having the prefix. Its OK to remove the prefix only if no command or function already exists with the shortened name: We dont want to redefine any pre-existing commands or functions. If any name clash is found, the macro aborts with a message about the name clash. If there are no name clashes, the macro appends the definitions from the source file into the current buffer. It then uses replace() to change the command and function names in definitions, invocations, and key bindings. Once the macro is complete, the current buffer should have all the WROX command and function definitions and key bindings from the selected directory. You should be able to load the file and have all the commands available with shorter names. Be careful about doing this. At the time of writing, all of the wrox_ commands and functions do not clash with SlickEdit commands and functions. However, in any new release or update, SlickEdit may add or rename commands or functions, creating a clash. The approach outlined here is inherently risky because the checks for name clashes occur only when you generate the new macro source file, not when you load it. If you want to be safe, you should retain some kind of namespace convention to avoid clashes.
356
Example: N-Queens
The final example is not practical, but I couldnt resist throwing it in. Now you can solve the N-queens problem right in your editor. Simply load the code below (from the CD-ROM), open an empty buffer, type wrox-queens n, and press Enter. Dont try this with n too big, or you will need Ctrl+Alt+Shift+F2! I did it with n up to 22. In case you are curious about the performance of Slick-C, it turns out that it runs just a little slower than Perl, which is among the fastest of the dynamic scripting languages.
static static static static int q_pos[]; boolean q_col[]; boolean q_diag1[]; boolean q_diag2[];
void wrox_queens_init(int size) { q_pos._makeempty(); q_col._makeempty(); q_diag1._makeempty(); q_diag2._makeempty(); int i; for (i = 0; i < size; i++) { q_pos[i] = -1; q_col[i] = false; } for (i = 0; i < 2 * size + 1; i++) { q_diag1[i] = false; q_diag2[i] = false; } } int wrox_queens_size() { return q_pos._length(); } int wrox_queens_col(int row) { return q_pos[row]; } void wrox_queens_place(int row, int col) { q_pos[row] = col; q_col[col] = true; int size = wrox_queens_size(); q_diag1[col - row + size] = true; q_diag2[col + row] = true; } int wrox_queens_unplace(int row) { int col = q_pos[row]; q_pos[row] = -1; q_col[col] = false; int size = wrox_queens_size(); q_diag1[col - row + size] = false; q_diag2[col + row] = false; return col;
357
358
Summar y
This chapter was long, and could have been a lot longer. There are several features we havent mentioned. For example, Slick-C has C-style pointers, but they arent covered in this book. I find that they are not necessary for most user macros. We also dont cover GUI programming with Slick-C. We look at it briefly in the next chapter, but not in great detail. In my experience, users of SlickEdit use Slick-C to get a job done and are not generally too interested in spending time on a fancy interface. On the other hand, the SlickEdit team does use pointers, and GUI programming, in creating SlickEdit features. You can find out anything you need to know about SlickEdit by reading the supplied macro source. The supplied macro source contains about 750,000 lines of code, and many people write to the Community Forums to ask how it all works. Of course, there is no way to distill the entire 750,000 lines into an easy guide. There is a lot to say about Slick-C. The main aim of this chapter has been to give you an introduction to some of its most useful features, some of the common ways to get things done, and get you started writing your own macros. I hope this chapter has provided enough material to give you a useful start. I encourage you to read the supplied source to learn more. (Just dont try to read it all at once.) Join the Community Forums too. Ask questions. Share your macros and ideas.
359
Customization
Throughout this book, a major theme has been to show you many ways in which you can customize and extend SlickEdit for your own needs and preferences. In the previous chapter, we went into detail about Slick-C, which is the main power tool for customization in SlickEdit. In this chapter, we continue the theme of customization. Well look at how you can fine-tune the behavior of common keyboard commands by creating your own wrapper versions for them. This is easy to do and provides an effective way in many cases of getting the editor to behave just the way you want it to. SlickEdit supports a large number of programming languages out of the box, but new languages seem to appear just about every day. There are programming languages not supported by SlickEdit, from the ancient and obscure to some of the latest cutting-edge open-source languages. Well see how you can get a certain amount of support for these languages nevertheless, using SlickEdits features for defining new modes and lexers. In the previous chapter, we looked at several ways to use Slick-C to automate tasks in the editor and to create new features of your own. You may be surprised to learn that the capabilities of Slick-C are not limited to traditional programming, but also cover GUI programming. You can customize most of SlickEdits user interface, that is, forms and menus, using GUI tools provided in the editor. You can also create your own GUI elements for use with SlickEdit using these tools, or directly in code. Well take a look at a couple of relatively simple but useful examples of editing forms and working with menus. Finally, to be a truly expert user of SlickEdit, you need to be able to take control of your configuration. That means controlling it in code, so that your configuration settings are intentional and repeatable. All SlickEdit configuration settings can be accessed and controlled from Slick-C. Well cover several examples and show how you can determine the Slick-C code required for specific configuration changes you want to make.
Keyboard Customization
Sometimes the standard behavior of SlickEdit keys is not what you want. Most of the time, various behaviors are available, such as those for Enter, Delete, and other keys, as discussed in Chapter 2. Occasionally, you may find you want completely different behavior from what SlickEdit provides. In this case, you can write your own macros and replace the SlickEdit commands bound to the keys. We saw an example of this in Chapter 6, where we replaced SlickEdits prev-word and next-word commands with wrox-prev-whitespace-word and wrox-next-whitespace-word, bound to Ctrl+Left and Ctrl+Right. Other times, the behavior for a key may be almost what you want, but not quite. In these cases, you can study the supplied source for the command bound to the key, to see whether configuration options are available. If you dont find a suitable configuration option, you may opt to write your own version of the command. A good approach to this can be to write a wrapper command that delegates to the original command but provides additional behavior.
Example: Page-Down
For example, you may have noticed that when you press Page-Down and reach the bottom of the file, you can sometimes end up with only a few lines of the buffer on screen, the bottom line of the buffer being partway up the window. In this situation, you might like Page-Down to realign the buffer in the window so that the bottom line of the buffer is at the bottom of the window. Realizing that the line-to-bottom command effectively does this very realignment, you might write a replacement page-down command:
_command void wrox_page_down_realign() name_info(,VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY) { if (p_line != p_Noflines) { page_down(); } else { line_to_bottom(); } }
You can bind this command to Page-Down by including these lines in the macro file when you load it:
defeventtab default_keys; def PGDN=wrox_page_down_realign;
This will get the command working in ordinary buffers. Recall from Chapter 13 that some modes of SlickEdit require special attention for user-defined commands on standard keys. Because Page-Down is a commonly used key in DIFFzilla, you will need to modify diffedit.e as explained in that chapter, to include wrox-page-down-realign as a supported command.
362
You can bind this command to Alt+J by including these lines in the macro file when it is loaded:
defeventtab default_keys; def A-J=wrox_join_line_with_space;
363
You can bind these commands to Tab and Shift+Tab by including these lines in the macro file when you load it:
defeventtab default_keys; def TAB= wrox_tab_matchtabs; def S-TAB= wrox_backtab_matchtabs;
For many programming languages, SlickEdits default binding for the tab key is the smarttab command. The smarttab command indents the current line if the cursor is in the white space at the beginning (and the line needs to be indented); otherwise, it calls the root event table behavior for the Tab key. These
364
You can find out more about this format at http://en.wikipedia.org/wiki/Portable_ game_notation.
365
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Invoke setupext (Tools Options File Extension Setup) to open the Extension Options dialog. SlickEdit displays the dialog. Click New to create a new extension. SlickEdit displays the New Extension dialog. Enter pgn for the Extension. Leave Refer to blank. You can use this when you add additional extensions sharing the mode of an existing one, such as the way .h files use C mode. Click OK. SlickEdit closes the New Extension dialog and creates the new mode. Click the Advanced tab. Click Color Coding. SlickEdit prompts you to confirm whether you want to start a new lexer for this extension. Click Yes. SlickEdit displays the Enter New Lexer Name dialog. Enter Portable Game Notation for the New Lexer Name. Click OK. SlickEdit displays the Color Coding Setup dialog. Click the Tokens tab. Click the Keywords category. Click the New button next to the token list. SlickEdit displays the Enter New Keywords dialog. Enter the words Event, Site, Date, Round, White, Black, and Result, separated by spaces. Click OK. SlickEdit adds the seven tokens as keywords in the PGN language. Click the Strings tab. Click the checkbox for \ represents a double quote. SlickEdit does not color code strings unless something is checked on this tab. Click the Comments tab. Click New Line comment. Enter ; for Use delimiter. Click New Multi-line comment.
366
Note that when adding tokens, you can add as many as you want at once, separated by spaces. This is great for pasting in a list of keywords. If you have a keyword that contains a space character, you can enter it in double quotes. When you open a .pgn file now, there should be some degree of syntax highlighting. The comment color coding in particular is a powerful visual cue, even for a simple file format like this one. You can use a similar technique to create color syntax highlighting support for file formats you encounter. For example, you may have particular data file formats specific to your work. By adding color syntax highlighting, you can often make these files easier to read.
You can also define classes in Groovy, similarly to Java. Heres a partial example of a class:
class Board { int size
367
Board(int size) { this.size = size this.pos = new int[size] for (i in 0..<size) { pos[i] = -1 } this.col = new boolean[size] this.diag1 = new boolean[2 * size + 1] this.diag2 = new boolean[2 * size + 1] } void place(int row, int col) { pos[row] = col this.col[col] = true diag1[col - row + size] = true diag2[col + row] = true } }
In this section, well set up limited syntax support for Groovy in SlickEdit. Well be able to provide pretty good (though not perfect) color syntax highlighting. Well also be able to provide some navigation assistance. We wont be able to provide tagging support or complete color syntax highlighting. Full tagging requires support from within the SlickEdit engine and cannot be added for arbitrary languages. Some Groovy features are beyond SlickEdits color highlighting capabilities. For example, Groovy GStrings can contain blocks of code, but theres no way to get SlickEdits string coloring to recognize this in a user-defined language. However, it turns out that even partial support is considerably more useful than no support at all. Most IDE support for dynamic languages is a lot less than for statically typed languages. It is virtually impossible to provide full syntax assistance with dynamically typed languages. SlickEdits basic text features such as word completion are extremely useful for such languages.
1. 2.
Invoke setupext (Tools Options File Extension Setup) to open the Extension Options dialog. SlickEdit displays the dialog. Click New to create a new extension. SlickEdit displays the New Extension dialog.
368
as assert boolean break case catch char class continue def default do double else extends false finally float for if implements import in instanceof int interface long new null package private property return short static switch this throw throws true try void while
15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
Click OK. SlickEdit adds the tokens as keywords in the Groovy language. Ensure that the Case sensitive option is checked. Click the Strings tab. Click the checkbox for \ represents a double quote. SlickEdit does not color code strings unless something is checked on this tab. Click the checkbox for Search for end quote across multiple lines, for both double-quoted strings and single-quoted strings. Click the Language tab. Click the checkbox for Color identifiers followed by ( as a function. This will result in method names being highlighted as they are in Java. Click the Comments tab. Click New Line comment. Enter // for Use delimiter. Click New Multi-line comment. Enter /* for the Start delimiter. Enter */ for the End delimiter. Click OK. SlickEdit closes the Color Coding Setup dialog and creates the lexer. Click OK. SlickEdit closes the Extension Options dialog.
369
Improved Navigation
In addition to syntax highlighting for Groovy language, it would be nice to have some improved navigation, beyond that provided by default in the fundamental mode. We wont be able to get tagging support, because SlickEdit doesnt have a Groovy parser and therefore wont tag Groovy files. But we can do some things. For example, we can provide rudimentary navigation between methods. For most programming languages, SlickEdit uses prev-tag (Ctrl+Up) and next-tag (Ctrl+Down) to navigate between procs. We can do something similar for Groovy. Its possible to support prev-tag and next-tag, as well as several other tagging features, in a user-defined language. To support these features, implement ext_proc_search() and/or vsext_list_tags() as described in tags.e. These procedures require some fairly complex parsing for some programming languages. The approach taken here for Groovy is a bit simpler, but not as powerful. The trick to navigating between procs or sections of code in SlickEdit is to come up with a regular expression search that is reasonably reliable at identifying the start of a proc or section of code. After considering a few things, I came up with these commands:
_command void wrox_groovy_prev_proc() name_info(,VSARG2_REQUIRES_EDITORCTL) { int cur_line = p_line; int cur_col = p_col; int status = search(^ \:w, -<UH@CO); if (!status) { if (p_line == cur_line && p_col == cur_col - 2) { p_line--; status = search(^ \:w, -<UH@CO); } } if (!status) { cursor_right(2); } } _command void wrox_groovy_next_proc() name_info(,VSARG2_REQUIRES_EDITORCTL) { int status = search(^ \:w, +<UH@CO); if (!status) { cursor_right(2); } } defeventtab groovy_keys; def C-Up=wrox_groovy_prev_proc; def C-Down=wrox_groovy_next_proc;
370
371
The defload() routine has two main parts. The first part creates the extension, mode, and event table by calling the create_ext() function. The second part adds all the lexer data to the user lexer file user.vlx. The specifics of the lines to add to the user lexer file were determined by first setting up the lexer manually and seeing what SlickEdit put in the file. The advantage of placing the lexer definitions into Slick-C code is that it can be run easily for a new SlickEdit installation, or if you reset your configuration. We take this approach to configuration further in the Programmatic Configuration section below. To install Groovy support, including the navigation routines, the extension setup, and the color coding rules, load the wrox_groovy.e module. You may need to restart SlickEdit afterward to pick up the changes to the user lexer file user.vlx. At this point you should have reasonable color coding and navigation in Groovy files.
Customizing a Dialog
As mentioned in Chapter 6, the Windows 3.1 or fast Open dialog can be preferable to the standard Open dialog for opening files with SlickEdit. The main problem with it is that it is too small. In newer versions of SlickEdit, more and more of the supplied dialogs are resizable. In a future version, we may be able to resize the Fast Open dialog with the mouse. In the mean time, we can resize it with the Form Editor. The _edit_form form is used whenever you invoke gui-open to open a file (provided you are using the fast Open dialog). For other Open dialogs, such as _OpenDialog() invoked from macros, the very similar _open_form form is used. If you want all Open dialogs to be larger, you need to change both forms.
372
1. 2. 3.
Open an empty file called edit_form_original.e. Insert this line at the top:
#include slick.sh
Invoke insert-object (Macro Insert Form or Menu Source). SlickEdit displays the Insert Form/Menu Source dialog, shown in Figure 17-1.
Figure 17-1
4. 5.
Select _edit_form. Click OK. SlickEdit closes the dialog and inserts the form source code into the buffer.
You can use this file to restore the original form at any time. To restore the form, open the file and invoke load (F12). To open the Form Editor for a form, when the form is open and has focus, press Ctrl+Shift+Space. SlickEdit puts the form into edit mode and displays its properties in a separate window. The Open dialog is shown in edit mode in Figure 17-2. The properties for the form are shown in Figure 17-3.
Figure 17-2
373
Figure 17-3
In Figure 17-3, the Open dialog starts with a width of 7,110 and a height of 5,355. To see more files and directories, you can increase the width and height by 4,000 units each, provided your screen is large enough. (The Open dialog seems to have been designed for a very small screen.) To do this, follow these steps in the Form Editor:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Add 4,000 units to the width and height properties of the form. SlickEdit resizes the form on screen so that you can see what it will look like. (You can resize with the mouse too, if you prefer. However, its hard to get precise units with the mouse.) Add 4,000 units to the y properties of all the controls under the file and directory lists. You can alter the properties of a group of controls by holding down Control or Shift to multiselect them. Add 4,000 units to the y property of the Advanced button. The Open dialog opens with the advanced controls hidden, and the height of the form when initially shown is actually based on the position of the Advanced button. Add 4,000 units to the x properties of all the controls to the right of the directory list, including the Advanced button. You now have enough space to move the directory list over and increase the sizes of the file and directory lists. Add 2,000 units to the x properties of the Directories and _opencd labels, the directory list control, the Drives label, and the drives control. Add 2,000 units to the width properties of the directory list control and the drive list control. Add 2,000 units to the width of the File name control, file list control, and file types control. When you are finished making changes to the form, click the system menu box in the top-left corner. SlickEdit displays a special system menu for the form in the Form Editor, shown in Figure 17-4. Click Save Form. Close the form and the properties dialog.
374
Figure 17-4
SlickEdit stores the form definition in the configuration state file. If you find you are resetting your configuration frequently, you probably dont want to have to resize the form manually every time you do. You can extract the form source to a source file, and load it to reset the form. To do this, follow these steps:
1. 2. 3. 4. 5.
Open an empty file called edit_form_large.e. Insert this line at the top:
#include slick.sh
Invoke insert-object (Macro Insert Form or Menu Source). SlickEdit displays the Insert Form/Menu Source dialog. Select _edit_form. Click OK. SlickEdit closes the dialog and inserts the form source code into the buffer.
You can save this source and load it any time you want to restore your changes to the form. Be aware that a new release of SlickEdit might include changes to the form. If you receive an upgrade to SlickEdit, you can check whether the form code is significantly different from what you have. To do this, extract the form code before changes using Insert Form/Menu Source, then use DIFFzilla to compare the source to your earlier version.
375
1.
Invoke open-menu (Macros Menus). SlickEdit displays the Open Menu dialog, shown in Figure 17-5.
Figure 17-5
2. 3.
Select the _mdi_menu entry from the list. This is the main menu. Click Open. SlickEdit displays the Menu Editor, shown in Figure 17-6.
Figure 17-6
You can use the Menu Editor to browse to any menu item. You can review the command associated with the menu item, and other information. You can also customize any existing menu. But any changes you make will be lost if you reset your configuration. If you want to provide menu access to your own commands, rather than changing the existing main menu structure, you can add your own pop-up menu. You can use the Menu Editor to create menus if you want, but here well take a look at how to do it using Slick-C code.
376
If you place this code in an .e file and load it, SlickEdit creates the menu resource. Next, we create a command to display this pop-up menu:
_command void wrox_show_wrox_popup_menu() name_info(,) { int index = find_index(wrox_popup_menu, oi2type(OI_MENU)); if (!index) { message(Cant find wrox_popup_menu); return; } int x = _screen_width()/2; int y = _screen_height()/3; int flags = VPM_CENTERALIGN|VPM_LEFTBUTTON; int child = index.p_child; child++; child.p_caption = -; int menu_handle = _menu_load(index, P); _menu_show(menu_handle, flags, x, y); _menu_destroy(menu_handle); } // middle across // one-third down screen
377
After you load all this code, when you press Ctrl+W, you should see the WROX commands menu, shown in Figure 17-7.
Figure 17-7
If you prefer the keyboard to the mouse, you can also create a simple command to show the SlickEdit context menu, normally invoked by right-clicking:
_command void wrox_show_context_menu() { int index = find_index(_ext_menu_default, oi2type(OI_MENU)|IGNORECASE_TYPE); if (!index) { message(Cant find _ext_menu_default.); } else { int x = _screen_width()/2; // middle across int y = _screen_height()/3; // one-third down screen int flags = VPM_CENTERALIGN|VPM_LEFTBUTTON; int menu_handle = _menu_load(index, P); _menu_show(menu_handle, flags, x, y); _menu_destroy(menu_handle); } } defeventtab default_keys; def S-F10= wrox_show_context_menu;
This code binds the command to Shift+F10, which is used for the context menu in most Windows applications. The default CUA emulation has the command project-compile bound to Shift+F10. If you prefer to keep project-compile on Shift+F10, you will need to select another key for wrox-show-context-menu.
Programmatic Configuration
If you work with SlickEdit a lot, you probably change many configuration options. If you install on a new machine, or you reset your configuration to fix a problem or for any other reason, you have to remember all your favorite settings and restore them before the editor is back working the way you like it. This can be tedious and time-consuming, and sometimes its hard even to remember all the settings. If
378
Some other configuration data are stored in other files and subdirectories under the user configuration directory. A simple approach to recovering your configuration is simply to save a backup copy of your configuration directory and restore it when necessary. This is certainly a fast and effective way to restore your exact configuration, down to files open and cursor positions. However, it suffers from several limitations: You need to back up the directory at appropriate times, that is, after any significant change to your configuration. There is no way to control, identify, or version the changes you make to the configuration. If your configuration becomes corrupted, the corruption could make it into your backup. At that point, you may have to begin from scratch to recover to a clean configuration. New features or other changes in new releases of SlickEdit may clash with data in your configuration, requiring it to be reset.
This section takes a different approach to configuration. Rather than configuring all options via the GUI and backing up the configuration data as a meaningless binary blob, well specify configuration as Slick-C source code. Weve already seen some examples of this approach. In Chapter 2, we presented the WROX emulation, a set of keyboard bindings that extends the CUA emulation. The bindings were provided as Slick-C source that you load in the editor for them to take effect. Some of the example commands we present in Chapter 16 and in this chapter are accompanied with keyboard binding code. The pop-up menu we defined above in this chapter is another example. By placing configuration into Slick-C, well get these advantages: Configuration choices are clear and explicit, and can be documented. Configuration source can be versioned, like other source files. Its easy to re-apply the entire configuration at any time. You start with a default configuration and run a script.
379
This approach does not make the GUI configuration obsolete. The GUI configuration dialogs are all still tremendously useful for experimenting with configuration options and for learning what options are available in the first place, and how they are related. Once you have learned the options you want to change and have experimented to find the settings you prefer, you can express those settings in Slick-C code for applying them in the future.
380
1. 2.
Use cd to change the working directory to the (drive and) directory where the wrox_load_modules.e file is located. Enter ./wrox_load_modules on the command line, and press Enter. SlickEdit executes the batch macro.
In the rest of this chapter, we will see how to put other configuration settings into batch macros.
Defining Aliases
When you define a global alias, it is stored in the alias.slk file in your configuration directory. When you define an extension-specific alias, it is stored in an extension-specific alias file, such as c.als, java.als, e.als, and the like. These files are ordinary text files, and you can edit them normally. Thus you can simply edit and version the alias files to manage them, because their contents are transparent. Alternatively, you can define aliases programmatically in the batch macro too. Heres an example of a batch macro to define several of the aliases weve seen in this book:
defmain() { int temp_window_id; int orig_window_id = _create_temp_view(temp_window_id); // fundamental mode alias(hosts C:\Windows\system32\drivers\etc\hosts); alias(cpr Copyright %\m wrox_ year% John Hurst); alias(local C:\cygwin\usr\local\); alias(pdir %\m wrox_project_dir%); alias(bdir %\m wrox_buffer_dir%); select_mode(Slick-C); alias(_command _command void %\c(%\c) name_info(%\c,%\c) {%\m nosplit_insert_line%}); _delete_temp_view(temp_window_id); if (orig_window_id) { activate_window(orig_window_id); } }
This macro uses a temporary buffer to ensure that the first bunch of aliases are defined in fundamental mode, and are thus global aliases. Then it switches to Slick-C mode to define the _command alias, which is an extension-specific alias. Note also that the _command alias expansion is more than one line. Its easy enough to enter multiple lines in the alias editor. One way to get multiline alias expansions when defining them programmatically is to embed a newline command such as nosplit_insert_line into the alias, as shown here. You can also place global aliases in files of your choice. The environment variable VSLICKALIAS can define one or more files containing global alias definitions. Separate the filenames with ; (a semicolon) on Windows and : (a colon) on UNIX. The VSLICKALIAS variable doesnt work for extension-specific aliases.
381
382
// // // //
Use Windows 3.1 / fast-open dialog allow def Alt keys for commands preserve column on top/bottom turn off toolbar autohide animation
Font Settings
Fonts are particularly attractive to set programmatically. Most programmers have a favorite programming font and would prefer to use it for most of the SlickEdit UI elements that involve display or editing of code. The GUI for configuring fonts is flexible because it lets you choose a different font for different elements. But this makes it tedious when you simply want to set the same font for a bunch of elements. Fortunately, its rather easy to do this programmatically. Below is a batch macro that sets Bitstream Vera Sans Mono as the font for these UI elements: Selection lists. DIFFzilla editor window. File manager. Hex mode. SBCS editing. Unicode editing.
defmain() { set_var(def_sellist_font Bitstream Vera Sans Mono,10,0,1,); _default_font(CFG_DIFF_EDITOR_WINDOW, Bitstream Vera Sans Mono,10,0,1,); _default_font(CFG_FILE_MANAGER_WINDOW, Bitstream Vera Sans Mono,10,0,1,); _default_font(CFG_HEX_SOURCE_WINDOW, Bitstream Vera Sans Mono,10,0,1,); _default_font(CFG_SBCS_DBCS_SOURCE_WINDOW, Bitstream Vera Sans Mono,10,0,1,); _default_font(CFG_UNICODE_SOURCE_WINDOW, Bitstream Vera Sans Mono,10,0,1,); setall_wfonts(Bitstream Vera Sans Mono,10,0,1, CFG_DIFF_EDITOR_WINDOW); setall_wfonts(Bitstream Vera Sans Mono,10,0,1, CFG_FILE_MANAGER_WINDOW); setall_wfonts(Bitstream Vera Sans Mono,10,0,1, CFG_HEX_SOURCE_WINDOW); setall_wfonts(Bitstream Vera Sans Mono,10,0,1, CFG_SBCS_DBCS_SOURCE_WINDOW); setall_wfonts(Bitstream Vera Sans Mono,10,0,1, CFG_UNICODE_SOURCE_WINDOW); }
Obviously, you need to have the font installed for this macro to work. The selection list font is actually controlled by a macro variable. The other fonts for the other UI elements are set using the _default_font() and setall_wfonts() functions. The _default_font() function is described in the online Help, but the example presented here should be sufficient for most purposes.
383
1 1 1 1
1 1 1 1
0 0 0 0
4 4 4 1
1 1 1 0
1 0 1 0
The possible options and settings for _setext() are quite intricate. The online Help recommends using macro recording to generate calls that set these options. This process is described below, under Determining Programmatic Configuration.
Other Settings
A handful of other settings use their own specific APIs. Below are some examples:
defmain() { _default_option(F,1); _default_option(u,1); _default_option(L,250); display_top(y); }
// // // //
Maximize first window. Draw box around current line Left margin Show Top-of-File line
Again, its not practical to document all of these in detail. Instead, refer to Determining Programmatic Configuration below to find out how to discover these APIs for yourself.
1. 2.
Invoke record-macro-toggle (Ctrl+F11). SlickEdit begins recording a macro. Open the General Options configuration dialog (Tools Options General).
384
These steps apply only on Windows. On UNIX there is only one Open dialog. Now open the lastmac.e file in your configuration directory. It contains these lines:
#include slick.sh _command last_recorded_macro() name_info(,VSARG2_MARK|VSARG2_REQUIRES_EDITORCTL) { _macro(R,1); execute(show -modal _config_form); def_fast_open=1; }
By reading this source, you can discover (if you didnt already know) that the Fast Open dialog is controlled by the def_fast_open macro variable. Heres another example, where we alter line wrapping and cursor behavior using Redefine Common Keys:
1. 2. 3. 4. 5. 6. 7. 8.
Invoke record-macro-toggle (Ctrl+F11). SlickEdit begins recording a macro. Open the Redefine Common Options configuration dialog (Tools Options Redefine Common Keys). Uncheck the Cursor wrap option. Uncheck the Up/Down on text option. Uncheck the Line wrap on text option. Click OK. Invoke record-macro-toggle (Ctrl+F11). SlickEdit prompts you how to save the macro. Click Cancel.
385
With some thinking (not too much!), we can determine that the values we changed are:
def_cursorwrap corresponds to the Cursor wrap option. def_updown_col corresponds to the Up/Down on text option. def_linewrap corresponds to the Line wrap on text option.
You should be able to use a similar procedure to determine most configuration settings in SlickEdit.
Using list-source
Another way to find out a lot about SlickEdit configuration is the list-source command. When you invoke this command, SlickEdit opens and updates vusrdefs.e in your configuration directory. This file contains Slick-C code for your current configuration. The first part of the listing contains all the key definitions, first for the default event table and then for mode-specific event tables. The second part of the listing contains Slick-C statements to set macro variables and other settings. On UNIX, the file is called vunxdefs.e. The format is basically the same, but paths are expressed in UNIX format rather than DOS format. The list-keydefs command populates the same key definitions as list-source into an empty buffer called keydefs.e, and the list-config does the same for the configuration settings into an empty buffer called lconfig.e. Sometimes you can find a configuration setting you are looking for by searching for a keyword in the output of list-source. For example, by issuing the command below, you can find all macro variables pertaining to bookmarks.
all/def.*book/u
Another thing you can do with list-source is run it at different times while you experiment with configuration. Use DIFFzilla to compare the new vusrdefs.e with the one last saved on disk, to see what changes. You can then take lines from vusrdefs.e and paste them into your own batch macro. It can be a good idea to save a copy of vusrdefs.e from your emulation before you start any customization, so that you can later review the net effect of your changes. However, if you dont take a snapshot, its easy to create one by starting SlickEdit with a fresh configuration at any time. We cover restoring to the default configuration in Chapter 2. You could simply use vusrdefs.e for managing your configuration. It is a text file, and the format is transparent. One problem with this is that vusrdefs.e contains too much information. It contains all the settings, not just the ones you changed. This is not appropriate for migrating your changes to a different version of SlickEdit, if you want your changes to be applied on top of SlickEdits defaults. Using vusrdefs.e, you will clobber new settings and new defaults when they arrive in new versions.
386
1. 2. 3. 4.
Open the Redefine Common Keys dialog (Tools Options Redefine Common Keys). Press Ctrl+Shift+Space. SlickEdit displays the Form Editor. Note that the name of the form is _rc_keys_form. Close the Form Editor. Invoke gui-find-proc (Macro Go to Slick-C Definition). SlickEdit displays the Go to Definition dialog, shown in Figure 17-8.
Figure 17-8
5. 6. 7.
Enter _rc_keys_form for the Symbol. Click OK. SlickEdit displays the Select a tag dialog, shown in Figure 17-9. The sysobjs.e file contains the definition of the form and its GUI components. The config.e file contains the code.
Figure 17-9
387
By reading this function, you can easily determine which macro variables are set by which options. Initialization (of configuration settings) is generally done in ok.on_create(), and finalization is done in ok.lbutton_up(). Most SlickEdit forms follow this pattern. Reading the macro source requires somewhat more effort and investment than using the macro recording approach, but sometimes the benefits are worth it. Sometimes the macro recording approach is imprecise, because it may output code that is not relevant to what you are trying to achieve. For example, with the Redefine Common Keys example above, the recorded macro outputs code for all the controls on the dialog, not just the ones we changed. In that case, it was easy to see which macro variables we really wanted. In other cases, such as color configuration, recorded macros output many Slick-C statements, not all of which are relevant. Reading the supplied configuration code can give you a clear idea of how the configuration really works and how best to program it. In the end, you decide what investment you want to make into studying the supplied macro source, what level of customization you would like, and what level of repeatability you require.
388
Summar y
Thats the end of Chapter 17, and thats the end of the book. SlickEdit is the result of many years of text editor evolution. Its biggest strength is its underlying architecture, which has allowed it to mature over a long time but still have new features added every year. It is remarkably easy to customize and extend, thanks to Slick-C. The last two chapters should have given you a pretty good idea of whats possible with SlickEdit. Actually, anything is possible! Slick-C is a versatile and yet easy programming language. The existing source code is rich and extensive. The biggest challenge is trying to understand it all. I hope that with these two chapters youve got enough of an introduction to see how you can use Slick-C to customize the editor for your own needs. Every company and every developer is different. A powerful tool is one that can be adapted to your needs and the way you like to work. On the other hand, SlickEdit is surprisingly versatile. Features and macros work alike across all major operating systems currently in use, and developers use SlickEdit for languages from Ada to Yacc (and Groovy!) and everything in between. Perhaps you will write some macros that could be useful to others, and post them at the SlickEdit Community Forums (http://community.slickedit.com). See you there!
389
The emulations included are: CUA, or Windows. SlickEdit. Visual C++ 6.0. Visual Studio.
The tables listed here were generated using a Slick-C macro command wrox-make-emulations. The code for this macro is included on the CD-ROM, under Author/Chapter16/wrox_make_ emulations.e. You can use the macro to generate plain text or HTML tables of selected emulations. The tables printed in this book are for SlickEdit version 12.0.2. SlickEdit emulations change in minor ways from release to release.
In this book, modifier keys have been spelled out, like Alt for the Alternate key and Ctrl for the Control key. In the tables in this appendix, the modifier keys are abbreviated to single letters to save space. Thus the tables list A+ for the Alternate key modifier and C+ for the Control key. Many commands have multiple alternative key bindings. For these, the alternatives are separated by semicolons. Some key bindings are for sequences of keys, where one key must be pressed after another (not at the same time). These sequences are shown with the keys separated by commas. For example, the SlickEdit emulation has two key combinations for the insert-toggle command. You can press the Insert key, or you can press Ctrl+X followed by Ctrl+O. These alternatives are shown in the table as INS; C+X,C+O.
Debugging Commands
Table A-1
Command
activate_autos
C+A+B; C+M+B
C+A+B; C+M+B
C+A+B; C+M+B
392
C+A+M; C+M+M
C+A+M; C+M+M
C+A+M; C+M+M
A+6; M+6
A+6; M+6
A+6; M+6
A+6; M+6; C+A+M,1; C+A+M,2; C+A+M,3; C+A+M,4 A+5; C+A+G; M+5 C+A+H; C+M+H A+4; C+A+V; C+M+V; M+4 A+3; C+A+W, 1; C+M+W; M+3 C+A+W,2 C+A+W,3 C+A+W,4 C+A+Q
A+5; M+5
A+5; M+5
A+5; M+5
C+A+H; C+M+H A+4; C+A+V; C+M+V; M+4 A+3; C+A+W; C+M+W; M+3
C+A+H; C+M+H A+4; C+A+V; C+M+V; M+4 A+3; C+A+W; C+M+W; M+3
C+A+H; C+M+H A+4; C+A+V; C+M+V; M+4 A+3; C+A+W; C+M+W; M+3
activate_watch2 activate_watch3 activate_watch4 debug_add_watch debug_ breakpoints debug_clear_all_ breakpoints debug_restart debug_run_to_ cursor
continued
393
Visual Studio A+Pad-star; M+Pad-star F11 S+F11 F10 S+F5 C+B; F9 C+F9
Editing Commands
Table A-2
Command
adjust_block_ selection append_cut append_to_ clipboard beautify beautify_ selection cap_selection cap_word cbacktab codehelp_ complete
CUA
C+S+X C+S+C
C+S+X C+S+C
C+S+A
C+S+A
C+S+A
S+TAB C+Space
C+Space
C+Space
394
CUA
SlickEdit
Visual C++ 6
C+S+Space C+S+dot C+S+comma A+V; C+Ins; M+V A+C; M+C C+S+dot C+S+comma C+C; C+Ins; M+C A+C C+S+dot C+S+comma C+C; C+Ins; M+C A+C
C+K
C+X,C+W Tab
C+L A+L
C+L A+L
C+S+K
A+W; C+S+K; M+W C+D; DEL C+S+L C+Backspace A+F4; M+F4 C+Del C+Del A+U C+S+L C+Backspace
C+U
A+U
continued
395
CUA
SlickEdit
Visual C++ 6
Ins
S+Enter ) S+Space
Backspace
list_symbols
A+dot; M+dot
A+dot; M+dot
lowcase_selection lowcase_word maybe_complete maybe_list_ matches move_text_backtab move_text_tab move_to_cursor nosplit_insert_ line nosplit_insert_ line_above
C+S+L
Space ?
Space ?
C+M; Tab
Tab
C+Enter C+S+Enter
C+Enter C+S+Enter
396
CUA
Visual C++ 6
Visual Studio
C+Y; S+Ins
reflow_paragraph reflow_selection select_all select_block select_char select_line select_matching_ brace select_next_ condition select_prev_ condition select_whole_word shift_selection_ left shift_ selection_right split_insert_line split_line transpose_chars
A+P; M+P C+X,C+P C+A; M+A C+B F8 C+L A+B; M+B A+Z; M+Z A+L; M+L C+A; M+A C+B A+Z; F8 C+F8 C+S+E C+S+K C+S+J C+W S+F7 S+F8 Enter A+S; M+S; C+X,S C+T continued S+F7 S+F8 S+F7 S+F8 Enter Enter A+Z C+F8 C+S+E C+S+K C+S+J C+W S+F7 C+A; M+A
397
CUA
SlickEdit
undo_cursor
S+Backspace; S+F9
C+F9; S+Backspace
C+S+Del C+S+U
C+S+Del C+S+U
File Commands
Table A-3
Command
close_all close_buffer file gui_cd gui_open gui_print new quit safe_exit
CUA A+M+W S+M+W F4 C+D C+O; F7; M+O M+P M+N F3 A+F4; M+F4; M+Q
F7; C+X,C+F
F3; C+X,K A+X; M+X; C+X,Ctrl+C A+F4; A+X; M+F4; M+Q A+F4; A+X; M+F4; M+Q
398
save_all save_as
Macro Commands
Table A-4
Command
end_recording execute_last_ macro_key
CUA
SlickEdit C+X,)
Visual C++ 6
Visual Studio
Miscellaneous Commands
Table A-5
Command
abort api_index
CUA
SlickEdit C+G
Visual C++ 6
Visual Studio
A+F1; M+F1
A+F1; M+F1
A+F1; M+F1
399
CUA Esc
F6
F6 F5
F6
F6
C+equals
C+equals C+X,C+E
C+equals
C+equals
A+equals; M+equals
A+F8; M+F8 A+comma; M+comma A+comma; M+comma A+comma; C+S+Space; C+T; M+comma
F1; S+M+slash
C+M,C+H C+S+W C+S+D C+S+B C+S+D C+S+B; C+X,C+B C+S+D C+S+B C+S+D
400
CUA C+S+V
C+backslash
C+backslash
C+backslash
C+Q
C+Q C+X,C+Z
C+Q
S+F6
S+F6
S+F6
C+S+M
C+S+M
C+S+M
C+Break
C+Break C+M,C+L
C+S+8
C+S+8
C+R,C+W
C+F1 C+F2
C+F1
C+F1
401
Navigation Commands
Table A-6
Command
alias_cd alt_gtbookmark back
CUA
SlickEdit C+X,C+D
Visual C++ 6
Visual Studio
C+S+9 Back-ButtonDown M+Left Home Back-ButtonDown M+Left C+U; Home A+Y; M+Y C+End; M+Down C+End; M+Down; C+X,C+J C+PgDn Back-ButtonDown M+Left Home A+Y C+End; M+Down
C+PgDn
C+PgDn C+S+F2
C+PgDn C+K,C+L Down A+1; C+S+G; M+1 Left Right Up End; M+Right
C+J; Left C+L; Right C+I; Up C+O; End; M+Right A+E; M+E
end_select fast_scroll
402
CUA Forward-ButtonDown
SlickEdit Forward-ButtonDown
C+J C+S+E C+S+E F2 C+N C+B; F8 C+K C+S+Pad-minus C+S+Down A+F10; C+S+Down; M+F10; C+X,C+N C+[ A+Down C+Down C+Tab; C+W; C+X,O A+Right; C+Right C+N; PgDn C+P; PgUp C+comma; C+X,C+H C+F6; C+S+N; C+Tab A+Right; C+Right PgDn PgUp C+comma; C+Pad-star S+F2 C+P A+F8; C+F8; C+V; M+F8 continued C+F6; C+Tab C+S+Down; F4 C+S+Down; F4; F8 C+K,C+N
C+[ A+Down
C+[ A+Down
next_word
prev_bookmark prev_buffer
403
CUA
SlickEdit
C+S+Up
C+S+Up
C+S+Up; S+F4
C+S+[ A+Up C+Up C+S+F6; C+S+Tab; C+S+W A+Left; C+Left C+slash C+dot
C+S+[ A+Up C+Up C+S+F6; C+S+Tab; C+S+W A+Left; C+Left C+slash C+dot; C+H
C+S+[ A+Up
C+S+F6; C+S+Tab
C+S+F6; C+S+Tab; C+S+W A+Left; C+Left C+slash; S+F12 C+dot; C+F12; F12 C+Down
scroll_down scroll_left scroll_page_down scroll_page_up scroll_right scroll_up set_bookmark set_next_error toggle_bookmark top_of_buffer
C+Down
C+Wheel-Down C+Wheel-Up
C+Wheel-Down C+Wheel-Up
C+Up
top_of_window
C+PgUp
C+PgUp
C+PgUp
404
Project Commands
Table A-7
Command
project_add_file project_build
CUA
SlickEdit
Visual C++ 6
C+M
F7
C+S+B
project_compile
S+F10
C+F7; S+F10
C+F7; S+F10
F5
F5 A+F7; M+F7
C+F5
C+F5
C+F5
Search Commands
Table A-8
Command
find_in_files find_next
SlickEdit
Visual C++ 6
C+F
C+Pad-plus; F3; M+G C+Pad-minus; C+S+F3; S+F3; S+M+G A+F3; C+F; M+F; M+F3 C+H
F3; M+G
find_prev
C+S+G; S+M+G
gui_find
C+F; M+F
C+F; M+F
C+I C+F3
405
SlickEdit
Visual C++ 6
C+S+I; C+X,C+R
C+S+I M+E
Toolbar Commands
Table A-9
Command
activate_ bookmarks activate_build activate_call_ stack activate_output activate_output_ toolbar activate_ project_classes activate_ project_files activate_ project_toolbar activate_tag_ properties_ toolbar
CUA C+S+N
SlickEdit C+S+N
A+2; M+2
A+0
406
Window Commands
Table A-10
Command
close_window create_tile fullscreen hsplit_window iconize_all iconize_window maximize_mdi move_edge move_mdi move_window one_window restore_mdi size_mdi size_window zoom_window
SlickEdit
A+F3; M+F3
C+H A+M+M M+M A+F10; M+F10 A+F2; M+F2 A+F7; M+F7 C+F7
C+X,2 A+M+M A+M+M M+M A+F10; M+F10 A+F2; M+F2 A+F7; M+F7 C+F7 C+X,1 A+M+M M+M A+F10; M+F10 M+F2 M+F7
A+F5; M+F5
407
Key Commands
Table A-11 lists the commands bound to keys in the different emulations.
Table A-11
Key Space C+Space C+S+Space S+Space ) * ? Back-Button-Down Backspace Del Down End Enter Esc F1 F2 F3 CUA
maybe_ complete codehelp_ complete complete_more
SlickEdit
maybe_ complete codehelp_ complete complete_more
Visual C++ 6
maybe_ complete codehelp_ complete function_ argument_help keyin_space keyin_match_ paren rexx_star maybe_list_ matches back linewrap_ rubout linewrap_ delete_char cursor_down end_line split_insert_ line cmdline_ toggle help next_bookmark find_next
Visual Studio
maybe_ complete codehelp_ complete function_ argument_help keyin_space keyin_match_ paren rexx_star maybe_list_ matches back linewrap_ rubout linewrap_ delete_char cursor_down end_line split_insert_ line cmdline_ toggle help save find_next
keyin_space keyin_match_ paren rexx_star maybe_list_ matches back linewrap_ rubout linewrap_ delete_char cursor_down end_line split_insert_ line cmdline_ toggle help save quit
keyin_space keyin_match_ paren rexx_star maybe_list_ matches back linewrap_ rubout delete_char
408
SlickEdit
file config compare gui_open next_buffer undo
Visual C++ 6
next_error project_debug compare project_build select_char debug_ toggle_ breakpoint debug_step_ over debug_step_ into push_tag forward
Visual Studio
next_error project_debug compare
next_error debug_ toggle_ breakpoint debug_step_ over debug_step_ into push_tag forward
F10 F11 F12 Forward-ButtonDown Home Ins LButton-doubleclick LButton-Down LButton-triple-click Left MButton-Down Mouse-Move PgDn PgUp
begin_line_ text_toggle insert_toggle mou_select_ word mou_click mou_select_ line cursor_left mou_paste _mouse_move page_down page_up
begin_line_ text_toggle insert_toggle mou_select_ word mou_click mou_select_ line cursor_left mou_paste _mouse_move page_down page_up
begin_line_ text_toggle insert_toggle mou_select_ word mou_click mou_select_ line cursor_left mou_paste _mouse_move page_down page_up
begin_line_ text_toggle insert_toggle mou_select_ word mou_click mou_select_ line cursor_left mou_paste _mouse_move page_down page_up
continued
409
SlickEdit
mou_click_ menu_block cursor_right ctab cursor_up fast_scroll fast_scroll
Visual C++ 6
mou_click_ menu_block cursor_right move_text_tab cursor_up fast_scroll fast_scroll activate_ project_ toolbar
Visual Studio
mou_click_ menu_block cursor_right move_text_tab cursor_up fast_scroll fast_scroll activate_ project_ toolbar cursor_error activate_ output_ toolbar activate_ watch activate_ variables activate_ registers activate_ memory activate_ call_stack adjust_block_ selection
A+1 A+2
cursor_error
cursor_error
activate_ watch activate_ variables activate_ registers activate_ memory activate_ call_stack
activate_ watch activate_ variables activate_ registers activate_ memory activate_ call_stack adjust_block_ selection select_block copy_to_ cursor end_select
activate_ watch activate_ variables activate_ registers activate_ memory activate_ call_stack adjust_block_ selection
copy_to_ cursor
copy_to_ cursor
410
Visual C++ 6
Visual Studio
A+P A+R A+S A+T A+U A+V A+W A+X A+Y A+Z A+comma A+dot
continued
411
SlickEdit
execute_ selection undo next_paragraph api_index move_edge create_tile
Visual C++ 6
execute_ selection undo next_paragraph api_index set_bookmark gui_find
Visual Studio
execute_ selection undo_cursor next_paragraph api_index
toggle_so_ backwards toggle_so_ matchcase toggle_so_ regex safe_exit restore_mdi delete_tile project_build project_ compile move_mdi size_mdi move_mdi prev_buffer project_edit format_ selection debug_ breakpoints maximize_mdi activate_tag_ properties_ toolbar mou_click_copy prev_word mou_click_copy prev_word mou_click_copy prev_word project_edit format_ selection debug_ breakpoints maximize_mdi find_tag safe_exit restore_mdi safe_exit restore_mdi
A+LButton-Down A+Left
mou_click_copy prev_word
412
CUA
debug_show_ next_statement next_word
SlickEdit
debug_show_ next_statement next_word
Visual C++ 6
debug_show_ next_statement next_word
Visual Studio
debug_show_ next_statement codehelp_ complete prev_paragraph iconize_all
prev_paragraph iconize_all
prev_paragraph iconize_all
close_all
close_all
close_all
transpose_ lines
select_block
select_block
copy_to_ clipboard
stop_process
copy_to_ clipboard
continued
413
SlickEdit
delete_char
Visual C++ 6
maybe_active_ search_hist_ list find_matching_ paren gui_find gui_goto gui_replace i_search prev_ condition next_condition
Visual Studio
maybe_active_ search_hist_ list find_matching_ paren gui_find gui_goto gui_replace i_search prev_ condition
C+E
cut_end_line
cut_end_line
C+F C+G C+H C+I C+J C+K C+K,C+C C+K,C+D C+K,C+F C+K,C+K C+K,C+L C+K,C+N C+K,C+P C+K,C+U C+K,C+W C+L C+M C+M,C+H
copy_word
cursor_down
comment beautify beautify_ selection toggle_ bookmark clear_ bookmarks next_bookmark prev_bookmark comment_erase activate_ bookmarks select_line project_build cursor_right project_build cut_line move_text_tab hide_selection cut_line
414
paste
cut
continued
415
Visual C++ 6
Visual Studio
416
CUA
SlickEdit
start_process next_error insert_toggle reflow_ selection reverse_i_ search save top_of_buffer copy_word nothing list_ clipboards resume paste zoom_window pop_bookmark push_tag push_ref next_hotspot plusminus find_matching_ paren diff cut_line
Visual C++ 6
Visual Studio
redo undo pop_bookmark push_tag push_ref next_hotspot plusminus find_matching_ paren diff delete_prev_ word
redo undo_cursor pop_bookmark push_tag push_ref next_hotspot plusminus find_matching_ paren diff delete_prev_ word
continued
417
CUA
SlickEdit
Visual C++ 6
stop_process delete_word
Visual Studio
stop_process delete_word
wh wh2
upcase_word lowcase_word
upcase_ selection close_window lowcase_ selection project_ execute project_ compile move_window
quick_search
close_window
close_window
move_window
size_window debug_toggle_ breakpoint_ enabled debug_run_to_ cursor record_macro_ toggle record_macro_ end_execute
prev_buffer undo_cursor
load
push_tag
418
CUA
top_of_buffer copy_to_ clipboard mou_click_copy prev_word
SlickEdit
top_of_buffer copy_to_ clipboard mou_click_copy prev_word
Visual C++ 6
top_of_buffer copy_to_ clipboard mou_click_copy prev_word mou_select_ word find_prev find_next pop_bookmark bottom_of_ window top_of_window mou_move_to_ cursor next_word next_window scroll_up scroll_page_ down scroll_page_up unsurround next_error cua_select nosplit_ insert_line_ above
Visual Studio
top_of_buffer copy_to_ clipboard mou_click_copy prev_word mou_select_ word prev_doc
pop_bookmark bottom_of_ window top_of_window mou_move_to_ cursor next_word next_window scroll_up scroll_page_ down scroll_page_up unsurround next_error cua_select insert_ blankline_ below
continued
419
CUA
SlickEdit
cap_word cap_selection
Visual C++ 6
Visual Studio
clear_ bookmarks find_prev debug_restart prev_window debug_ clear_all_ breakpoints find_prev debug_restart prev_window debug_ clear_all_ breakpoints
420
SlickEdit
activate_ call_stack
Visual C++ 6
activate_ call_stack
Visual Studio
activate_ call_stack activate_ exceptions activate_ registers
activate_ threads
activate_ threads
activate_ threads
C+A+L C+A+M C+A+M,1 C+A+M,2 C+A+M,3 C+A+M,4 C+A+O C+A+Q C+A+R C+A+T C+A+V
activate_ project_files activate_ members activate_ memory activate_ memory activate_ memory activate_ memory activate_ output debug_add_ watch goto_url
list_symbols
continued
421
activate_autos activate_ breakpoints activate_ call_stack activate_ threads activate_ locals activate_ members activate_ variables activate_watch
activate_autos activate_ breakpoints activate_ call_stack activate_ threads activate_ locals activate_ members activate_ variables activate_watch
activate_autos activate_ breakpoints activate_ call_stack activate_ threads activate_ locals activate_ members activate_ variables activate_watch view_ specialchars_ toggle alt_ gtbookmark
activate_autos activate_ breakpoints activate_ call_stack activate_ threads activate_ locals activate_ members activate_ variables activate_watch view_ specialchars_ toggle alt_ gtbookmark
C+S+9
422
CUA
SlickEdit
Visual C++ 6
cap_selection list_buffers append_to_ clipboard javadoc_ editor select_ matching_brace
Visual Studio
cap_selection project_build append_to_ clipboard javadoc_ editor select_ matching_brace find_in_files
cursor_error replace_in_ files reverse_i_ search select_prev_ condition select_next_ condition delete_line
lowcase_ selection start_process activate_ bookmarks expand_alias expand_ extension_ alias replace_in_ files set_next_error
start_process next_window
start_process workspace_new
C+S+R C+S+S
continued
423
Visual Studio
transpose_ words
M+1 M+2
M+3
424
CUA
activate_ variables activate_ registers activate_ memory activate_ call_stack select_all
SlickEdit
activate_ variables activate_ registers activate_ memory activate_ call_stack adjust_block_ selection select_block copy_to_ cursor end_select fill_ selection
Visual C++ 6
activate_ variables activate_ registers activate_ memory activate_ call_stack select_all
Visual Studio
activate_ variables activate_ registers activate_ memory activate_ call_stack select_all
find_next join_line cut select_line move_to_ cursor keyin_buf_name overlay_block_ selection reflow_ paragraph
find_next
find_next
M+P M+Q
gui_print
gui_print
gui_print
safe_exit
safe_exit
safe_exit
continued
425
CUA
SlickEdit
root_keydef split_line find_matching_ paren deselect
Visual C++ 6
Visual Studio
M+U M+V M+W M+X M+Y M+Z M+comma M+dot M+equals M+Backspace M+Down M+F1 M+F2 M+F3 M+F4 M+F5
bottom_of_ buffer api_index move_edge create_tile safe_exit restore_mdi undo function_ argument_help list_symbols execute_ selection paste
copy_to_ clipboard cut_word safe_exit begin_select select_char function_ argument_help list_symbols execute_ selection undo bottom_of_ buffer api_index move_edge create_tile delete_tile project_build
paste
paste
close_window cut
close_window cut
close_window cut
undo function_ argument_help list_symbols execute_ selection undo bottom_of_ buffer api_index set_bookmark gui_find safe_exit restore_mdi
426
Visual C++ 6
Visual Studio
M+Left M+Pad-star M+Right M+Up S+Backspace S+Del S+Down S+End S+Enter S+F1 S+F2 S+F3 S+F4 S+F5
debug_stop
debug_stop
continued
427
SlickEdit
resync shift_ selection_left shift_ selection_ right redo project_ compile debug_step_out save cua_select paste mou_extend_ selection cua_select cua_select cua_select cua_select cbacktab
Visual C++ 6
resync shift_ selection_left shift_ selection_ right undo_cursor project_ compile debug_step_out push_ref cua_select paste mou_extend_ selection cua_select cua_select cua_select cua_select cbacktab
Visual Studio
resync shift_ selection_left prev_error
S+F9 S+F10 S+F11 S+F12 S+Home S+Ins S+LButton-Down S+Left S+PgDn S+PgUp S+Right S+Tab S+Up S+M+C S+M+G S+M+S S+M+W S+M+Z
undo_cursor project_ compile debug_step_out push_ref cua_select paste mou_extend_ selection cua_select cua_select cua_select cua_select cbacktab
428
SlickEdit
help cua_select cua_select cua_select cua_select cua_select cua_select
Visual C++ 6
help cua_select cua_select cua_select cua_select cua_select cua_select
Visual Studio
help cua_select cua_select cua_select cua_select cua_select cua_select
Table A-12
Variable
def_advanced_ select def_alt_menu def_brief_word def_buflist def_click_past_ end def_cursor_ beginend_select def_cursorwrap def_deselect_copy def_deselect_ paste
CUA P 1 0 3 0
SlickEdit P 0 0 3 1
Visual C++ 6 P 1 0 3 0 1
Visual Studio P 1 0 3 0 1 1 0 1
1 1 1
0 1 0
1 1 1
continued
429
430
Table A-13
Key Alt+A Alt+B Alt+C Alt+D Alt+E Alt+F Alt+J Alt+L Alt+M Alt+N WROX
adjust-block-selection select-block copy-to-cursor cut end-select fill-selection join-line select-line move-to-cursor keyin-buf-name
continued
431
alt-gtbookmark
432
continued
433
434
Table B-1
Definition Match beginning of line. Match end of line. Match any character except newline. Maximal match of zero or more occurrences of X. Maximal match of one or more occurrences of X. Maximal match of zero or one occurrences of X. Match exactly n1 occurrences of X. Maximal match of at least n1 occurrences of X. Maximal match of at least 0 occurrences but not more than n2 occurrences of X. UNIX
^
SlickEdit
^
Brief
% < $ > ? X\:@ X\:+ X\:0,1 X\:n1 X\:n1? X\:n1, X\:,n2
? X@ X# X:0,1 X:n1
X:n1, X:0,n2
continued
SlickEdit
X:n1,n2
Brief
X\:n1,n2
.*
?@
X\:*
X{n1,n2}?
X:*n1,n2
X\:n1,n2?
.*?
?*
(X)
{X}
{X}
(?dX)
{#dX}
{@dX}
[charset]
[charset]
[charset]
[^charset]
[~charset] [^charset]
[~charset]
436
SlickEdit
[charset1[charset2]]
Brief
[charset1[charset2]]
\p{Unicode CategorySpec]
\p{Unicode CategorySpec]
\p{Unicode CategorySpec]
\P{UnicodeIs BlockSpec]
\P{UnicodeIs BlockSpec]
\P{UnicodeIs BlockSpec]
\xhh
\xhh
\xhh
\dnnn
\nnn
\dnnn
\d
\gd
\d
\c
\c
\c
\n
\n
\n
continued
437
UNIX
\r \t
SlickEdit
\r \t \b \f \od
Brief
\r \t \b \f \od
\om
\om
\om
\ol
\ol
\ol
\char \:char
\char :char
\char \:char
Predefined Expressions
Table B-2 lists the predefined expressions that can be used in the special regular expression escape sequence \:char (or :char with SlickEdit regexes). This table also appears in Chapter 7.
Table B-2
Description Matches an alphanumeric character. Matches an alphabetic character. Character A C
438
439
SlickEdit Callbacks
Table C-1 lists the complete set of SlickEdit callbacks at the time of writing. Callbacks are covered in detail in Chapter 16. The list of callbacks here was generated using the macro presented in that chapter. You can use the macro to get an up-to-date list, or adapt it for your own needs.
Table C-1
Name
_actapp_
Event Application activated (such as getting focus). Before writing state file. New buffer opened.
_b4wrst_ _buffer_add_
Buffer ID, buffer name, buffer flags. Buffer ID, buffer name, new name, buffer flags.
_buffer_renamed_
_cbmdibufferhidden_
Event MDI buffer unhidden. Some windows are marked KEEP_ ON_QUIT, which means they are never quit, even when the user explicitly quits them. An example of this would be the Find Results window. If a user manages to pull the Find Results into an editor window, quitting it will simply hide the buffer, because it gets reused by the Find dialog. Before file closed.
Arguments
_cbquit_
Buffer ID, buffer name, filename, buffer flags. Buffer ID, buffer name, filename, buffer flags.
_cbquit2_
File saved. Stopping build. Directory changed. End of DIFFzilla operation. Start of DIFFzilla operation. Filename or buffer name changed. Key bound. FTP busy. FTP idle. Color coding lexer changed. Lexer name as stored in .vlx file. Buffer ID, old name, new name, buffer flags. Key binding table, key. New directory.
_lostfocus_ _MenuAddFileHist_
Lost focus. Adding filename to File History on File Menu. Adding workspace filename to Project History on Project Menu. Filename.
_MenuAddWorkspaceHist_
Filename.
442
Event Before loading module. Before an editor window popup/context menu is displayed. Before any pop-up menu is displayed. Before unloading module. Build completed. Build about to start. Called after _project_name is set to blank, when closing project. Active project configuration changed. Project properties edited. Opening project. Project saved. File added to project. Only called when another tool or tool window adds a file to a project (e.g., the Project tool window, Add Files). Save/restore. Save/restore global. Switching buffer.
_on_popup2_
_prjconfig_
Switching mode in vi emulation. Closing workspace. File added to workspace. Before workspace opened. After workspace opened. Project name, filename. Workspace filename.
443
System Requirements
Make sure that your computer meets the minimum system requirements listed in this section. If your computer doesnt match up to most of these requirements, you may have a problem using the contents of the CD. For Windows Vista, Windows 2000, Windows NT4 (with SP 4 or later), or Windows XP: At least 256 MB of total RAM installed on your computer. 170 MB disk space. A CD-ROM drive.
For Linux kernel 2.6 and compliance with LSB 3.1 or later: At least 256 MB of total RAM installed on your computer. 200 MB disk space. A CD-ROM drive.
For HP-UX 11 and later: At least 256 MB of total RAM installed on your computer. 270 MB disk space. A CD-ROM drive.
For IRIX 6.5 and later: At least 256 MB of total RAM installed on your computer. 280 MB disk space. A CD-ROM drive.
For Solaric SPARC 7 and later: At least 256 MB of total RAM installed on your computer. 240 MB disk space. A CD-ROM drive.
For Solaris x86: At least 256 MB of total RAM installed on your computer. 240 MB disk space. A CD-ROM drive.
For Macintosh OS X v10.4: At least 256 MB of total RAM installed on your computer. 190 MB disk space. A CD-ROM drive. X11 for Mac OS X.
446
1.
Insert the CD into your computers CD-ROM drive. The license agreement appears.
The interface wont launch if you have autorun disabled. In that case, click Start >Run (For Windows Vista, Start >All Programs >Accessories >Run). In the dialog box that appears, type D:\Start.exe. (Replace D with the proper letter if your CD drive uses a different letter. If you dont know the letter, see how your CD drive is listed under My Computer.) Click OK.
2. 3.
Read through the license agreement, and then click the Accept button if you want to use the CD. The CD interface appears. The interface allows you to install the programs and run the demos with just a click of a button (or two).
1. 2. 3.
Log in as root. Insert the CD into your computers CD-ROM drive. If your computer has Auto-Mount enabled, wait for the CD to mount. Otherwise, follow these steps:
a.
mount /dev/cdrom /mnt/cdrom. (This mounts the cdrom device to the mnt/cdrom directory. If your device has a different name, change cdrom to that device name e.g., cdrom1.) To prevent filename casing issues on HP-UX, use the -o cdcase option when mounting.
b. 4.
Graphical: Right-click on the CD-ROM icon on the desktop, and choose Mount CD-ROM. This mounts your CD-ROM.
At an xterm or full-screen prompt, change to the applicable UNIX platform directory on the CD-ROM (where <cdrom> is your CD-ROM mount point):
AIX <cdrom>/SlickEdit/aix/RS6000. HP-UX <cdrom>/SlickEdit/hpux/hp9000. IRIX <cdrom>/SlickEdit/irix. Linux <cdrom>/SlickEdit/linux/x86.
447
5. 6.
Start the installation at the prompt: ./vsinst. To remove the CD from your CD-ROM drive, follow these steps:
a. b.
umount /mnt/cdrom. Graphical: Right-click on the CD-ROM icon on the desktop, and choose UMount CD-ROM. This mounts your CD-ROM.
1. 2. 3. 4. 5.
Ensure that X11 is fully installed on your system (see the Note below). Insert the CD into your CD-ROM drive. Browse to the SlickEdit/mac folder on the product CD. Double-click slickedit.dmg. A disk image is mounted, with Finder displaying the contents. Double-click slickedit.pkg, and the installation process begins.
The default installation path is /Applications. After installing SlickEdit, if you want to use SlickEdit keyboard shortcuts instead of X11 shortcuts, you will need to disable X11 keyboard shortcuts. See Mac OS X in the Help system for instructions. SlickEdit runs as an X11 application; thus X11 must be installed prior to installing SlickEdit. To check if X11 is installed, select Finder Applications Utilities. A file named X11.app should exist at this location. Otherwise, you will need to install X11 from your OS X installation CD: 1. Using installation disk 1, run the Optional Installs.mpkg utility. 2. At the Install Type phase, expand the Applications tree, and select X11. 3. Continue with the X11 installation.
Whats on the CD
The following sections provide a summary of the software and other materials youll find on the CD.
Author-Created Materials
All author-created materials from the book, including code listings and samples, are on the CD in the folder named Author.
448
Applications
The CD also contains a 30-day trial version of SlickEdit 2007 for Windows, Linux, UNIX, and Mac OS X. Installation instructions for each platform are given above. When you run SlickEdit for the first time, you will be prompted to request a trial license. Click the Launch Browser button to open the SlickEdit Trial Registration Web page. Fill in the requested information, and click the I Agree button. The trial license key will be e-mailed to the address you specified. When it arrives, paste it into the text area under Step 2 on the Request a Trial License dialog. Click the Activate button, and SlickEdit is ready to use. Shareware programs are fully functional, trial versions of copyrighted programs. If you like particular programs, register with their authors for a nominal fee and receive licenses, enhanced versions, and technical support. Freeware programs are copyrighted games, applications, and utilities that are free for personal use. Unlike shareware, these programs do not require a fee or provide technical support. GNU software is governed by its own license, which is included inside the folder of the GNU product. See the GNU license for more details. Trial, demo, or evaluation versions are usually limited either by time or functionality (such as being unable to save projects). Some trial versions are very sensitive to system date changes. If you alter your computers date, the programs will time out and will no longer be functional.
Troubleshooting
If you have difficulty installing or using any of the materials on the companion CD, try the following solutions: Turn off any anti-virus software that you may have running Installers sometimes mimic virus activity and can make your computer incorrectly believe that it is being infected by a virus. (Be sure to turn the anti-virus software back on later.) Close all running programs The more programs youre running, the less memory is available to other programs. Installers also typically update files and programs; if you keep other programs running, installation may not work properly. Reference the ReadMe Please refer to the ReadMe file located at the root of the CD-ROM for the latest product information at the time of publication.
Customer Care
If you have trouble with the CD-ROM, please call the Wiley Product Technical Support phone number at (800) 762-2974. Outside the United States, call 1 (317) 572-3994. You can also contact Wiley Product Technical Support at http://support.wiley.com. John Wiley & Sons will provide technical support only for installation and other general quality-control items. For technical support on the applications themselves, consult the programs vendor or author. To place additional orders or to request information about other Wiley products, please call (877) 762-2974.
449
Index
A
activate-bookmark, 128 activate-build, 283 activate-files-files, 127 activate-files-project, 118 Active Project, 44 add, 206207 Add Jar File, 63 Add Source Files dialog, 52 Add Tag File dialog, 91, 93, 99, 103 Add Tags Database dialog, 99, 103 Add Tree dialog, 45, 52, 91, 92, 99, 100, 103 Add Wildcard, 45, 52, 94, 95 adjust-block-selection, 201 AdoTemplate, 103 aliases, 229240 in code, use of, 232234 and configuration directory, 31, 240, 381 defining, macro for, 381 directory aliases, 232 dynamic directory aliases, 234235 escape sequences, 233234 extension-specific aliases, 235236 file aliases, 230232 file and directory, to open files, 116117 file extension for, 240 functions of, 229230 global aliases, 230, 231 with macros, 233234 with parameters, 239240 surround-with aliases, 238 syntax expansion with, 237238 aligning data. See data alignment all/expr[/options], 141 allnot/expr[/options], 141 *.als, configuration directory, 31, 240 alt-bookmark, 128, 129 alt-gtbookmark, 128, 129 Alt key combinations, menu access with, 21 key binding commands, 12 animation, tool windows, 40 Ant Java project, management with, 65 project file, example, 65 appearance, 2425 current line, box around, 24 current line highlighting, 24 fonts, 2526 left margin size, 25 line behavior, 2629 special characters, display of, 25 Top of file line, 25 vertical line column, 24 window, first, maximize, 24 append append-cut, 154 append-to-clipboard, 154 to clipboard, 155 arguments auto-complete, 1011 callbacks, listing of, 441443 command arguments, 328330 and commands, 10 Slick-C, 318, 327330 variable arguments, 327 arrays, in Slick-C, 320321 ASCII file, byte offset 124 assertions, functions of, 307308 auto-complete, 186190 command-line arguments, 1011 compared to word completion, 190
Index
auto-complete (continued)
auto-complete (continued) configuring, 189190 in programming, 188189 timeout, default, 186 compared to word completion, 186188 auto-hide docking groups, 36 pin icon for, 36 auto-list compatible, Context Tagging problems, 111112 Auto-List Members, troubleshooting, 107, 109 Auto-Parameter, troubleshooting, 107, 109 Auto-Tag, 75, 96 auto-updated tag databases converting from global tag database, 93 functions of, 89, 90 refresh of, 90, 93 separate workspace for, 9495, 100102 and shared tag database, 90, 9394 auto-updated tag files contents of, 89 use of, 93 auto-validation, XML, 257 block comments. See multiline comments block editing, 208213 block insert mode, 211212 pros/cons of, 209 XML data, creating from test file 209213 block insert mode block editing example, 211212 columns, entering data, 203204 implementing, 204 and macros, 204 block selections, 159160, 200201 copying, 201 deleting, 201 moving, 200 navigating, 202 overwriting, 201202 sorting within, 204 blocks of code color, changing, 176 deleting, 184185 bookmarks, 127130 Bookmarks tool window, activating, 39 configuring, 129130 named bookmarks, 128129 pushed bookmarks, 83, 127128 bottom-of-buffer, 120, 121, 202 bottom-of-window, 120 branches Concurrent Version System (CVS), 282283 release branch, creating, 282283, 290 Subversion, 290291 Brief regular expressions, 137139 syntax, listing of, 435438 buffer(s) block selections, 202 buffer-to-window, associating, 34 defined, 7 moving between, 35 names of, 7 navigation among, commands, 125127 navigation in, commands, 120123 one file per window setting, 34 ring, creating, 125126 Slick-C interaction with, 337
B
backspace hack tabs, 28 pull chars, 28 settings, 2829 tabs, converting to spaces, 28 backup(s), configuration settings, 31, 379 Backup History tool window activating, 39 viewing with DIFFzilla, 269270 bash shell, 96 batch macros invoking, 311 See also Slick-C macros begin-select, 156, 161, 202 bin alias, 232 binary files, display of, 254 binary search, 144 Bitstream Vera, 26
452
Slick-C temporary buffers, 340341 sorting, 204 use of term, 7 bugs detection. See debug; unit tests build dependency, projects, 44 build systems GNU C/C++ project, 60 Java project, 6162 options, 51, 60 Build tool window activating, 39 building project, 5253 functions of, 9 builtins.e, 343 byte offset navigation to, commands, 124 Byte Order Mark (BOM), 124, 255
C
C# global tag database for, 104 indentation, 179 cache, Tag files cache size, 111 calculations, 206207 invoice, example, 206207 callbacks callback traces, example macro, 353354 events, listing of, 344345 invoking, 345 listing of, 441443 Slick-C, 343346 capturing groups. See tagged expressions case command-line search, 143 Match case search, 134 selection, 156, 162 toggle for, 133 C/C++ c-mode, 174 compiler definition, creating, 9698 file extensions, 173 global tag database with header files for, 9293 header files. See C/C++header files indentation, 178179
JavaDoc comments, 195 pointer style, choosing, 178 Preprocessing options, 105, 179 preprocessor, tagging difficulties, 104105, 107108 proprocessing definitions, adding, 107108 Visual C++. See Visual C++6 C/C++header files C/C++, global tag database with, 9293 extensionless, configure in library, 108109, 175 Extensionless C++ Files dialog, 108 navigation to, 119 CD-ROM, 445449 applications on, 449 system requirements, 445448 troubleshooting, 449 center-line, 123 c/exp1/exp2[/options], 141142 character offset, showing in message line, 124 character selection, 155, 157158 Choose Include Directory dialog, 98 classpath, Java project, 63 Class tool window activating, 39 use of, 8687 clear-bookmarks, 128 clipboard, 153155 append to, 155 commands, listing of, 154 moving and copying, 154 multiple, 154 selections, 153 CMD shell, path, specifying, 96 code blocks. See blocks of code coding styles, 177 omitting, comments, 192 code editing, 173197 auto-complete, 186190 color syntax highlighting, 175177 comments, 192196 control structures, 180185 embedded languages, 190192 indentation, 177180
453
Index
code editing
454
functions of, 271272 key bindings, 284285 merge conflicts, 278279 reference guide to, 272 shortcuts, 285 Update Directory, 276277 working copy, checking, 272274 config alias, 232 configuration for appearance, 2425 backups, 31, 379 bookmarks, 129130 changes, saving, 30 default, reverting to, 3031 directory. See configuration directory emulations, 1921 for fonts, 2526 line behavior, 2629 macro variables, changing settings with, 2223 non-default configuration, use of, 3132 Slick-C, placement into. See programmatic configuration target configurations, 60 configuration directory and aliases, 31, 240 contents, deleting, 30 files/subdirectories, listing of, 31 functions of, 30 location of, 16, 30 macros, storage location, 16 non-default, changing to, 3132 state file, 30 and updates, 30 Context Tagging auto-tagging, 75 Class tool window, 8687 definitions, navigating to, 8182 Defs tool window, 8588 errors, control of, 74 files to tag, 74 functions of, 73 list members, configuring, 78 members, listing, 7678 parameter information, 7880
Preview tool window, 81 problems. See Context Tagging troubleshooting pushed bookmarks, 83 push-tag, 93 references, navigating to, 8283 standard libraries, 7374 symbols, finding, 8485 Symbols tool window, 8788 tag databases, 74, 89104 tag files, managing, 8889 workspace tagging, 44, 74 Context Tagging troubleshooting, 105109 Auto-List Members, 107, 109 Auto-Parameter, 107, 109 C/C++ tagging difficulties, 104105, 107108 and complex code, 111112 file extension alias, creating, 109 Go to definition, 105106, 109 Go to Reference, 107, 109 and large projects, 110, 111 Maximums, exceeding limit, 110 and qualified symbols, 106 References performance, 111 solutions, 107109 and symbol names, duplicates, 110 tag file cache size, 111 tag files, adding symbols, 108 tag files, rebuilding, 109 and unqualified symbols, 105106 Control key (Ctrl) key binding commands, 12 settings, 2829 control structures, 180185 adding to code, 182183 deleting, 184185 dynamic surround, 183184 Slick-C, 324326 syntax expansion, 181182 copying, with locked selections, 161 copy-selective-display, 146, 147 copy-to-clipboard, 154 troubleshooting, 16 copy-to-cursor, 156, 161, 201 Courier New, 26
455
Index
Courier New
D
data alignment, 222226 alignment commands, 223224 with macro, 225226 databases. See tag databases data editing, 199227 block editing, 208213 block selections, 200201 calculations, 206207 columns, entering data, 202204 data alignment, 222226 data generation, 205206 large files, 226227 macro record and playback, 213219 search and replace, 220222 sorting, 204 data generation, 205206 enumerate, 205 debug, 332333 command keys, 392394 Debug and Release, 60 GNU C/C++ project, bugs detection, 5460 See also Slick-C macros declarations event tables, 331 Slick-C, 326327 def_complete_flags, 170 def_complete_vars, 170 definit, 310 definitions Defs tool window, 8586 navigating to, 8182 Slick-C, 326327 defload, 310 Defs tool window activating, 39 use of, 8586
456
delete with block selections, 201 bookmarks, 128 code block, 184185 Delete key, settings, 2829 dependency checking, automatic, 60 deselect, 156, 161162, 207 dialogs, customization, 372375 DIFFzilla Backup History, viewing, 269270 comparison with. See Comparison macro, use with, 263264 settings, 266 unsupported commands, 261 Digital Mars, C/C++ compiler definition, creating, 9798 directory comparing, 265 configuration/settings. See configuration directory listing, Slick-C, 340342 workspaces, 44 directory alias dynamic directory aliases, 234235 to open files, 116117 predefined, SlickEdit, 232 display lines on screen, number of, 33 resolution and programming, 33 screen elements, color syntax highlighting, 176 window, 3440 DLL assemblies, global tag database for, 103 do ( ), Slick-C, 325 docked tool windows, 3638 auto-hide, 36 converting to floating, 38 docking groups, 36 order of tabs, changing, 38 documentation, comments, 192 document mode, 253254 select-mode, 254 Document Type Definition (DTD), XML, 255258 dos commands, 11 Doxygen, 195
driver program, GNU C/C++ project, 4849 duplicate-line, 153 dynamic directory aliases, 234235 dynamic languages global tag databases for, 91 standard libraries, 90 tag databases for, 90 tagging source files, 90 See also Groovy; Perl; Ruby dynamic surround disabling, 184 invoking, 183184
E
edit buffer, toggle to command line, 10 edit command in macros, 117 to open files, 117 Edit Expression, 70 editing command keys, 394398 editing pane, 78 remote, FTP/SSH, 302305 See also code editing; data editing; text editing embedded languages, 190192 here documents, 191192 Web programming, 190191 emulations, 1921 changing, 20 command keys, 392407 CUA (Common User Access), 1920 key bindings, 11 key commands, 408429 macro variable settings, 429431 Slick-C, listing of, 20 SlickEdit customizability, 56 WROX, 21, 431434 End key, settings, 29 end-select, 156, 161, 202 Enter key, settings, 2829 enumerate, data generation, 205 errors Edit Expression, 70
457
Index
errors
errors (continued)
errors (continued) error parsing, 6870 Error Regular Expressions, 6870 Matched Error Expression, 70 navigation among, 53, 62, 67 next-error, 53, 59, 67 prev-error, 53, 59, 67 Escape key toggle, edit buffer to command line, 10 tool windows, closing, 36, 39 escape sequences, aliases, 233234 event(s), callbacks, listing of, 441443 event tables Groovy, 371372 key bindings, 331 Slick-C, 331 execute-selection, 332 executing project GNU C/C++ project, 5354 Java project, 62 Ruby project, 6667 expand-alias, 235 /expr [/options], 141142 expressions predefined, listing of, 438439 selection, 156, 161 See also regular expressions extensibility, of SlickEdit, 56 extensionless files UNIX shell scripts, 175 See also C/C++header files Extension Options dialog Auto-complete settings, 189190 comments settings, 195196 tab/indendation settings, 177 extensions, files. See file extensions comparing, 260261 extensions. See file extensions listing, Slick-C, 340342 sections, comparison of, 262264 tag files, 4445 use of term, 7 file aliases, 230232 defining, 230231 to open files, 116117 file extensions alias, creating, 109 alias files, 240 for C/C++, 173 .e, macros, storing, 1718 edit settings, 174 extensionless files, 108109, 174 Extension Options dialog, 108109, 175 extension-specific aliases, 235236 settings, macro for, 384 Slick-C header files, 311 tag database, troubleshooting, 109 FileMan, 297 file manager, 298302 commands, 299300 grouping files, 300 invoking, 298 macros, use of, 301302 to open files, 119 selecting files, 300301 tasks, automating, 301302 filepos.slk, configuration directory, 31 Files tool windows activating, 39 to open files, 117119 File Tabs, toolbar, 78 file templates, 241252 creating, 242246 functions of, 241 instantiating, 241242 instantiating in macros, 248252 managing, 248 substitution parameters, 242, 246248, 250 file tree, Open tool window, 117
F
Fast Open Dialog, 114115 file(s) add file, 45 browse history, 283284, 291 command keys, 398399
458
fill-selection, 202203, 207 filters, selection, 157, 163 find ( ), Slick-C, 337338 find and replace. See Find and Replace tool window; search and replace Find and Replace tool window, 133137 Find, 134135 Find in Files, 135136 grep, 136 Look in selection box, 134 output results, editor window, 136 Replace, 137 Replace in Files, 137 Search Results tool window, 136 values of checkboxes, 134 find/exp[/options), 141142 find-in-files, 132133 keyboard shortcut, 132 find-matching-paren, 120 find-next incremental search, 133 keyboard shortcut, 132 repeat searches with, 132 find-prev incremental search, 133 keyboard shortcut, 132 repeat searches with, 132 Find Symbol tool window activating, 39 use of, 84 FishEye, 281 floating point numbers, Slick-C, 315 floating tool windows, 3638 choosing/closing, 36 converting to docked type, 3738 fonts changing, 2526 default font, 26 screen elements related to, 26 settings, macro for, 383 Web sources for, 26 for ( ), Slick-C, 325 FTP/SSH, 302305 FTP Client, 304305
FTP tool window, 39, 305 set-up for, 302304 full screen, enabling, 35 functions, Slick-C, 311312 of arrays, 321 callbacks, 343346 commands, 311 and declarations, 326327 ordinary functions, 311312 primitive functions, 309, 312 use of, 326327 Functions definitions, selective display, 148 fundamental mode accessing, 174 key bindings in, 13 syntax assistance, suppressing, 185
G
games, Portable Game Notation (PGN), 365366 generic project type, 65, 71 global aliases file alias added to, 231232 functions of, 230 global tag databases building, 89 for C# source files, 104 for C/C++ with header files, 9293 Context Tagging features, confirming, 99100 converting to auto-updated tag database, 93 for DLL assemblies, 103 editing files in, 90 file management, 90 functions of, 89 for Java Jar files, 98100 for Java source files, 98100 naming, 92 for Ruby, 91 testing working of, 103 global variables, Slick-C, 330 GNU C/C++, installing, 47 GNU C/C++ project, 4760 building project, 5253 build systems, 60 creating project, 4952
459
Index
I
if ( ) hotspots, 181 Slick-C, 324 #include, navigate to header files, 119 incremental search options, changing, 133 steps in, 132133 indentation, 177180 C#, 179 C/C++, 178179 Extensions Options, Indent tab settings, 177 HTML, 180 Java, 179 insert-toggle, 215 installation emulation, selection of, 19 program installation directory, 30 user configuration directory, 30 integers, Slick-C, 314315
H
hash tables functions of, 321 Slick-C, 321322 header files C languages. See C/C++header files Slick-C, 311 here documents, 191192 hex mode color, changing, 176 switching to, 254
460
Integrated Development Environments (IDEs) features of, 34 functions of, 3 i-search incremental search, steps in, 132133 keyboard shortcut, 131
J
Java aliases for, 236 auto-updated tag database workspace, creating, 100102 compiler definitions, SlickEdit support, 102 indentation, 179 JAR files, adding to workspace, 102 JAR files, global tag database for, 98100 Jar files compared to source files, 98 libraries, tagging, 98 library, standard, 98 mode, 174 project with SlickEdit. See Java project source files, global tag database for, 100 JavaDoc comments, 195, 312 Java project, 6165 Ant, management with, 65 building project, 6162 creating project, 61 executing project, 62 Java Options dialog, 6263 JDK, installing, 61 unit tests, 6264 JavaScript, web programming, 191 JdbcTemplate, 99100 joining lines, common key settings, 29
event tables, 331 in fundamental mode, 13 listing, 1314 macros, binding to keys, 1516 setting, 1213 Subversion, 292293 syntax expansion, 181182 tool windows, toggle with, 39 WROX emulation, 21 See also command keys keyboard menus, accessing with, 21 search, commands, 131132 tool windows, activating, 3840 use versus mouse, 8 use versus toolbars, 35 keyboard customization, 362365 joining lines, 362363 page-down, 362 tabbing, 363365 key commands listing of, 408429 WROX emulation, 431434
L
language groups, contents of, 89 leading spaces, treating as tabs, 28 left margin, sizing, 25 lexers functions of, 174, 175 settings, 174 l/expr[/options], 141 libraries C/C++, tagging of, 9293 for dynamic languages, 90 global library tree, 90 Java, tagging of, 98 .NET runtime, tagging, 102104 path to, specifying, 92 Ruby, tagging of, 91 run-time, tag files, creating, 9697 standard, tagging of, 7374 third-party libraries, 95
K
key bindings, 1114 Bind Key dialog, 13 Concurrent Version System (CVS), 284285 Ctrl/Alt/Shift combinations, 13 dialog, features of, 1213 display, what-is command, 12 emulations, 11
461
Index
libraries
line(s)
line(s), 2629 highlighting, current line, 24 joining, 29 joining, macro for, 362363 line model, 26 moving up/down, macro for, 351353 navigation to, commands, 124 selection, 157, 160 settings, Redefine Common Keys dialog, 27 sorting within, 204 splitting, 29 as statements, 26, 159 stream model, 26 trailing spaces, stripping, 28 vertical line column, 24 wrapping. See line wrapping line commands, listing of, 153 line comments, 192194 applying, 193194 defined, 192 deleting, 193 wrapping, 193 Line Hex, 254 line model, 26 lines, navigation to, 124 line selection, 158159 line-to-bottom, 123 line-to-top, 123 line wrapping, 2728 cursor wrap, 27 line comments, 193 settings, 2728 soft wrapping mode, 28 word wrap mode, 28 list-buffers, 125, 127 list-clipboards, 154 list-keydefs, 1314 List Macros dialog, 15 list members, configuring, 78 list-source, programmatic configuration, 386 list-symbols, 105107 locked selections deselecting, 161162 moving among, 161 moving and copying, 161 select commands, 155157 long integers, Slick-C, 315 Look in selection box, Find and Replace tool window, 134 lookup tables, creating with alias, 239240 lowcase-selection, 156, 162 Lucinda Console, 26
M
ma alias, 232 McConnell, Steve, 34 macro(s), 1418 aborting, 16 binding to keys, 1516 and block insert mode, 204 command keys, 399 custom project, 72 custom projects, 7172 data alignment with, 225226 with DIFFzilla, 263264 edit command in, 117 in file manager, 301302 List Macros dialog, 15 loading macro, 1718 macros/directory macro source, 18 naming, 15, 16 next-word, use of, 122 programmatic configuration, macro source information, 387388 push bookmarks, use of, 128 recording, 1416 record-macro-end-execute, 14, 16 record-macro-toggle, 1416 saving, 15 source code, location of, 16 use of term, 14 writing macro, 1617 macro record and playback, 213219 data editing tips, 217220 and large files, 226227 macro, invoking, 216 pros/cons of, 213214
462
syntax assistance with, 218219 XML data, creating from test file, 214216 macros aliases with, 233234 file templates, instantiating in, 248252 keyboard customization, 362365 Slick-C. See Slick-C macros macro variables, 2223 functions of, 22, 330 settings, listing of, 429431 settings, macro for, 382383 set-var command, 23 Set Variable dialog, 2223 Slick-C, 330331 word completion options, 169171 main.e, 343 makefile build option, 60 and tab character, 365 make-tags, 102 Matched Error Expression, 70 match groups. See tagged expressions Maximums, exceeding limit, 110 members listing, 7678 list members, configuring, 78 menus accessing, Alt key combinations, 21 accessing, with keyboard, 21 pop-up, creating, 375378 merge, 266269 3 Way Merge, example of use, 266269 Concurrent Version System (CVS) conflicts, 278279 Subversion conflicts, 289290 message ( ), 332333 message area, functions of, 89 Microsoft Visual Studio, SlickEdit functionality with, 44 modes document mode, 253254 fundamental, changing to, 174 fundamental, key bindings in, 13 for programming languages, 13
selecting, 174 settings, 174 of SlickEdit, 174 modules, Slick-C, 309310 definit, 310 defload, 310 mouse, use versus keyboard, 8 move-to-cursor, 156, 161, 200 moving, with locked selections, 161 Multi-File Diff Output, 265 Multi-level mode, selective display, 149 multiline comments, 192, 194 defined, 192 inserting */, 194 JavaDoc, 195 My SlickEdit Config directory, 16
N
named bookmarks commands, 128 as set bookmarks, 128 uses of, 128129 navigation, 113130 bookmarks, 127130 in buffer, 120123 among buffers, 125127 to byte offset, 124 to columns, 124 command keys, 402404 cursor movement, commands, 120 to header files, 119 to lines, 124 opening files, 114119 pages, movement on, commands, 120 windows, positioning, 123 among words, 120 .NET DLL assembly, global tag database for, 103 New Project dialog, 49, 65 New Project Information dialog, 51 next, 124 next-bookmark, 128 next-buffer, 125, 126 next-buff-tab, 125
463
Index
next-buff-tab
Next Diff
Next Diff, 260 next-error, 53, 59, 62, 67 next-tag, 120 next-window, 125, 126 next-word, 120, 121, 122 numbers color, changing, 176 in Slick-C, 314315
P
page-down, 120 keyboard macro, 362 pages, navigation commands, 120 page-up, 120 paragraphs, selection, 156, 161 parameter information, 7880 configuring, 80 parsing Slick-C strings, 318320 unit tests, error parsing, 6870 Pascal, pascal-mode, 174 passes, auto-complete, 186187 paste, 154 troubleshooting, 16 pattern matching open dialog, 115116 and regular expressions, 137140 Perl, CxxTest tool, 57 PHP files, 191 plusminus, 136, 146 pointer style, C/C++, 178 pop-all-bookmarks, 127 pop-bookmark, 127 pop-up menu, creating, 375378 Portable Game Notation (PGN), 365366 color syntax highlighting, 366367 predefined expressions, listing of, 438439 prefix, search for, 143144 preprocessing C languages. See C/C++ selective display directives, 148 Slick-C, 311 prev-bookmark, 128 prev-buffer, 125, 126 prev-buff-tab, 125 Prev Diff, 260 prev-error, 53, 59, 62, 67 Preview tool window activating, 39 Context Tagging, 81 and source files, 100 symbol information in, 93
O
objects listing of, 336 Slick-C, finding, 334336 one file per window setting buffer-to-window, associating, 34 for split windows, 35 one-window, 34 Open dialog, 114116 Fast Open Dialog, 114115 file name combo box, 115 pattern matching, 115116 size issue, 116 opening files, 114119 cursor-error command, 119 edit command, 117 file and directory aliases, 116117 File Manager, 119 Files tool window, 117119 gui-open command, 114 header files, navigating to, 119 Open dialog, 114116 Open tool window, 117 Project tool window, 117 Open tool window activating, 39 to open files, 117 operating systems commands, 11 SlickEdit functionality, 5, 7 orientation, tool windows, 38 Output tool window, activating, 39 overlay-block-selection, 201202 overwrite mode, 215
464
prev-tag, 120 prev-window, 125 prev-word, 120, 121 primitive functions, 309, 312 procedures, selection, 156, 161 program installation directory, 30 programmatic configuration, 379388 aliases, defining, 381 definitions/code, loading, 380381 extension-specific settings, 384 font settings, 383 list-source, use of, 386 macro recording for determining, 384386 macro source, reading, 387388 macro variable settings, 382383 setting code, macro for, 380381 programming auto-complete, 188189 coding styles, 177 programming languages SlickEdit modes, 13 See also Slick-C; dynamic languages; embedded languages; specific languages programming language support, 365372 Groovy language example, 367372 Portable Game Notation (PGN) example, 365366 project(s), 4972 Active Project, 44 Add Source Files dialog, 52 Add Tree, 45, 52 Add Wildcard, 52 build dependency, 44 build system options, 51, 60 Build tool window, 5253 command keys, 405 console application, example, 46 custom project, steps in, 7072 defined, 4344 dependency checking, 60 errors, navigation among, 53 generic project type, 65, 71 GNU C/C++ project with SlickEdit. See GNU C/C++ project Java project with SlickEdit. See Java project
New Project dialog, 49 New Project Information dialog, 51 preconfigured in SlickEdit, 70 project definition, 45 Project Properties dialog, 5153 projects files, placement of, 50 project type, determining, 44 project type, selecting, 50 Ruby with SlickEdit. See Ruby project storing, file for, 43 tag files, 45 target configurations, 6061 workspaces for, 4344 project-build, 52, 61 project-edit, 97, 108 project-execute, 53, 59 Project Properties dialog, 5153, 97 executing project, 53 functions of, 51 GNU C/C++ project, 5152 opening, 51 Project tool window activating, 39 to open files, 117 properties, Slick-C, 312314 documentation on, 312 functions of, 312 listing of, 312313 pserver, Concurrent Version System (CVS), accessing, 272 pushed bookmarks, 83 commands, 128 functions of, 127, 152 in macros, 128 push-ref, 127 troubleshooting, 107, 111 push-tag, 93, 94, 127 troubleshooting, 105106
Q
quick-reverse-search, keyboard shortcut, 131 quick-search key binding commands, 12
465
Index
quick-search
quick-search (continued)
quick-search (continued) keyboard shortcut, 131 use of, 132 quote-key, 185 replace-in-files, 132133, 137 See also search and replace replace/exp1/exp2[/options], 141 resolution, display, 33 reverse-i-search incremental search, 133 keyboard shortcut, 131 ring, buffers, 125126 Ruby downloading/installing, 65 global tag database for, 91 here documents, 192 libraries, tagging, 91 project with SlickEdit. See Ruby project Ruby project, 6570 creating project, 66 error navigation, 67 executing project, 6667 unit tests, 6770
R
record-macro-end-execute, 14, 16, 216217 record-macro-toggle, 1416, 214, 216 Redefine Common Keys common key settings, 2829 line wrapping, settings, 2728 white space, settings, 28 redo, 152 refactor-option, 97 references, navigating to, 8283 References tool window activating, 39 improving performance, 111 troubleshooting, 111 updates, 111 Regex Evaluator tool window, 305 regular expressions backslash in, 139 Brief, 137139 defined, 137 Error Regular Expressions, 6870 examples of, 141 Regex Evaluator tool window, 305 Regular Expression Evaluator tool window, activating, 39 search and replace with, 137141, 221 SlickEdit, 137139 syntax, listing of, 435438 and tagged expressions, 140 UNIX, 137139 remote editing, FTP/SSH, 302305 Remove Tag File, 93 remove-training-spaces, 28, 157, 162 Reorder windows, 126 replace keyboard shortcut, 132 Replace, 137
S
saving, selections, 163164 say ( ), 333 SBCS/DBCS Source Window, 25 screen. See display scripting language here documents, 191192 See also Slick-C scroll buffer, positioning, commands, 123 scroll-down, 123 scroll-left, 123 scroll-right, 123 scroll-up, 123 search command keys, 405406 quick-search, key bindings, 1213 Slick-C, 338339 search and replace, 131150, 220222 color, search match, 176 color syntax searching, 135, 144145 command-line search/replace, 141146 data editing pros/cons, 220221 default search options, configuring, 149150
466
Find and Replace tool window, 133137 incremental search, 132133 keyboard search, 131132 long search, terminating, 132 quick-search, 132 with regular expressions, 137141, 221 selections, 162 selective display, 146149 with tagged expressions, 140 XML data, creating from test file, 221222 Search Results tool window activating, 39 functions of, 136 options, choosing, 136 seek, 124 seek +n, 124 seek n, 124 seek -n, 124 selections block selection, 159160, 200201 character selection, 157158 character sequence model, 153 clipboard operations, 153 code block, 160161 color, changing, 176 configuring, 164165 deselecting, 161162 filtering, 163 functions of, 153 lines, 160 line selection, 158159 locked selections, 155157 moving among, 161 moving and copying, 161 paragraphs, 161 procedure/function/method, 161 reuse of, 163164 saving, 163164 searching and replace, 162 select commands, 155157 Slick-C macros, 339 sorting, 204 words, 160
selective display, 146149 command-line, 149 custom capability, 148149 Functions definitions, 148 Multi-level mode, 149 predefined commands, 146147 Preprocessor directives, 148 select-mode, 174 set-bootmark, 128 set-var command, 23 Set Variable dialog, 2223 shared tag database, and auto-updated tag databases, 90, 9394 Shift key, key binding commands, 12 shift-selection-left, 156, 162 shift-selection-right, 157, 162, 203 show-all, 141, 146 show-procs, 146, 147 signature, Byte Order Mark (BOM), 255 Single Byte Character Set/Double Byte Character Set (SBCS/DBCS), 255 Slick-C aliases for, 237 arguments, 318, 327330 arrays in, 320321 batch macros, 310311 callbacks, 343346 Call Stack Tool window,activating, 39 commands, 11, 328330, 332 configuration placed in. See programmatic configuration control structures, 324326 declarations, 326327 event tables, 331 functions, 309, 311312, 326327 functions of, 6 global variables, 330 hash tables, 321322 header files, extension, 311 help, online, 312 JavaDoc, 195, 312 language, features of, 308309 macros. See Slick-C macros
467
Index
Slick-C
Slick-C (continued)
Slick-C (continued) mode, 174 modules, 309310 names, caution about, 309310 numbers in, 314315 parsing, 318320 preprocessing, 311 properties, 312314 static variables, 330 strings in, 315320 structs, 323 typeless type, 323324 Slick-C macros, 331358 aliases, defining, 381 buffer, interaction with, 337 callback traces, example macro, 353354 code, executing, 332 configuration-settings, placement in, 380381 debug messages, display, 332333 duplicate line counting, example macro, 347348 execute-selection, 332 executing macro, 332 extension-specific settings, 384 files, choosing, 342 files/directories, listing, 340342 font settings, 383 HTML end tag insertion, example macro, 348351 line movement, example macro, 351353 macro variables, 330331 macro variable settings, 382383 N-Queens, example macro, 357358 objects, finding, 334336 search with, 337339 selections, 339 stack traces, 333334 temporary buffers, use of, 340341 terminating, 332 WROX function names conversion, example macro, 355356 SlickEdit command keys, listing of, 392407 compared to other IDEs, 4 configurability of, 4, 19 as development environment, 5 emulations, 5, 1921 extensibility of, 56 key bindings, 1114 key commands, listing of, 408429 macros, 1418 macro variable settings, listing of, 429431 operating systems and functionality, 5, 7 programmability of, 5 scripting language. See Slick-C user interface, 79 versions of, 7 Smart next window, 126 smarttab, 364365 snapshots, Backup History tool window, 269270 soft wrapping mode, enabling, 28 sorting commands, 204 file manager files, 300 source files Add Source Files dialog, 52 dynamic languages, tagging, 90 Java, compared to Jar files, 98 Java, global tag database for, 100 and preview tool window, 100 spaces leading, treating as tabs, 28 tabs to spaces, converting, 28 trailing, removing, 28 special characters, display of, 25 splitting lines, common key settings, 29 split windows commands, 3435 moving between, 35 one file per window setting, 35 Spring library. See Java SQL aliases for, 236 plsql-mode, 174 stable, sorting algorithm, 204 stack traces, 333334 navigating, 334
468
standard libraries, tagging, 7374 Standard Toolbar, 35 state file configuration directory, 30 functions of, 30 saving on exit, 30 statement, line as, 26, 159 static variables, Slick-C, 330 status indicators, location of, 9 stdcmds.e, 343 stream model, 26 strings, color, changing, 176 strings, Slick-C, 315320 concatenation of, 316 delimiters, 315316 examples of, 316317 indexed, 316 parsing, 318320 stripping, 316 structs, Slick-C, 323 substitution parameters file templates, 242, 246248, 250 listing of, 246247 Subversion, 285293 branches and tags, 290291 browse history, 291 changes, committing, 289 changes, review of, 289 configure for SlickEdit, 287 environment variables with, 286 files, adding to, 289 functions of, 285286 hidden files, viewing, 286 key bindings, 292293 merge conflicts, 289290 new project, creating, 287 reference work on, 286 shortcuts, 292293 Update Directory, 289 working copy, checking, 288 suffix, search for, 143144 surround-with aliases, 238 control-structure, adding, 182183
switch, 290291, 325326 symbols adding to tag file, 108 duplicate names problem, 110, 111 Find Symbol tool window, 39, 84 grep-tag options, 85 large projects, problems with, 110 list-symbols, 105107 qualified and tagging problems, 106 in tag database, 73 unqualified and tagging problems, 105106 Symbols tool window activating, 39 use of, 8788 syntax assistance macro record and playback with, 218219 suppressing, 185 word completion, 168169 syntax expansion with aliases, 237238 example of, 181182 key bindings, 181182
T
tabs characters, jump over, 27 converting to spaces, 28 indentation, 177180 keyboard behavior, changing, 363365 leading spaces, treating as, 28 smarttab, 364365 tag databases, 89104 automating creation of, 96 auto-updated tag databases, 90 categories of, 89 compiler definition, creating, 9698 creating (tagging), 73 creating, 9596, 102 file types, specifying, 92 global tag databases, 8990 language, categorization by, 74 naming, 92
469
Index
tag databases
tag files
tag files cache size, 111 functions of, 45 managing, 8889 rebuilding, 109 for run-time libraries, 9697 symbols, adding to, 108 tagfiles, configuration directory, 31 workspaces, 44 tagged expressions and regular expressions, 140 search and replace with, 140 tagging Concurrent Version System (CVS), 282283 defined, 43, 73 and dynamic languages, 9091 Subversion, 290291 testing, push-tag, 94 See also Context Tagging; tag databases target configurations defaults, 60 GNU C/C++ project, 60 templates complex code, problems, 111112 configuration directory, 31 custom project definitions, 71 metaprogramming, 112 See also file templates temporary buffers, Slick-C, 339340 Test Case, 70 test runner, GNU C/C++ project, 5758 test suites GNU C/C++ project, 5457 Java project, 63 text, shifting left-right, 158159 text editing, 151172 clipboard, 153155 line commands, 152153 redo, 152 selections. See selections undo, 152 word completion, 165171 3 Way Merge, example of use, 266269 toggle, edit buffer to command line, 10 toggle-all-outlining, 146, 147 toggle-bookmark, 128 toolbars command keys, 406 Current Context, 35 customizing, 35 defaults, restoring, 40 File Tabs, 78 specialized, 35 Standard, 35 tool windows, 3540 activate with keyboard, 3840 animation, 40 arrangement, changing, 3738 arrangement options, 3637 defaults, restoring, 40 docked, 3638 floating, 3638 functions of, 8, 3536 hidden, 8 orientation, 38 toggle with keyboard bindings, 39 updates, 38 top-of-buffer, 120121, 202 Top of file line, 25 top-of-window, 120 trace callback traces, 353354 stack traces, 333334 trailing spaces removing, 28 selection, 157, 162 stripping, 28 typeless type, Slick-C, 323324
U
underscores, in commands, 9, 328 undo, 152, 227 undo-cursor, 152 Unicode byte offset, 124 Byte Order Mark (BOM), 124, 255 Unicode Source Window, 25
470
unit tests CxxTest, 5458 error parsing, 6870 GNU C/C++ project, 5460 Java project, 6264 Ruby project, 6770 running tests, 5960, 64, 68 test runner, 5758 test suites, 5457, 63 UNIX configuration directory location, 16 extensionless shell scripts, 175 path, specifying, 96 regular expressions, 137139 regular expression syntax, listing of, 435438 Ruby, downloading/installing, 65 unsurround, 185 upcase-selection, 156, 162 updates and configuration directory, 30 tool windows, 38 UP/Down within soft wrapped lines, 2728 on text, 27 URL resources, downloading, macro for, 257258 uscheme.ini, configuration directory, 31 user configuration directory, 30 user.cpp, configuration directory, 31 user interface, 79 Build tool window, 9 command line, 1011 editing pane, 78 message area, 89 status indicators, 9 toolbar, 78 tool windows, 8 usrprjtemplates.vpt, 71 util.e, 343
static, 330 typeless container type, 323324 variable arguments, Slick-C, 327 version control. See Concurrent Version System (CVS); Subversion Version Control Setup dialog, 272274 View Files in Current Project, 118 Visual C++6 command keys, listing of, 392407 key commands, listing of, 408429 macro variable settings, listing of, 429431 Visual Studio command keys, listing of, 392407 key commands, listing of, 408429 macro variable settings, listing of, 429431 vrestore.slk, configuration directory, 31 vsdelta, configuration directory, 31 vslickconfig, 32 vslick.sta, 379 vslick.stu, 379 vsmktags, 95 vsplit-window, 34 .vtg file, workspaces, storing, 43 vusrdefs.e, configuration directory, 31 vusrmacs.e directory, 1617
W
Web programming, embedded languages, 190191 what-is, key bindings, display of, 12 while ( ), Slick-C, 325 white space, settings, 2728 whole word, search by, 134 wildcards add wildcard, 45 in File tools window, 118 window(s), 3440 buffer-to-window, associating, 34 command keys, 407 configuration settings, 126 full screen, 35 Maximize first window, 24 navigation among, 120
V
variable(s) global, 330 macro, 2223, 330331
471
Index
window(s)
window(s) (continued)
window(s) (continued) one file per window setting, 34 positioning, commands, 123 split windows, 3435 tool windows, 3540 use of term, 7 Windows configuration directory location, 16 Fast Open Dialog, 114115 wizards, and IDEs, 3 word(s) navigation among, 120 selection, 156, 160 word completion, 165171 compared to auto-complete, 186188 compared to auto-complete, 190 examples of, 166167 options, 169171 in programming, 168169 usefulness of, 165 word wrap mode, 28 workspace(s), 4349 for auto-updated tag database, 9495, 100102 directory, 44 functions of, 43 Jar files, adding to, 102 naming, 95 for projects, 4344 storing, file for, 43 tag databases, updating, 95 tag files, 44 tag files, rebuilding, 109 tagging, 74 vsmktags, 95 workspace definition, 45 workspace state, 45 workspace-close, 283 workspace-open, 283 Workspace Tag File, contents of, 89 wrapping. See line wrapping WROX emulation, 21 and DIFFzilla, 261 function names, converting, macro for, 355356 key commands, 431434 tool windows, keyboard activation, 3839 wrox-align-left-with-field-above, 223225 wrox-align-right-with-field-above, 223225 wrox-diff-lines, 264 wrox-makestacktrace, 333334 wrox-next-whitespace-word, 217, 224225 wrox-next-word, 120, 121122 source code for, 122123 wrox-prev-whitespace-word, 217, 261 wrox-prev-word, 120, 121 source code for, 122123 wrox-restore-line-sel, 163164 wrox-retain-exts, 301 wrox-save-line-sel, 163164 wrox-toggle-comment, 193194
X
XML auto-validation, 257 Document Type Definition (DTD), 255258 SlickEdit DTE retrieval, 256257 tags, matching of, 350 XML Schema, 25525
472
Programmer to Programmer
TM
Find books on
ASP.NET C#/C++ Database General Java Mac Microsoft Office
.NET Open Source PHP/MySQL SQL Server Visual Basic Web XML
www.wrox.com