Download as pdf or txt
Download as pdf or txt
You are on page 1of 506

22150ffirs.

qxd:WroxPro

9/25/07

12:12 AM

Page v

Professional

SlickEdit
John Hurst

Wiley Publishing, Inc.

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page ii

22150ffirs.qxd:WroxPro

9/25/07

1:20 PM

Page i

Professional SlickEdit
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv

Part I: Getting Started with SlickEdit

Chapter 1: Introducing SlickEdit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3


Chapter 2: Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Chapter 3: Managing Windows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Part II: Using SlickEdit

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

Part III: Advanced SlickEdit

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

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page ii

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page iii

Professional

SlickEdit

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page iv

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page v

Professional

SlickEdit
John Hurst

Wiley Publishing, Inc.

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page vi

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.

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page vii

For Zena.

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page viii

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page ix

About the Author


John Hurst has been programming computers for fun and profit since he was 14. He started with BASIC
on a home computer and then moved on to Pascal and C. He has worked with many other languages
since, and today works mostly with Java and Ruby.
He is an independent consultant/developer and provides design, development and training services
to companies in New Zealand and Australia. You can find out about John on his website at http://
www.skepticalhumorist.co.nz.
John lives in Wellington, New Zealand, with his partner, Zena, and their two children, Rose and Oliver.

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page x

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page xi

Credits
Acquisitions Editor

Compositor

Chris Webb

Kate Kaminski, Happenstance Type-O-Rama

Development Editor

Proofreader

Kenyon Brown

Nancy Carrasco

Technical Editor

Indexer

Mark Berger

Melanie Belkin

Production Editor

Project Coordinator, Cover

Debra Banninger

Lynsey Osborn

Copy Editor

Media Development Project Supervisor

Cate Caffrey

Laura Atkinson

Editorial Manager

Media Development Specialist

Mary Beth Wakefield

Angie Denny

Production Manager

Media Quality Assurance

Tim Tate

Kit Malone

Vice President and Executive Group Publisher

Anniversary Logo Design

Richard Swadley

Richard Pacifico

Vice President and Executive Publisher


Joseph B. Wikert

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page xii

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page xiii

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.

22150ffirs.qxd:WroxPro

9/25/07

12:12 AM

Page xiv

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

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xv

Contents
Acknowledgments
Introduction

xiii
xxv

Part I: Getting Started with SlickEdit

Chapter 1: Introducing SlickEdit

Programmers Edit Code


Power Editing with SlickEdit
SlickEdit As a Development Environment
Multiple Platforms
Customizable
Extensible: Slick-C

This Book
SlickEdit Terminology
Overview of Interface
The Build Tool Window

Commands and the Command Line


The Command Line

Key Bindings
Setting Key Bindings
Listing Key Bindings

Macros
Recording a Macro
Writing a Macro
Loading a Macro
Supplied Macro Source

Summary

Chapter 2: Configuration
Emulations and Key Bindings
The WROX Emulation
Alt Keys

3
4
5
5
5
6

6
7
7
9

9
10

11
12
13

14
14
16
17
18

18

19
19
21
21

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xvi

Contents
Macro Variables
Using the Set Variable Dialog
Using the set-var Command

22
22
23

Common Settings

24

Appearance
Fonts
Line Behavior

24
25
26

Managing Configurations
Configuration Directory
Reverting to the Default Configuration
Working with a Different Configuration

Summary

Chapter 3: Managing Windows


Windows and Buffers
Split Windows
Full Screen
Toolbars
Tool Windows
Tool Window Arrangement
Activating Tool Windows with the Keyboard
Tool Window Animation
Restoring the Defaults

Summary

30
30
30
31

32

33
34
34
35
35
35
36
38
40
40

40

Part II: Using SlickEdit

41

Chapter 4: Workspaces and Projects

43

How to Organize Your Files


The Example
Creating a GNU C/C++ Project

45
46
47

Creating the Project


Building the Project
Executing the Project
Adding Unit Tests
Target Configurations
Build Systems

49
52
53
54
60
60

Creating a Java Project

61

Creating the Project

61

xvi

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xvii

Contents
Building the Project
Executing the Project
Adding Unit Tests
Managing the Project with Ant

Creating a Project for a Dynamic Language


Creating the Project
Executing the Project
Adding Unit Tests

Custom Projects
Summary

Chapter 5: Context Tagging


Setting Up for Tagging
Tagging Your Workspace
Tagging Built-in and Standard Libraries

Listing Members
Configuring List Members

Getting Parameter Information


Configuring Parameter Information

61
62
62
65

65
66
66
67

70
72

73
74
74
74

76
78

78
80

Navigating with Symbols

81

The Preview Tool Window


Navigating to Definitions
Navigating to References
Pushed Bookmarks

81
81
82
83

Finding Symbols
The Find Symbol Tool Window
Using the grep-tag command

Browsing Definitions
The Defs Tool Window
The Class Tool Window
The Symbols Tool Window

Managing Tag Files


Global Tag Databases
Auto-Updated Tag Databases
Tagging Dynamic Languages
Tagging C/C++ Libraries
Tagging Java Libraries
Tagging .NET Runtime Libraries

The C/C++ Preprocessor


Troubleshooting Tagging
Go to Definition Doesnt Work

84
84
85

85
85
86
87

88
89
90
90
92
98
102

104
105
105

xvii

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xviii

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

109

Tuning Maximums
Tag Cache Size
References
Complex Code

110
111
111
111

Summary

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

Moving Around
Navigating in the buffer
Positioning the Window
Navigating to a Line, Column, or Byte Offset
Navigating among Buffers

Bookmarks
Pushed Bookmarks
Named Bookmarks
Configuring Bookmarks

Summary

Chapter 7: Search and Replace


Keyboard Searching
Terminating a Long Search
Quick Search
Incremental Search

xviii

112

113
114
114
116
117
117
119
119

119
120
123
124
125

127
127
128
129

130

131
131
132
132
132

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xix

Contents
The Find and Replace Tool Window
Using Find
Using Find in Files
Using Replace and Replace in Files

Regular Expressions
Tagged Expressions
Regular Expression Examples

Command-Line Search and Replace


Command-Line Options
Command-Line Search Examples

Selective Display
Predefined Selective Display
Custom Selective Display

Configuring Default Search Options


Summary

133
134
135
137

137
140
141

141
143
145

146
146
148

149
150

Chapter 8: Editing Text

151

Using Basic Editing

152

Undo and Redo


Line Commands

152
152

Using Selections and Clipboards

153

Working with the Clipboard


Locked Selections
Selection Models
Special Selection Commands
Working with Selections
Using Selection Scopes
Saving and Reusing Selections
Configuring Selection Options

153
155
157
160
161
162
163
164

Saving Typing with Word Completion


Introduction to Word Completion
Word Completion in Programming
Options with Word Completion

Summary

Chapter 9: Editing Code


File Extensions, Modes, and Lexers

165
165
168
169

171

173
173

Extensionless Files

175

Syntax Highlighting

175

xix

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xx

Contents
Indentation and Code Style
C/C++ Options
Java and C# Options
HTML Options
Other Languages

Working with Control Structures


Syntax Expansion
Adding a Control Structure
Dynamic Surround
Deleting a Control Structure
Avoiding Syntax Assistance

Unified Completions with Auto-Complete


Introduction to Auto-Complete
Auto-Complete in Programming
Configuring Auto-Complete
Manual Completion or Auto-Complete?

Embedded Languages
Web Programming
Here Documents in Scripts

178
179
180
180

180
181
182
183
184
185

186
186
188
189
190

190
190
191

Working with Comments

192

Line Comments
Multiline Comments
JavaDoc Comments
Configuring Comments

193
194
195
195

Summary

Chapter 10: Editing Data


Block Selection
Moving, Copying, and Deleting with Block Selections
Navigating Block Selections

197

199
200
200
202

Entering Data in Columns

202

Filling Data
Using Block Insert Mode

203
203

Sorting Data
Generating Data
Calculating with Data
Manipulating Data
Block Editing
Macro Record and Playback
Search and Replace with Data

xx

177

204
205
206
207
208
213
220

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xxi

Contents
Aligning Data
Large Data Files
Summary

Chapter 11: Aliases and File Templates


Aliases
File Aliases
Using Aliases in Code
Dynamic Directory Aliases
Extension-Specific Aliases
Syntax Expansion with Aliases
Surround Aliases
Aliases with Parameters
Aliases and Configuration

File Templates
Instantiating a Template
Creating a Template
Substitution Parameters
Managing Templates
Instantiating Templates in Macros

Summary

Chapter 12: Document Types


Document Mode
Binary Files
Character Sets and Encodings
XML Document Types
Summary

Chapter 13: Comparing and Merging


Comparing Files and Directories
Comparing Two Files
Comparing Sections within a File
Comparing Directories
DIFFzilla Options
Running DIFFzilla Standalone

Merging Changes
Backup History
Summary

222
226
227

229
229
230
232
234
235
237
238
239
240

241
241
242
246
248
248

252

253
253
254
254
255
258

259
259
260
262
265
266
266

266
269
270

xxi

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xxii

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

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

Summary

Part III: Advanced SlickEdit


Chapter 15: Other Tools
The File Manager
File Manager Commands
Selecting Files
Automating Tasks

FTP/SSH for Remote Editing


The FTP Client
Using HTTP To Open Web Pages

The Regex Evaluator


Summary

Chapter 16: Slick-C Macro Programming


The Slick-C Language
Modules and Names

xxii

271
271
272
274
275
277
278
278
279
282
283
284

285
287
287
288
289
289
290
291
292

293

295
297
298
299
300
301

302
304
305

305
306

307
308
309

22150ftoc.qxd:WroxPro

9/25/07

12:13 AM

Page xxiii

Contents
Preprocessor
Functions
Properties
Data Types
Control Structures
Declarations and Definitions

Working with Macros


Executing Slick-C Code
Terminating a Macro
Writing Messages
Stack Traces
Finding Slick-C Objects

Useful Techniques
Interacting with the Buffer
Searching
Selections
Temporary Buffers
Listing Files and Directories
Choosing Files
Useful Macro Files
Callbacks

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

Summary

311
311
312
314
324
326

331
332
332
332
333
334

336
337
337
339
339
340
342
342
343

346
347
348
351
353
355
357

359

Chapter 17: Customization

361

Keyboard Customization

362

Example: Page-Down
Example: Joining Lines
Example: Tabbing Behavior

362
362
363

Custom Language Support

365

Example: Portable Game Notation Files


Example: Groovy Language

Customizing Menus and Dialogs


Customizing a Dialog
Creating a Pop-up Menu

365
367

372
372
375

xxiii

22150ftoc.qxd:WroxPro

9/26/07

7:12 AM

Page xxiv

Contents
Programmatic Configuration
Loading Key Definitions and Code
Defining Aliases
General Configuration Settings
Determining Programmatic Configuration

Summary

Appendix A: Settings for Different Emulations

378
380
381
382
384

389

391

Command Keys by Category

392

Debugging Commands
Editing Commands
File Commands
Macro Commands
Miscellaneous Commands
Navigation Commands
Project Commands
Search Commands
Toolbar Commands
Window Commands

392
394
398
399
399
402
405
405
406
407

Key Commands
Macro Variable Settings
WROX Emulation Key Commands

Appendix B: Regular Expression Syntax


Predefined Expressions

408
429
431

435
438

Appendix C: SlickEdit Callbacks

441

Appendix D: Whats on the CD-ROM

445

System Requirements
Using the CD with Windows
Using the CD with Linux and UNIX
Using the CD with the Mac OS
Whats on the CD

445
447
447
448
448

Author-Created Materials
Applications

448
449

Troubleshooting

449

Customer Care

449

Index

xxiv

451

22150flast.qxd:WroxPro

9/25/07

12:15 AM

Page xxv

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.

Whos the Book For?


This book is intended for experienced programmers. You are more than comfortable with computers.
You do not need to be told how to install simple software packages, or how to navigate your directory
tree to open a file, or how to select text with a mouse. You should have a preference for using the keyboard rather than the mouse, for tasks you do regularly.
If you are using SlickEdit, you almost certainly have experience in other programming environments,
and you probably program in more than one language, perhaps on more than one platform. On the
other hand, SlickEdit is not about any particular programming language.

Whats Covered in the Book?


SlickEdit is a very feature-rich product. This book does not attempt to document every feature. The
SlickEdit User Guide that is shipped with the product does not even document every feature, and it is
longer than this book!
Instead, this book covers techniques and strategies to make the most of SlickEdit. I hope that, by reading
this book, you will learn about one or two (at least!) nice features you didnt know about. But more importantly, if you are new to SlickEdit or havent explored it in detail, I hope you will learn some ways of making it work effectively for you.
It would be hard to guess which programming languages and environments are most common among
SlickEdit users, since SlickEdit works well with all programming languages and most operating systems. SlickEdit has many features that support certain programming languages, but I personally feel
that its feature set for C/C++ is the strongest. Nevertheless, in this book, we will not be focusing very
much on particular languages. SlickEdit supports compiling running and debugging programs in C/C++
and other languages, but we wont concentrate on those aspects. Instead, were going to focus mainly on
editing and related tasks, and also on how you can customize and extend SlickEdit to meet your needs,
regardless of what programming language you are using. Most of the information in this book should
apply to all programming languages. If you dont find examples in the language youre using, you should
still find the techniques useful.

22150flast.qxd:WroxPro

9/25/07

12:15 AM

Page xxvi

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

22150flast.qxd:WroxPro

9/25/07

12:15 AM

Page xxvii

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.

Go to http://p2p.wrox.com, and click the Register link.

4.

You will receive an e-mail with information describing how to verify your account and
complete the joining process.

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 can read messages in the forums without joining P2P, but in order to post your own messages, you
must join.

xxvii

22150flast.qxd:WroxPro

9/25/07

12:15 AM

Page xxviii

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

22150flast.qxd:WroxPro

9/25/07

12:15 AM

Page xxix

Professional

SlickEdit

22150flast.qxd:WroxPro

9/25/07

12:15 AM

Page xxx

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 1

Part I: Getting Started


with SlickEdit
Chapter 1: Introducing SlickEdit
Chapter 2: Configuration
Chapter 3: Managing Windows

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 2

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 3

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.

Programmers Edit Code


These days programming is dominated more and more by Integrated Development Environments
(IDEs). IDEs can be very useful and productive in many situations. They tend to emphasize certain
aspects of the development process such as setting up projects, organizing code, and debugging.
Many tasks in IDEs are done with wizards, which lead the user through a process, collecting information to complete a task.
Software development does involve a lot of different activities. Its important to use tools that
make your workflow smooth and efficient. But the focus on wizards and other bells and whistles
in IDEs misses an important point. Despite all these other activities, the single thing programmers
spend most of their time doing is editing code.
In his book Code Complete (2nd ed., Microsoft Press, 2004), Steve McConnell cites evidence that
some programmers estimate they spend as much as 40 percent of their time editing source code.
He recommends using a good IDE, and gives a list of features:

Compilation and error detection from within the editor.

Integration with source-code control, build, test, and debugging tools.

Compressed or outline views of programs.

Jump to definitions of classes, routines, and variables.

Jump to all places where a class, routine, or variable is used.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 4

Part I: Getting Started with SlickEdit

Language-specific formatting.

Interactive help for the language being edited.

Brace (begin-end) matching.

Templates for common language constructs.

Smart indenting.

Automated code transforms or refactorings.

Macros programmable in a familiar programming language.

Listing of search strings so that commonly used strings dont need to be retyped.

Regular expressions in search and replace.

Search and replace across a group of files.

Editing multiple files simultaneously.

Side-by-side diff comparisons.

Multilevel undo.

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.

Power Editing with SlickEdit


In The Pragmatic Programmer (Addison-Wesley, 1999), Andrew Hunt and Dave Thomas devote a section
to Power Editing. They summarize their position as Use a Single Editor Well. They list several
environment-specific features it is desirable for an editor to have, such as syntax highlighting, autocompletion, and autoindentation. But more important than any such specific features, they outline three
basic abilities we think every decent editor should have:

Configurable All aspects of the editor should be configurable to your preferences, including
fonts, colors, window sizes, and keystroke bindings (which keys perform what commands).
Using only keystrokes for common editing operations is more efficient than mouse or menudriven commands, because your hands never leave the keyboard.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 5

Chapter 1: Introducing SlickEdit

Extensible An editor shouldnt be obsolete just because a new programming language


comes out. It should be able to integrate with whatever compiler environment you are using.
You should be able to teach it the nuances of any new language or text format (XML, HTML
version 9, etc.).

Programmable You should be able to program the editor to perform complex, multistep
tasks. This can be done with macros or with a built-in scripting language (Emacs uses a variant
of Lisp, for instance).

These abilities are at the center of SlickEdits philosophy and design.

SlickEdit As a Development Environment


IDEs tend to be targeted at specific programming platforms and specific development processes. They
automate a variety of standard tasks with wizards and other tools. They can be very productive if you
are comfortable working the IDEs way.
SlickEdit has a lot of overlap with IDEs. It also provides support for a lot of IDE-type features: building,
running, and debugging programs. The main focus of SlickEdit is a little different though. Rather than
focusing on a particular programming platform, SlickEdit places the emphasis on editing and navigating
code. The SlickEdit philosophy is that programmers spend most of their time writing code, and SlickEdit
aims to make that as fast and productive as possible.
SlickEdit is fast. IDEs get loaded up with more and more features. Many of them are useful, but they all
come at a price. How long does it take the IDE to open a file? How responsive is it while typing in code?
Many IDEs have so many intelligent features that they spend a lot of time thinking while youre trying
to type in code. SlickEdit is always responsive.

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.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 6

Part I: Getting Started with SlickEdit


Many configuration settings are available as settings in the extensive configuration dialogs. Others are
controlled by environment and macro variables. But it doesnt stop there. Beyond configuration,
SlickEdit is also very extensible.
Many Integrated Development Environments (IDEs) are extensible to some degree. These days, plug-ins
are a popular way to extend IDEs. But in most cases, the plug-in system is relatively complex, with a
steep learning curve before anything useful can be achieved. Because most plug-ins require a considerable amount of work, plug-ins are generally used for significant add-on modules only.

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.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 7

Chapter 1: Introducing SlickEdit


This book is written from my own perspective. I was a C++ programmer when I started with SlickEdit,
and C/C++ programming is perhaps SlickEdits strongest area. But Im not a C/C++ programmer
now, and I have not used SlickEdit for C or C++ for quite some time. I dont know the details of many
aspects of C/C++ features in SlickEdit, and we wont be covering those features. For example, SlickEdit
has debugger integration, but we dont cover that at all in this book.
Although SlickEdit is available for many different operating systems, Windows is probably the most
common. The screen shots in this book are almost all taken on Windows. In most cases, the discussion
should apply to all operating systems equally well, but in some cases there are differences. For example,
Macs use different keyboards from most computers, thus the discussion of Alt key bindings in Chapter 2
does not work with Macs.
The current version of SlickEdit at the time of this writing is 12.0.2, which was released in July 2007. The
12.x series of SlickEdit is marketed as SlickEdit 2007. Most of this book was written using SlickEdit
12.0.0 and 12.0.1 for examples. Naturally, things change from version to version. I hope that most of the
material in this book will remain useful and relevant through future versions of SlickEdit, but without
doubt some changes in future versions will be incompatible with information presented here. Updates to
macro sources will be placed online.

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.

Over view of Interface


Figure 1-1 shows the SlickEdit user interface. The main part of the window is the editing pane. Below the
editing pane is the File Tabs toolbar, showing the open files. SlickEdit has several other toolbars, not shown.
Toolbar functions are generally invoked using the mouse, and in most cases it is a lot faster and easier to
use the keyboard, rather than the mouse.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 8

Part I: Getting Started with SlickEdit

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.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 9

Chapter 1: Introducing SlickEdit


To the right of the message area are several status indicators. For example, you can see the current line
and column, the state of the current selection, and the character code at the cursor position. There is a lot
more to SlickEdit than this main window. We cover many dialogs and tool windows throughout the book.

The Build Tool Window


One tool window worth mentioning now is the Build tool window. This tool window contains build output when you compile and/or run programs within SlickEdit.
We cover compiling and running in Chapter 4.
The Build tool window also provides an operating system shell environment. For example, Figure 1-2
shows the Build tool window with the output of a dir command on Windows. You can enter any operating system command in the Build tool window. You can also navigate around the window, scroll back
through its history, and copy/paste from and to it.

Figure 1-2

Commands and the Command Line


Commands are at the core of SlickEdits power and flexibility. Virtually every operation in SlickEdit is a
command. For example, simple cursor movement is performed by the commands cursor-up, cursordown, cursor-left, and cursor-right. Complex operations are also performed by commands, such
as config and project-compile. In fact, SlickEdit ships with several thousand commands! Dont
worry though; you only need to remember a small fraction of these to master SlickEdit.
When a command consists of two or more words, it is defined internally in SlickEdit with the words separated by underscores, like cursor_up. You will use this form when you define your own commands.
However, for better readability, SlickEdit displays these commands using hyphens instead of underscores,
and they can usually be entered either way: cursor-up or cursor_up.
Commands are fundamental to the way SlickEdit works, particularly when customizing and extending
SlickEdit via macro programming. For example, when doing macro programming, you probably will
have occasion to use the cursor-up command to move the cursor. With this in mind, we focus on command names first and give keyboard shortcuts and menu choices when applicable. When we introduce
a feature, well show the SlickEdit command for that feature, and then, if there is one, the standard key
binding or menu item.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 10

Part I: Getting Started with SlickEdit


Commands can be invoked in several different ways:

All commands can be entered on the command line.

Commands without mandatory arguments can be bound to keyboard shortcuts.

Commands without mandatory arguments can also be added to toolbars and menus.

Commands can be invoked by other Slick-C macros and commands.

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.

The Command Line


The bottom-left area of the SlickEdit window doubles as both a message area and the command line.
Use the Escape key to toggle the cursor between the edit buffer and the command line.
Even toggling from and to the command line is done by a command: cmdline-toggle. The cmdlinetoggle command is bound to the Escape key in CUA and several other emulations. In other emulations,
it is bound to different keys.
When you start typing a command, SlickEdit begins prompting with matching commands based on
what you have typed, as shown in Figure 1-3.

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

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 11

Chapter 1: Introducing SlickEdit


Well show how you can make autocompletion work with your own commands in Chapter 16.
When autocomplete for command-line arguments is active, you can also press the question mark key to
open a selection list for matching arguments.
The command line also supports history. You can navigate backward and forward through the history
list using the up and down arrow keys. You can edit commands and execute them again.
You can enter several different types of commands on the command line. These include:

SlickEdit Commands These can be commands provided by SlickEdit, such as find, or commands you write yourself in Slick-C. There is no difference between SlickEdit-provided commands and user-written commands.

Slick-C batch macros These are routines written in Slick-C that are not compiled into
internal commands.

Operating System Commands You can enter any operating system command on the
SlickEdit command line, as well as in the Build tool window.

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

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 12

Part I: Getting Started with SlickEdit


If you want to find out what command is bound to a key, use the what-is command, like this:

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.

Setting Key Bindings


You can review and edit key bindings using the Key Bindings dialog (Tools Options Key Bindings).
The Key Bindings dialog is shown in Figure 1-5.

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:

12

1.

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.

2.

Click in the Search by key sequence field.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 13

Chapter 1: Introducing SlickEdit


3.

Press Ctrl+F3. If the key is already used by a command, that command is added to the list so
that you can see it.

4.

Click the Add button to add the binding. SlickEdit displays the Bind Key dialog, shown in
Figure 1-6.

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.

Listing Key Bindings


To list all the key bindings, enter the command list-keydefs. SlickEdit creates a new buffer called
keydefs.e and fills it with Slick-C definitions for all the key bindings. This listing can be useful for

13

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 14

Part I: Getting Started with SlickEdit


comparing large sets of key bindings, such as those provided by different emulations. It can also help
sometimes if you are trying to plan a set of key bindings and need to review which keys are currently in
use and which are not.
Appendix A contains several tables listing key bindings.

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

Key

Description

record-macro-toggle

Ctrl+F11

Start recording macro, or stop recording and


save macro.

record-macro-end-execute

Ctrl+F12

Stop macro recording and execute macro.

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.

14

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.

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 15

Chapter 1: Introducing SlickEdit

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.

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.

7.

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

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 16

Part I: Getting Started with SlickEdit


9.
10.
11.
12.
13.

Click in the Search by key sequence field.


Press Alt+quote.
Click Add. SlickEdit displays the Bind Key dialog with wrox-dup-line as the command, and
Alt+ as the key sequence.
Click Bind. SlickEdit adds the binding and updates the Key Bindings dialog.
Click Close to close the Key Bindings dialog.

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

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 17

Chapter 1: Introducing SlickEdit


_macro(R,1);
select_line();
copy_to_clipboard();
paste();
}

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

22150c01.qxd:WroxPro

9/25/07

12:20 AM

Page 18

Part I: Getting Started with SlickEdit


which the code is presented. For example, the wrox-dup-line command above is found in Author/
Chapter01/wrox_dup_line.e. To load any example, simply open the .e file in SlickEdit, and invoke
the load command (F12).
We cover modules and loading in more detail in Chapter 16, along with other aspects of Slick-C programming.

Supplied Macro Source


The entire source code for all of SlickEdits features that are implemented in Slick-C is included with
the product. The macro source is installed in the macros/ directory underneath the product installation
directory. In this book, we occasionally refer to files in the supplied macro source.

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

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 19

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.

Emulations and Key Bindings


During the installation process, you are prompted to select an emulation. The emulation defines
keyboard shortcuts and other behavior in the editor. SlickEdit ships with more than a dozen
emulations, providing compatibility with several other popular editors.
Appendix A includes listings of key bindings for some popular emulations.
The default emulation is CUA (Common User Access). Some of the other emulations, such as
Visual C++ and Visual Studio, are very similar to CUA. Others are different, reflecting quite
different user-interface styles.

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 20

Part I: Getting Started with SlickEdit


CUA is an acronym for Common User Access, the user interface standard developed by IBM and
Microsoft during the 1980s. CUA defines standard menus such as the File and Help menus. It also
defines standard behavior for some function keys, such as F1 for help, and key combinations such as
Ctrl+X, Ctrl+C, and Ctrl+V for cut, copy, and paste, respectively.
You can change emulation at any time by choosing Tools Options Emulation from the main menu.
You should be aware that changing emulations is not a perfectly reversible process. If you change from
CUA emulation to Brief, for example, and then back to CUA, your CUA settings are not completely
restored to what they were before.
To get a clean configuration with a given emulation, you need to start with a default, or empty, configuration. We cover managing configurations in more detail below in this chapter.
Configuring your settings programmatically is also a good way to reset your settings reliably. We cover
programmatic configuration in Chapter 17.
You can understand key bindings for emulations by reading the emulation chart or using the Key Bindings
dialog. To understand emulation settings other than key bindings in detail, you need to study the Slick-C
code defining the emulation. The Slick-C files defining the different emulations are listed in Table 2-1.

Table 2-1

20

Emulation

Source File

BBEdit (Mac)

bbeditdef.e

Brief

briefdef.e

CodeWarrior

codewarriordef.e

CodeWright

codewrightdef.e

Epsilon

emacsdef.e

GNU Emacs

gnudef.e

ISPF

ispfdef.e

SlickEdit

slickdef.e

Visual C++ 6

vcppdef.e

Vim

videf.e

Visual Studio

vsnetdef.e

CUA

windefs.e

Xcode

xcodedef.e

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 21

Chapter 2: Configuration

The WROX Emulation


This book provides an extension to the CUA emulation called the WROX emulation. You can find the
definitions for the WROX emulation in the file Chapter02/wrox_emulation.e on the books CD-ROM.
To load the emulation, open wrox_emulation.e in SlickEdit, and invoke the load command (F12).
The WROX emulation affects only key bindings. In most cases, it defines additional key bindings for
commands not bound in the CUA emulation. In a few cases, it changes CUA key bindings. Many of the
bindings in the WROX emulation are copied from the SlickEdit emulation, where the SlickEdit defines a
key binding for a key not bound in the CUA emulation.
Throughout this book, we assume that you are working with either the CUA or the WROX emulation.
When we present key bindings, we identify WROX-specific bindings explicitly; otherwise, all key bindings in this book are defined in the CUA emulation.
You can use the WROX emulation as a starting point for your own customizations. As well as adding or
changing bindings for commands you use frequently, you can also remove bindings for commands you
dont use, so that you dont invoke them accidentally.

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

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 22

Part I: Getting Started with SlickEdit

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.

Using the Set Variable Dialog


The Set Variable dialog provides a GUI dialog you can use to query or change the value of any macro
variable. To query or set a macro variable using the Set Variable dialog, follow these steps:

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

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 23

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.

Using the set-var Command


While the Set Variable dialog is easy to use, its often faster to use the set-var command on the command line. To query or set a macro variable using the set-var command, follow these steps:

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

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 24

Part I: Getting Started with SlickEdit

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.

Maximize First Window


By default when you install SlickEdit, windows are cascaded in the editor. They are small and dont
show many lines of your source files. Check the Maximize first window checkbox on the General tab
of the General Options dialog (Tools Options General). With this setting, buffers are opened in windows that fill the entire SlickEdit application window. This is usually a more effective way of working
when programming.
We talk about managing windows in more detail in Chapter 3.

Draw Box around Current Line


It can be quite helpful to be able to see at a glance which line your cursor is on. SlickEdit provides several
choices for this, found on the General tab of the General Options Dialog (Tools Options General).
You can have no box (the default), a simple box, or one of several ruler styles. Try the ruler styles, and
use one of them if you like it; otherwise use the plain box. You can also customize the color of the box or
ruler if you wish.
You can add per-extension current line highlighting too. This is hidden away in the Advanced tab of the
Extension Options dialog (Tools Options Extension Options). There are two checkboxes in the Color
coding section labeled Modified lines and Current line. If you check the Current line checkbox, the
current line gets color syntax highlighting, in addition to any box or tabs. If you check the Modified lines
checkbox, SlickEdit marks changed lines with color in the left margin. The modification markers remain
visible as long as the file is loaded.
Note that the Current line and Modified lines settings need to be set independently for each file
extension.
See Chapter 13 to find out other ways you can see what changes you have made to a file.

Vertical Line Column


Also on the General tab of the General Options dialog is the option to place a vertical line on the screen
at a certain column. You can use this if you prefer to limit the length of lines in your source files, perhaps
for printing purposes. Some coding conventions place a maximum on source file line length. You can
change the color of the line and what column it appears in.

24

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 25

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.

Left Margin Size


SlickEdit places several markers in the left margin, for example, the modified line colors seen above.
Another example is bookmark icons. Sometimes when you activate different features in the editor that
use the left margin for visual cues, it causes the margin to be resized. This can be distracting. You can
reduce the amount of resizing that occurs by setting the margin to a sufficiently large initial size, such
as 0.25 inches. This setting is found on the More tab of the General Options dialog.
We cover bookmarks in detail in Chapters 5 and 6.

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.

We discuss some Unicode-specific issues in more detail in Chapter 12.

25

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 26

Part I: Getting Started with SlickEdit


However, if you change these, you will likely also want to change:

File Manager Windows.

Diff Editor Source Windows.

Selection List.

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

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 27

Chapter 2: Configuration

Figure 2-7

Line Wrapping and White Space


The checkboxes in the lower part of the Redefine Common Keys dialog are mainly concerned with white
spaces and tabs. Note that these checkbox settings actually have nothing to do with the common key settings in the upper part of the dialog. Table 2-2 contains descriptions of the checkbox settings, and more
notes follow afterward.

Table 2-2
Setting

Description

Cursor wrap

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.

Up/Down on text

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.

Up/Down within
soft wrapped
lines

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.

Line wrap 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.

Jump over tab


characters

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

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 28

Part I: Getting Started with SlickEdit


Table 2-2 (continued)
Setting

Description

Pull chars
backspace

When on, in both insert and replace mode, backspace pulls characters to the
right of the cursor with the cursor while deleting. When off, in replace mode,
characters are not pulled. Spaces are left instead.

Hack tabs
backspace

When on, backspace converts tabs to spaces and deletes only one space. The
cursor moves back only one column. When off, backspace deletes entire tab
characters, moving the cursor back to the character before the tab.

Treat leading
spaces as tabs

When on, the cursor moves by tab stops in leading spaces on the line. When off,
the cursor moves one column at a time.

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.

Backspace, Delete, and Enter


The Redefine Common Keys dialog contains five common keys and their standard commands in the top
part. This part of the dialog is simply a shortcut for binding a limited set of possible commands to each
of these five keys.
For the Backspace, Delete, and Enter keys, the choices available determine the line behavior. For example,
the default command for Delete (in CUA) is linewrap-delete-char. If you press Delete on the end of
a line, the following line is joined to it. If you configure the key to the other option, delete-char, then
Delete never joins lines.
Backspace is similar, with commands linewrap-rubout and rubout. These commands differ when the
cursor is on the beginning of the line.

28

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 29

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

Description

Command for Ctrl-Enter

nosplit-insert-line

Does not split line. A new line


is added below the current line.

split-insert-line

split-insert-line

Splits line.

nosplit-insert-line

maybe-split-insert-line

In insert mode, splits line. In


replace mode, moves cursor to
first column of next 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.

Home and End


The Home and End keys also have two behaviors each that can be selected in the Redefine Common Keys
dialog. For Home, the choices are begin-line and begin-line-text-toggle. The begin-line command simply takes you to the beginning of the line, regardless of any indentation. The begin-linetext-toggle command toggles you between the first non-blank character and the beginning of the line.
This can be handy for heavily indented lines.
Similarly, the End key can have either end-line or end-line-text-toggle. The end-line command
takes you to the end of the line, including any white space. The end-line-text-toggle command toggles between the last non-blank character and the end of the line. Again, this command would be useful
if you had a lot of lines with trailing white space. This isnt as common as having indented lines.

29

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 30

Part I: Getting Started with SlickEdit

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.

Reverting to the Default Configuration


Sometimes you may wish to revert SlickEdit to the default configuration. To do this, delete the contents
of your configuration directory before starting SlickEdit. If SlickEdit finds an empty configuration directory, it initializes it with the default configuration.

30

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 31

Chapter 2: Configuration
Table 2-4
File/Directory

Description

tagfiles/

Global runtime library tag files (see Chapter 5).

templates/

User-defined code templates (see Chapter 11).

vsdelta/

File backup history (see Chapter 13).

alias.slk

Global aliases (see Chapter 11).

*.als

Extension-specific aliases (see Chapter 11).

filepos.slk

Cursor positions in files opened.

uscheme.ini

User-defined color schemes.

user.cpp

User-defined C/C++ preprocessing configuration settings.

vrestore.slk

GUI state, command history, file histories, etc.

vusrdefs.e (UNIX: vunxdefs.e)

Slick-C representation of key bindings, user settings (see


Chapter 17).

vusrobjs.e

Toolbar customizations.

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.

Working with a Different Configuration


Occasionally you may wish to run SlickEdit using a different configuration directory from the default.
Some examples of times you might want to do this are:

You want to place your configuration in a different location. For example, your home directory
may be on a network drive, and you want to put your SlickEdit configuration on the local drive.

You want to try something with a default configuration.

You want to experiment with different settings.

31

22150c02.qxd:WroxPro

9/25/07

12:22 AM

Page 32

Part I: Getting Started with SlickEdit


To use a non-default configuration directory location, you can use one of these options:

Set the environment variable VSLICKCONFIG to point to your configuration directory.

Use the sc option when invoking SlickEdit to specify the configuration directory.

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

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 33

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.

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 34

Part I: Getting Started with SlickEdit


If you use them all, you can easily get back to a situation where you can see only 20 lines or less of
your code.
The trick is to manage the toolbars, tool windows, and your editing area to maximize your productivity.
SlickEdit allows several options for how you arrange its tools. In this chapter, we take a look at those
options and recommend some strategies for using the features most effectively.

Windows and Buffers


When you look at the SlickEdit interface with the Edit window maximized, its easy to think that the editor
has a single editing window, into which it places the buffer you are editing. This is not really true. The
relationship between windows and buffers is controlled by the One file per window setting, found on
the General tab of the General Options dialog (Tools Options General).
The default is One file per window turned on, which is usually the best setting. With this setting,
there is actually a separate window for each buffer. You can move among buffers effectively using either
next-window (Ctrl+Tab) or next-buffer (Ctrl+N).
We discuss commands for moving between buffers in more detail in Chapter 6.
With the One file per window setting turned off, you can associate more than one buffer with a window. With this setting, next-window moves between windows, and next-buffer moves between
buffers associated with the window. This is mostly useful when using split 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

34

Command

Key

Description

hsplit-window

Ctrl+H (Window Split Horizontally)

Split window horizontally

vsplit-window

(Window Split Vertically)

Split window vertically

one-window

(Window One Window)

Restore to single window

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 35

Chapter 3: Managing Windows


When using split windows, its best to have One file per window turned off. Then you can use
next-window/prev-window (Ctrl+Tab/Ctrl+Shift+Tab) to move between the windows, and
next-buffer/prev-buffer (Ctrl+N/Ctrl+P) to move between buffers in a window.

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

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 36

Part I: Getting Started with SlickEdit


Even so, for most of the tool windows, you wont want to have them visible all the time they simply
take up too much room. There are more than a dozen of them, thus its impossible to display them all
anyway. The best strategy is to arrange the tool windows so that you can access the ones you need quickly,
and dismiss them just as quickly. With the default configuration this is not possible, since you need to
use the mouse to activate most of the tool windows and also to hide them.
Fortunately, tool window features make it pretty easy to set things up to be productive with the keyboard.
The WROX emulation supplied with this book contains one approach to managing the tool windows
with the keyboard. Before we go into details of the key bindings, lets take a bit of time to understand
some things about tool windows.

Tool Window Arrangement


Tool windows can be either floating or docked. Floating tool windows can be placed anywhere on the screen.
They do not have to be placed within the SlickEdit window. In fact, its often better to place them outside
it, so that they do not obstruct the view of the buffer. If you place a floating tool window outside the
main SlickEdit window, you can leave it visible all the time if you choose. You can close a floating tool
window by clicking the X in its top-right corner. You can also press Escape to close some floating tool
windows. For most floating tool windows, though, pressing Escape does not close the window but
instead restores the focus to the main SlickEdit window.
Docked tool windows are stuck to the inside of one edge of the main SlickEdit window: either the left,
top, right, or bottom edge. Docked tool windows belong to docking groups. Only one tool window in a
docking group can be visible at a time. The others show only their tabs in the docking group. You can
switch among tool windows in a docking group by clicking tabs, but our goal is to switch using the
keyboard, not the mouse.
Docking groups can have auto-hide enabled for them. If auto-hide is not enabled, the docking group
remains visible all the time, taking up a certain amount of screen space. If auto-hide is enabled, the docking group remains visible only while it has the focus or the mouse is over it. When the focus is moved
away and the mouse is not over the docking group, it disappears.
Auto-hide is indicated by a pin icon on the top right of the docking group, next to the Close icon. If the
pin is upright, auto-hide is disabled. If the pin is on its side, auto-hide is enabled.
Figure 3-2 shows some arrangements of tool windows. The Find Symbol tool window is floating and
appears over everything else. It could be moved outside of the SlickEdit window if desired. The lefthand docked group contains the Projects, Defs, Class, Symbols, and Files tool windows. The group has
auto-hide enabled and is, in fact, hidden so that only the tabs are visible. The bottom docked group contains the Search Results, Preview, Build, Output, and References tool windows. The group has auto-hide
enabled, as indicated by the pin on its side in the upper-right. The group is visible because the Build tool
window, displaying a directory listing, currently has the focus. The right-hand docked group contains
the Bookmarks and Backup History tool windows. The group has auto-hide disabled, indicated by the
upright pin in the upper-right corner. The Bookmarks tool window is visible. The Backup History tool
window is shown only by a tab, which is, in fact, covered by the Build tool window. Auto-hidden tool
windows appear over non-auto-hidden tool windows when they are showing. When tool windows are
not auto-hidden, SlickEdit arranges them so that they dont overlap.

36

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 37

Chapter 3: Managing Windows

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

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 38

Part I: Getting Started with SlickEdit


5.
6.

Drop the tool window. It now joins the docking group.


Enable auto-hide on the docking group, if desired.

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.

Ensure that the docking group has auto-hide turned off and is visible.

7.

Drag the tool window to the desired location, and resize it if necessary.

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.

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.

Activating Tool Windows with the Keyboard


Make sure that you have loaded the WROX emulation, described in Chapter 2. The WROX emulation
defines keyboard sequences for activating each of the tool windows, listed in Table 3-2. The keyboard
sequences all begin with Alt+T, for tool window, and are followed by a key that is supposed to be a
mnemonic for the specific tool window. Many of the tool windows start with the same letter, thus some
of the mnemonics are less natural than others. If you have a preferred set of tool windows you use, you
can easily customize the emulation to personalize your mnemonics.
Most of the tool windows dont have standard keyboard bindings in SlickEdit, but some of them can
also be reached by other means using the keyboard. For example, activate-files-files is the same
as list-buffers, which is bound to Ctrl+Shift+B. Of course, all of them can be reached via View
Toolbars, but thats a little slow for frequent use, particularly since there are no mnemonics for the tool
windows in the cascaded menu.

38

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 39

Chapter 3: Managing Windows


Table 3-2
Command

Key

Tool Window

activate-bookmarks

Alt+T, K

Bookmarks

activate-build

Alt+T, B

Build

activate-call-stack

Alt+T, A

Slick-C Call Stack

activate-tbclass

Alt+T, C

Class

activate-defs

Alt+T, D

Defs

activate-deltasave

Alt+T, H

Backup History

activate-files-files

Alt+T, L

Files: Open Files tab

activate-files-project

Alt+T, P

Files: Project Files tab

activate-files-workspace

Alt+T, W

Files: Workspace Files tab

activate-find-symbol

Alt+T, F

Find Symbol

activate-ftp

Alt+T, T

FTP

activate-open

Alt+T, O

Open

activate-output

Alt+T, U

Output

activate-preview

Alt+T, V

Preview

activate-projects

Alt+T, J

Projects

activate-references

Alt+T, R

References

activate-regex-evaluator

Alt+T, X

Regular Expression Evaluator

activate-search

Alt+T, S

Search Results

activate-symbols-browser

Alt+T, Y

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

22150c03.qxd:WroxPro

9/25/07

12:23 AM

Page 40

Part I: Getting Started with SlickEdit


the tool windows are managed in detail and possibly design your own scheme for managing and
arranging them.
If you want to keep a tool window visible for an extended period, while you work on a particular task,
you can turn auto-hide off for its group. Turn auto-hide back on afterward to get better screen utilization.

Tool Window Animation


Another thing you may or may not like about tool windows in docked mode is the way they slide
across the screen when being activated or hidden. You can adjust the rate at which they move, or disable
the animation altogether, in the Options tab of the Toolbar Customization dialog (View Toolbars
Customize). I recommend turning off the animation, since it is distracting and slows things down.

Restoring the Defaults


You can restore your toolbars and tool windows to the shipped settings by invoking the tbResetAll
command on the command line.

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

22150c04.qxd:WroxPro

9/25/07

12:25 AM

Page 41

Part II: Using SlickEdit


Chapter 4: Workspaces and Projects
Chapter 5: Context Tagging
Chapter 6: Navigation
Chapter 7: Search and Replace
Chapter 8: Editing Text
Chapter 9: Editing Code
Chapter 10: Editing Data
Chapter 11: Aliases and File Templates
Chapter 12: Document Types
Chapter 13: Comparing and Merging
Chapter 14: Version Control

22150c04.qxd:WroxPro

9/25/07

12:25 AM

Page 42

22150c04.qxd:WroxPro

9/25/07

12:25 AM

Page 43

Wor kspaces and Projects


With most programming IDEs, you organize your work into projects. In some IDEs, you cannot
open a file unless it is part of your project. With SlickEdit, its easy to open any file on your system,
but all the same its usually best to organize your work to get the most effective use of the editors
features.
SlickEdit organizes your work using two concepts: workspaces and projects. Workspaces and projects are important for two main reasons:

They allow you to organize, manage, and tag the files in your project.

They provide structure around tasks such as building, running, and debugging your
project.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 44

Part II: Using SlickEdit


project. For C/C++, you would have a project for each library, DLL or SO, that is built and one for each
executable. Even if you dont use the SlickEdit build system, partitioning files into projects like this is
useful so that you can see the structure of your projects and do things like restricting searches to the
current project.
Projects can be shared between workspaces. Once a project is defined, you can add it to a different workspace. The exact same project is shared; it is not a copy. This is useful if you have internal libraries that
might be used and edited in multiple programs.
SlickEdit does not require that the files in a workspace be under the workspace directory. They can be
located anywhere on the local machine or on a network, although local is always best. Some prefer that
structure, creating a single root directory that contains subdirectories for each project, which contains a
source tree. However, you can create a workspace directory that has no subdirectory and stores projects
and files in other directories. Even if your source files are remote, it is very important to have your workspace and project files stored locally.
SlickEdit tags all of the files in a workspace (i.e., all of the files in the projects that the workspace contains) and creates the workspace tag file. It does not have project-specific tag files. For code that is used
but not edited, it is generally best not to add it to the project. Instead, tag the library, and add the tag file
to your environment. Because of the way in which Context Tagging works, its best to restrict your files
to those that will be edited.
When you create a project, it is critical to get the project type correct. It is impossible to change some
project types into others. For example, if you create a Generic C/C++ project, you will never be able to
configure it through the GUI to work properly with GNU C/C++. You need to start with that project
type to be successful.
Projects can be dependent on one another, creating a build dependency. If you have multiple projects,
certain operations work on the Active Project. It is shown in bold in the Project tool window. You can
change the Active Project by right-clicking on it or using Project Set Active Project.
SlickEdit cannot create Microsoft Visual Studio project types. It can open them and change the set of
defined files, but you have to create the solution or project in Visual Studio before opening it in
SlickEdit. You will also have to make most of the changes related to build settings in Visual Studio.
In this chapter, you will see how to create workspaces and projects. Well take a look at how to set up
projects for different build targets in your work, and how to automate building and testing your project
in SlickEdit. Well look at several examples using programming languages with compilers C/C++
and Java and also an example of using SlickEdit projects with an interpreted language, Ruby. You can
find the code for the sample projects on the accompanying CD-ROM.
For compiled languages such as C++ and Java, SlickEdit provides dialogs with a large number of
compiler and linker options. Most of the options you can use with the command-line tools are available through the SlickEdit GUI. However, we dont cover the compiler options in detail here, or even
all the compilers. You can find better information about using a compiler in that compilers own
documentation. Instead, we focus on using SlickEdit with programming language compilers and
interpreters in general, and how to create an effective and productive development workflow using
SlickEdit.

44

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 45

Chapter 4: Workspaces and Projects

How to Organize Your F iles


When you create a workspace and a project, SlickEdit creates these files:

project_name.vpw the workspace definition.

project_name.vpj the project definition.

project_name.vtg the tag file.

project_name.vpwhist the workspace state.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 46

Part II: Using SlickEdit


Some people have experienced performance problems with wildcards with large projects. If you run into
performance problems, you should try both methods to see if one is faster.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 47

Chapter 4: Workspaces and Projects

Creating a GNU C/C++ Project


To use SlickEdit with a GNU C/C++ project, you need to have the GNU C/C++ compiler and related
tools installed already. On GNU/Linux, you should have this installed by default on your development
machine. On Windows, the easiest way to install GNU C/C++ is to install CygWin: http://
www.cygwin.com.
Well start with a very simple GNU C++ project. Suppose we already have some files for this project:

board.h The header for the Board class.

board.cpp The definition of the Board class.

queens.cpp The main() function.

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_;
};

The listing for board.cpp is below:


#include board.h
Board::Board(int size) :
size_(size), pos_(size, -1), col_(size, false), diag1_(2*size+1, false),
diag2_(2*size+1, false) {
}
int Board::size() {
return size_;
}

47

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 48

Part II: Using SlickEdit


void Board::place(int row, int col) {
pos_[row] = col;
col_[col] = true;
diag1_[col-row+size_] = true;
diag2_[col+row] = true;
}
int Board::unplace(int row) {
int col = pos_[row];
pos_[row] = -1;
col_[col] = false;
diag1_[col-row+size_] = false;
diag2_[col+row] = false;
return col;
}
bool Board::is_ok(int row, int col) {
return !(col_[col] || diag1_[col-row+size_] || diag2_[col+row]);
}
bool Board::solve() {
int row = 0;
int col = 0;
while (row >= 0 && row < size_) {
while (col < size_ && !is_ok(row, col)) {
col++;
}
if (col < size_) {
place(row, col);
row++;
col = 0;
}
else {
row--;
if (row >= 0) {
col = unplace(row) + 1;
}
}
}
return row == size_;
}
int Board::col(int row) {
return pos_[row];
}

Finally, the driver program is in queens.cpp:


#include
#include
#include
#include

<ctime>
<iostream>
<string>
board.h

int main (int argc, char *argv[]) {

48

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 49

Chapter 4: Workspaces and Projects


if (argc < 2) {
std::cerr << I need a number. << std::endl;
exit(-1);
}
int size = atoi(argv[1]);
Board b(size);
time_t start = time(0);
if (b.solve()) {
time_t elapsed = time(0) - start;
for (int i = 0; i < size; i++) {
std::cout << std::string(b.col(i), ) << * << std::endl;
}
std::cout << elapsed << seconds. << std::endl;
}
return(0);
}

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.

Creating the Project


To create a GNU C/C++ project for these files, follow these steps:

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 50

Part II: Using SlickEdit


2.
3.
4.

Select project type GNU C/C++ Wizard.


Enter gnu_queens for the Project name.
Enter the Location for SlickEdit to place its project files. Its often simplest to place the SlickEdit
project files in the top directory of your source tree. However, you can place them wherever you
wish. The most important thing is that they are on a local drive, because SlickEdit accesses them
frequently. On my system, the source files are in Z:\ProfessionalSlickEdit\projects\
gnu_queens; thus I will put this as the location for the SlickEdit project files too.

5.

Enter queens for the Executable name. This is the name given to the output executable produced
by the build process.

6.

Click OK. SlickEdit opens the first page of the Create GNU C/C++ Project wizard, shown in
Figure 4-3. For the queens application, the source code is C++, and the output is a console
executable; thus the default settings are correct.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 51

Chapter 4: Workspaces and Projects


8.

Click Next. SlickEdit displays the third page of the wizard, shown in Figure 4-5. Here we can
choose between three options for the build system. For the queens project, there are only a
couple of source files, thus the first option, Build without a makefile, will be fine.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 52

Part II: Using SlickEdit


11.

Click Add Files. SlickEdit displays the Add Source Files dialog, where you can select one or
more source files to add to the project. As mentioned above, for a larger project you would use
Add Tree or Add Wildcard.

12.

Select the three files board.cpp, board.h, and queens.cpp, and click OK. SlickEdit shows the
three Project files. Were done setting up the project.

13.

Click OK to close the Project Properties dialog.

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.

Building the Project


To build the project, invoke project-build (Ctrl+M). SlickEdit invokes the configured build process
and displays output in the Build tool window. If there is an error, the details are shown in the Build tool
window. An example of a build with compile errors is shown in Figure 4-7.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 53

Chapter 4: Workspaces and Projects

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.

Executing the Project


You can execute the project target with project-execute (Ctrl+F5). For the queens project, the program
requires a number as a command-line argument. On the Tools tab of the Project Properties dialog, select
the Execute tool, and click Options. SlickEdit displays the GNU C Options dialog. On the Run/Debug
tab, you can provide program arguments.
By the way, dont try to run the queens program with large numbers! It is a hard problem, and even on a
fast computer it takes a long time to solve. A 30 30 board takes nearly a minute to run on my machine,
and boards not much larger take much longer.
There are many other options available on the different tabs for the GNU C compilers. Most of these
options are translated directly into compiler or linker options for the command-line GNU tools that
SlickEdit invokes.

53

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 54

Part II: Using SlickEdit

Adding Unit Tests


Unit tests are an effective way to detect bugs in your code. They are becoming increasingly popular, and
there are frameworks for unit testing for most major programming languages today. For Java, the JUnit
framework is a de facto standard, although other alternatives exist. Well see SlickEdits support for
JUnit shortly.
For C++, there is no standard testing framework, but many are available. In this section, well show an
example of how to get SlickEdit to work with CxxTest (http://cxxtest.sourceforge.net/).
Most of the time, you would develop unit tests before or while you develop your main code. But because
we are learning mostly about SlickEdit in this book, rather than about unit testing, well cover unit testing now, even though our program is already working. (The tests would be useful if we changed the
program later.)
To test with CxxTest, we follow these steps:

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.

Writing the Test Suite


CxxTest test suites are simply classes that contain tests. The simplest way to organize tests for your own
classes is to create a test suite for each class under test. An example of a CxxTest suite for our Board class
is in board_tests.h:
#include board.h
#include <cxxtest/TestSuite.h>
class BoardTests : public CxxTest::TestSuite {
public:
void test_create(void) {
Board b1(1);
Board b4(4);
Board b20(20);
TS_ASSERT(true);
}
void test_size(void) {
Board b1(1);
TS_ASSERT_EQUALS(1, b1.size());
Board b4(4);
TS_ASSERT_EQUALS(4, b4.size());
Board b20(20);
TS_ASSERT_EQUALS(20, b20.size());
}
void test_place(void) {
Board b(4);
TS_ASSERT_EQUALS(-1, b.col(0));
TS_ASSERT_EQUALS(-1, b.col(1));
TS_ASSERT_EQUALS(-1, b.col(2));

54

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 55

Chapter 4: Workspaces and Projects


TS_ASSERT_EQUALS(-1, b.col(3));
b.place(0, 1);
b.place(1, 3);
b.place(2, 0);
b.place(3, 2);
TS_ASSERT_EQUALS(1, b.col(0));
TS_ASSERT_EQUALS(3, b.col(1));
TS_ASSERT_EQUALS(0, b.col(2));
TS_ASSERT_EQUALS(2, b.col(3));
}
void test_unplace(void) {
Board b(4);
b.place(0, 1);
TS_ASSERT(!b.is_ok(1, 1));
TS_ASSERT(!b.is_ok(0, 1));
TS_ASSERT(!b.is_ok(2, 3));
b.unplace(0);
TS_ASSERT(b.is_ok(1, 1));
TS_ASSERT(b.is_ok(0, 1));
TS_ASSERT(b.is_ok(2, 3));
b.place(1, 3);
b.place(2, 0);
b.place(3, 2);
TS_ASSERT_EQUALS(3, b.unplace(1));
TS_ASSERT_EQUALS(-1, b.col(1));
TS_ASSERT_EQUALS(2, b.unplace(3));
TS_ASSERT_EQUALS(-1, b.col(3));
}
void test_is_ok(void) {
Board b(4);
TS_ASSERT( b.is_ok(0,
TS_ASSERT( b.is_ok(0,
TS_ASSERT( b.is_ok(0,
TS_ASSERT( b.is_ok(0,
TS_ASSERT( b.is_ok(1,
TS_ASSERT( b.is_ok(1,
TS_ASSERT( b.is_ok(1,
TS_ASSERT( b.is_ok(1,
TS_ASSERT( b.is_ok(2,
TS_ASSERT( b.is_ok(2,
TS_ASSERT( b.is_ok(2,
TS_ASSERT( b.is_ok(2,
TS_ASSERT( b.is_ok(3,
TS_ASSERT( b.is_ok(3,
TS_ASSERT( b.is_ok(3,
TS_ASSERT( b.is_ok(3,

0));
1));
2));
3));
0));
1));
2));
3));
0));
1));
2));
3));
0));
1));
2));
3));

b.place(0, 1);
TS_ASSERT(!b.is_ok(1,
TS_ASSERT(!b.is_ok(1,
TS_ASSERT(!b.is_ok(1,
TS_ASSERT( b.is_ok(1,
TS_ASSERT( b.is_ok(2,

0));
1));
2));
3));
0));

55

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 56

Part II: Using SlickEdit


TS_ASSERT(!b.is_ok(2,
TS_ASSERT( b.is_ok(2,
TS_ASSERT(!b.is_ok(2,
TS_ASSERT( b.is_ok(3,
TS_ASSERT(!b.is_ok(3,
TS_ASSERT( b.is_ok(3,
TS_ASSERT( b.is_ok(3,

1));
2));
3));
0));
1));
2));
3));

b.place(1, 3);
TS_ASSERT( b.is_ok(2,
TS_ASSERT(!b.is_ok(2,
TS_ASSERT(!b.is_ok(2,
TS_ASSERT(!b.is_ok(2,
TS_ASSERT( b.is_ok(3,
TS_ASSERT(!b.is_ok(3,
TS_ASSERT( b.is_ok(3,
TS_ASSERT(!b.is_ok(3,

0));
1));
2));
3));
0));
1));
2));
3));

b.place(2, 0);
TS_ASSERT(!b.is_ok(3,
TS_ASSERT(!b.is_ok(3,
TS_ASSERT( b.is_ok(3,
TS_ASSERT(!b.is_ok(3,

0));
1));
2));
3));

}
void test_solve_false(void) {
Board b(3);
TS_ASSERT(!b.solve());
}
void test_solve_true(void) {
Board b(4);
TS_ASSERT(b.solve());
TS_ASSERT_EQUALS(1, b.col(0));
TS_ASSERT_EQUALS(3, b.col(1));
TS_ASSERT_EQUALS(0, b.col(2));
TS_ASSERT_EQUALS(2, b.col(3));
}
};

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

Open the New Project dialog (Project New).

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 57

Chapter 4: Workspaces and Projects


2.
3.
4.
5.
6.
7.

Select the GNU C/C++ wizard again.


Enter tests for the Name of the second project
Specify the same location as the gnu_queens project.
Enter test_runner for the Name of the executable.
Select the option to add this project to the current workspace.
Click OK. SlickEdit displays the first page of the Create GNU C/C++ Project wizard. Again, the
default settings are appropriate for a console C++ application.

8.
9.
10.

Click Next. SlickEdit shows the second page of the wizard.

11.
12.
13.

Click OK to dismiss the dialog. SlickEdit shows the Project Properties dialog.

14.

Leave An empty project selected, and click Next. SlickEdit shows the last page of the wizard.
Again, well let SlickEdit deal with the dependencies for this example project. Leave Build
without a makefile selected, and click Finish. SlickEdit shows the New Project Information
dialog.

Click Add Files.


Select the three files board.cpp, board.h, and board_tests.cpp, and click OK. SlickEdit
shows the three Project files. Youre done setting up the project.
Click OK to close the Project Properties dialog.

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.

Generating the Test Runner


The CxxTest tool uses Perl to generate a test runner for your test suites. If you dont already have Perl,
you need to install that. If youre running on GNU/Linux, you almost certainly have Perl already. If
you are running on Windows with Cygwin, as we use for this example, you can install Perl as part of
your Cygwin installation. If you are using Windows without Cygwin, you can get a good Windows distribution from http://www.activestate.com. If you are using another platform, you should be
able to get Perl by consulting http://www.perl.com.
Once you have Perl, download and install CxxTest. The package comes as a ZIP file, which expands to
create a cxxtest/ folder. On my system Ive unzipped the archive in C:\Cygwin\usr\local, so that
the package is in C:\Cygwin\usr\local\cxxtest.
Using CxxTest, we will generate a test runner to run the tests. The command to generate a test runner for
the board_tests.h file is
perl cxxtestgen.pl -o runner.cpp --error-printer board_tests.h

Well add a tool to our project to generate the test runner. Follow these steps:

1.

Open the Project Properties dialog.

57

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 58

Part II: Using SlickEdit


2.
3.

Select the Tools tab.


Click New. SlickEdit displays the New Project Tool window, as shown in Figure 4-9.

Figure 4-9

4.

Enter Generate Test Runner for the New Tool Name. Click OK. SlickEdit adds the tool to the
tool list and shows you its properties.

5.

Enter the command line:

C:\cygwin\bin\perl.exe C:\cygwin\usr\local\cxxtest\cxxtestgen.pl -o runner.cpp


--error-printer board_tests.h

The command line should be all one line. You may need to adjust the paths for your own installation of Perl and CxxTest.

6.

Click OK to close the Project Properties dialog.

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.

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 59

Chapter 4: Workspaces and Projects


Running the Tests
Everything is now set up to run the test suite. To run it, Invoke project-execute (Ctrl+F5 or Build
Execute). If everything is set up correctly, you should see output from a successful test run, as shown in
Figure 4-10.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 60

Part II: Using SlickEdit

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 61

Chapter 4: Workspaces and Projects

Creating a Java Project


To use SlickEdit with a Java project, you need to have a JDK installed.
In this section, well create a Java version of the queens program we developed in C++. First well show
how to set up the project, then how we can compile Java code from within SlickEdit. Finally, well show
how to execute the Java application and its tests.
The structure of the Java project is the same as the C++ project. Well have these files:

Board.java The definition of the Board class.

Queens.java The main() function.

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.

Creating the Project


To create a Java project for these files, follow these steps:

1.
2.

Open the New Project dialog (Project New).

3.
4.

Enter java_queens for the Project name.

5.

Enter Queens as the Executable name. For Java programs, the executable name is the class
containing the main() function.

6.
7.
8.

Click OK. SlickEdit opens the Project Properties dialog.

9.

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 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.

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.

Building the Project


To build the project, invoke project-build (Ctrl+M or Build Build), as for C/C++. SlickEdit invokes
the configured build process and displays output in the Build tool window. An example of a build with
compile errors is shown in Figure 4-12.

61

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 62

Part II: Using SlickEdit

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.

Executing the Project


To execute the Java program, invoke project-execute (Ctrl+F5). Again, this project requires a number
as a command-line argument. Java options are completely different from GNU C/C++. To specify the
command-line argument, follow these steps:

1.

Open the Java Options dialog (Build Java Options). This dialog has several tabs to configure
all aspects of compiling, running, and debugging Java programs.

2.
3.
4.

Select the JRE tab.


Enter a number (such as 4) in the Arguments field.
Click OK to dismiss the Java Options dialog.

Adding Unit Tests


Lets add some JUnit tests to our project. SlickEdit has integrated JUnit support; thus theres no need to
add a separate project for running the tests, as we did with C/C++. This is a more natural way to work,
reflecting Javas more standardized approach to unit testing. Well write the tests using JUnit 3.8.1.

62

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 63

Chapter 4: Workspaces and Projects


At this writing, SlickEdit does not support the 4.x versions of JUnit. See www.junit.org for more
information about JUnit and downloads.

Writing the Test Suite


The standard approach to unit testing with Java is to write a test class for each main class in your application. The test classes are usually named with Test (or sometimes TestCase) appended to the name
of the application class. The test classes must extend junit.framework.TestCase.
In our case, we write the test class as BoardTest in file BoardTest.java. This file is included on the
accompanying CD-ROM. An excerpt of the test class is shown below:
import junit.framework.TestCase;
public class BoardTest extends TestCase {
// ... other test methods ...
public void testUnplace() {
Board b = new Board(4);
b.place(0, 1);
assertFalse(b.isOk(1, 1));
assertFalse(b.isOk(0, 1));
assertFalse(b.isOk(2, 3));
b.unplace(0);
assertTrue(b.isOk(1, 1));
assertTrue(b.isOk(0, 1));
assertTrue(b.isOk(2, 3));
b.place(1, 3);
b.place(2, 0);
b.place(3, 2);
assertEquals(3, b.unplace(1));
assertEquals(-1, b.getCol(1));
assertEquals(2, b.unplace(3));
assertEquals(-1, b.getCol(3));
}
// ... other test methods ...
}

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 64

Part II: Using SlickEdit


Running the Tests
SlickEdit has JUnit support integrated, using the JUnit tool window. To activate this window and run
the tests:

1.
2.

Activate the Projects tool window. (Click its tab or use View Toolbars Projects.)

3.

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.

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.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 65

Chapter 4: Workspaces and Projects

Managing the Project with Ant


Many Java projects are managed using Ant (http://ant.apache.org/). SlickEdit can execute Ant
tasks in the editor.
Heres an example of an Ant project file, build.xml, for the queens project:
<project name=queens basedir=. default=all>
<target name=clean>
<delete dir=build/>
</target>
<target name=prepare>
<mkdir dir=build/>
</target>
<target name=compile depends=prepare>
<javac srcdir=. destdir=build/>
</target>
<target name=test depends=compile>
<junit printSummary=true fork=true>
<classpath path=build/>
<formatter type=brief usefile=false/>
<test name=BoardTest/>
</junit>
</target>
<target name=all depends=clean,test/>
</project>

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.

Creating a Project for a Dynamic Language


Dynamic languages dont have compilers, thus in many ways they are a lot simpler to deal with than
compiled languages. For one thing, there are no default tools or compiler settings. For this reason,
SlickEdit doesnt contain specific project types for dynamic languages.
Its still worthwhile to use SlickEdits workspaces and projects for dynamic languages, for the benefits of
file organization and tagging. In this section, we show how you can also use SlickEdits project settings
and build menu to run code from your dynamic language project.
For this example, well port the queens project to Ruby. The techniques shown apply just as well to any
other interpreted language, such as Perl or Python.
To follow this example, you need to have Ruby installed. See http://www.ruby-lang.org/en/.
Ruby downloads are at http://www.ruby-lang.org/en/downloads/. If you are running
Windows, use the one-click installer for Windows. If you are using a UNIX-like system, you may
already have Ruby. Otherwise, you can download the source and build Ruby from source.

65

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 66

Part II: Using SlickEdit


For the Ruby version, we have these files:

board.rb The definition of the Board class.

queens.rb The main program.

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.

Creating the Project


This part should be familiar by now. Here are the steps to create the Ruby project:

1.
2.

Open the New Project dialog (Project New).

3.
4.

Enter ruby_queens for the Project name.

5.
6.
7.
8.

Enter queens.rb as the Executable name.

9.

Click OK to close the Project Properties dialog.

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 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.

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.

We now have the Ruby project set up. We can use SlickEdit to run it.

Executing the Project


SlickEdit has no built-in support for executing dynamic languages, but its easy to add customized tools
to SlickEdits build menu to run them. Here well customize the Execute tool to run our program with
the Ruby interpreter. Follow these steps:

66

1.
2.
3.
4.
5.

Open the Project Properties dialog.

6.

Click OK to close 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.

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 67

Chapter 4: Workspaces and Projects


You can now run the program using project-execute (Ctrl+F5).
SlickEdit can provide some error navigation for Ruby. Suppose we alter the main script so that the output line is missing its terminating quote:
puts #{elapsed} seconds.

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).

Adding Unit Tests


Ruby developers are very enthusiastic about unit testing, and the standard Ruby library has unit testing
built in. Well add Ruby unit tests for the Board class in the test_board.rb file. An excerpt of the test
class is shown below:
require test/unit
require board
class TestBoard < Test::Unit::TestCase
# ... other test methods ...
def test_unplace
b = Board.new(4)
b.place!(0, 1)
assert(!b.ok?(1, 1))
assert(!b.ok?(0, 1))
assert(!b.ok?(2, 3))
b.unplace!(0)
assert(b.ok?(1, 1))
assert(b.ok?(0, 1))
assert(b.ok?(2, 3))
b.place!(1, 3)
b.place!(2, 0)
b.place!(3, 2)
assert_equal(3, b.unplace!(1))
assert_equal(nil, b.col(1))
assert_equal(2, b.unplace!(3))
assert_equal(nil, b.col(3))
end
# ... other test methods ...
end

67

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 68

Part II: Using SlickEdit


Running the Tests
To run these tests, well add another item to the build tools. Follow these steps:

1.
2.
3.
4.
5.
6.
7.

Open the Project Properties dialog.

8.

Click OK to close 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.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 69

Chapter 4: Workspaces and Projects

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 70

Part II: Using SlickEdit


2.

Click the + beside the Expression Category list to add a new category. SlickEdit displays the
New Expression Category dialog.

3.
4.

Enter Ruby for the category.

5.

Click the + beside the Expressions list to add a new expression. SlickEdit displays the Edit
Expression dialog.

6.
7.

Enter Test Error for the Name.

Click OK to close the New Expression Category dialog. The new category appears in the
Expression Category list, and is selected and checked.

Enter this Expression:

{#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.

8.
9.
10.
11.
12.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 71

Chapter 4: Workspaces and Projects

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.

6.
7.

Click OK to save the new project type, and close the Project Package dialog.

8.

Click Cancel to close 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 close the Customize Packages dialog. The new project type should now appear in
the project types in the New Project dialog.

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.

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:

<Template Name=Java - WROX InitMacro=wrox_create_java_dirs>

4.

Save the file.

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

22150c04.qxd:WroxPro

9/25/07

12:26 AM

Page 72

Part II: Using SlickEdit


#include project.sh
_command void wrox_create_java_dirs() 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);
}

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 73

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.

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 74

Part II: Using SlickEdit

Setting Up for Tagging


For Context Tagging to work, you need to have tag databases for the symbols in your project and libraries.
To get the most benefit from Context Tagging, you should tag all these files:

All the source files in your workspace.

Standard libraries installed as part of the language or compiler.

Additional libraries you have installed globally on your system.

Additional libraries specific to your project.

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.

Tagging Your Workspace


To make use of Context Tagging, you must set up a project and an associated workspace. One of the files
SlickEdit creates automatically for your workspace is a tag file, with the extension .vtg. This file is the
tag database for symbols defined in files in your workspace.
SlickEdit maintains the workspace tag database automatically when you add and change files in the
workspace. Because of the high level of activity on the workspace tag database, it works best if you store
it on your local hard drive. The easiest way to do this is to create your SlickEdit workspace definition on
your local hard drive, even if source files are themselves somewhere else, such as on a network drive.
Also, because the workspace tag database is frequently rescanned to pick up changes in your source
files, you should avoid tagging read-only files in your workspace tag database. For example, if you have
libraries associated with your project, you will get better performance if those libraries are tagged as
global or per-workspace runtime libraries. That way, SlickEdit will not waste CPU effort rescanning
them continuously.
To ensure that tagging features work smoothly, avoid getting duplicate definitions of symbols included
in your workspace tag file. For example, if you have a build process or directory structure that requires
multiple copies of some source files, you should take care that only the main, master versions of the
source files are included in your project definition(s), so that the tagging system does not create duplicate definitions.

Tagging Built-in and Standard Libraries


As well as your workspace tag file, SlickEdit maintains global tag databases, categorized by language. In
each language category, you can create one or more tag databases. Usually you will use one tag database
for the standard library for a given language, and perhaps additional tag databases for other global libraries.
Languages such as C/C++ and Java, and many others, have a standard library that is normally installed
as part of the compiler or SDK. For C/C++, the standard library is described by header files such as
stdio.h and vector. For Java, the standard library consists of all the classes provided in the java.*

74

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 75

Chapter 5: Context Tagging


and javax.* packages and subpackages. The Java standard library source code is provided with the
JDK, for example, in src.zip. Other languages have similar conventions.
Tagging the standard library of your language is hugely valuable, as you will get all the benefits of the
Context Tagging system across your standard library classes and functions.
When you run SlickEdit for the first time, it performs some one-time configurations. One of these is
auto-tagging the standard libraries for several popular languages or SDKs:

C/C++.

Java.

.NET.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 76

Part II: Using SlickEdit

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 77

Chapter 5: Context Tagging


As you move around the list, SlickEdit displays information about the selected member. An example is
shown in Figure 5-5, where SlickEdit shows the containing class and method signature. You can click the
green arrow to invoke push-tag and jump to the methods definition.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 78

Part II: Using SlickEdit


JavaDoc-style comments are widely used in Java programs, but they are also supported for several other
languages such as C/C++ using tools like Doxygen (see http://www.stack.nl/~dimitri/doxygen/).
As illustrated by SlickEdit and Doxygen, various programming tools can make good use of a standard
format for documentation comments.

Configuring List Members


You can customize the behavior of the list members feature. The configuration options for list members
are found on the Context Tagging tab of the Extension Options dialog (Tools Options File Extension
Setup). The options are shown in the group titled List members and are described in full in the online
Help. Figure 5-9 shows the Context Tagging tab of the Extension Options dialog.

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).

Getting Parameter Information


When you are coding a function or method call, SlickEdit can provide information about the parameters
for you. Figure 5-10 shows an example using the apply() method of our FooBase sample class. SlickEdit
shows the name and type of each parameter to the method, highlighting the current parameter in bold.
The editor places the documentation above or under the current line, so that it does not obscure what
you are typing. As with list members, you can move the documentation above or below using Shift+Up
and Shift+Down.

Figure 5-10

78

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 79

Chapter 5: Context Tagging


If the method has Javadoc comments, the parameter help shows those as documentation for the current
parameter. Figure 5-11 shows this using the start() method of our example. The cursor is on the first
parameter, savepoints, thus it is highlighted in bold both in the parameter list and in the documentation. As with list members, you can use Ctrl+PgUp and Ctrl+PgDn to move between method overrides,
and Shift+PgUp and Shift+PgDn to scroll the comments.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 80

Part II: Using SlickEdit

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

Configuring Parameter Information


You can customize how parameter information works. The configuration options for parameter information are found on the Context Tagging tab of the Extension Options dialog (Tools Options File
Extension Setup). The options are shown in the group titled Parameter information and are described
in full in the online Help. The Context Tagging tab was shown above in Figure 5-9.
For example, the behaviors to insert matching parameters automatically or to list compatible parameters
are optional. They can be disabled in the configuration dialog.
Parameter information is usually invoked automatically when you press an opening parenthesis. You
can turn off automatic parameter information in the configuration dialog by unchecking Auto-display
parameter information. You can always invoke parameter information manually with the functionargument-help command (Alt+comma).

80

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 81

Chapter 5: Context Tagging

Navigating with Symbols


One of the most useful features supported by Context Tagging is the ability to navigate directly to definitions and references for any symbol with a single keystroke. This is a tagging feature you will come to
depend on. There are several different ways to do this.

The Preview Tool Window


The Preview tool window is common to many features that make use of Context Tagging. The Preview
tool window shows information about a symbol. An example is shown in Figure 5-15. In the WROX
emulation, you can show the Preview tool window with Alt+T followed by V.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 82

Part II: Using SlickEdit

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 83

Chapter 5: Context Tagging


The left-hand pane shows the files and functions where references to the given symbol exist. You can
double-click on an entry to open the file at the line of the reference, or use the arrow keys and Enter.
Depending on your needs, you may not need to open the file, because the right-hand pane provides a
scrollable preview showing the lines surrounding the reference. If you prefer, you can hide the preview
to provide more room for the references themselves. For example, if you prefer to arrange the References
tool window vertically by attaching it to the left-hand side of the editor, there isnt really enough room
for the preview. To hide the preview pane, click the Hide Preview Pane button in the upper-right corner.
To restore the preview pane, click the Display Preview Pane button next to it.
If you do use the References tool window arranged vertically, you can view it and the Preview tool window at the same time. The Preview tool window synchronizes automatically with the selected item in
the References tool window.
The Symbol dropdown at the top of the References tool window contains previously searched symbols,
so that you can easily repeat previous searches. You can also type new searches into the entry field.
If you have a lot of references, it will be faster to build the list of files but not expand it. That way you
can investigate references in the files you want. Select Tools Options Tagging Options, and put a
check in Find references incrementally. Also, if you want push-ref to build the list but not jump to
the first reference, put a check in Go to Reference only lists references.
We cover other aspects of performance tuning for tagging below in this chapter.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 84

Part II: Using SlickEdit

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.

The Find Symbol Tool Window


The easiest way to search for a symbol is to use the GUI Find Symbol tool window, shown in Figure 5-18.
Activate the tool window with the activate-find-symbol command (WROX: Alt+T, followed by F).

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 85

Chapter 5: Context Tagging

Using the grep-tag command


Sometimes you may find it faster to search for symbols from the command line. The grep-tag command provides some of the capabilities of the Find Symbol tool window. One example in which you
might prefer grep-tag is in writing your own macros.
The syntax of the grep-tag command is:
grep-tag/pattern/options

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

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.

The Defs Tool Window


The Defs (Definitions) tool window shows definitions in the current file. It allows you to browse and
navigate among those definitions, and also to other open files. Figure 5-19 shows the Defs tool window.
In the WROX emulation, you can show the Defs tool window using Alt+T followed by D.

85

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 86

Part II: Using SlickEdit

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.

The Class Tool Window


The Class tool window shows the class hierarchy and members for the current class. You can browse and
navigate to any member by double-clicking on it. The Class tool window is shown in Figure 5-20. In the
WROX emulation, you can show the Class tool window using Alt+T followed by C.

Figure 5-20

86

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 87

Chapter 5: Context Tagging


Notice in the Class tool window that the class hierarchy is actually shown upside-down from what some
people are used to. This is because the tree starts with the current class and expands nodes for the superclasses. This scheme works well for classes that have multiple superclasses, as frequently occurs in C++.
The arrow buttons at the top work in the direction of the displayed hierarchy; thus you have to click the
up arrow button to navigate to a subclass.
If you have the Preview tool window showing, it is synchronized automatically with selections in the
Class tool window.
You can right-click in the Class tool window for a Context menu, and select or deselect Organize members by class to control how members are listed. When the option is on, members are listed under the
class that defines them. When it is off, you see all of the members visible in the current class. This is just
like the completion list youd get in the editor, but its shown in a big window that provides a preview to
the method in the Preview window, helping you make the correct selection.

The Symbols Tool Window


The Symbols tool window is a kind of general-purpose symbol browser. You can browse symbols in the
workspace tag database and any other tag database. The Symbols tool window is shown in Figure 5-21.
In the WROX emulation, you can show the Symbols tool window using Alt+T followed by Y.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 88

Part II: Using SlickEdit

Figure 5-22

Managing Tag F iles


As weve seen, its pretty easy to use tagging with the source files for your own projects. As long as you
remember to add each source file to your workspace via a project, tagging is taken care of automatically.
To get the full benefits of Context Tagging, you should tag the runtime libraries used in your projects.
This will make SlickEdits navigation, completion, and browsing features available for symbols in the
runtime libraries.
The main tool for managing tag databases is the Context Tagging Tag Files dialog, shown in
Figure 5-23.

Figure 5-23

88

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 89

Chapter 5: Context Tagging


SlickEdit organizes tag databases across these categories:

The Workspace Tag File contains the tag database for all the source files in projects in the current
workspace.

The Auto-Updated Tag Files group contains tag databases for other files associated with the
workspace.

The Compiler groups each contain tag databases for compiler runtime libraries for C/C++
and Java.

The language groups each contain tag databases for global libraries for that language.

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.

Global Tag Databases


If you have a runtime library that is global, so that you want to use it any time you are using a particular language, you can tag the library in a global tag database under the languages category, just as with
the standard libraries.
You can add the librarys files to the main tag database for the language if you want to, but it is usually
cleaner to set up a separate tag database per additional library or group of libraries. Thus, for example, if
you are using the wxWidgets library, you might create a tag database in a file named wxWidgets.vtg.
Well use the wxWidgets library for some of the examples. It is an open-source C++ GUI library. You
can find out more from http://ww.wxwidgets.org.
Note that if you tag a library globally, that version of the library is used whenever you use that language,
across all your workspaces. This is often inappropriate, because different workspaces may require different versions of a library.
Global tag databases are pretty straightforward. Basically you have a tag database and a set of associated
source files. When you create the tag database, you specify the language and the source files. SlickEdit
scans the source files for symbols and populates the tag database.

89

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 90

Part II: Using SlickEdit


If you edit any file in the global tag database, SlickEdit retags the file when you save it. If you change the
source files outside SlickEdit, you can rebuild the tag file manually. This might happen if you upgrade a
library. You can also manage specific source files included in the tag database. Therefore, over time, you
might move certain files in and out of the tag database as your usage of libraries changes.
The idea with global libraries is that they shouldnt change very often. Once you set them up, they
shouldnt require much further attention.
Well look at some specific examples of setting up global tag databases below in this section.

Auto-Updated Tag Databases


Auto-updated tag databases are designed for sets of source files that are in between being part of your
project and being global libraries. For example, you might have some common libraries within your
organization that you import into multiple projects. The common libraries dont change as often as the
files in specific projects do. You dont want to have SlickEdit rescanning the common library source files
all the time, because it would be a waste of resources. With an auto-updated tag database, you control
when the tag database is refreshed.
Auto-updated tag databases are defined in workspaces. This means that you can have different libraries
tagged differently for different workspaces. This is very useful if different workspaces require different
versions of runtime libraries. Thus, for example, you could have wxWidgets-2.8.3.vtg being used by
one project and wxWidgets-2.0.vtg being used by another.
You cannot create an auto-updated tag database from scratch, and you cannot directly manage the
source files tagged in an auto-updated tag database. Instead, an auto-updated tag database is linked to
another pre-existing tag database, referred to as the shared tag database. You can create the shared tag
database using another workspace or as a global tag database.
When you open a workspace containing auto-updated tag databases, SlickEdit checks the shared tag
databases to see if they have changed since the last refresh. If a shared tag database has changed,
SlickEdit automatically refreshes the auto-updated tag databases (hence the name auto-updated).
You can automate the creation and refresh of shared tag databases. Well look at some specific examples
of setting up and using auto-updated tag databases below in this section.

Tagging Dynamic Languages


The standard library for an interpreted language such as Perl, Python, or Ruby is usually simply a set of
source files in that language. For these libraries, you simply tag the source files themselves. The tagging
engine tags them in the same way it would tag your own project files, which means that you get all the
Context Tagging features for the standard library automatically. For example, you can navigate to function
definitions and browse function documentation.
Additional installed libraries are often installed in the global library tree, perhaps under a site/ subdirectory. The same benefits apply to these libraries. If additional libraries are installed in a separate directory, it is easy to add files from that directory tree to the same tag database, or a separate tag database.
As mentioned above, SlickEdit automatically creates tag databases for most dynamic languages as soon as
you start using them. Sometimes it is necessary to manage tag databases for standard libraries manually.

90

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 91

Chapter 5: Context Tagging


SlickEdit might not be able to find your language installation, or you might want to update your tag
database to use a different installation.

Creating a Global Tag Database for Ruby


For example, suppose you are doing a Ruby project, and you find that SlickEdit has no tag database for
Ruby. To tag the installed Ruby libraries, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit shows the Context Tagging Tag Files
dialog. There is no Ruby category at this stage.

2.

Click Add Tag File. SlickEdit displays the Add Tag File dialog, shown in Figure 5-24.

Figure 5-24

3.
4.
5.
6.

Select the Ruby source type.

7.
8.

Navigate to the location of your Ruby library files. On my system, they are in C:\ruby\lib.

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.

Click OK to add the files. The tag database has the source files added, as shown in Figure 5-25.

Figure 5-25

91

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 92

Part II: Using SlickEdit

Tagging C/C++ Libraries


The standard library for C/C++ is described by a set of header files. Tagging the header files gives many
of the benefits of the Context Tagging system. For example, you can navigate to function declarations.
If functions are well documented using a comment style that SlickEdit can understand, you can browse
function documentation.
Many additional C++ libraries are implemented as C++ code in header files. In these cases, you can navigate to function implementations also. Obviously, if libraries are implemented as compiled object code
and you dont have the source, you cannot navigate to implementations.

Creating a Global Tag Database with Header Files


In this section, well work through an example of setting up tagging for a C++ runtime library. For the
example, well use the wxWidgets GUI library, available at http://www.wxwidgets.org. Before working through the example, assume that weve downloaded the code archive and expanded into a suitable
location. On my system, I have expanded it to C:\lib\wxWidgets-2.8.3.
In this example, well create a global tag library for wxWidgets. See the following sections for ways to
create workspace auto-updated tag databases. To create the global tag database, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit shows the Context Tagging Tag Files
dialog.

2.
3.
4.

Click Add Tag File. SlickEdit shows the Add Tag File dialog.

5.

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.

6.

Specify the location for the tag database. The default location is the easiest, because that is
where SlickEdit looks for tag databases by default.

7.
8.

Click OK. SlickEdit displays the Add Tree dialog.

9.

Specify the path to the library Include files. In my system, it is C:\lib\wxWidgets2.8.3\include.

10.

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.

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.

Click OK. SlickEdit builds the tag database. At this point, we have the tag database defined as a
global runtime library.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 93

Chapter 5: Context Tagging


The identifier wxDialogBase is a class in the wxWidgets library.
You should be able to view symbol information for the class in the Preview tool window, or navigate to
the class definition in the header file wx/dialog.h by invoking push-tag (Ctrl+dot).
If you are happy to have the library available globally to all your C/C++ projects, you can stop here. If
you want to have the library available only in the current workspace, read on through the following
sections.

Converting a Global Tag Database to an Auto-Updated Tag Database


Suppose we have already set up the wxWidgets library as described in the above section. But now, we
need to work on a different workspace/project that also uses wxWidgets, but an earlier version. If we
tag the earlier version as a global tag database, SlickEdit will match symbols in both databases.
To have Context Tagging features run smoothly, we need to have the separate workspaces refer to distinct tag databases for wxWidgets. An auto-updated tag file is the way to do this. Given that we have
already got a tag database built for wxWidgets, we can convert it to use via an auto-updated tag file.
Follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit shows the Context Tagging Tag Files
dialog.

2.
3.

Select Auto-Updated Tag Files. This step is important!

4.
5.

Select the tag database. In my case, it is wxWidget-2.8.3.vtg.

6.
7.

Select the tag database under the global C/C++ Tag Files category.

8.
9.
10.

Click Add Tag File. SlickEdit prompts for the tag file to add. The default location is the tagfiles/
subdirectory under your SlickEdit configuration directory.

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.

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.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 94

Part II: Using SlickEdit


Creating a Separate Workspace for an Auto-Updated Tag Database
Creating an auto-updated tag database from a global tag database is a fairly long procedure. If you
know ahead of time that you want an auto-updated tag database, you can create the shared tag database
as a separate workspace instead. Lets begin the example again, using a separate workspace for the
wxWidgets library.
If you have the tag databases created in the previous examples, you need to delete them for this example.
You can delete the auto-updated tag database using the Context Tagging Tag Files dialog. If you still
have the global tag database in tagfiles/, you can delete that using the file system, because SlickEdit
contains no references to it anymore.
To create a separate workspace for wxWidgets, follow these steps:

1.
2.
3.
4.

Invoke workspace-new (Project New). SlickEdit displays the New Project dialog.

5.
6.
7.
8.

Click OK to create the workspace. SlickEdit displays the Project Properties.

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 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.

9.
10.

Click OK to close the Add Wildcard dialog.

11.

Close the workspace (workspace-close, or Project Close Workspace).

Click OK to close the Project Properties dialog. SlickEdit scans the files and creates the tag
database.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 95

Chapter 5: Context Tagging


If you dont have a reason to open the separate workspace, you can update its tag database using the
vsmktags command-line tool. The syntax of the tool is:
vsmktags workspaces

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.

Creating a Tag Database Directly


The wxWidgets library is actually a third-party library, not a part of the code base of our organization.
With true third-party libraries, some aspects of the separate workspace/vsmktags approach are often
inappropriate. For example, the copy of the library were using probably doesnt change over time. If we
upgrade to a new version of wxWidgets, we might prefer to install the new version in a new directory
and create another tag database, rather than overwriting the existing one.
For this situation, we can dispense with the workspace altogether and get SlickEdit to create just a tag
database for a set of files. This functionality is not available through the GUI, however. Instead, it is provided by a SlickEdit batch macro, which we can invoke from the SlickEdit command line.
Lets use this technique to repeat our wxWidgets example one more time. Before starting, remove any
SlickEdit tag and project files we created for wxWidgets. (Project Organize Workspaces, and use the
Delete button.)
To create the tag database, follow these steps:

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.

2.

Enter this command on the SlickEdit command line:

make-tags -t C:\lib\wxWidgets-2.8.3\include\*.h -o wxWidgets-2.8.3.vtg

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 96

Part II: Using SlickEdit


You can automate the creation of tag databases by invoking SlickEdit from the command line. For example,
you can run the above SlickEdit procedure from the command line with a command like this:
vs.exe +new -p make-tags -t C:\lib\wxWidgets-2.8.3\include\*.h
-o C:\lib\wxWidgets-2.8.3\include\wxWidgets-2.8.3.vtg -c

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.

Working with Different Compilers


SlickEdits support for C/C++ and Java compilers is more sophisticated than its support for other languages. SlickEdit supports multiple installed C/C++ compilers and can switch among them easily. For
each installed compiler, you create a SlickEdit configuration that contains details about the compiler,
including a tag database for the compilers runtime library. One compiler is designated as the default
C/C++ compiler and becomes associated with new C/C++ projects by default. You can change the
default at any time, and you can change the compiler associated with any project.
To create a compiler definition and associated tag database, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.

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.

3.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 97

Chapter 5: Context Tagging


4.

Uncheck the Java and .NET compilers if you are not interested in them, or if you have already
tagged them.

5.

Click Create tag file(s). SlickEdit closes the Create Tag Files for Run-Time Libraries dialog
and creates the tag database.

6.

Click Done.

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.

Invoke project-edit (Project Project Properties). SlickEdit displays the Project Properties
dialog.

2.
3.
4.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 98

Part II: Using SlickEdit


2.
3.
4.
5.

Click Add. SlickEdit prompts you to enter the name of the new configuration.

6.
7.
8.

Navigate to C:\dm\include.

9.
10.

Enter Digital Mars 8.49 for the name.


Click OK.
Click the .. button next to the Built-in Compiler Include Directories list. SlickEdit displays the
Choose Include Directory dialog for you to choose a directory.

Click OK to add the directory.


Click Build Tag File. SlickEdit scans the header files in the include directory and builds a tag
database.
Click OK. SlickEdit prompts you whether to make the new compiler the default configuration.
Click No.

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.

Tagging Java Libraries


Many of the techniques for managing C/C++ tag databases apply for Java and other languages too.
There are some differences, which we cover here.
The standard library for Java is supplied in source form in a ZIP file with the Java SDK. By tagging that
ZIP file, you get the full benefit of the Context Tagging system for standard library classes. You can navigate to method definitions and browse class and method documentation.
Additional libraries for Java are usually supplied as JAR files. You can tag JAR files, and get some of the
benefits of the Context Tagging system. The main benefit you get is completions. However, the support
is not as good as with source files, because JAR files lack several features from the source files:

Parameter information does not show the original names of parameters. Rather, SlickEdit will
show parameters as A, B, and so on. Seeing the type of each parameter is helpful, but not as
helpful as seeing both the type and the name.

No JavaDoc information is available. This also reduces the amount of assistance you get from
Context Tagging.

You cannot navigate to a symbol defined in a JAR file.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 99

Chapter 5: Context Tagging


Creating a Global Tag Database with JAR Files
The quickest and easiest way to get up and running with Context Tagging for Java is simply to add all
your JAR files to one or more global tag databases. Lets work through an example. Suppose we wish to
do a Java project using the popular Spring framework (http://www.springframework.org). Before
starting, download the framework with dependencies, and unzip it under C:\lib. On my system, the
full directory of the framework is C:\lib\spring-framework-2.0.2.
Well create an empty Java project, called java_spring. In the project directory, create a subdirectory
called lib. This is where well put the JARs for the project.
The Spring distribution comes with many additional JARs that can be used with various Spring features.
Because the framework as a whole has a dependency on commons-logging.jar, well start by copying
just spring.jar and commons-logging.jar from the distribution into the projects lib directory.
We now have a single Java project, and all of the runtime library JARs are in the projects lib directory.
To set up tagging for those libraries in a global tag database, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.
3.
4.
5.

Select the Java category.

6.
7.
8.
9.
10.
11.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 100

Part II: Using SlickEdit


JdbcTemplate and open the Preview tool window, there is no preview available. SlickEdits preview is

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.

Creating a Global Tag Database with Java Source Files


Lets replace spring.jar in the global tag database with the Spring framework Java source files. For
Spring on my system, the source code is in C:\lib\spring-framework-2.0.2\src. To change the
global tag database to use the source files, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.
3.
4.

Select the java_libs.vtg tag database in the Java category.

5.
6.
7.
8.
9.
10.

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.

Creating a Separate Workspace for an Auto-Updated Tag Database


As with the C++ example, we can create a workspace for a Java runtime library and use an auto-updated
tag database to link our project to it. Lets work through this procedure using the Spring library. First,
well remove the Spring source files from the global tag database:

100

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.

Select the java_libs.vtg tag database in the Java category.

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 101

Chapter 5: Context Tagging


3.
4.

Select all of the Spring source files in the right-hand pane.

5.
6.

Click Yes. SlickEdit removes the source files and updates the tag database.

Click Remove Src File. SlickEdit prompts you to confirm that you wish to remove the selected
files from the tag database.

Click Done.

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.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.
3.
4.

Select the Auto-Updated Tag Files category.

5.
6.

Select the tag database (spring-framework-2.0.2.vtg).

7.

Click Done.

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).

Click OK. SlickEdit creates the auto-updated tag database and updates it with the source files
from the shared tag database.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 102

Part II: Using SlickEdit


The auto-updated tag database is specific to the workspace. You can create different auto-updated tag
databases in different workspaces, linking to different versions of libraries.

Creating a Tag Database Directly


As in the C++ example, you might prefer a shorter way to create the tag database for the Spring source
files, if youre not interested in opening Spring as a workspace in its own right. You can use the maketags command as we did for the C++ example. To do this for the Spring framework, first remove the
workspace files (*.vpj, *.vpw, *.vpwhist, and *.vtg). Then follow these steps:

1.

Change the directory to the location of the framework distribution (C:\lib\spring-framework-2.0.2).

2.

Enter this command on the SlickEdit command line:

make-tags -t src\*.java o spring-framework-2.0.2.vtg

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.

Adding JARs to the Workspace


Sometimes you have a JAR for a runtime library, and the Java source code is not available. As described
above, you can tag JARs in a global tag database for some of the benefits of Context Tagging.
You can also add JARs to your workspace for similar (limited) benefits. The advantage of adding them to
your workspace is that you dont clutter up the global tag databases with lots of different JARs, and also
you can tag different versions in different projects. SlickEdit scans for when the files timestamp on disk
changes; thus if the file never changes and its modification date doesnt change, SlickEdit doesnt retag
it. Therefore, theres no performance penalty in including JARs in your workspace.

Working with Different JDK Versions


SlickEdit (as of 12.0.2) supports multiple Java compiler definitions, as it does for C/C++. There is a
global tag database per compiler definition. Refer to the C/C++ information above for configuring multiple compilers.

Tagging .NET Runtime Libraries


The .NET considerations are mostly the same as for Java. The standard library is supplied as a set of
assemblies, for example, mscorlib.dll. SlickEdit tags the DLLs to form the tag database. Many of the
metadata required for tagging are present in .NET DLLs.

102

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 103

Chapter 5: Context Tagging


SlickEdit can also parse the documentation XML files provided with the assemblies and use the comments from the documentation to provide help on classes and members.

Creating a Global Tag Database with DLL Assemblies


Lets work through an example of a global database using a .NET DLL assembly. For this example,
well use the .NET variation of the Spring Framework, found at http://www.springframework.net.
Download the distribution, and unzip it in a suitable location. On my system, it is in C:\lib\Spring
.NET-1.1.0 Preview 3.
To set up a global tag database for the Spring.NET DLL, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.
3.
4.
5.
6.
7.
8.
9.

Select the C# category.

10.
11.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 104

Part II: Using SlickEdit


Creating a Global Tag Database with C# Source Files
Lets replace the Spring DLLs in the global tag database with the Spring framework C# source files. For
Spring.NET on my system, the source code is in C:\lib\Spring.NET-1.1.0 Preview 3\src. To
change the global tag database to use the source files, follow these steps:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.
3.
4.

Select the springnet.vtg tag database in the C# category.

5.
6.
7.
8.
9.
10.

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.

The C/C++ Preprocessor


C/C++ suffers from considerable extra complexity in tagging because of the preprocessor. The language
is designed for the preprocessor to translate the source file before compilation, and the possible effects of
translation are virtually unlimited. SlickEdit needs to parse the code as closely as possible to how the
compiler parses it, in order to generate accurate tagging information.
Here are some examples of common preprocessing constructs that can all prevent tagging from working
correctly:
class MYDLLEXPORT MyClass { ... }
void funcName PROTO(args);
BEGIN_MY_NAMESPACE
USING_MY_NAMESPACE(my.ns)
MY_STD_CLASS_FUNCTIONS(MyClass)

104

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 105

Chapter 5: Context Tagging


You can help SlickEdit parse source files accurately by specifying some preprocessor information. To
access C/C++ Preprocessing options, follow these steps:

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.

Go to Definition Doesnt Work


Use these tips if the push-tag (Ctrl+dot) command doesnt work. There are two basic cases:

An unqualified symbol x.

A qualified symbol expr.x, expr->x, or expr::x.

Case 1: An Unqualified Symbol


Suppose you have an unqualified symbol x, and Go to Definition (push-tag, Ctrl+dot) doesnt work
for it.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 106

Part II: Using SlickEdit


2.

Go to the file and line where x is defined or declared.

Does the source file come up in the correct source language mode? Is this an extensionless C/C++ header file? If yes, see Solution C below. Does this file have an unrecognized file extension (like .hhh)? If yes, see Solution D below.

Does x 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. Should the
symbol be visible from the scope you were in? (Maybe the symbol is private, or needs
to be imported?)

If x shows up correctly in the Defs tool window, but Go to Definition was failing, make
sure the tag file is up to date. See Solution E below.

Case 2: A Qualified Symbol


Suppose you have a qualified symbol such as expr.x, expr->x, or expr::x, and Go to Definition (push-tag,
Ctrl+dot) doesnt work for it.

1.

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?

2.

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.)

3.

4.

106

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?

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.

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.

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 107

Chapter 5: Context Tagging

Go to Reference Doesnt Work


Use these steps if the push-ref (Ctrl+slash) command doesnt work.

1.

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.

2.

Are references missing?

3.

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.

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.

Auto-List Members Doesnt Work


Use these steps if the list-symbols (Alt+dot) command doesnt work.
See Case 2 of the Go to Definition debugging procedure in order to determine if the prefix expression
(the expression before the member access operator) is correctly recognized.

Auto-Parameter Information Doesnt Work


Use these steps if the function-argument-help (Alt+comma) doesnt work.

1.

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.

2.

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.

Solution A: Define C/C++ Preprocessing


The symbol needs C/C++ preprocessing to define it correctly. Add the preprocessing definitions:

1.
2.

Open the Extension Options dialog (Tools Options File Extension Setup).
Select extension cpp.

107

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 108

Part II: Using SlickEdit


3.
4.
5.
6.

Click C/C++ Options. SlickEdit shows the C/C++ Formatting Options dialog.

7.
8.
9.

Click OK to close the C/C++ Preprocessing dialog.

Click the Other tab.


Click C/C++ Preprocessing. SlickEdit displays the C/C++ Preprocessing dialog.
Add your #define using this dialog. Let SlickEdit rebuild your workspace tag file when you
are done.

Click OK to close the C/C++ Formatting Options dialog.


Click OK to close the Extension Options dialog.

For more information about C/C++ Preprocessing setup, see the online Help.

Solution B: Add Symbol to Tag File


The symbol is not in the tag database. Add the file where the symbol is defined to the workspace:

1.

Invoke project-edit (Project Project Properties). SlickEdit displays the Project Properties
dialog.

2.
3.
4.

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.

Solution C: Configure C/C++ Extensionless Header Files


The symbol is defined in an extensionless header file, and SlickEdit didnt recognize or treat the file correctly. Configure the names of the extensionless header files in your libraries:

108

1.
2.
3.
4.
5.

Open the Extension Options dialog (Tools Options File Extension Setup).

6.
7.
8.

Click Extensionless C++ Files. SlickEdit displays the Extensionless C++ Files dialog.

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.

Add the names of your extensionless header files.


Click OK to close the Extensionless C++ Files dialog.

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 109

Chapter 5: Context Tagging


9.
10.

Click OK to close the C/C++ Formatting Options dialog.


Click OK to close the Extension Options 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.

Solution D: Create a File Extension Alias


The file extension is not recognized for the correct language. Add a new extension for the language:

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.

Solution E: Rebuild Your Tag File(s)


The tag database is out of date. Rebuild the workspace tag file:

1.

Invoke gui-make-tags (Tools Tag Files). SlickEdit displays the Context Tagging Tag Files
dialog.

2.
3.
4.
5.
6.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 110

Part II: Using SlickEdit


If you do need to do some tuning, the tips here might help. Otherwise, you may need to contact
SlickEdit support for specific suggestions relating to your environment.
Some of the things that can affect the performance of Context Tagging are:

Very large projects The more symbols you have, the more work for the tagging engine.
Weve seen in this chapter some approaches you can use to tag files that dont change frequently
offline, so that they dont slow down the editor while you are working with it. Depending on
the size of the active files in your projects, you may need to adjust the amount of memory
SlickEdit uses for tagging them.

Many symbols sharing the same name SlickEdit indexes the tag database with the symbols
name. In order to find a particular symbol, SlickEdit needs to scan through all the symbols with
the same name. For some operations, this can be prohibitive if you have many symbols with the
same name. For example, in some C++ projects, every class has an init() method. In Java projects, many classes may provide an override of toString(). If you are working with symbols
for which there are many occurrences with the same name, you may want to tweak the way
SlickEdit treats these.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 111

Chapter 5: Context Tagging

Tag Cache Size


The Tag file cache size determines how much tagging information SlickEdit can hold in memory. The
default is currently 64 MB, and this default has been changed several times over the years, as the typical
developers machine has grown in capacity. Depending on your project size and the RAM in your machine,
you may want to fine-tune this parameter. If you have 2 GB and dont run many applications other than
SlickEdit, you may be happy to set this value to 256 MB or 512 MB. If you have less RAM or need to run
many applications besides SlickEdit, you need to be careful not to make the setting too high. Otherwise,
it may make SlickEdits memory footprint too large and cause memory swapping, which will slow down
your system rather than speed it up. You can use the Task Manager in Windows to get an idea of the
memory used by different applications and whether you can afford to have SlickEdit use more.
You can get an idea of how large your tag cache should be to fit your tag database in memory by looking
at the size of the tag file itself. For example, the GNU/Linux kernel source (version 2.6.20) includes
about 9,000 .c files totaling 5.7 million lines and 8,500 .h files totaling 1.3 million lines. A tag database
for it is about 120 MB.

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

22150c05.qxd:WroxPro

9/25/07

12:28 AM

Page 112

Part II: Using SlickEdit


use of templates, especially template metaprogramming, or makes heavy use of overloading and/or
namespace/package scoping. These two auto-list compatible... features are trying to determine for
each variable in the immediate scope whether or not it is (at least loosely) assignment-compatible in
the current context. The harder the type compatibility is to calculate, the longer it takes.
Turning off the auto versions of these features does not take away the features. You can still invoke
them on demand as described above in this chapter.
For C#, there is a special consideration. If you turn off Show Comments, you might see some performance improvements, because it will allow SlickEdit to avoid loading the large XML files in which
Microsoft packages their .NET library documentation.

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 113

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.

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 114

Part II: Using SlickEdit

F inding and Opening F iles


Before you can navigate in a file, you have to open one. When you first use SlickEdit, you may be inclined
to use the gui-open command (File Open) to open files. For some situations, this is the most effective
way to open a file. But other times, particularly on large projects with many directories, other methods
are faster.

Using File Open


Figure 6-1 shows the default Open dialog on Windows.

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 115

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 116

Part II: Using SlickEdit


having some pattern in common. You type the pattern, press Enter, and then select the ones you want
from the resulting list. You can also use select-all (Ctrl+A) in the list to select all the filtered files.
On the other hand, the fast Open dialog on Windows does not allow you to specify the encoding when
opening a file, something you can do with the standard Open dialog on Windows.
The choice of Open dialog on Windows is mostly a matter of personal preference and depends on your
preferred layout for navigating file and directory lists. The main problem with the fast Open dialog on
Windows, as shipped with SlickEdit, is that it is too small. The file and directory lists do not show enough
entries, and they are not wide enough. Fortunately, SlickEdit allows you to change any supplied dialog,
as well as create your own.
Chapter 17 shows how to change the fast Open dialog to be larger, as shown in Figure 6-4.

Figure 6-4

Using File and Directory Aliases


File and directory aliases are a great combination with the Open dialog, for files and directories you
open frequently. Basically, a file or directory alias is shorthand for a frequently used file or directory.
Instead of manually navigating the file tree or typing the full pathname of the file or directory, you type
the alias and expand it. Its a very fast way to navigate to a directory or open a given file.

116

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 117

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.

Using the edit Command


Sometimes opening a file from the command line can be quicker than invoking the Open dialog. If you
know the name of the file and the file is in the working directory, or can be quickly reached by a file or
directory alias, you can open it with the command line with very few keystrokes.
The edit command (with shorthand just e) is used to open a file from the command line. Because
SlickEdit knows that edit expects a filename as a parameter, it can prompt you with completions from
matching files in the working directory.
Another time you might want to use the edit command is in macros. Your macros can open, navigate,
and edit files programmatically using the edit command. The edit command has many options available when called from a macro. See the online Help for more details.

Using Tool Windows


Several of SlickEdits tool windows can be used to open files.
The Project tool window allows you to navigate your project structure and open files. This is occasionally useful for browsing and discovering files, such as when you open someone elses project. For your
own code, it is not usually a fast way to open files, because it requires too much navigation of different
folders. For large projects, its just too hard to arrange and navigate a tree quickly to any file.
The Open tool window shows the file tree and lists files in the selected directory. Again, for large projects, this requires too much navigation to be really effective.
The Files tool window is a very effective way of opening any file in your project or workspace. The two
big advantages of using the Files tool window are:

You dont have to navigate directories at all.

You can type any part of the files name. You dont have to begin at the start.

117

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 118

Part II: Using SlickEdit


To open a file in your project using the Files tool window:

1.

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.

2.

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.

3.

Use the arrow keys to select a file from the list, and press Enter to open the file.

Figure 6-5 shows the Files tool window in action.

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 119

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.

Using the File Manager


SlickEdits built-in File Manager provides another way to navigate directories and open files.
See Chapter 15 for more information on using the File Manager.

Navigating to Header Files


C and C++ header files are a very familiar part of the life of programmers working in those languages.
The top of virtually every source file contains several #include directives. Navigating to those header
files is so common that SlickEdit provides a command to do just that.
To navigate to a header file for which you have an #include directive:

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 120

Part II: Using SlickEdit

Navigating in the buffer


You can use several commands for moving around the buffer. Table 6-1 shows the basic navigation commands. We include basic arrow key commands like cursor-up in the table because although you usually invoke them by pressing the arrow keys, you can use the commands by name in macros.

Table 6-1

120

Command

Key

Description

cursor-up

Up arrow

Move the cursor up.

cursor-down

Down arrow

Move the cursor down.

cursor-left

Left arrow

Move the cursor left.

cursor-right

Right arrow

Move the cursor right.

prev-word

Alt+Left (WROX)

Move the cursor left one word.

next-word

Alt+Right (WROX)

Move the cursor right one word.

wrox-prev-word

Ctrl+Left (WROX)

Move the cursor left one word


(alternative).

wrox-next-word

Ctrl+Right (WROX)

Move the cursor right one word


(alternative).

prev-tag

Ctrl+Up

Move to previous function or class


definition.

next-tag

Ctrl+Down

Move to next function or class definition.

page-up

PgUp

Move up one page.

page-down

PgDn

Move down one page.

top-of-window

Ctrl+PgUp

Move the cursor to the top of the window.

bottom-of-window

Ctrl+PgDn

Move the cursor to the bottom of the window.

top-of-buffer

Ctrl+Home

Move the cursor to the top of the buffer.

bottom-of-buffer

Ctrl+End

Move the cursor to the bottom of the buffer.

find-matching-paren

Ctrl+]

Move the cursor to the matching brace, parenthesis, etc.

goto-parent

(none)

Move to next higher-level block or definition.

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 121

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 122

Part II: Using SlickEdit


If we use wrox-next-word instead, the cursor will move through the positions shown in Figure 6-7.
1

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 123

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

Positioning the Window


Often you have the cursor where you want it, but you cannot see everything you want to see on the
screen. Some important information may be just off the top or the bottom of the screen. Or, you may
have lines that are too long for the screen, and you want to see some data to the left or the right. In these
cases, you could move the cursor to cause the window to reposition, but its often more convenient to
cause the window to move while leaving the cursor where it is. Table 6-2 shows several commands that
reposition the window.

Table 6-2
Command

Key

Description

line-to-top

Alt+PgUp (WROX)

Reposition the window so that the current


line is at top.

line-to-bottom

Alt+PgDn (WROX)

Reposition the window so that the current


line is at bottom.

center-line

Alt+Home (WROX)

Reposition the window so that the current


line is in the middle.

scroll-up

Shift+F1 (WROX)

Scroll buffer up one line.

scroll-down

Shift+F2 (WROX)

Scroll buffer down one line.

scroll-left

Shift+F3 (WROX)

Scroll buffer left one character.

scroll-right

Shift+F4 (WROX)

Scroll buffer right one character.

None of these commands has key bindings in the CUA emulation; thus its easy to miss them.

123

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 124

Part II: Using SlickEdit

Navigating to a Line, Column, or Byte Offset


You can use commands on the command line to navigate to an absolute or relative position in the file. You
can navigate to a precise line, column or byte offset. Table 6-3 shows the commands for precise navigation.

Table 6-3
Command

Description

goto-line n

Go to line n.

Go to line n (shorthand form).

cursor-up n

Go up n lines.

-n

Go up n lines (shorthand form).

cursor-down n

Go down n lines.

+n

Go down n lines (shorthand form).

goto-col n

Go to column n.

cursor-left n

Go left n columns.

cursor-right n

Go right n columns.

seek n

Go to character n in file.

seek n

Go backward n characters.

seek +n

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 125

Chapter 6: Navigation

Navigating among Buffers


When you have more than one file loaded, you need to be able to switch between them effectively. The
most obvious way to move among files is to click them in the File Tabs tool window. But that breaks our
number one rule of using SlickEdit: Avoid the Mouse! Clicking tabs is a very slow way to switch among
buffers.
If there are only two or three files loaded, it can be sufficient to cycle through them in turn with a keyboard
command. If there are more than two or three files, you need a faster way to get to the buffer you want.
Table 6-4 shows commands for switching among buffers.

Table 6-4
Command

Key

Description

next-buffer

Ctrl+N

Move to the next buffer.

prev-buffer

Ctrl+P

Move to the previous buffer.

next-buff-tab

(none)

Move to the next buffer tab.

prev-buff-tab

(none)

Move to the previous buffer tab.

next-window

Ctrl+Tab, Ctrl+F6

Move to the next window.

prev-window

Ctrl+Shift+Tab, Ctrl+Shift+F6

Move to the previous window.

list-buffers

Ctrl+Shift+B

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.

We edit file A. The ring now contains only file A, and prev-buffer and next-buffer do
nothing.

2.

We edit file C. The ring is now A, C.

125

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 126

Part II: Using SlickEdit


3.
4.
5.
6.
7.

We edit file E. The ring is now A, C, E.


We invoke next-buffer. This takes us to buffer A.
We edit file B. The ring is now A, B, C, E because we opened B while A was the current buffer.
We invoke next-buffer. This takes us to buffer C.
We edit file D. The ring is now A, B, C, D, E.

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 127

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

Key

Description

push-bookmark

Ctrl+semicolon (WROX)

Push a bookmark explicitly.

push-tag

Ctrl+dot

Push a bookmark and go to definition.

push-ref

Ctrl+slash

Push a bookmark and go to reference.

pop-bookmark

Ctrl+comma

Pop last bookmark.

pop-all-bookmarks

(none)

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 128

Part II: Using SlickEdit


Pushed bookmarks are also quite useful in macros. If you want a macro to be able to navigate around the
file and do something, then return to where the user was editing, use a pushed bookmark. An example
might be a macro that adds a header to a file. Be careful to ensure that your macro pops all the bookmarks
that it pushes, regardless of how it returns.

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

Menu or Key

Description

set-bookmark

Search Set bookmark

Sets a named bookmark.

delete-bookmark

(none)

Deletes current or named bookmark.

goto-bookmark

Search Go to bookmark

Go to a named bookmark.

toggle-bookmark

Search Toggle bookmark or


Ctrl+Shift+J

Toggle a named bookmark on the


current line.

activate-bookmarks

Search Bookmarks or
Ctrl+Shift+N

Show the Bookmarks tool window.

next-bookmark

Search Next bookmark

Go to next named bookmark.

prev-bookmark

Search Previous bookmark

Go to previous named bookmark.

alt-bookmark

Ctrl+Shift+number key
(WROX)

Set a quick bookmark.

alt-gtbookmark

Ctrl+number key (WROX)

Go to a quick bookmark.

clear-bookmarks

(none)

Clear named bookmarks.

There are three ways to use named bookmarks:

128

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.

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 129

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

22150c06.qxd:WroxPro

9/25/07

12:32 AM

Page 130

Part II: Using SlickEdit


closing the file. Alternatively, if you have turned on Automatically close visited files in the General tab
of the General Options dialog (Tools Options General), a visited file will be closed when you use
pop-bookmark to return from a reference.
Finally, the Max stack depth setting controls how many pushed bookmarks SlickEdit remembers.

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

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 131

Search and Replace


A particularly important tool for navigation is searching. SlickEdit has a rich set of searching features. These range from a simple search for a string, up through sophisticated searches using regular expressions and context-sensitive criteria. You can use selective display to filter which lines of
the buffer are displayed on the screen, based on search conditions. You can selectively hide sections
such as comments or arbitrary code blocks. You can also search across many files.
Along with searching, SlickEdit also supports replacing, with virtually the same set of features.
Regular expression replacements are a particularly powerful way to edit files.

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

Menu or Key

Description

quick-search

Ctrl+F3 (WROX)

Quick search for selection or word at


cursor.

quick-reverse-search

Ctrl+Shift+F3 (WROX)

Quick search backward for selection


or word at cursor.

i-search

Ctrl+I

Incremental search forward.

reverse-i-search

Ctrl+Shift+I

Incremental search backward.


continued

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 132

Part II: Using SlickEdit


Table 7-1 (continued)
Command

Menu or Key

Description

gui-find

Ctrl+F

Show Find dialog.

find-in-files

Ctrl+Shift+F

Show Find in Files dialog.

gui-replace

Ctrl+R

Show Replace dialog.

replace-in-files

Ctrl+Shift+R

Show Replace in Files dialog.

find-next

Ctrl+G

Find next match.

find-prev

Ctrl+Shift+G

Find previous match.

Terminating a Long Search


Sometimes you start a search in a long file and realize its going to hang your machine for a while. To
terminate a long search in SlickEdit, press Ctrl+Alt+Shift.

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

132

2.

Type the first character of your search expression. SlickEdit advances the cursor to the next
match for that character.

3.
4.

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.

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 133

Chapter 7: Search and Replace


5.

Use find-next (Ctrl+G) to skip to the next match, if desired, or find-prev (Ctrl+Shift+G) to
search backward.

6.

Use Escape or a cursor movement key to terminate the search.

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

Description

Ctrl+C

Toggles case sensitivity. The key bound to the BRIEF emulation command
case_toggle will also toggle the case sensitivity.

Ctrl+M

Toggles searching within mark.

Ctrl+O

Toggles incremental search mode.

Ctrl+Q

Quotes the next character typed.

Ctrl+R

Searches in reverse for the next occurrence of the search string.

Ctrl+S

Searches forward for the next occurrence of the search string.

Ctrl+T

Toggles regular expression pattern matching on/off. The key bound to the
BRIEF emulation command re_toggle will also toggle regular expression
pattern matching.

Ctrl+W

Toggles word searching on/off.

The F ind and Replace Tool Window


Quick Search and Incremental Search are nice for simple searches. For complex, repeatable searches, use
the find command. We will begin by looking at the Find and Replace tool window, and then examine the
command-line version of find.
The four commands gui-find, find-in-files, gui-replace, and replace-in-files all bring up
similar GUI dialogs. Each is actually a separate tab in the Find and Replace tool window. When the tool
window is open, you can click the tabs to switch from one function to another.

133

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 134

Part II: Using SlickEdit

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:

134

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.

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 135

Chapter 7: Search and Replace

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.

Using Find in Files


When you want to search in multiple files, invoke find-in-files. This opens the Find in Files tab of
the Find and Replace tool window, shown in Figure 7-4.

Figure 7-4

135

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 136

Part II: Using SlickEdit


Many of the options in Find in Files are the same as in the regular Find tab. The different options concern which files to search in, and what to do with the results.
When you use the Find tab to search within a buffer, SlickEdit navigates in the buffer for each match.
Using Find in Files, there are generally many matches in many different files. Therefore, the options
from the Find tab concerning cursor positioning and match highlighting do not apply for Find in Files.
SlickEdit usually shows Find in Files results in the Search Results tool window, where you can preview
them and open selected results as you choose. If you prefer, you can output the results to an editor window by selecting Output to editor window. In this case, a new editor window is created for the search
output. The window uses a special mode called grep to provide the same features as the Search Results
tool window.
Figure 7-5 shows the Search Results tool window, with the output of the search for Auto-Complete.

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

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 137

Chapter 7: Search and Replace

Using Replace and Replace in Files


The Replace and Replace in Files tabs of the File and Replace tool window are very similar to the Find
and Find in Files tabs, and their usage is obvious.

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

UNIX

SlickEdit

Brief

Match beginning of line.

%
<

Match end of line.

$
>

Match any character except newline.

Maximal match of zero or more occurrences of X.

X*

X@

X\:@

Maximal match of one or more occurrences of X.

X+

X#

X\:+

continued

137

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 138

Part II: Using SlickEdit


Table 7-3 (continued)

138

Definition

UNIX

SlickEdit

Brief

Maximal match of zero or one occurrences of X.

X?

X:0,1

X\:0,1

Match exactly n1 occurrences of X.

X{n1}
X{n1}?

X:n1

X\:n1
X\:n1?

Maximal match of at least n1 occurrences of X.

X{n1,}

X:n1,

X\:n1,

Maximal match of at least 0 occurrence but not more


than n2 occurrences of X.

X{,n2}

X:0,n2

X\:,n2

Maximal match of at least n1 occurrence but not


more than n2 occurrences of X.

X{n1,n2}

X:n1,n2

X\:n1,n2

Search fails if expression X is matched.

(?!X)

~X

Matches X or Y.

X|Y

X|Y

X|Y

Matches subexpression X and specifies a new tagged


expression. No more tagged expressions are defined
once an explicit tagged expression number is specified as shown below.

(X)

{X}

{X}

Matches any one of the characters specified by


charset. A hyphen (-) character may be used to
specify ranges.

[charset]

[charset]

[charset]

Matches any character not specified by charset. A


hyphen (-) character may be used to specify ranges.

[^charset]

[~charset]
[^charset]

[~charset]

Matches hexadecimal character hh, where


0 hh 0xff.

\xhh

\xhh

\xhh

Matches decimal character nnn, where 0 nnn 255.

\dnnn

\nnn

\dnnn

Defines a back reference to tagged expression


number d.

\d

\gd

\d

Specifies cursor position if match is found.

\c

\c

\c

Matches newline character sequence. Useful for


matching multiline search strings. What this matches
depends on whether the buffer is a DOS (ASCII 13,10
or just ASCII 10), UNIX (ASCII 10), Macintosh
(ASCII 13), or user-defined ASCII file.

\n

\n

\n

Matches carriage return (ASCII 13).

\r

\r

\r

Matches tab character.

\t

\t

\t

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 139

Chapter 7: Search and Replace


Table 7-3 (continued)
Definition

UNIX

SlickEdit

Brief

Turns on multiline matching. This enhances the


match character set, or match any character primitives to support matching end of line characters. For
example, \om.+ matches the rest of the buffer.

\om

\om

\om

Turns off multiline matching (default). You can still


use \n to create regular expressions that match one
or more lines. However, expressions like .+ will not
match multiple lines. This is much safer and usually
faster than using the \om option.

\ol

\ol

\ol

Declares character after slash to be literal.

\char

\char

\char

Matches predefined expression corresponding to


char.
See Table 7-4.

\: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);

Alternatively, use a single-quoted string, like this:


search(\:d{4}-\:d{2}-\:d{2}, U);

We explain more about Slick-C strings in Chapter 16.

139

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 140

Part II: Using SlickEdit


Table 7-4
Character

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

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 141

Chapter 7: Search and Replace

Regular Expression Examples


Table 7-5 contains some examples of regular expressions. The examples use the UNIX variant.

Table 7-5
Expression

Description

\:d{4}-\:d{2}-\:d{2}

Match an ISO date (yyyy-mm-dd).

\:d{1,2}/\:d{1,2}/\:d{4}

Match a USA date (mm/dd/yyyy), with months and


days being one or two digits.

(\:d{1,2})/(\:d{1,2})/(\:d{4})

Match a USA date, with grouping expressions to capture the resulting fields.

#include\:b+([^]+)

Search for an #include directive using quotes, with


a group to capture the #included file.

<(/?(\:c|[0-9]|-|_|:)+)([^>]*)>

HTML/XML start or end tag, with attributes.

Command-Line Search and Replace


The Find tool window provides a powerful and flexible environment for searching and is particularly well
suited to complex searches and searches across multiple files and directories. For searching within the current buffer, the find command is just as powerful and often faster. The command-line find supports some
options that are not supported by gui-find, and also it sometimes works in a more effective way.
Table 7-6 shows the variants of the command-line search, replace, and selective display commands.

Table 7-6
Command

Description

find/expr[/options]

Find command.

/expr[/options]

Find command (shorthand form).

l/expr[/options]

Find command (alternative shorthand form).

replace/exp1/exp2[/options]

Replace command.

c/exp1/exp2[/options]

Replace command (shorthand form).

all/expr[/options]

Selective display show matches.

allnot/expr[/options]

Selective display hide matches.

show-all

Cancel selective display.

141

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 142

Part II: Using SlickEdit


The syntax of the command-line find is
find/expr[/options]

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

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 143

Chapter 7: Search and Replace

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

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.

W:P

Limits search to word prefix.

W:PS

Limits search to strict word prefix.


continued

143

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 144

Part II: Using SlickEdit


Table 7-7 (continued)
Option

Description

W:S

Limits search to word suffix.

W:SS

Limits search to strict word suffix.

Binary search.

Delimiter to separate ambiguous options.

Cletters

Requires the first character of the match to be one of the color coding elements
specified by letters.

Xletters

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.

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

144

Letter

Color Coding Element

Other

Keyword

Number

String

Comment

Preprocessing

Line number

Symbol 1

Symbol 2

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 145

Chapter 7: Search and Replace


Table 7-8 (continued)
Letter

Color Coding Element

Symbol 3

Symbol 4

Function color

No save line

Command-Line Search Examples


Table 7-9 contains several examples of Search commands using the command line.

Table 7-9
Command

Description

/ERROR/e

Search for ERROR, matching exact case.

all/ERROR/e

Show only lines containing ERROR, exact case.

allnot/DEBUG/e

Show only lines not containing DEBUG, exact case.

/def_

Search for next occurrence of def_.

/def_/-

Search for previous occurrence of def_.

/def_/xc

Search for next occurrence of def_, outside comments.

all/def_/xc

Show only lines containing def_, outside comments.

/_command/ck

Search for _command as a keyword.

l|\:d{1,2}/\:d{1,2}/\:d{4
}|u

Search for US style date (mm/dd/yyyy).

l|\:d{1,2}/\:d{1,2}/\:d{4
}|u>

Search for US style date, place cursor at end.

l|\:d{1,2}/\:d{1,2}/\c\:d
{4}|u

Search for US style date, place cursor at beginning of year.

c|(\:d{2})/(\:d{2})/(\:d{
4})|\3-\1-\2|u

Change US style date to ISO (yyyy-mm-dd) (doesnt handle


single-digit days or months).
continued

145

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 146

Part II: Using SlickEdit


Table 7-9 (continued)
Command

Description

c|;$|\n/|uxc*

Change SQL semicolon terminator to a slash on its own line


(excludes commented lines).

c/\x0d\x0a/\x0a/uh*

Change line endings DOS to UNIX (includes hidden lines).

c/\x0a/\x0d\x0a/uh*

Change line endings UNIX to DOS (includes hidden lines).

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.

Predefined Selective Display


There are several ways to use selective display. The most straightforward is to use the predefined selective display commands, also available from the View menu.
The predefined selective display commands are listed in Table 7-10.

Table 7-10

146

Command

Menu

Description

hide-all-comments

View Hide All Comments

Hides all comments.

hide-code-block

View Hide Code Block

Hides block containing cursor.

hide-selection

View Hide Selection

Hides lines containing selected text.

hide-dotnet-regions

View Hide #region Blocks

Hides .NET #region blocks.

show-procs

View Function Headings

Shows only function headings.

toggle-all-outlining

(none)

Toggles selective display of function bodies and comments.

plusminus

View Expand/Collapse
Block (Ctrl+backslash)

Expand or collapse a hidden block.

copy-selective-display

View Copy Visible

Copies visible part of selection to


clipboard.

show-all

View Show All

Cancels selective display.

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 147

Chapter 7: Search and Replace


Most of these are self-explanatory. In some cases, its necessary to invoke more than one command
in order to achieve the desired result. For example, show-procs shows JavaDoc comments. Thus, if
you really want to see just the function headings, with no comments, you need to invoke show-procs
and then hide-all-comments. Most of the commands cannot be combined in this way, however. If
you need combinations of selective display, you can use Custom Selective Display, explained below.
The toggle-all-outlining command also works well for hiding both comments and function
bodies.
Figure 7-6 shows selective display after invoking show-procs and hide-all-comments. The + and
bitmaps indicate regions you can expand or collapse. As with the Search Results tool window, you
can click the and + buttons, or invoke plusminus (Ctrl+backslash) to expand or collapse selective
display sections.

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

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 148

Part II: Using SlickEdit


Table 7-11
Language

Start Region

End Region

C#

#region

#endregion

C++

#pragma region

#pragma endregion

C++

#region

#endregion

VB.NET

#Region

#End Region

Custom Selective Display


The predefined selective display features on the View menu are useful for various common cases. Very
often, though, youll want to use selective display with your own search criteria. This is easily done
using either the command line or the Selective Display dialog. You can open the Selective Display dialog
with the selective-display command (View Selective Display). Each of these has different strengths
and capabilities. Weve shown some examples of the command-line versions all and allnot above.
The Selective Display dialog is shown in Figure 7-7.

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

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 149

Chapter 7: Search and Replace


The Multi-level mode makes all the control structures in your source file expandable and collapsible.
This is one way you can filter out parts of the code youre not interested in and concentrate on the parts
you are interested in.
Figure 7-8 shows selective display displaying only those lines containing the text _command. In a
Slick-C file, this is the most effective way of seeing only the command definitions.

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.

Configuring Default Search Options


You can configure several default search options in the Search tab of the General Options configuration
dialog: Tools Options General. The dialog, shown already in Chapter 6, is repeated in Figure 7-9.
The Default search options provides defaults. Command-line find uses these defaults for any options
that are not specified explicitly in the command. These defaults are pre-populated into the GUI Find dialog when it is activated, if Initialize with default options is checked. If Initialize with default options
is not checked, the Find dialog remembers the options you used last time.
The Leave selected option, on by default, causes search matches to be selected automatically. Sometimes
this is not desired, particularly if you are searching within a selection. Uncheck this option to make the
search commands leave selections alone.

149

22150c07.qxd:WroxPro

9/25/07

1:17 AM

Page 150

Part II: Using SlickEdit

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 151

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.

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 152

Part II: Using SlickEdit

Using Basic Editing


SlickEdit has hundreds of commands, and its hard to know how to get started and how to learn the
most important ones for basic editing. Features such as insert and overtype mode and deletion of characters with the Backspace or Delete keys are virtually universal. Here we look at several more specific
editing commands.

Undo and Redo


The idea of undo and redo is familiar to most programmers. And for most programmers, its pretty
indispensable! SlickEdit supports full undo/redo of changes to a buffer and also two alternative
schemes for undoing cursor movement within the buffer. The commands are summarized in Table 8-1.

Table 8-1
Command

Key

Description

undo

Ctrl+Z; Alt+Backspace

Undo last change or cursor movement.

undo-cursor

Shift+F9; Shift+Backspace

Undo all cursor movement to last change.

redo

Ctrl+Y

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 153

Chapter 8: Editing Text


Table 8-2
Command

Key

Description

cut-end-line

Ctrl+E

Delete from cursor to end of line.

cut-line

Ctrl+Backspace

Delete current line.

duplicate-line

WROX: Alt+quote

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.

Using Selections and Clipboards


Selections are used for the classic clipboard operations:

Moving.

Copying.

Deleting.

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.

Working with the Clipboard


SlickEdit supports the usual clipboard concepts cut, copy, and paste familiar in many GUI environments. SlickEdit also provides several useful clipboard extensions beyond these. Table 8-3 is a summary
of SlickEdit clipboard commands. These commands are explained in more detail in the following sections.

153

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 154

Part II: Using SlickEdit


Table 8-3
Command

Key

Description

cut

Ctrl+X

Delete text and place a copy in the clipboard.

copy-to-clipboard

Ctrl+C

Copy text to the clipboard.

paste

Ctrl+V

Paste text from clipboard to buffer.

append-cut

Ctrl+Shift+X

Delete text and append it to the current clipboard.

append-to-clipboard

Ctrl+Shift+C

Copy text and append it to the current clipboard.

list-clipboards

Ctrl+Shift+V

Display multiple clipboards to paste from.

Moving and Copying with the Clipboard


You can use the regular clipboard operations with all selections:

Use cut (Ctrl+X) to cut or delete text.

Use copy-to-clipboard (Ctrl+C) to copy text to the system clipboard.

Use paste (Ctrl+V) to paste text from the system clipboard.

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 155

Chapter 8: Editing Text

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

Key

Description

select-char

F8; WROX: Alt+Z

Start or extend a character selection.

select-line

Ctrl+L; WROX: Alt+L

Start or extend a line selection.


continued

155

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 156

Part II: Using SlickEdit


Table 8-4 (continued)

156

Command

Key

Description

select-block

Ctrl+B; WROX: Alt+B

Start or extend a block selection.

select-word

(none)

Make a character selection from the cursor


to the end of the current word.

select-next-word

(none)

Make or extend a character selection from


the cursor to the end of the current word.

select-whole-word

(none)

Make a character selection for the whole


word under the cursor.

select-all

Ctrl+A

Make a line selection for the entire buffer.

select-code-block

(none)

Make a selection for the code at the current


scope.

select-paragraph

(none)

Make a line selection for a group of lines


bounded at the top and bottom by a blank
line.

select-paren-block

(none)

Make a character selection for the next


block of code bounded by parentheses,
brackets, or braces.

select-proc

(none)

Make a line selection for the entire procedure, function, or method the cursor is in.

move-to-cursor

WROX: Alt+M

Move the selection to the current cursor


position.

copy-to-cursor

WROX: Alt+C

Copy the selection to the current cursor


position.

begin-select

WROX: Alt+Y

Move to the beginning of the selection.

end-select

WROX: Alt+E

Move to the end of the selection.

deselect

Ctrl+U, WROX: Alt+U

Turn off existing selection.

upcase-selection

Ctrl+Shift+U

Convert all words in selection to uppercase.

lowcase-selection

Ctrl+Shift+L

Convert all words in selection to lowercase.

shift-selection-left

Shift+F7

Shift text in selection one character to


the left.

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 157

Chapter 8: Editing Text


Table 8-4 (continued)
Command

Key

Description

shift-selection-right

Shift+F8

Shift text in selection one character to


the right.

remove-trailingspaces

(none)

Remove trailing spaces from lines in


selection.

filter-command

(none)

Pass selection as input to external


command.

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 158

Part II: Using SlickEdit


When you make a character selection within a single line, SlickEdit displays the number of characters
selected in the status line, as shown in Figure 8-4.

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.

Move the cursor to the first character.

4.

Press select-char (F8) to lock the selection.

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.

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 159

Chapter 8: Editing Text


Lines are usually the fundamental elements of programs. Programs are made up of lines. Typically, each
line contains a single statement. Line selection is the most useful kind of selection when you are working
with code.
When you paste or otherwise copy data from a character selection, the text is pasted in at the cursor
position. With a line selection, the text is pasted either above or below the current line. Which it does is
determined by your choice of Line insert style on the More tab of the General Options dialog (Tools
Options General).
To make a line selection:

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 160

Part II: Using SlickEdit


To make a block selection:

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.

Special Selection Commands


SlickEdit provides a few more useful shortcuts for selecting text in common cases. Some of these deal
with individual words. Others deal with larger units such as whole functions or classes.
All of these commands produce regular, or unlocked, selections. Depending on your configuration settings, you may optionally lock the selection after making it. See the section Configuring Selection
Options below.
Apart from select-all, these commands are not bound to keyboard shortcuts in the CUA emulation.
Some of them are available in the Edit menu, under Edit Select. The others need to be invoked from
the command line. If you find yourself using any of these frequently, you can bind them to keyboard
shortcuts of your choice.

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.

Selecting Larger Units

160

Use select-all (Ctrl+A) to make a line selection for the entire buffer. This command is familiar from other CUA-based programs.

Use select-code-block to make a selection for the code at the current scope. If the cursor is
on a statement, the entire statement is selected. If it is in a block but outside a statement, the
block is selected. Use the command repeatedly to extend the selection to the next higher level,
up through functions and classes. The selection begins as a character selection and changes to a
line selection as it grows.

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 161

Chapter 8: Editing Text

Use select-paragraph to make a line selection for a group of lines bounded at the top and
bottom by a blank line.

Use select-paren-block to make a character selection for the next block of code bounded by
parentheses, brackets, or braces. This is useful for selecting expressions.

Use select-proc to make a line selection for the entire procedure, function, or method the
cursor is in.

Working with Selections


You can do many things with selections. The most common operations are the classic clipboard operations:
move, copy, and delete. With SlickEdit, you can do these operations using clipboard copy and paste, or
you can use locked selections to do them in more flexible and powerful ways. You can also use locked
selections to define the scope of many other operations.

Moving and Copying with Locked Selections


You can use locked selections to move and copy text more quickly, powerfully, and flexibly. There is no
need to use the clipboard for simple move and copy operations.

Use move-to-cursor (WROX: Alt+M) to move the selection to the current cursor position.

Use copy-to-cursor (WROX: Alt-C) to copy the selection to the current cursor position.

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.

Moving around in Locked Selections


You can move quickly to the top or bottom of the selection using these commands:

Use begin-select (WROX: Alt+Y) to move to the beginning of the selection.

Use end-select (WROX: Alt+E) to move to the ending of the selection.

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 162

Part II: Using SlickEdit


If you start a new selection in a different buffer, the previous selection is deselected. You can restore the
previous selection by switching back to its buffer and invoking undo (Ctrl+Z).

Using Selection Scopes


You can also use selections to define the scope of many other operations. In Chapter 10, we see how
block selections can be used for many useful techniques when editing data in columns. Character and
line selections are also useful in defining the scope of operations. Here are some examples:

Use upcase-selection (Ctrl+Shift+U) to convert all words in the selection to uppercase.

Use lowcase-selection (Ctrl+Shift+L) to convert all words in the selection to lowercase.

Use shift-selection-left (Shift+F7) to move the selected text left.

Use shift-selection-right (Shift+F8) to move the selected text right.

Use remove-trailing-spaces to remove trailing spaces from selected lines.

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

or use the shorter command:


/edit/m

To replace tabs with commas in the selection, use the command:


replace /\t/,/um

or use the shorter command:


c/\t/,/um

For more information about searching and replacing, see Chapter 7.

162

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 163

Chapter 8: Editing Text


Filtering Selections
You can pass a selection as input to an external program using filter-command (Edit Other Filter
Selection). The output of the external program replaces the selected text in the buffer. This enables many
techniques familiar to UNIX programmers using editors such as vi.

Saving and Reusing Selections


One of the things I often use SlickEdit for is a kind of super scratchpad for other programs. Most programs provide rather poor editing abilities compared to SlickEdit. Thus I often copy text from another
program into SlickEdit, edit it, and then paste it back into the other program. Sometimes I need to do
this repetitively. An example is when Im working with a database tool, such as Oracle SQL-Plus. I often
edit some SQL commands, enter them in SQL-Plus, then repeat the process.
If I have more than one set of commands in my scratchpad, Id like to be able to select the different sets
quickly and easily. Bookmarks provide an easy way to navigate to specific lines in a file, and they can be
combined with line selections to provide a kind of bookmarked selection. The commands wrox-saveline-sel and wrox-restore-line-sel below show how to do this.
_command void wrox_save_line_sel(_str bookmark = SELECTION)
name_info(,VSARG2_REQUIRES_AB_SELECTION) {
if (_select_type() != LINE) {
message(Line selection required.);
return;
}
delete_bookmark(bookmark _START);
delete_bookmark(bookmark _END);
push_bookmark();
begin_select();
set_bookmark(bookmark _START);
end_select();
set_bookmark(bookmark _END);
pop_bookmark();
}
_command void wrox_restore_line_sel(_str bookmark = SELECTION)
name_info(BOOKMARK_ARG*,VSARG2_REQUIRES_EDITORCTL) {
push_bookmark();
goto_bookmark(bookmark _START);
_str filename = p_buf_name;
goto_bookmark(bookmark _END);
if (p_buf_name != filename) {
message(Bookmark _END must be in same file as bookmark _START.);
pop_bookmark();
return;
}
deselect();
goto_bookmark(bookmark _START);
select_line();
goto_bookmark(bookmark _END);
select_line();
pop_bookmark();
}

163

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 164

Part II: Using SlickEdit


To save a line selection as two bookmarks, named SET1_START and SET1_END, enter the command:
wrox-save-line-sel SET1

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.

Configuring Selection Options


You can configure various options for selections, according to your preferences. Selection options are
configured on the Selections tab of the General Options dialog (Tools Options General), shown in
Figure 8-9.

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:

164

1.
2.

Move the cursor to the start.

3.
4.

Move the cursor to the end of the selection. The selection grows as you move the cursor.

Use a selection command (select-char, select-line, or select-block) to start the


selection.

Use the selection command again to lock the selection.

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 165

Chapter 8: Editing Text


If Extend selection as cursor moves is not checked, the procedure is slightly different:

1.
2.
3.

Move the cursor to the start.

4.

Use the selection command again to extend the selection to the current cursor position and lock
the selection.

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.

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.

Saving Typing with Word Completion


SlickEdit has several features designed to save you typing. Some of these features apply to specific programming languages and are discussed elsewhere in this book. The word completion feature is generic
and applies to any text file.

Introduction to Word Completion


Word completion is a feature that has been in SlickEdit since the very earliest days, and it is arguably still
the biggest time-saver of all the completion features. If you are using SlickEdit regularly, you owe it to
yourself to become familiar with word completion and its various modes of use.
The basic premise of word completion is that when youre programming, you very often have to type a
word, or sequence of words, that is already in the file somewhere else. Word completion allows you to
search quickly for a match to a partially typed word elsewhere in the file and automatically fill in the
rest of it. Word completion can also continue to fill in text following the original match, as far as desired.
This turns out to be useful very often.
The best way to understand word completion is to work through a brief example.

165

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 166

Part II: Using SlickEdit


Suppose you are reviewing some log files from the last few days of running a batch job. You have the list
of log files in a buffer. At the beginning, the buffer contains the following text:
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

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

data
data
review required
data

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 167

Chapter 8: Editing Text

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 168

Part II: Using SlickEdit

Word Completion in Programming


The word completion features are useful for a wide variety of editing scenarios. The examples weve
seen so far involve repetitive entry of phrases into a plain text file. Word completion is also useful in programming, whether or not the language supports intelligent syntax completion.
Many languages have limited syntax assistance from SlickEdit. These include older lower-level languages such as SQL and shell scripts, as well as modern languages that use dynamic typing. Word completion is a big time-saver with these languages.
In SQL, for example, its common to find oneself entering repetitive statements such as the following:
INSERT INTO network_category (id, description, header, active_yn)
VALUES (BASIC, Basic, STANDARD, Y);
INSERT INTO network_category (id, description, header, active_yn)
VALUES (EXTENDED, Extended, STANDARD, Y);
INSERT INTO network_category (id, description, header, active_yn)
VALUES (CONTINUOUS, Continuous, PARTIAL, Y);

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 169

Chapter 8: Editing Text


After typing the first line of the method body in full, you can use word completion to complete both
Condition and firstOrChangedToAnyOf on the second, third, and fourth lines.
On the fifth line of the method body and onward, you can use word completion to complete any of the
identifiers aaaCondition, bbbCondition, cccCondition, and dddCondition. Not only that, but
notice that these variables occur in sequence on lines 5, 8, 10, 13, and 15. In these cases, complete-more
saves a lot of time.
After the sixth line of the method, you dont need to type assertTrue or assertFalse again use
word completion instead.
Figure 8-16 shows the method entered in the editor, with gray rectangles overlaid over the parts that can
be completed with word completion.

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.

Options with Word Completion


Word completion offers several options you can use to fine-tune its behavior. These options relate to:

How to reverse the search when alternating between searching forward and backward.

Whether to include or skip duplicate matches.

What matches to include when searching (the scope of the search).

169

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 170

Part II: Using SlickEdit


There is no GUI dialog for configuring these options. The options are configured via a combination of
two macro variables: def_complete_flags and def_complete_vars. These macro variables are
defined in the macro file compword.e.
See Chapter 2 for more information about setting macro variables.
The macro variable def_complete_flags is a combination of flags:

1 (COMPLETE_REVERSE_AT_CURSOR).

2 (COMPLETE_CHECK_SCOPE).

4 (COMPLETE_ALLOW_DUP_MATCHES).

8 (COMPLETE_LOOK_FOR_ANYTHING).

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

170

passes
passes
fails: missing data
fails: missing data
followup: user review required
fails: missing data
fails: incorrect dates
fails: incorrect dates
fails: missing data

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 171

Chapter 8: Editing Text


If duplicates are not allowed, then its impossible to match to different lines containing the word fails.
With duplicates allowed, you can navigate among the different lines.
The COMPLETE_LOOK_FOR_ANYTHING flag controls whether word completion includes matches within
strings and comments. By default, SlickEdit behaves like this:

If you are inside a comment or a string, then complete-prev and complete-next include
matches found elsewhere in comments and strings, as well as matches in code.

If you are not inside a comment or a string, then complete-prev and complete-next do not
include matches in comments and strings.

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

22150c08.qxd:WroxPro

9/25/07

1:22 AM

Page 172

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 173

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.

F ile Extensions, Modes, and Lexers


For SlickEdit to be able to provide syntax assistance for your file, it must know what language the
file is in. SlickEdit does this through associations between file extensions, modes, and lexers.
A file extension is simply the extension part of a filename. C programs typically have the file extension c. C++ programs, on the other hand, have different file extensions, such as cpp and cxx.
C and C++ programs also have header files, with extensions like h, hpp, and hxx.

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 174

Part II: Using SlickEdit


The mode defines the language-specific behaviors for SlickEdit. The default mode is set automatically
based on the file extension. You can set the mode manually using the select-mode command
(Document Select Mode). There is also a command for each mode to switch to that mode. For
example:

c-mode.

html-mode.

pascal-mode.

plsql-mode.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 175

Chapter 9: Editing Code

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 176

Part II: Using SlickEdit

Functions.

Strings.

Numbers.

Comments.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 177

Chapter 9: Editing Code


When customizing colors, keep in mind how they will work with selections. When you make a selection,
SlickEdit tries to combine the colors of the elements on screen with the selection color. The editor tries to
maintain a good contrast so that all elements are legible. Some color combinations can cause trouble for
SlickEdits heuristic.

Indentation and Code Style


Different programmers and programming communities use widely different styles for coding, even in
the same language. Some Linux hackers speak of the prophets, Kernighan and Ritchie. (See http://
lxr.linux.no/source/Documentation/CodingStyle.) Other GNU programmers follow the GNU
coding style. (See http://www.gnu.org/prep/standards/standards.html#Formatting.) Some
coding styles encourage the use of tabs for indentation. Other styles prohibit them. The debates over
tabs and brace placement are an ongoing staple of programmer culture and will probably go on for as
long as there are programmers.
SlickEdit takes no position in the debate, but attempts to support most of the major styles in use. Generic
indentation settings are found on the Indent tab of the Extension Options dialog (Tools Options File
Extension Setup). This tab is shown in Figure 9-3.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 178

Part II: Using SlickEdit

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 179

Chapter 9: Editing Code

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.

Java and C# Options


As weve seen, there are a lot of options specific to C/C++ source files. In contrast, other programming
languages have fewer options. For example, Figure 9-7 shows the options specific to Java programs.
The options for C# are the same. For these languages, the brace and indentation standards are not as
varied or complex as C/C++. Also, these languages have no preprocessor, which greatly simplifies
parsing them.

Figure 9-7

179

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 180

Part II: Using SlickEdit

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.

Wor king with Control Str uctures


A lot of programming involves control structures and blocks of code. As well as entering structures
such as conditionals and loops, programmers often need to modify them. SlickEdit has several features
that help greatly with common operations. These features have been developed and refined over many
years, and sometimes reflect different ways of doing the same thing. We review some of them here. The
ones you use will depend on your own preferences.

180

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 181

Chapter 9: Editing Code

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.

Type argc == 0. The screen now appears as in Figure 9-11.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 182

Part II: Using SlickEdit


determining what control structure to expand, and the exact text and hotspots to output, is contained in
the macros defined in that file. You can examine those macros to see how it works, and you can change the
behavior if you wish.
For example, the syntax expansion for the _command keyword in Slick-C mode inserts the following
template:
_command void () name_info(,)
{
}

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.

Adding a Control Structure


It is pretty common when programming to need to add a control structure around some code thats
already there. For example, suppose you have the file shown in Figure 9-14. You need to add a test
around the printf() statements.

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.

182

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.)

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 183

Chapter 9: Editing Code

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.

Type argc == 0 for the condition.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 184

Part II: Using SlickEdit

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.

Deleting a Control Structure


Sometimes you want to do the opposite remove a control structure, without removing the code it surrounds. Lets remove the if() test of the last example. We start with the file as shown in Figure 9-21.

Figure 9-21

1.
2.
3.

184

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.

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 185

Chapter 9: Editing Code

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

Avoiding Syntax Assistance


Most of the time, SlickEdits syntax assistance reduces typing and helps you get your work done.
Sometimes, though, you may be doing something where you dont want syntax assistance to be
invoked. For example, you might be recording a macro for repeated playback. Usually with macros,
you dont want syntax assistance to be activated.
One way to avoid syntax assistance is to switch to fundamental mode. This is appropriate if you are
doing a series of edits for which you dont want assistance.
If you want to suppress assistance for one keystroke, use the quote-key command (Ctrl+Q). You can
use it before any keystroke that would normally result in syntax assistance, such as Space or {. With
quote-key, you just get the character, not the extra assistance.

185

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 186

Part II: Using SlickEdit

Unified Completions with Auto-Complete


Weve seen several different completion features: word completion, syntax expansion, list members,
and parameter information. These features have evolved over different releases of SlickEdit. At some
point it became clear that there were too many completion features for new users to learn them all separately. Thus, the SlickEdit team added the Auto-Complete feature, which unifies all the other completions under one umbrella and provides a common interface combining them all.
In some ways, Auto-Complete is more powerful than individual features such as word completion. For
one thing, it happens automatically. And it is more modern-looking. On the other hand, it is less direct
and maybe not as fast to use for the advanced user.
Auto-Complete uses several advanced searches to find possible entries for the current context. The full
list of searches is documented in the online Help, but as well as word completion, it includes things like
syntax completion, keywords, aliases, and symbols. See Configuring Auto-Complete below for more
information.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 187

Chapter 9: Editing Code

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 188

Part II: Using SlickEdit


Invoke complete-more (Ctrl+Shift+Space). The next word (missing) is completed. Invoke completemore once again to get data. The entire matching comment is selected, as shown in Figure 9-30.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 189

Chapter 9: Editing Code


As well as showing matches grouped by category, Auto-Complete displays other information it can find
about the highlighted match. For symbols with no documentation in the code, Auto-Complete displays
just the brief definition of the symbol, as shown in Figure 9-33.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 190

Part II: Using SlickEdit


The Enable auto-completion checkbox controls whether Auto-Complete activates automatically. If you
uncheck that box, Auto-Complete does not activate automatically, but you can still activate it with the
autocomplete command. There is no key binding for autocomplete in the CUA emulation.
The other checkboxes in the group under Enable auto-completion control which searches are used. By
default, all searches are used, but you may turn off some of them if you like.
The controls in the Options group control how Auto-Complete behaves once it is activated. The controls in the Details group control which visual elements are shown by Auto-Complete. The graphic
underneath is updated dynamically when you make changes, so you can see what Auto-Complete will
look like with your settings.

Manual Completion or Auto-Complete?


Auto-Complete is an umbrella for other distinct completion features in SlickEdit. Its possible to use those
features exclusively through Auto-Complete, to use a mixture of distinct features and Auto-Complete, or
not to use Auto-Complete at all. It depends on your needs, experience, and preferences.
Auto-Complete can get in the way sometimes, and then it is necessary to press something (usually Escape)
to get rid of it. Some features are faster to use without Auto-Complete, once you are familiar with them.
For example, if you know where you are going and are familiar with word completion, it is faster to use
directly than via Auto-Complete. Its more lightweight, and more intentional. You invoke word completion when you want to complete something, rather than waiting for the editor to decide whether it can
help you and choosing from its list. Usually when using word completion, you will know exactly how
many times to press complete-prev or complete-next to get to the match you want, and it becomes
second nature.
That said, a newcomer to SlickEdit might prefer Auto-Complete because its more obvious. Theres less
to learn, and less to think about.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 191

Chapter 9: Editing Code


JavaScript embedded within HTML. In both of these cases, the structure is similar. The main file is an
HTML file, but it contains code embedded in it in another language.
For server-side web programming, files are usually identified by an extension corresponding to the programming language, such as .php. Code in these files is delimited by character sequences such as <?
and ?>.
Figure 9-36 shows an example of a PHP file. The main file is treated as HTML. The portions within the
<?php and ?> delimiters are treated as PHP. As well as getting different syntax coloring, most other syntax assistance features also work for the embedded language. It may not be clear in the printed book, but
here SlickEdit displays the comments in green, keywords in orange, the string in turquoise, and the rest
of the text in black.

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

Here Documents in Scripts


UNIX shells, and several scripting languages, support multiline strings called here documents. These are
extremely convenient for templates that output code, such as HTML or SQL.

191

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 192

Part II: Using SlickEdit


Here documents begin with <<IDENT, where IDENT is some identifier, often EOF. The multiline string
extends to the next occurrence of IDENT in the code.
Figure 9-38 shows an example of a here document in a Ruby script. Between the <<HTMLEOF and HTMLEOF,
SlickEdit treats the text as HTML. Color syntax highlighting is applied, and other syntax assistance
features work too. It may not be clear on the printed page, but the color syntax in this example highlights an error. The closing tag for <html> is misspelled as </hmtl>. On the screen, this shows as
orange, the color for unknown XML element. The correct HTML elements show in purple, the color
for keywords.

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.

Wor king with Comments


SlickEdit understands two kinds of comments: line comments and multiline comments. Line comments
are the kind where a character or sequence of characters marks the rest of the line as a comment. Familiar
examples are:

// in C++, Java, and many other languages.

# in shell and scripting languages.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 193

Chapter 9: Editing Code

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 194

Part II: Using SlickEdit


}
if (!selection) {
cursor_down();
}
}
defeventtab default_keys;
def C-S-/ = wrox_toggle_comment;

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 195

Chapter 9: Editing Code

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 196

Part II: Using SlickEdit


See the online Help for detailed descriptions of these options.

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 197

Chapter 9: Editing Code

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

22150c09.qxd:WroxPro

9/25/07

1:25 AM

Page 198

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 199

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.

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 200

Part II: Using SlickEdit

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.

Moving, Copying, and Deleting with Block Selections


The basic operations with block selection are the same as with other kinds of selection, but work in a
particular way with block selection. Consider the data shown in Figure 10-1. A column of data is
selected, 10 lines by 3 columns. Well use this selection and starting position to illustrate the various
move, copy, and delete commands.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 201

Chapter 10: Editing Data

Use copy-to-cursor (WROX: Alt+C) to copy the selected block to the cursor position, moving
existing text to the right. Figure 10-3 shows the result of a copy.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 202

Part II: Using SlickEdit

Figure 10-6

These commands are intelligent enough to handle source/destination conflicts.

Navigating Block Selections


If the data you are working on fill the entire buffer, you can simply use the normal buffer commands to
get to the top or bottom:

Use top-of-buffer (Ctrl+Home) to get to the top of the buffer.

Use bottom-of-buffer (Ctrl+End) to get to the bottom of the buffer.

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.

Entering Data in Columns


Its often necessary to enter text repeatedly into every line. SlickEdit has a couple of ways of doing this,
using block selections. Which you choose depends on your preferences, and several considerations.

202

Use fill-selection (WROX: Alt+F) to fill a block with a particular character.

Use block-insert-mode (Edit Other Block Insert Mode) to put SlickEdit into block
insert mode.

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 203

Chapter 10: Editing Data

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.

Using Block Insert Mode


Block insert mode is a powerful and intuitive way to enter text or data in columns. Using block insert
mode, you can type, edit, and move the cursor as if you were typing on one line, but SlickEdit applies
your changes to all lines in the selection.
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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 204

Part II: Using SlickEdit


Block insert mode is implemented in a rather special way. The block-insert-mode command actually contains its own event loop, and listens directly for keyboard events. This is different from most
parts of SlickEdit.
You may find that while in block insert mode, if you use commands (i.e., press keys) other than the ones
mentioned here, you get funny characters on the screen. If this happens, use undo to undo the changes.
Another consequence of the way in which block insert mode works is that you cannot record macros that
use block insert, and you cannot play macros to enter text while in block insert mode.
If you want to mix macros with inserting text into columns, use fill-selection. (Block insert
mode actually uses fill-selection itself.)

Sor ting Data


Sorting is not a common part of programming or text editing, but it is very common when dealing
with data.
SlickEdit provides several commands for sorting:

Use sort-buffer to sort the entire buffer.

Use sort-on-selection to sort using a selection as the key.

Use sort-within-selection to sort within a line or block selection.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 205

Chapter 10: Editing Data

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.

The enumerate command has the following arguments:

start the starting number. Optional, defaults to 0.

increment the number to increment by. Optional, defaults to 1.

width the number of digits to pad with leading zeros. Optional, default does not add leading

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 206

Part II: Using SlickEdit

Figure 10-9

Calculating with Data


Generally speaking, text editors are not strong for doing calculations. Thats what spreadsheets are for.
However, it often happens that you need a quick calculation done on data that are already in the editor,
such as adding a column of numbers that are data in your file. SlickEdit provides some basic support for
these tasks.
Suppose we have some invoice data in a file as shown in Figure 10-10.

Figure 10-10

To add up the shipping charges from these data:

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 207

Chapter 10: Editing Data


SlickEdit can compute more elaborate expressions too. To compute the entire invoice cost from the data
above:

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 208

Part II: Using SlickEdit


Were going to illustrate these three techniques using a simple example. We start with a file that contains
some data representing codes and start dates, like this:
GBA7
GBX2
GBX6
GBY3
GBY6
GBY7
GBY8
GBZ2
GBZS
GCB5

02/12/2007
02/14/2007
04/01/2007
03/07/2007
03/17/2007
02/14/2007
02/09/2007
02/15/2007
04/03/2007
05/06/2007

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:

208

Using move, copy, and delete commands to rearrange columns.

Using block fill and block insert to add or remove delimiters and other text.

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 209

Chapter 10: Editing Data


The main advantages of the block editing technique are:

It is intuitive and interactive.

It works well in combination with other block techniques.

It works reasonably well with medium amounts of data.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 210

Part II: Using SlickEdit

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

9.
10.
11.
12.
13.
14.

210

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.

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 211

Chapter 10: Editing Data

Figure 10-16

15.
16.
17.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 212

Part II: Using SlickEdit

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.

Invoke delete-char (Delete key) three times to delete the space and the two unwanted slash
characters.

6.

Type start_date=. Block insertion adds the text to all lines, as shown in Figure 10-23.

Figure 10-23

7.
8.

212

Invoke cursor-right four times to move the cursor past the year field.
Type the hyphen date separator.

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 213

Chapter 10: Editing Data


9.
10.
11.
12.

Invoke cursor-right twice more to move the cursor past the month field.
Type the hyphen date separator again.
Invoke cursor-right twice more to move the cursor past the day field.
Type /> to complete the XML markup. The final version is shown in Figure 10-24.

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.

Macro Record and Playback


Macro record and playback is often a quick and convenient way to do the same operations to a set of lines.
For example, it is an easy way to add commas at certain positions on each line.
The basic idea of macro record and playback is this: You start recording on the first line, do what you
need done, then finally move the cursor to the beginning of the next line and finish recording. You can
now play back the macro for each line.
The main advantages of the macro record and playback technique are:

It is somewhat intuitive and interactive.

It is often more flexible than block editing.

It can often be used even if data are not aligned.

It can be made repeatable.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 214

Part II: Using SlickEdit


If you have recorded a complex sequence of commands into a macro and you think you might use the
same sequence again, you can save the macro with a name and use it again later.
The main disadvantages of the macro record and playback technique are:

It is not automatically repeatable.

It doesnt work well with large amounts of data.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 215

Chapter 10: Editing Data


5.
6.
7.
8.

Invoke cursor-right to move the cursor to the beginning of the year field.
Invoke select-block (WROX: Alt+B) to start a block selection.
Invoke cursor-right three more times to move the cursor to the end of the year field.
Invoke select-block to lock the block selection on the year, as shown in Figure 10-28.

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

11.
12.

Invoke deselect (WROX: Alt+U) to drop the selection.

13.

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.

Invoke insert-toggle (Insert key) to switch to overwrite mode. The cursor should change to a
block cursor.

Figure 10-30

14.
15.
16.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 216

Part II: Using SlickEdit


17.

Invoke record-macro-toggle again to finish recording the macro. SlickEdit displays the Save
Macro dialog, shown in Figure 10-31.

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.

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.

20.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 217

Chapter 10: Editing Data


Discussion
Macro record and playback is a convenient solution for data editing and can be more flexible than block
editing if fields are not aligned. Its not necessary always to use cursor-left and cursor-right to
move the cursor. These commands can move the cursor a fixed number of columns. In contrast, the
prev-word and next-word commands are often more useful for moving the cursor a fixed number of
fields, regardless of their alignment.
The prev-word and next-word commands are bound to Ctrl+Left and Ctrl+Right by default in the
CUA emulation. In the WROX emulation, they are bound to Alt+Left and Alt+Right, and the alternative
commands wrox-prev-whitespace-word and wrox-next-whitespace-word are bound to Ctrl+Left
and Ctrl+Right. Both sets of word movement commands are useful for macro recording and playback, in
different situations.
See Chapter 6 for a more detailed discussion of these word movement commands.
Macros can also help with aligning data. See the section below, Aligning Data.
When using the macro record and playback technique to work with data, the pattern followed is often to
start with the cursor at the beginning of the line, do some edits, then move the cursor to the beginning of
the next line before finishing the macro. As we saw, this movement to the next line can be done with the
begin-line-text-toggle and cursor-down commands. If youre doing this a lot, it can be worth creating a short macro for taking the cursor straight to the first column of the next line and binding that macro
to a key of its own. The following code does this, binding the command wrox-start-of-next-line to
Alt+Enter.
_command void wrox_start_of_next_line()
name_info(,VSARG2_REQUIRES_MDI_EDITORCTL) {
p_line++;
p_col = 1;
}
def A-ENTER=wrox_start_of_next_line;

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 218

Part II: Using SlickEdit


int i;
for (i = 0; i < n; i++) {
execute(command);
}
}

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 219

Chapter 10: Editing Data


keyin(\);
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();
}

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 220

Part II: Using SlickEdit


next_word();
keyin(\);
keyin());
keyin(,);
cursor_right();
keyin(ma(\);
end_line();
keyin(\);
keyin());
keyin());
keyin());
keyin(;);
begin_line_text_toggle();
cursor_down();
}

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.

Search and Replace with Data


Using search and replace in conjunction with block selection is one of the fastest and most powerful ways
of manipulating data in SlickEdit.
The main advantages of the search and replace technique are:

It is very flexible, if you are good with regular expressions.

It is relatively fast with large amounts of data.

It is more repeatable.

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:

220

It is not interactive.

It is relatively complex and unintuitive.

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 221

Chapter 10: Editing Data


You need to compose regular expression search and replace without seeing the results as you do it. This
requires some planning and skill with regular expressions.
Regular expression syntax is notoriously difficult to read. Simple expressions like /[A-Z][a-z]+/
(which matches a capitalized word) are easy enough. But search and replace expressions for data are
usually a lot more complicated than that.
For example, you can use a regular expression search and replace to re-format dates from local
mm/dd/yyyy format to ISO yyyy-mm-dd format. A SlickEdit command for this is
c|(\:d\:d)/(\:d\:d)/(\:d\:d\:d\:d)|\3-\1-\2|u

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 222

Part II: Using SlickEdit

Figure 10-35

4.
5.

Move the cursor back to the top of the file.


Invoke the following command to add the XML markup:

c |(\:a+) (.*)|<code id=\1 start_date=\2/>|u

SlickEdit asks you to confirm the search and replace again.

6.

Press g to confirm all changes. The job is done.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 223

Chapter 10: Editing Data


In this example, we have some CSV data that need to be converted to another format, as before. But this
time, the data are not aligned. This does not affect the search and replace method of conversion much. It
may or may not affect the macro record and playback method, depending on how good we are about
getting from one field to another. It severely affects how we can work with block selections, though.
One approach we can take to this problem is to align the data before we do anything else. With the help
of some macros, this is not difficult. The code below defines two alignment commands:

Use wrox-align-left-with-field-above to left-align the current field with the field above.

Use wrox-align-right-with-field-above to right-align the current field with the field


above.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 224

Part II: Using SlickEdit


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;
// move forward to end of next field on current line
next_word();
// remember column of stuff to move
int cur_col = p_col;
// go to end of next field on line above
cursor_up();
next_word();
int diff = p_col - cur_col;
// if we stayed on the same line when moving forward by a field ...
if (diff > 0 && p_line == cur_line-1) {
// shift the text, returning to the original position afterward
pop_bookmark();
push_bookmark();
_insert_text(substr( , 1, diff, ));
pop_bookmark();
}
else if (diff < 0 && p_line == cur_line-1) {
pop_bookmark();
int i;
for (i=0; i<(-diff); i++) {
_delete_char();
}
}
else {
// return to the original position
pop_bookmark();
}
}
// default key bindings to alignment commands
defeventtab default_keys;
def
A-S-L= wrox_align_left_with_field_above;
def
A-S-R= wrox_align_right_with_field_above;

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 225

Chapter 10: Editing Data


To use the alignment macros to align the data in the test file, follow these steps:

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.

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.

4.

Invoke wrox-next-whitespace-word (Ctrl+Right), to move the cursor to the beginning of the


date field.

5.

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.

Invoke wrox-next-whitespace-word twice more, to move the cursor to the beginning of the
first numeric field.

7.

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 226

Part II: Using SlickEdit


8.
9.
10.
11.

Repeat Steps 6 and 7 two more times to align the other two numeric fields.
Invoke begin-line-text-toggle (Home) to move the cursor back to the first column.
Invoke cursor-down (down arrow) to move the cursor to the beginning of the next line.
Invoke record-macro-end-execute (Ctrl+F12) to save the macro and execute it for the third
line of data. Figure 10-39 shows the file after the third line has been aligned.

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.

Large Data F iles


The different techniques presented here perform at quite different speeds, particularly for large files.
Macro playback is the slowest technique and is probably best avoided for files with more than 1,000
lines of data. Block editing is the next fastest and could be used for files up to around 10,000 lines, sometimes more. Search and replace is quite fast and usable with files containing 100,000 lines or more.
Table 10-1 compares the performance of the three techniques. I ran all three techniques via a benchmarking macro. I used the same data and conversion as presented in the Data Manipulation section, but
duplicated to a large number of lines.

226

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 227

Chapter 10: Editing Data


Table 10-1
Technique

100 Lines

1,000 Lines

10,000 Lines

100,000 Lines

Block Editing

0:00

0:01

0:10

Macro Playback

0:00

0:04

0:33

Search and
Replace

0:00

0:00

0:00

0:06

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.

Here is the code for the (very simple) benchmarking macro:


_command void wrox_benchmark(_str command = null)
name_info(COMMAND_ARG,VSARG2_EDITORCTL) {
if (command == null) {
message(I need a command.);
return;
}
long start = (long) _time(G);
execute(command);
long finish = (long) _time(G);
long elapsed = finish - start;
message(Command [ :+ command :+ ] took :+ elapsed :+ seconds.);
}

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

22150c10.qxd:WroxPro

9/25/07

1:27 AM

Page 228

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 229

Aliases and F ile Templates


Programming often involves creating certain constructs repetitively, but with variations. For
example, the classic C++ for() loop looks like this:
for (int i = 0; i < size; i++) {
// do something
}

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.

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 230

Part II: Using SlickEdit

Frequently used programming constructs.

Overriding SlickEdit syntax expansion.

Larger multiline chunks of text, such as file or function headings.

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.

230

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.

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 231

Chapter 11: Aliases and File Templates

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.

Click OK when you are finished.

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 232

Part II: Using SlickEdit


Aliases can be very useful for frequently accessed directories too. SlickEdit ships with some useful predefined directory aliases, including:

bin for the SlickEdit executables directory.

config for the users configuration directory.

ma for the directory containing supplied macro source.

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.

Using Aliases in Code


Lets define an alias for a copyright notice. Suppose your company places a notice like this in the top of
every file:
Copyright 2007 Acme Inc

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 233

Chapter 11: Aliases and File Templates


The %\d is a special escape sequence for insert the date. The date is formatted yyyy-mm-dd, which is
according to my Windows short date preference. SlickEdit offers several escape sequences in aliases, as
shown in Table 11-1.

Table 11-1
Escape Sequence

Description

%EnvVar%

Insert the value of the EnvVar environment variable.

%\d

Insert the date (locale preference format).

%\e

Insert the date (MMDDYY).

%\t

Insert the time.

%\f

Insert the filename.

%\i

Indent.

%\b

Unindent.

%\c

Place cursor.

%\l

Preserves leading spaces at beginning of line.

%\s

Preserves trailing spaces at end of line.

%\n

Inserts current function name.

%\o

Inserts current function name with signature.

%(ParamName)

Argument replacement.

%\m macro %

Execute macro in-place.

%\xcol

Moves the cursor to the specified column.

%\x+col

Increment column by amount.

%\x-col

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 234

Part II: Using SlickEdit


Lets use the %\m escape sequence with a macro to change the copyright alias to insert only the current
year, rather than the full date. Heres a Slick-C function that returns the current year as a string:
_str wrox_year() {
_str mm;
_str dd;
_str yyyy;
parse _date() with mm/dd/yyyy;
return yyyy;
}

Change the substitution value of the cpr alias to:


Copyright %\m wrox_year% Acme Inc.

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.

Dynamic Directory Aliases


Using %\m, you can create some handy aliases that evaluate directories dynamically. The following two
routines, wrox_project_dir() and wrox_buffer_dir(), return the current projects directory and
the current buffers directory, respectively:
_str wrox_project_dir() {
return maybe_quote_filename(strip_filename(_project_name, N));
}
_str wrox_buffer_dir() {
// switch windows to _mdi child to get buffer name,
// so that this macro works in other windows
int new_wid = _mdi.p_child;
int orig_wid = p_window_id;
p_window_id = new_wid;
_str buf_name = p_buf_name;
p_window_id = orig_wid;
return maybe_quote_filename(strip_filename(buf_name, N));
}

You can define a pdir alias as:


%\m wrox_project_dir%

234

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 235

Chapter 11: Aliases and File Templates


You can also define a bdir alias as:
%\m wrox_buffer_dir%

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

We can easily fix this with a simple wrapper for expand-alias:


_command void wrox_expand_alias_inline() name_info(,) {
expand_alias();
}

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

And now the result of expanding the alias is correct:


C:\jhurst\My SlickEdit Config\12.0.2\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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 236

Part II: Using SlickEdit


For SQL files, it should be this instead:
-----

$Id$
Copyright 2007 Acme Inc
username
date

To create the Java-specific alias, follow these steps:

1.
2.

Invoke alias (Tools Options Aliases). SlickEdit displays the Select Alias File dialog.

3.
4.
5.
6.

Click New to add a new Java alias. SlickEdit displays the Enter New Alias Name dialog.

//
//
//
//

7.

Select the java.als file for Java-specific aliases, and click OK. SlickEdit displays the Alias
Editor.

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

Click OK to save the alias and close the Alias Editor.

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 237

Chapter 11: Aliases and File Templates

Syntax Expansion with Aliases


You can also use aliases to override some of the built-in syntax expansion features supplied with SlickEdit.
For example, SlickEdits syntax expansion recognizes the class keyword in C++, but it doesnt expand
it to anything. This is because, when typing class in C++, you might be starting a forward declaration.
If you would like to make class expand to a class definition template by default, you can create a Cspecific alias called class, with this substitution:
class %\c {
public:
private:
};

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 238

Part II: Using SlickEdit


The placement of the hotspots matches that of the original syntax expansion behavior.
Another idea for extension-specific aliases is to use aliases for commonly required include or import
statements. For example, when using Java with the EasyMock library in unit tests, its common to
import several methods statically:
import
import
import
import

static
static
static
static

org.easymock.EasyMock.createMock;
org.easymock.EasyMock.expect;
org.easymock.EasyMock.replay;
org.easymock.EasyMock.verify;

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.

Invoke alias (Tools Options Aliases). SlickEdit displays the Select Alias File dialog.

3.
4.

Click the Surround With box. SlickEdit displays the surround-with aliases for HTML files.

5.
6.

Enter div for the Alias Name, and click OK to close the dialog.

Select the html.als alias file for HTML aliases, and click OK. SlickEdit displays the Alias
Editor.

Click New to add a new surround-with alias. SlickEdit displays the Enter New Alias Name
dialog.

Enter the following for the substitution value:

<div name=%\c>%\m sur_text -select%</div>

7.

Click OK to close the Alias Editor.

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 239

Chapter 11: Aliases and File Templates

Aliases with Parameters


You can specify parameters for variable content in your alias. Suppose you are developing a database
application and you commonly create reference, or lookup, tables with SQL scripts like this:
CREATE TABLE name (
id
INTEGER NOT NULL,
description VARCHAR(50) NOT NULL,
active_yn
CHAR(1) CONSTRAINT name_active CHECK (active_yn IN (Y, N))
);
ALTER TABLE name ADD CONSTRAINT name_pk
PRIMARY KEY (id);

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 240

Part II: Using SlickEdit


7.
8.
9.
10.

Enter NAME for the Parameter Name.


Enter Table Name for the Prompt.
Click OK to create the parameter. SlickEdit adds the parameter to the list of parameters for the
alias.
Click OK to save the alias and close the Alias Editor.

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.

Aliases and Configuration


When SlickEdit initializes your configuration, it copies the default alias files into your configuration
directory. New alias files (*.als) that you create are also placed in the configuration directory. Be
careful if you delete your configuration directory, because you will lose your aliases.
In Chapter 17, we look at programmatic configuration of aliases, which can be used to avoid this problem.

240

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 241

Chapter 11: Aliases and File Templates

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.

Expand the C++ category. Subcategories are displayed under C++.

4.
5.

Select C++ Basic Class.

Select the Class category under C++. The C++ Class category includes templates for C++ Basic
Class, C++ Derived Class, and C++ Header File.

Enter MyNewClass for the Name.

241

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 242

Part II: Using SlickEdit


6.
7.

Change the Location if necessary.


Click Add. SlickEdit creates two new files:

MyNewClass.cpp the class definition.

MyNewClass.h the class declaration.

SlickEdit opens MyNewClass.h for editing.

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 243

Chapter 11: Aliases and File Templates


-- $localdate$
CREATE OR REPLACE PACKAGE BODY pkg_$itemname$ AS
-- complete definitions of members here ...
PROCEDURE test IS
BEGIN
NULL; -- fill in test method.
END;
END;
/

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.

Right-click on the User Templates category, and select New Category from the context menu.
SlickEdit displays the New Category dialog.

3.
4.

Enter PLSQL for the Category name.


Click OK to close the New Category dialog.

243

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 244

Part II: Using SlickEdit


5.

Right-click on the PLSQL category, and select New Template in Category from the context
menu. SlickEdit displays the New Template dialog.

6.
7.

Enter create_package for the Template name.


Click OK to close the New Template dialog. SlickEdit creates the template entry in the Template
Manager.

8.
9.
10.
11.

Enter New PL/SQL package for the Description.

12.

Enter the path and filename for your create_package_template.sql file, or use Browse to
navigate to it.

13.
14.
15.

Enter create_pkg_$itemname$.sql for the Target filename.

Enter name for the Default name.


Select the Files tab.
Click the + next to the Files list to add a file to the template. SlickEdit displays the Add File
dialog.

Click OK to close the Add File dialog and add the file to the template. SlickEdit adds the file.
Repeat the process to add the create_package_body_template.sql file. Enter create_pkg_
body_$itemname$.sql for its Target filename.

16.
17.

Select the Custom Parameters tab.

18.
19.
20.
21.
22.
23.

Enter granted_user for the Name.

Click the + next to the Custom Parameters list to add a custom parameter. SlickEdit displays
the Add Parameter dialog.

Enter PUBLIC for the Value.


Check the Prompt for value checkbox.
Enter User to grant EXECUTE to for the Prompt string.
Click OK to close the Add Parameter dialog.
Click Options. SlickEdit displays the Template Options dialog, shown in Figure 11-7.

Figure 11-7

244

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 245

Chapter 11: Aliases and File Templates


24.

Click the + next to the Global substitution parameters list. SlickEdit displays the Add
Parameter dialog.

25.
26.
27.

Enter copyright for the Name.

28.

Click Close to close the Template Manager.

Enter Copyright 2007 Acme Inc for the Value.


Click OK to close the Template Options dialog and add the global substitution parameter. The
$copyright$ substitution parameter can now be used in all our templates.

That was a lot of steps, but the result is quite powerful. Lets instantiate the template. Follow these steps:

1.

Invoke add-item (File New Item from Template). SlickEdit displays the Add New Item
dialog.

2.
3.
4.
5.
6.
7.

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.

The instantiated contents of create_pkg_customer.sql are:


-----

$Id$
Copyright 2007 Acme Inc
jhurst
2007-04-06

CREATE OR REPLACE PACKAGE pkg_customer AS


-- add members here ...
PROCEDURE test;
END;
/
GRANT EXECUTE ON pkg_customer TO ADMIN;

The instantiated contents of create_pkg_body_customer.sql are:


-----

$Id$
Copyright 2007 Acme Inc
jhurst
2007-04-06

CREATE OR REPLACE PACKAGE BODY pkg_customer AS


-- complete definitions of members here ...
PROCEDURE test IS

245

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 246

Part II: Using SlickEdit


BEGIN
NULL; -- fill in test method.
END;
END;
/

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

246

Parameter

Description

$itemname$

Name of item entered, as on the Add New Item dialog.

$fileinputname$

Name of item entered, as on the Add New Item dialog, without


file extension.

$safeitemname$

Name of item entered, as on the Add New Item dialog, with all
unsafe characters replaced with safe characters.

$upcasesafeitemname$

Same as $safeitemname$ with all characters uppercased.

$lowcasesafeitemname$

Same as $safeitemname$ with all characters lowercased.

$tempdir$

Location of operating system temp directory. No trailing file


separator.

$rootnamespace$

Root namespace or package for the current project.

$ampmtime$

Time of day in the form hh:mm[am|pm]. Example: 11:34pm.

$localtime$

Time of day in locale-specific format.

$time$

Time of day in the form hh:mm:ss.

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 247

Chapter 11: Aliases and File Templates


Table 11-2 (continued)
Parameter

Description

$localdate$

Current date in locale-specific format.

$date$

Current date in the form mm/dd/yyyy.

$projectname$

Current project name (no path, no extension).

$safeprojectname$

Current project name (no path, no extension), with all unsafe


characters replaced with safe characters.

$workspacename$

Current workspace name (no path, no extension).

$safeworkspacename$

Current workspace name (no path, no extension), with all


unsafe characters replaced with safe characters.

$projectworkingdir$

Current project working directory. No trailing file separator.

$projectbuilddir$

Current project build (output) directory. No trailing file separator.

$projectconfigname$

Current project configuration name.

$workspaceconfigname$

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.

$projectdir$

Location of current project file. No trailing file separator.

$workspacedir$

Location of current workspace file. No trailing file separator.

$username$

Operating system login name.

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 248

Part II: Using SlickEdit


We could create an extension-specific alias, grantx, with expansion:
GRANT EXECUTE ON %\c TO %\c;

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.

Instantiating Templates in Macros


In Chapter 4, we saw how you can create custom project types and use the InitMacro attribute to run
an initialization macro when the project type is instantiated. When creating a new project of a custom
type, its often useful to instantiate one or more file templates. You can, of course, do this manually after
creating a new project. If you want certain file templates to be a standard part of your custom project
type, you can instantiate them in your initialization macro.
Lets revisit the Java example from Chapter 4. Most Java projects are built using Ant, with a build.xml
file. If you are using Java, you probably have a standard layout for your Ant build scripts that you re-use
with each project. Obviously, the same idea applies to makefiles and other standard build scripts for other
languages. In this section, well add a file template for build.xml and related files and show how to
instantiate the template when creating a new project of a custom project type.
First, well create the new file template. For this example, well have three files:

build.xml the Ant build script.

build.properties the default build properties used by the script.

build.number.properties a special properties file with build numbers for numbered

builds.
To follow the example, perform these steps:

1.

Create a file called build.xml, with the following content:

<!-$$Id$
$copyright$
$username$
$localdate$
-->
<project name=$projectname$ basedir=. default=compile-java >
<tstamp>

248

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 249

Chapter 11: Aliases and File Templates


<format property=build.date pattern=yyyy-MM-dd HH:mm:ss/>
</tstamp>
<!-- Properties: local properties override common properties -->
<property file=build.local.properties/>
<property file=build.number.properties/>
<property file=build.properties/>
<path id=classpath.lib>
<fileset dir=${lib}/>
</path>
<path id=classpath.test>
<fileset dir=${lib.test}/>
</path>
<target name=clean description=Clean temporary/generated files and
directories>
<delete dir=${build}/>
</target>
<target name=prepare description=Create directory structure for build>
<mkdir dir=${build}/>
<mkdir dir=${build.classes}/>
</target>
<target name=compile-java depends=prepare
description=Compile prod code >
<javac srcdir=${src.java} destdir=${build.classes}
debug=${compile.debug} optimize=${compile.optimize}
source=${compile.source} target=${compile.target}>
<classpath refid=classpath.lib/>
</javac>
<copy todir=${build.classes}>
<fileset dir=${src.java} excludes=**/*.java/>
</copy>
</target>
<target name=compile-test depends=prepare,compile-java
description=Compile test code>
<javac srcdir=${src.test} destdir=${build.classes}
debug=${compile.debug} optimize=${compile.optimize}
source=${compile.source} target=${compile.target}>
<classpath refid=classpath.lib/>
<classpath refid=classpath.test/>
</javac>
<copy todir=${build.classes}>
<fileset dir=${src.test} excludes=**/*.java/>
</copy>
</target>
<target name=compile depends=compile-java,compile-test
description=Compile all code/>
<target name=test depends=compile description=Run all tests>
<delete dir=${test.xml.dir}/>
<mkdir dir=${test.xml.dir}/>

249

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 250

Part II: Using SlickEdit


<junit fork=true dir=.
errorProperty=test.failed failureProperty=test.failed>
<classpath path=${build.classes}/>
<classpath refid=classpath.lib/>
<classpath refid=classpath.test/>
<formatter type=brief usefile=false/>
<test name=AllTests/>
</junit>
<fail message=Tests failed! Check test reports. if=test.failed/>
</target>
</project>

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.
#
#
#
#

Create an accompanying build.properties file, with this content:


$$Id$
$copyright$
$username$
$localdate$

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.

Create a build.number.properties file, with this content:

build.number=00
version.number=01
release.number=00

250

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 251

Chapter 11: Aliases and File Templates


4.
5.
6.
7.

Create a new file template category Java, under User Templates.


In the Java category, create a template called Ant build file.
In the template, set the name, description, and default name to Ant build file.
Link the template to the three source files build.xml, build.properties, and build.number
.properties.

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

22150c11.qxd:WroxPro

9/25/07

1:29 AM

Page 252

Part II: Using SlickEdit


when appropriate. However, remember that the internal workings can change from release to release.
The more your own code relies on low-level functionality and implementation details, the more likely it
is to break between releases. Try to use higher-level functionality and documented commands and functions as much as possible, as they are less likely to change.

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

22150c12.qxd:WroxPro

9/25/07

1:32 AM

Page 253

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.

22150c12.qxd:WroxPro

9/25/07

1:32 AM

Page 254

Part II: Using SlickEdit


Sometimes you dont want the features enabled, or you want a different mode. For example, syntax expansion features can get in the way when using Macro Record and Playback. You can use select-mode
(Document Select Mode) to select a different mode for the editor. You can also switch modes using
specific commands for each mode. The mode switching commands are simply the name of the mode followed by -mode. For example, the command to switch to Fundamental mode is fundamental-mode,
and the command to switch to HTML mode is html-mode.
An example in which this mode-switching is useful is in Ruby on Rails views, which are .rhtml files
containing a mixture of HTML and Ruby code. SlickEdit supports some combinations of HTML and
scripting languages (such as ASP and JavaScript), but not HTML and Ruby. However, you can get some
of the benefits of both languages by switching between HTML and Ruby modes while editing the file.
We gave some examples of working with embedded languages in Chapter 9.

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.

Character Sets and Encodings


Before Unicode became popular, all source code editors used code pages to edit source files. Originally,
SlickEdit could only edit code page source files like the other source code editors. There are some advantages to code page editors. Code page editors do not need to translate the bytes in your file when you
open the file. This has some speed advantages, allows for a single editor storage format that can display
the bytes in your file as lines of text or in hex, and guarantees that there are no translation errors. The

254

22150c12.qxd:WroxPro

9/25/07

1:32 AM

Page 255

Chapter 12: Document Types


disadvantage of code page editors is that realistically you cant edit Unicode files. This is because there is
no code page that contains all the characters in the Unicode character set.
Now that Unicode is widely used for XML and other text files, code page editing is not enough. Today,
most source code editors that support Unicode files convert code page files to an internal Unicode representation (usually UTF-16 or UTF-8). All Microsoft text editors, including Visual Studio, do this.
In order to retain the advantages of code page editing for those files for which it is suitable, SlickEdit has
two basic in-memory representations:

Single Byte Character Set/Double Byte Character Set (SBCS/DBCS) SBCS/DBCS mode
means code page editing. In this mode, the text in your file is not translated except for EBCDIC,
which is a slight variant of this mode because characters are translated to ASCII.

Unicode (represented internally as UTF-8) This is typically used for XML. In this mode, if
the data in your file are not already in UTF-8, SlickEdit will translate them into UTF-8.

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.

XML Document Types


XML files are often described using a Document Type Definition, or DTD, which is a specification describing the valid content of files of the given type. The DTD specifies which elements the document may
contain, what content the elements may contain, whether they are mandatory or optional, their attributes,
and so forth. An XML document that conforms to its DTD is said to be valid.
In 2001, the W3 Consortium introduced the XML Schema standard as a new and more powerful way to
describe content rules for XML documents. XML Schema is used by many modern XML systems, including most of those in Web Services, such as SOAP and WSDL.

255

22150c12.qxd:WroxPro

9/25/07

1:32 AM

Page 256

Part II: Using SlickEdit


When SlickEdit opens an XML file that references a DTD or schema, the editor loads the document definition so that it can validate the document structure and provide syntax assistance. If the document is
not valid, SlickEdit displays error messages in the Output tool window and also highlights unknown
elements using the configured Unknown XML Element color.
In order to validate a document, SlickEdit needs to refer to the DTD or schema. Usually the DTD or
schema is given by a URL. For example, the URL for the DTD for configuration files for the Spring
framework is http://www.springframework.org/dtd/spring-beans-2.0.dtd.
This downloading can take a noticeable time, even if you are on a fast network. If you are behind a firewall or not connected to the network, the downloading fails after a timeout. During this time the editor
is effectively hung, and you cannot work.
One solution to this issue is to store a copy of the DTD/schema on your local hard disk and refer to that
copy instead. Lets configure SlickEdit to refer to a local copy of the Spring configuration DTD. On my
system, the framework is installed in C:\lib\spring-framework-2.0.2. Follow these steps:

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

22150c12.qxd:WroxPro

9/25/07

1:32 AM

Page 257

Chapter 12: Document Types


If you dont have a local copy of the DTD or schema and you are working offline, you may prefer to disable SlickEdits document validation, so that you can open files quickly, without timeouts. The autovalidation setting is in the XML Formatting Options dialog, reached from the XML Options button on
the Extension Options dialog for XML (Tools Options File Extension Setup).
Turning off auto-validation prevents SlickEdit from validating XML documents when it opens them. You
can still validate them manually at any time by invoking the xml-validate command.
Even with auto-validation turned off, SlickEdit still tries to download the DTD or schema, so that it can
use it to provide syntax expansion and color highlighting. You can prevent SlickEdit from downloading
DTDs or schemas for syntax expansion by adding extensions to the def_xml_no_schema_list macro
variable. For example, enter this command:
set-var def_xml_no_schema_list .xml .xsd

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

22150c12.qxd:WroxPro

9/25/07

1:32 AM

Page 258

Part II: Using SlickEdit


To use this macro to download the Spring configuration DTD to a local copy, load the macro and enter
this command on the SlickEdit command line:
wrox-make-url-mapping http://www.springframework.org/dtd/spring-beans-2.0.dtd

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 259

Comparing and Merging


For some reason or another, we programmers always seem to end up with multiple, slightly different versions of the same file. Or worse multiple, slightly different versions of the same
source tree. Now, one thing Ive noticed in my career is that this has been happening a lot less
since I started using version control. Proper use of version control reduces the need for archived
or backup copies of source code, or copies of the same source tree all over your disk.
We look at version control in more detail in the next chapter.
Of course, it still happens. (Usually when it happens to me, it means I havent been using version
control properly!) This must be a fairly common occurrence for programmers, and perhaps other
computer users too, because there are several commercial tools on the market whose sole function
is to compare directories and files and resolve the differences. Happily, if you already own SlickEdit,
you probably dont need one of those tools, because SlickEdit has great file and directory comparison and merging built right in. You can even run SlickEdits comparison tools outside the editor, as
a full replacement for standalone tools for the same purpose.
In this chapter, well take a look at comparing and merging files and directories. Well also take a
look at some basic versioning capabilities built into SlickEdit.

Comparing F iles and Directories


SlickEdits file and directory comparison tool is called DIFFzilla. You can use DIFFzilla to compare
buffers with each other, buffers with files, or files with other files. You can also use it to compare
entire subdirectories of your file system.

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 260

Part II: Using SlickEdit

Comparing Two Files


Suppose that, in a fit of performance-tuning enthusiasm, we re-wrote the gnu_queens program to use
old style C arrays instead of STL collections. We have a copy of the old source code in a separate backup
directory. Lets use DIFFzilla to examine the differences between the STL board.h and the arrays
board.h. Follow these steps:

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.

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.

3.
4.

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 261

Chapter 13: Comparing and Merging

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:

_command void wrox_next_whitespace_word();


_command void wrox_prev_whitespace_word();

3.

Add these lines to the declaration of the DiffCommands array:


wrox-next-whitespace-word
wrox-prev-whitespace-word

4.

=>wrox_next_whitespace_word,
=>wrox_prev_whitespace_word,

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 262

Part II: Using SlickEdit

Comparing Sections within a File


Sometimes, instead of comparing entire files, you need to compare only a range of lines. Occasionally
you may need to compare ranges of lines within a file. For example, here is a fragment from an XML
schema definition:
<?xml version=1.0?>
<xsd:schema xmlns:xsd=http://www.w3.org/2001/XMLSchema>
...
<xsd:complexType name=PartialAddress>
<xsd:annotation>
<xsd:documentation>
Purpose - Define a partial address.
Detail - This type allows the transfer of portions of an address.
Where a complete address is to be transferred,
the Address type should be used.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:choice minOccurs=0>
<xsd:element name=StructuredAddress
type=StructuredAddressPartialComponents/>
<xsd:element name=UnstructuredAddress>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=AddressLine type=AddressLine nillable=true
maxOccurs=3/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:element name=SuburbOrPlaceOrLocality type=SuburbOrPlaceOrLocality
nillable=true minOccurs=0/>
<xsd:element name=StateOrTerritory type=StateOrTerritory nillable=true
minOccurs=0/>
<xsd:element name=PostCode type=PostCode nillable=true minOccurs=0/>
<xsd:element name=DeliveryPointIdentifier type=DeliveryPointIdentifier
nillable=true minOccurs=0/>
</xsd:sequence>
</xsd:complexType>
...
<xsd:complexType name=Address>
<xsd:annotation>
<xsd:documentation>
Purpose - Define an address.
Detail - The address format allows for either a structured or an
unstructured physical address, with locality, state and postcode
always being carried as structured elements.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:choice>
<xsd:element name=StructuredAddress type=StructuredAddressComponents/>
<xsd:element name=UnstructuredAddress>

262

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 263

Chapter 13: Comparing and Merging


<xsd:complexType>
<xsd:sequence>
<xsd:element name=AddressLine type=AddressLine nillable=true
maxOccurs=3/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:choice>
<xsd:element name=SuburbOrPlaceOrLocality type=SuburbOrPlaceOrLocality
nillable=true minOccurs=0/>
<xsd:element name=StateOrTerritory type=StateOrTerritory/>
<xsd:element name=PostCode type=PostCode/>
<xsd:element name=DeliveryPointIdentifier type=DeliveryPointIdentifier
nillable=true minOccurs=0/>
</xsd:sequence>
</xsd:complexType>
...
</xsd:schema>

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 264

Part II: Using SlickEdit


}
goto_bookmark(bookmark3);
_str filename2 = p_buf_name;
int start_line2 = p_line;
goto_bookmark(bookmark4);
if (p_buf_name != filename2) {
message(Bookmark 4 must be in same file as bookmark 3.);
pop_bookmark();
return;
}
int end_line2 = p_line;
if (end_line2 <= start_line2) {
message(Bookmark 4 must be after bookmark 3 in file.);
pop_bookmark();
return;
}
_str commandline = ;
commandline =
commandline :+ -range1: :+ start_line1 :+ , :+ end_line1 :+ ;
commandline =
commandline :+ -range2: :+ start_line2 :+ , :+ end_line2 :+ ;
commandline = commandline :+ maybe_quote_filename(filename1) :+ ;
commandline = commandline :+ maybe_quote_filename(filename2);
diff(commandline);
pop_bookmark();
}

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.

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.

3.

Navigate to the end of the first range. The end of the first range should be after the start, and in
the same file.

4.
5.

Invoke alt-bookmark with bookmark 2 (WROX: Ctrl+Shift+2).

6.
7.

Invoke alt-bookmark with bookmark 3 (WROX: Ctrl+Shift+3).

8.
9.

Invoke alt-bookmark with bookmark 4 (WROX: Ctrl+Shift+4).

Navigate to the start of the second range. This can be in the same file as the first range, or in a
different file.

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 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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 265

Chapter 13: Comparing and Merging

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 266

Part II: Using SlickEdit

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.

Running DIFFzilla Standalone


You can run DIFFzilla as a standalone tool. Under Windows, the SlickEdit installation creates a shortcut
for DIFFzilla in the SlickEdit folder in your Start Menu. You can also use DIFFzilla from the command
line, provided that the SlickEdit executable directory is in your path. The command is called vsdiff.
Consult the online Help to find out about the command-line options.

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 267

Chapter 13: Comparing and Merging


Lets look at a simple example. In order to make things as clear as possible, well use a rather contrived
set of files. Heres the original:

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.

Heres the first revised version:

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.

Here is line 2 to be deleted.

Heres the second revised version:

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.

Here is line 1 to be deleted.

Lets run 3 Way Merge on these files, placing the result in a new file, output.txt:

1.

Invoke merge (Tools File Merge). SlickEdit displays the 3 Way Merge Setup dialog, shown in
Figure 13-6.

2.
3.
4.

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 268

Part II: Using SlickEdit

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.

268

Use the buttons to navigate the merge, and apply changes from either of the revisions to the
output file as desired.

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 269

Chapter 13: Comparing and Merging


8.

Click Close to finish 3 Way Merge. SlickEdit prompts you whether you want to save the changes
to the output file.

9.

Click Yes to save the changes.

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

22150c13.qxd:WroxPro

9/25/07

1:34 AM

Page 270

Part II: Using SlickEdit


Ensure that Use file on disk is unchecked for Path 1 (to use the buffer version) and checked for Path 2
(to use the on-disk version).
Backup history changes are stored by default in the vsdelta subdirectory of your SlickEdit configuration directory. Therefore, for example, on Windows this might be in C:\Documents and Settings\
username\My Documents\My SlickEdit Config\12.0.0\vsdelta. You can change this and other
backup history settings on the Backup tab of the File Options dialog (Tools Options File Options).
Usually, its not important to know where the snapshots are stored: They just work. Be careful to keep the
location in mind if you delete your SlickEdit configuration though you will lose your backup history.

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 271

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.

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 272

Part II: Using SlickEdit


In the sections below, we go through common version control tasks with CVS. We assume that you have
a CVS server already set up and that you are familiar with the basic CVS commands.
If you are unfamiliar with CVS in general, you will need to consult reference documentation elsewhere
to learn how to set it up and how to use its basic functions. The definitive guide to CVS is the Cederqvist
manual, available online at http://ximbiot.com/cvs/manual/.
CVS determines the default server and protocol from the CVSROOT environment variable. You can specify an alternative server and protocol using the -d option, but its usually easiest to use CVS by setting
the CVSROOT environment variable. In our examples, we assume that you have CVSROOT set up for your
CVS server. You can set CVSROOT in your operating system environment, or in vslick.ini.
In our examples, well use the pserver protocol to access a CVS server over the network. On my system, the CVS server is on a host named vcs. Im using user name jhurst, and the repository is in directory /var/cvs on the server. My CVSROOT entry in vslick.ini looks like this:
CVSROOT=:pserver:jhurst@vcs:/var/cvs

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.

Using an Existing Working Copy


If you already have a working copy of your project checked out from CVS, you can set up your SlickEdit
project to use that working copy. Then you need to tell SlickEdit about your version control system. The
steps below assume you already have a SlickEdit workspace set up, and that the files in it are a working
copy from a CVS repository:

272

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.)

2.

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.

3.
4.

Select CVS in the list of Version Control Systems.

5.

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.

Click Setup. SlickEdit displays the CVS Setup dialog, containing setup options specific to CVS.
The dialog is shown in Figure 14-2.

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 273

Chapter 14: Version Control

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 274

Part II: Using SlickEdit


My CVS server is set up to use the pserver protocol, which is the most basic CVS authentication protocol. If you are using a different protocol, the details of connection will be different.

8.
9.
10.
11.
12.
13.

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.

Checking Out an Existing Project


If you dont have a working copy already checked out on your system, you can use SlickEdit to check
out the project. Follow these steps:

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.

274

Select the module you want to check out.


Enter the path where you want the new working copy to be created.

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 275

Chapter 14: Version Control


5.

Click Next. SlickEdit shows the next page of the Check Out CVS module wizard, shown in
Figure 14-5. This page shows the branches and tags that exist in the module. In Figure 14-5,
there are no branches or tags; only the tip of the project is available.

Figure 14-5

6.
7.

Select the branch or tag you want to check out.

8.

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.

Click Finish. SlickEdit displays the Checkout workspace dialog, summarizing your options
for checking out the module.

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 276

Part II: Using SlickEdit


Note that the macro requires the wrox_project_dir() function, defined in wrox_directories.e
from Chapter 11. Also, the command only works when there is an active project.
In the wrox_cvs.e file, this command is bound to Alt+V followed by U.
When you invoke cvs-gui-mfupdate for your project, SlickEdit shows the CVS Update Directory window, which looks something like what is shown in Figure 14-6.

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 277

Chapter 14: Version Control

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 278

Part II: Using SlickEdit

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 279

Chapter 14: Version Control


The icon indicates that the file has a merge conflict, because it has both a local and remote modification
and also a yellow error triangle. If you want to find out more about what has changed in the file, you can
use DIFFzilla. If you click Diff, you get a window prompting you which revisions to compare, as shown
in Figure 14-11.

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.

Using Commit Sets to Group Changes


A best practice of using version control is that a given change set should pertain to one and only one feature or bug fix. That makes it a lot easier to read the history of the project: You can see exactly why each
change was made to a given file if changes reflect specific features or issues. Also, if it becomes necessary
to back out a feature or fix, its a lot easier if the changes for it are not mixed up with other changes.
A good policy to follow is to commit early, commit often. This gets your code in front of the other
developers as early as possible, so that they can provide feedback and identify problems, rather than
waiting until the code is completely finalized. Also, integration and build problems resulting from combining changes from different developers are discovered as early as possible.
Sometimes, though, you find that you have made local changes that relate to different things and should
not be committed all together. This often happens, for example, when you are working on one fix and
discover that you need to refactor a class or function in a way that is tangential to your fix. For complex
fixes, you might find that you touch several different modules for different reasons. By the time you
realize it, you could have a couple dozen or more files changed that need to be committed separately to
make clear the reasons for the different changes.

279

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 280

Part II: Using SlickEdit


Commit sets are a standard way of dealing with this situation. Normally when you use CVS version
control, you probably wont use commit sets, because they involve extra steps and can interrupt your
workflow for simple changes. For complex changes, however, they are very useful.
SlickEdit allows you to create named commit sets, specify the check-in message for them, and move files
between them. Suppose we have changed four files in our project, but for two different reasons: For
Project Administration, weve added .cvsignore and changed README.txt. For Documentation,
weve updated board.cpp and board.h, adding some comments. Lets create some commit sets for
these two unrelated changes. (This example used only four files. Obviously, for four files you would
simply select the sets of related files in the CVS Update Directory and commit them together. Use commit sets when you have more files and its not so easy to remember which file belongs with which
change.)
Follow these steps:

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.

Click Add. SlickEdit displays the New Commit Set dialog.

5.

Repeat Steps 24 to add a commit set called Documentation.

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.

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 281

Chapter 14: Version Control


Having created a commit set, you need to add files to it and specify the check-in comments. Lets add
the source files and check-in comment to the Documentation commit set:

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 282

Part II: Using SlickEdit


commits sharing the same comments. For this reason, I recommend that you use a single comment for
all files in a commit set.
The Add File button on the Commit Set editor is one way to add files to a commit set. It is nice if you
know what files you want in the commit set, and it also has the advantage that a file doesnt have to
have any local changes at the time you add it to the set.
The other way to add files to a commit set is via the CVS Update Directory window. Lets add the other
two changed files to the default commit set, using the CVS Update Directory window:

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.

Invoke commit-sets (Tools Version Control Commit sets). SlickEdit displays the CVS
Commit Sets dialog.

2.
3.

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.

Branches and Tags


Branches and tags are the fundamental way of organizing your history and versions in version control.
Branching and tagging are relatively infrequent operations and not normally part of your regular
editcompiletest workflow. For this reason, SlickEdit doesnt provide branching and tagging commands in the editor. You can branch and tag your files from the command line using the normal CVS
commands.
The commands can be entered in SlickEdits Build tool window, if you like. For example, to create a
release branch for release 1.1 of the gnu_queens project, you would enter a command like:
cvs rtag b RB_01_01 gnu_queens

Figure 14-14 shows the command as executed in the Build tool window.

282

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 283

Chapter 14: Version Control

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:

cvs co r RB_01_01 d gnu_queens_cvs_01_01 gnu_queens

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.

Browsing the History


You can browse the history for a particular file in your project. To do this, follow these steps:

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 284

Part II: Using SlickEdit

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 285

Chapter 14: Version Control


description of the command. Use the WROX shortcuts provided here as an example, to set up your own
customized shortcuts to streamline your workflow.

Table 14-1
Command

Key

Description

commit-set-add

(none)

Adds the current file to the default commit set.

commit-sets

(none)

Shows the commit sets.

cvs-add

Alt+V, A

Adds the current file to CVS version control.

cvs-checkout-module

Alt+V, M

Checks out working copy of module from repository.

cvs-commit

Alt+V, C

Commits the current file.

cvs-diff-with-tip

Alt+V, D

Shows the local changes.

cvs-history

Alt+V, L

Shows the Log info window for the current file.


Invokes CVS login.

cvs-login
cvs-query

Alt+V, Q

Invokes the CVS query facility.

cvs-remove

Alt+V, R

Removes the current file from version control.

cvs-review-and-commit

Alt+V, V

Displays DIFFzilla showing local changes, allowing


revision. Then follows with commit dialog.

cvs-setup

(none)

Displays the CVS Setup dialog.

cvs-update

(none)

Updates the current file.

cvs-update-directory

(none)

Updates the current directory.

wrox-cvs-update-project

Alt+V, U

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 286

Part II: Using SlickEdit


Despite the differences, most of the Subversion features with SlickEdit work just the same as the CVS
features. For example, commit sets are the same; thus we wont repeat the details in this section. The
principles of branching and tagging are the same as for CVS, but the details are rather different; therefore, we discuss branching and tagging with Subversion in some detail.
If you are unfamiliar with Subversion, you will need to consult reference documentation elsewhere to
learn how to set it up and use its basic functions. A free version of Version Control with Subversion is
available online at http://svnbook.red-bean.com/. Many other books also cover effective use of
Subversion.
When you issue commands against the remote repository, you always must specify a full URL. When
you issue commands that work with the working copy, Subversion obtains the repository URL (if necessary) from control files in the working copy.
In our examples, well use the svn+ssh protocol, which is a way of accessing Subversion remotely via
an SSH tunnel. Subversion supports several other protocols, but we wont look at those in this book.
On my system, the Subversion server is on the same host as the CVS one, a machine named vcs. The
Subversion repository for the examples is in the directory /var/svn/slickedit/ on that host. Because
Im using the user name jhurst, the repository URL is svn+ssh://jhurst@vcs/var/svn/slickedit.
When using Subversion on the command line, the URLs can be rather long and painful to type. Its
handy to define some environment variables for often-used URLs or parts of URLs. For example, in my
Cygwin .bash_profile, I define the environment variable SVN like this:
export SVN=svn+ssh://jhurst@vcs/var/svn/slickedit

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 287

Chapter 14: Version Control

Configuring SlickEdit for Subversion


To configure SlickEdit for Subversion, follow these steps:

1.

Invoke vcsetup (Tools Version Control Setup). SlickEdit displays the Version Control
Setup dialog.

2.
3.
4.

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.

Creating a New Project


Creating a new project in Subversion is simply a matter of issuing the appropriate svn mkdir commands. As with CVS, SlickEdit does not provide GUI features for project management or branching or
tagging in Subversion. You have to create projects using the command line. You can create the gnu_queens
project in subversion with these commands:
svn mkdir %SVN%/gnu_queens -mCreating directory /gnu_queens/.
svn mkdir %SVN%/gnu_queens/trunk -mCreating directory /gnu_queens/trunk/.

(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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 288

Part II: Using SlickEdit

Checking Out a Working Copy


To check out a working copy from Subversion, follow these steps:

1.

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.

2.
3.
4.

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.

288

Enter the desired location for the project to be checked out to.
Click OK. SlickEdit checks out the project.

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 289

Chapter 14: Version Control

Reviewing and Committing Changes, Adding Files


The procedure for reviewing changes is the same for Subversion as for CVS. As with CVS, you may find
it handy to have a macro that you can use to update and review changes in your entire project. Heres a
Subversion version of the macro:
_command void wrox_svn_update_project() name_info(,) {
svn_gui_mfupdate(wrox_project_dir());
}

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 290

Part II: Using SlickEdit

board.cpp.r3 The file as it was in the repository at revision 3.

board.cpp.r7 The file as it is in the repository at revision 7.

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

Branches and Tags


In Subversion, branches and tags are not specific concepts in the system. Instead, branches and tags are
done by simply copying the source tree using svn copy. The designation of a copy as a branch or tag is
simply a matter of convention. A common convention is to put the main line of development in a subdirectory under your project in the repository called trunk/, and to place branches and tags in subdirectories
called branches/ and tags/, respectively.
Following this convention, lets create a release branch for the gnu_queens project. Issue this command
in the Build tool window:
svn copy %SVN%/gnu_queens/trunk %SVN%/gnu_queens/branches/RB-01.01
-mCreated release branch for gnu_queens 1.1.

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

To return to the trunk, the command is:


svn switch %SVN%/gnu_queens/trunk

The switch command switches your working copy to the desired branch. The advantages of using svn
switch are:

290

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.

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 291

Chapter 14: Version Control


The main disadvantage of using svn switch is that sometimes you might forget which branch you are
in. To check which branch you are currently working on with your working copy, use the svn info
command.
When you have completed all the testing and other work for a release and it is finished, you should
tag it so that you have a reproducible build. To tag the 1.1.0 release of the gnu_queens project, use this
command:
svn copy %SVN%/gnu_queens/branches/RB-01.01 %SVN%/gnu_queens/tags/REL-01.01.00
-mTagged gnu_queens 1.1.0.

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

Browsing the History


To view the history for a file, follow these steps:

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 292

Part II: Using SlickEdit

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

292

Command

Key

Description

commit-set-add

(none)

Adds the current file to the default commit set.

commit-sets

(none)

Shows the commit sets.

svn-add

Alt+V, A

Adds the current file to Subversion.

svn-browse

Alt+V, B

Opens the Subversion Browser.

svn-commit

Alt+V, C

Commits the current file.

svn-diff-with-tip

Alt+V, D

Shows the local changes.

svn-history

Alt+V, L

Shows the Log info window for the current file.

svn-remove

Alt+V, R

Removes the current file from version control.

svn-revert

Alt+V, T

Reverts the local changes on the current file.

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 293

Chapter 14: Version Control


Table 14-2 (continued)
Command

Key

Description

svn-review-and-commit

Alt+V, V

Displays DIFFzilla, showing local changes, allowing


revision. Then follows with commit dialog.

svn-setup

(none)

Displays the Subversion Setup dialog.

svn-update

(none)

Updates the current file. (This command is not really


meaningful for Subversion.)

svn-update-directory

(none)

Updates the current directory.

wrox-svn-update-project

Alt+V, U

Shows Update Directory window for the current


project.

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

22150c14.qxd:WroxPro

9/25/07

1:37 AM

Page 294

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 295

Part III: Advanced SlickEdit


Chapter 15: Other Tools
Chapter 16: Slick-C Macro Programming
Chapter 17: Customization

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 296

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 297

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.

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 298

Part III: Advanced SlickEdit

The F ile Manager


You can use the file manager for various file management tasks. You can also use it to navigate directories
and open files on your system. But perhaps the most powerful use of the file manager is to use Slick-C to
automate tasks on files with SlickEdit.
To invoke the file manager, follow these steps:

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

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 299

Chapter 15: Other Tools


Table 15-1
Option

Description

-|+D

Exclude/include directory files.

-|+H

Exclude/include hidden files. Ignored on UNIX; on Windows the default


follows the Windows Explorer Show all files setting.

-|+P

Append path. Default is on.

-|+S

Exclude/include system files. Ignored on UNIX; on Windows the default


follows the Windows Explorer Show all files setting.

-|+T

Tree file list. (Includes subdirectories.)

File Manager Commands


You can perform many different operations in the file manager. The file manager commands and shortcut keys are shown in Table 15-2. These commands can also be invoked through the right-click context
menu. There are the usual sorts of things, like move, copy, and delete. There are also several commands
concerning selections. Finally, you can run arbitrary commands on files selected in the file manager.

Table 15-2
Command

Key

Description

fileman-space

Space

Toggles select if file cursor is on.

fileman-enter

Enter

Edit file at cursor, or insert directory list.

select-all

Alt+Shift+A

Select all files.

fileman-backup

Alt+Shift+B

Back up (copies) selected files to a directory.

fileman-copy

Alt+Shift+C

Copy selected files.

fileman-delete

Alt+Shift+D

Delete selected files.

fileman-edit

Alt+Shift+E

Edit selected files.

fileman-find

Alt+Shift+F

Run multifile search in selected files.

fileman-replace

Alt+Shift+G

Run multifile search and replace in selected files.

fileman-move

Alt+Shift+M

Move selected files.

fsort

Alt+Shift+O

Sort list.
continued

299

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 300

Part III: Advanced SlickEdit


Table 15-2 (continued)
Command

Key

Description

fileman-attr

Alt+Shift+P

Set DOS attributes.

for-select

Alt+Shift+R

Repeat a command on each selected file.

deselect-all

(none)

Deselect all selected files.

select-reverse

(none)

Reverse selected files.

select-attr

(none)

Select files based on DOS attributes.

select-ext

(none)

Select files based on given extension.

gui-select-ext

(none)

Select files based on extension.

select-mark

(none)

Select files marked with a (character or line or


block) selection.

deselect-mark

(none)

Deselect files marked with a selection.

unlist-all

(none)

Empty the list.

unlist-select

(none)

Unlist the selected files.

unlist-ext

(none)

Unlist files based on given extension.

gui-unlist-ext

(none)

Unlist files based on extension.

unlist-attr

(none)

Unlist files based on DOS attributes.

unlist-search

(none)

Unlist files based on filename matching a search


string.

read-list

(none)

Read a list of filenames from a file.

write-list

(none)

Write the list of selected filenames to a file.

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

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 301

Chapter 15: Other Tools


Using the various selection commands and the unlist-select command, you can easily filter the list
down to the files in which youre interested. For example, to reduce a file manager list to show only
.cpp files, enter these commands:
deselect-all
select-ext cpp
select-reverse
unlist-select

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.

The filename is in the space-delimited list of filenames in the macro variable


def_user_langext_files.

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

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 302

Part III: Advanced SlickEdit


The macro receives a filename and appends it to the space-delimited list in def_user_langext_files.
To use this macro with the file manager, follow these steps:

1.

Invoke list to open a file manager buffer with the directory containing the extensionless
header files.

2.
3.

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.

FTP/SSH for Remote Editing


SlickEdits FTP connectivity is perfect for times you need to browse or edit files on a remote host. You
wouldnt use it for coding, but it is great for browsing log files or editing configuration files on servers.
As well as FTP, SlickEdit also supports connectivity via SSH, commonly used for logging into servers
these days.
Lets work through an example of setting up a SlickEdit connection to a remote machine.

302

1.

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.

2.

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.

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 303

Chapter 15: Other Tools

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

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 304

Part III: Advanced SlickEdit


4.

Fill in the details for your connection in the Add FTP Profile dialog. You can choose either FTP
or SFTP/SSH. If you use FTP, you can optionally specify the host type. If you use SFTP/SSH,
you can optionally specify the authentication type. If you use SFTP/SSH on Windows, SlickEdit
requires OpenSSH to be installed.

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.

Click OK to close the Add FTP Profile dialog. SlickEdit adds the profile to the list available in
the Connect dialog.

6.

Click Connect. If you are using SFTP/SSH on Windows, SlickEdit confirms the location of your
ssh executable.

7.

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.

The FTP Client


In addition to the FTP tool window, which is used for opening and editing remote files in the editor,
SlickEdit also provides the FTP Client tool window. This tool window is a GUI FTP client you can use
to browse local and remote directories and upload or download files. The FTP Client tool window is
shown in Figure 15-7.

Figure 15-7

304

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 305

Chapter 15: Other Tools


Note that the FTP tool window and FTP Client tool window are two distinct tool windows. They are displayed and hidden independently. However, they are linked, in that they share connection profiles and
open connections. If you open a connection in the FTP tool window, it is available in the FTP Client tool
window, and vice versa.
At the time of writing (i.e., as of SlickEdit 12.0.2), the FTP tool window is activated with activate-ftp
and toggled with toggle-ftpopen. The FTP Client tool window is toggled with toggle-ftp and
appears to have no command simply to activate it. This inconsistency may be remedied in a future
version of SlickEdit. In the meantime, its easy to add the missing activate command:
_command activate_ftpclient() name_info(,VSARG2_EDITORCTL) {
return activate_toolbar(_tbFTPClient_form,_ctl_profile);
}

Using HTTP To Open Web Pages


Its worth noting that as well as using the FTP tool window to browse or edit files via FTP or SSH protocols, you can also open files for browsing via HTTP. The edit command supports http:// URLs as filenames. Thus, for example, you can open the web page of my web site using this command on the
SlickEdit command line:
edit http://www.skepticalhumorist.co.nz/index.html

However, you cannot change or save files opened this way.

The Regex Evaluator


SlickEdit provides the Regex Evaluator tool window, which you can use to test regular expressions in
any of SlickEdits supported styles. You can open the Regex Evaluator tool window via View Toolbars
as with other tool windows. You can also invoke activate-regex-evaluator (WROX: Alt+T followed
by X). The Regex Evaluator tool window is shown in Figure 15-8.
You enter a regular expression into the Regular Expression field, specify options, and enter one or more
test strings in the Test Cases text area. The tool window updates automatically to indicate which test
strings match the expression. In Figure 15-8, the expression matches dates in MM/DD/YYYY format. (It
also matches DD/MM/YYYY.) The delimiters can be slashes or hyphens, and the months and days can
each be one digit or two. The test expressions test most of the possibilities.
The arrows in the left margin indicate matched test strings. The highlighted chunks of the test strings
correspond to matching groups in the expression. The tool window even allows you to save and load
regular expressions and their options and test strings. The data are saved as XML in the file you
specify.

305

22150c15.qxd:WroxPro

9/25/07

1:40 AM

Page 306

Part III: Advanced SlickEdit

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 307

Slick-C Macro Programming


Slick-C is the main tool you use to customize and extend SlickEdit. We have already seen a lot
of Slick-C code in this book. Most of SlickEdits features are implemented in Slick-C. Slick-C
source code is provided with SlickEdit, and you can use it as the basis for your own features. In
this chapter, we take a look at various aspects of the Slick-C language in more detail.
This chapter is not a complete reference for Slick-C. As well as reading this chapter, you should
refer to the online Help for detailed reference information about Slick-C programming. The
Slick-C Macro Programming Guide part of the online Help is also provided in PDF format in
the SlickEdit installation. The installation includes another document Slick-C Macro Conventions
and Best Practices for End Users which is also very useful. Finally, the SlickEdit Community
Forums at http://community.slickedit.com have a section specifically for Slick-C macro
programming.
For really learning Slick-C and SlickEdit customization, nothing beats studying the supplied macro
source code. If you are after extreme SlickEdit customization, you will want to become familiar with
the supplied source code. If you want to understand how a feature works, or perhaps you think
theres a bug in some feature, you can often find out by studying the source code for that feature.
And, when you are trying to write some new function for your own needs, often the best way to
see how to do things is to look for source code for features that do something similar.
In this chapter, we illustrate the usage of Slick-C for typical tasks. We provide code snippets to show
how to work with Slick-C features and useful library functions. To complete the chapter, we provide
several examples of full-length macros for automating tasks within SlickEdit.
For code snippets, Ive adopted a convention of using assertions to illustrate the behavior of Slick-C
features and functions. As of version 12.0.2, SlickEdit provides an assertion facility via the built-in
_assert() function.
An assertion tests a condition and generates an informative stack trace if the condition fails.
Assertions are useful in several aspects of programming, both in test code and live code. In this

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 308

Part III: Advanced SlickEdit


chapter, we will use the facility as a concise and informative way of presenting how Slick-C features
work. For example:
int i1 = 0x80000000;
int i2 = - i1;
_assert(i1 < 0);
_assert(i2 < 0); // anomaly of signed 32 bit integers!

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.

The Slick-C Language


Slick-C itself is a general-purpose language. Its basic features are similar to those found in many other
conventional languages and scripting languages. The libraries are a little different from what you would
find in a general-purpose language. The standard libraries in conventional languages are general-purpose.
Slick-Cs libraries tend to be about editor features.
For example, I/O is typically quite different in Slick-C macro programming from most other languages. To
read a file in most programming languages, you have to call functions to open the file, read bytes or lines,
and then close the file. With SlickEdit, you typically open the file in a buffer using _open_temp_view(),
then work with the contents of the buffer. There are several other peculiarities of working with Slick-C,
and well see some common Slick-C programming idioms in this chapter.
Slick-C is named after C and looks kind of like C, but in many ways it isnt really like C at all. Even though
Slick-C is compiled, it works more like a dynamic scripting language. Data structures in Slick-C are
more dynamic than in typical compiled languages, and the runtime environment is richly dynamic also.
The Slick-C Macro Programming Guide contains a section on the differences between Slick-C and C++.

308

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 309

Chapter 16: Slick-C Macro Programming


A great deal of SlickEdit is implemented in Slick-C. The engine itself, which includes the Slick-C interpreter, is implemented in native code (written mostly in C++). The interface between the Slick-C environment and the engine is via primitive functions and properties. Primitive functions are callable from Slick-C
but are implemented in the engine. These functions are declared in the macro source file builtins.e.
Properties are pseudovariables that provide an interface to attributes of the editor and are described in
the section Properties, below. Figure 16-1 shows the architecture.

Slick-C Code (Supplied and User)

Slick-C Engine

Builtins

SlickEdit executable

Operating System

Figure 16-1

In this section, well take a quick tour of the features of Slick-C.

Modules and Names


When you compile a Slick-C file mymodule.e, the compiled module containing the generated code is
created in a file mymodule.ex. You can unload a module using the unload command, which removes
all the modules definitions from memory. If you want to know what modules youve loaded, check the
contents of the def_macfiles macro variable. It contains a list of user-loaded modules.
The name of a module is determined by the filename of the .e source file alone. The location is not significant. The SlickEdit hot fix system makes use of this fact by placing hot-fixed source files in your
configuration directory, apart from the original product files. This makes it possible for you to switch
between original and hot-fixed modules by loading files from either location as desired.
Take care how you name your own modules. A couple of times while writing this book, I created modules with the same names as macro files provided with SlickEdit: html.e, util.e, and the like. If you
load such a file, SlickEdit replaces all definitions it previously had loaded in the module of that name.
This is a great way to trash your editor. For html.e, this removes or breaks a lot of HTML features. For
util.e, it removes or breaks many basic routines, giving rise to random failures throughout SlickEdit.
Be careful to name your modules uniquely. The best way to do this is to use a standard prefix that is
unlikely to be used by SlickEdit itself. That is why every Slick-C source file accompanying this book
begins with the prefix wrox_.
You need to be careful with the names of your Slick-C commands and functions too. At the time of writing,
Slick-C has no namespace facility. That means that all Slick-C definitions are global. If you define a routine with the same name as one provided by SlickEdit, you will replace its definition with yours, without
warning. Again, the best convention is to use a prefix to ensure that your command and function names
are unique. And similarly, that is why all the commands and functions provided in this book start with
wrox_. Its awkward but safe.

309

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 310

Part III: Advanced SlickEdit


Proposed changes for Slick-C in SlickEdit 2008 include the concept of namespaces. Once namespaces are
added to the language, supplied SlickEdit code will be either in no namespace or in a special SlickEdit
namespace, and user code will be in a different namespace. This will remove the problem as far as functions and commands are concerned. The current plan for namespaces does not change the module system;
thus you will still need to take care to name modules uniquely.
Despite all this, it is certainly not convenient to have all your commands names begin with wrox_ or
any other arbitrary prefix, particularly if you are typing them in. Not only are they unnecessarily long to
type, but features such as auto-completion dont work as effectively when all the commands start with
the same prefix. In the Example Macros section below in this chapter, well look at a macro you can
use, at your discretion, to rename all the wrox_ commands in this book by removing the prefix.

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 311

Chapter 16: Slick-C Macro Programming


Batch macros are not loaded using the load command. They are not stored in the configuration state file,
the way normal modules are. Instead, they are invoked explicitly and forgotten afterward.
You can invoke a batch macro by entering its filename as a command on the command line (with or
without the .e extension). You can specify an absolute or relative path when naming a batch macro to
run. If you do not give a path, then you must have the file in a directory specified in the VSLICKPATH
environment variable. You can also invoke a batch macro from macro code using the execute() function.
We see applications of Slick-C batch macros in Chapter 17, where they are used for programmatic
configuration.

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 312

Part III: Advanced SlickEdit


or defined just as they are in C. An ordinary function can be declared static, which means that it
is private to the current module.

Built-in or primitive functions are implemented in the SlickEdit engine, not in Slick-C. They
are declared in builtins.e, but only as prototypes. You cannot read the source or change their
behavior.

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 313

Chapter 16: Slick-C Macro Programming


Many properties are described in the online Help. They are also categorized from their documentation
comments and can be found in the Macro Functions by Category page (Help Macro Functions by
Category), along with functions. Some useful properties are shown in Table 16-1. Most of these properties apply to an editor control, but some properties apply specifically to other controls.

Table 16-1
Property

Description

p_buf_id

Determines buffer displayed in current window.

p_buf_name

Determines buffer name.

p_buf_size

Returns number of bytes in buffer.

p_caps

Returns True if capitalization mode is on.

p_col

Determines the character column position.

p_DocumentName

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.

p_embedded

Determines embedded language context mode.

p_EmbeddedLexerName

Determines embedded language lexer name.

p_encoding

Determines the default encoding that the buffer will be saved in.

p_encoding_set_by_user

Set to the encoding chosen if the user overrode automatic encoding


processing.

p_extension

Determines extension file type support.

p_hex_field

When in hex mode, determines whether cursor is displayed in hex


nibbles (True) or ASCII data (False).

p_hex_mode

Determines whether text is displayed in hex or ASCII lines. (Use


hex function to switch.)

p_LastModified

Buffer time stamp.

p_lexer_name

Determines lexer name, which defines the language coloring elements for a buffer.

p_line

Determines the current line number.

p_mode_name

Determines the mode name for the current buffer.


continued

313

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 314

Part III: Advanced SlickEdit


Table 16-1 (continued)
Property

Description

p_modify

Determines whether the current buffer is modified.

p_newline

Returns the new line characters used for the current buffer.

p_Nofhidden

Returns the total number of hidden lines in the current buffer.

p_Noflines

Returns the number of lines in the current buffer.

p_sel_length

Determines the length of a selection in bytes.

p_sel_start

Determines the position of the left-most character of a selection.

p_UTF8

Determines whether the buffers data are UTF-8.

p_window_id

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 315

Chapter 16: Slick-C Macro Programming


Long integers use a 32-bit representation up to 231 1. They preserve exact decimal accuracy up to 32
decimal digits and then switch to a floating-point representation beyond that:
long n1 = 99999999;
n1 = n1 * 100000000 + 99999999;
n1 = n1 * 100000000 + 99999999;
n1 = n1 * 100000000 + 99999999; // 32 9s
long n2 = n1 + 1; // 1 plus 32 0s
long n3 = n2;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1;
n3 = n3 + 1; // 1 plus 30 0s plus 10? Nope, lost precision.
wrox_assert_equals(n3, n2);
wrox_assert_equals(0x4EE2D6D415B85ACEF80FFFFFFFF, dec2hex(n1));
wrox_assert_equals(99999999999999999999999999999999, n1);
wrox_assert_equals(, dec2hex(n2));
wrox_assert_equals(1.0000000000000000000000000000000E+32, n2);
wrox_assert_equals(, dec2hex(n3));
wrox_assert_equals(1.0000000000000000000000000000000E+32, n3);

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 316

Part III: Advanced SlickEdit


backslashes are not used to escape characters in the string. To include a single quote within a string
delimited by single quotes, use a repeated single quote.
wrox_assert_equals(\, ); // double quote in string
wrox_assert_equals(, ); // single quote in string
wrox_assert_equals(\\, \); // backslash in string

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

Here are some more examples of useful functions with strings:


wrox_assert_equals(65, _asc(A));
wrox_assert_equals(A, _chr(65));
wrox_assert_equals(TOM THUMB, upcase(tom thumb));
wrox_assert_equals(the giant, lowcase(THE GIANT));
wrox_assert(strieq(ABC, abc));
wrox_assert_equals(wrox-execute-current-command,
translate(wrox_execute_current_command, -, _));
wrox_assert_equals(www.skepticalhumorist.co.nz,
stranslate(http://www.skepticalhumorist.co.nz,
, (http|ftp)://, U));

316

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 317

Chapter 16: Slick-C Macro Programming


There are several functions especially useful for working with filenames:
_str filename = C:\Documents and Settings\jhurst\trythis.c;
wrox_assert_equals(C:\Documents and Settings\jhurst\trythis.c, filename);
wrox_assert_equals(C:\Documents and Settings\jhurst\trythis.c,
maybe_quote_filename(filename));
wrox_assert_equals(trythis.c, strip_filename(filename, P));
wrox_assert_equals(\Documents and Settings\jhurst\trythis.c,
strip_filename(filename, D));
wrox_assert_equals(C:\Documents and Settings\jhurst\trythis,
strip_filename(filename, E));
wrox_assert_equals(C:\Documents and Settings\jhurst\,
strip_filename(filename, N));
wrox_assert_equals(c, get_extension(filename));

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;
}

And here are a couple of examples of using these functions:


wrox_assert_equals(http,
wrox_leftstr(http://www.skepticalhumorist.co.nz, 4));
wrox_assert_equals(000123,
wrox_rightstr(123, 6, 0));

317

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 318

Part III: Advanced SlickEdit


Parsing Strings
Slick-C uses a powerful and unusual construct for parsing strings, which it borrowed from the IBM
mainframe scripting language REXX. If you have worked with scripting languages, you are probably
used to using regular expressions for string parsing. Slick-C provides the parse with keywords for
string parsing. Heres an example:
_str s = 2007-05-19;
_str yyyy, mm, dd;
parse s with yyyy-mm-dd;
wrox_assert_equals(2007, yyyy);
wrox_assert_equals(05, mm);
wrox_assert_equals(19, dd);

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;
// ...
}

The user can invoke this command like this:


wrox-try-parse-command one two

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 319

Chapter 16: Slick-C Macro Programming


Although literal strings and output variables are the most common features used in parse with templates, several other features are supported. Table 16-2 shows the elements that can be contained in the
template.

Table 16-2
Item

Description

variable_name

Output variable.

Null output variable (match ignored).

nnn

New parse column.

+nnn

Parse column increment.

-nnn

Parse column decrement.

text[,search_options]

String constant or pattern to search for.

(expression)[,search_options]

String expression to search for.

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 320

Part III: Advanced SlickEdit


Table 16-3
Character

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 321

Chapter 16: Slick-C Macro Programming


a[a._length()] = two;
a[a._length()] = three;
a[a._length()] = four;
wrox_assert_equals(4, a._length());
wrox_assert_equals(one, a[0]);
wrox_assert_equals(two, a[1]);
wrox_assert_equals(three, a[2]);
wrox_assert_equals(four, a[3]);

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 322

Part III: Advanced SlickEdit


If you want to iterate over the elements in a hash table, the syntax is a little stranger, because you have to
use a typeless iterator for the keys and use several built-in functions for the iteration:
typeless k;
_str a[];
for (k._makeempty();;) {
h._nextel(k);
if (k._isempty()) {
break;
}
a[a._length()] = k :+ : :+ h:[k];
}
a._sort();
wrox_assert_equals(first:one, a[0]);
wrox_assert_equals(second:two, a[1]);
wrox_assert_equals(third:three, a[2]);

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 323

Chapter 16: Slick-C Macro Programming


Structs
Structs are familiar to C programmers, and a similar language feature is available in most other languages. Slick-C structs are much the same as in C.
struct NAMES {
_str first_name;
_str last_name;
};

As with arrays and hash tables, you can declare and initialize structs globally:
NAMES name = {
John,
Hurst
};

You can use structs to build up arbitrarily complex data structures:


struct NAMES_LIST {
NAMES head;
NAMES_LIST tail;
};

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.

Typeless Container Variables


As seen with hash table iterators, Slick-C supports a typeless type. Variables declared as typeless can
hold values from any type, including structs, arrays, and hash tables.
If you need to, you can determine the actual type of value currently stored in a typeless variable using its
_varformat() member function, declared in builtins.e. The function returns one of the VF_ constants
defined in slick.sh.
_str wrox_typeless_type(typeless v) {
switch (v._varformat()) {
case VF_ARRAY:
return ARRAY;
case VF_EMPTY:
return EMPTY;
case VF_FREE:
return FREE; // shouldnt happen!
case VF_FUNPTR: return FUNPTR;
case VF_HASHTAB: return HASHTAB;
case VF_INT:
return INT;
case VF_LSTR:
return LSTR;
case VF_PTR:
return PTR;
default: return UNKNOWN;
}

323

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 324

Part III: Advanced SlickEdit


}
_str a[];
a[0] = one;
a[1] = two;
typeless e = null;
_str h:[];
h:[one] = 1;
h:[two] = 2;
int i = 1;
_str s = Hello;
wrox_assert_equals(ARRAY,
wrox_assert_equals(EMPTY,
wrox_assert_equals(HASHTAB,
wrox_assert_equals(INT,
wrox_assert_equals(LSTR,

wrox_typeless_type(a));
wrox_typeless_type(e));
wrox_typeless_type(h));
wrox_typeless_type(i));
wrox_typeless_type(s));

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 325

Chapter 16: Slick-C Macro Programming


The for() statement is usually used for loops involving a known number of iterations:
int sum = 0;
int i;
for (i = 0; i < 10; i++) {
sum += i;
}
wrox_assert_equals(45, sum);

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 326

Part III: Advanced SlickEdit


case APRIL: mm = 4; break;
case MAY: mm = 5; break;
case JUNE: mm = 6; break;
case JULY: mm = 7; break;
case AUGUST: mm = 8; break;
case SEPTEMBER: mm = 9; break;
case OCTOBER: mm = 10; break;
case NOVEMBER: mm = 11; break;
case DECEMBER: mm = 12; break;
default: message(Unknown month: month); _StackDump();
}
wrox_assert_equals(5, mm);

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.

Declarations and Definitions


A Slick-C module is made up of declarations and definitions. In this section, well cover how you declare
some elements of Slick-C programs:

Functions.

Commands.

Variables.

Event Tables.

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 327

Chapter 16: Slick-C Macro Programming


Because Slick-C does not support overloaded functions, you can define any given function name only
once. This is not a limitation in practice because default arguments and variable arguments are supported;
thus it is possible to simulate overloaded functions by treating arguments flexibly.
Specify default arguments by assigning them in the function signature, like this:
_str wrox_leftstr(_str string, int len, _str pad= ) {
// ...
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 328

Part III: Advanced SlickEdit


Commands
Commands can be bound to keys or run on the command line; ordinary functions cannot.
Another difference between commands and ordinary functions is that the naming rules are relaxed for
commands; thus they can include special characters not normally allowed in function names. This is
how the names for some of the special SlickEdit commands work. For example, the find command is
declared like this:
_command int find,l,/(argument list) {
...

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

Description

COMMAND_ARG

The command takes a SlickEdit command name as an argument.

BOOKMARK_ARG

The command takes a bookmark name as an argument.

FILE_ARG

The command takes a filename.

DIR_ARG

The command takes a directory.

TAG_ARG

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 329

Chapter 16: Slick-C Macro Programming


it. Append an asterisk (*) character to the argument parameter if the command can take one or more
arguments.
You can make your commands prompt for their arguments using the handy prompt() function defined
in stdprocs.e. Suppose you have a command that takes a filename argument. Write the command
like this:
_command void wrox_try_prompt_filename(_str filename=) name_info(FILE_ARG,) {
filename = prompt(filename, Filename);
// ... rest of command
}

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

Description

VSARG2_CMDLINE

The command is supported on the command line.

VSARG2_EDITORCTL

The command is supported in an editor control.

VSARG2_READ_ONLY

The command is allowed in read-only mode.

VSARG2_REQUIRES_EDITORCTL

The command requires an editor control.

VSARG2_REQUIRES_AB_SELECTION

The command requires a selection in the active buffer.

VSARG2_REQUIRES_SELECTION

The command requires a selection.

329

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 330

Part III: Advanced SlickEdit


For example, consider the wrox-save-line-sel command given in Chapter 8. The purpose of the
command is to save the given line selection as a pair of bookmarks. The definition has a name_info()
expression specified like this:
_command void wrox_save_line_sel(_str bookmark = SELECTION)
name_info(,VSARG2_REQUIRES_AB_SELECTION) {
// ...
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 331

Chapter 16: Slick-C Macro Programming


Technically, macro variables are just global Slick-C variables. Most of them are declared in slick.sh.
Some commands work specifically with macro variables, by filtering on the def_ naming convention.
For example, list-config lists the contents of macro variables but not other global variables.

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

Description

argument_completion_keys

Argument completion.

auto_complete_keys

When Auto-Complete active.

fileman_keys

File Manager.

grep_keys

Search Results tool window.

process_keys

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.

Wor king with Macros


The above sections have covered some of the elements of the Slick-C language and common routines.
In this section, we take a look at techniques for working with macros themselves: the mechanics of executing them, terminating them, and debugging them. You should find some of this information useful
when you are developing or debugging your own macro code.

331

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 332

Part III: Advanced SlickEdit

Executing Slick-C Code


When you are developing macro code, you will want to run it frequently. The normal way to run some
Slick-C code is to invoke a command. You can obviously test your macros by running them on the command line or by binding commands to keys. If you have several different commands and functions, it
may not be feasible to set up key bindings for them all, but command retrieval on the command line is
often an effective way to test macro code repeatedly.
If you have a set of lines in the buffer, containing SlickEdit commands, you can execute them by selecting them and invoking execute-selection (Alt+equals). Its not exactly a graphical debugger, but its
pretty handy for quick macro development.
If you are working on a command and wish to execute it, the execute-selection command is not the
fastest way. You need to have the command name by itself on a line in the buffer to use execute-selection,
and this is not usually the case. (For one thing, if you put it in the same .e file as the command youre
working on, the file becomes invalid to compile.)
Instead, you can try this macro:
_command void wrox_execute_current_command()
name_info(,VSARG2_REQUIRES_EDITORCTL|VSARG2_READ_ONLY) {
execute(current_proc());
message(Command [current_proc()] executed successfully.);
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 333

Chapter 16: Slick-C Macro Programming


The messageNwait() function is a variation that pauses after displaying the message and waits for the
user to press a key:
messageNwait(Hello, World.

Press a key to continue.)

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 334

Part III: Advanced SlickEdit


}
void wrox_stacktrace2() {
_str a = arg(1) + 1;
}

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.

Finding Slick-C Objects


If you need to find a particular Slick-C command or function, use the find-proc command (shorthand
fp). The command opens the module in which the function is defined and navigates to the definition.
You can use this command at any time you dont have to be working in a Slick-C file or workspace.
The Slick-C environment stores all global objects in a single name table. The name table holds the names
of all functions, commands, variables, and other objects. In macro code, you can find out about objects in
the Slick-C global namespace using the find_index() function. For example, you can test whether a
command with a given name exists like this:
if (find_index(command, COMMAND_TYPE)) {
message(Command command exists.);
}

334

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 335

Chapter 16: Slick-C Macro Programming


else {
message(Command command does not exist.);
}

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;
}

This snippet illustrates the usage of the function:


int indexes[];
indexes = wrox_find_matching_name_indexes(cursor_, COMMAND_TYPE|PROC_TYPE);
wrox_assert_equals(7, indexes._length());
wrox_assert_equals(cursor-down, name_name(indexes[0]));
wrox_assert_equals(cursor-up, name_name(indexes[1]));
wrox_assert_equals(cursor-left, name_name(indexes[2]));
wrox_assert_equals(cursor-right, name_name(indexes[3]));
wrox_assert_equals(cursor-error2, name_name(indexes[4]));
wrox_assert_equals(cursor-error, name_name(indexes[5]));
wrox_assert_equals(cursor-shape, name_name(indexes[6]));

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 336

Part III: Advanced SlickEdit


The types of objects you can query in the names table are defined in slick.sh and shown in Table 16-7.

Table 16-7
Type

Description

PROC_TYPE

Matches global function.

VAR_TYPE

Matches global variable.

EVENTTAB_TYPE

Matches event table.

COMMAND_TYPE

Matches command.

MODULE_TYPE

Matches module.

PICTURE_TYPE

Matches picture.

BUFFER_TYPE

Matches buffer.

OBJECT_TYPE

Matches object.

MISC_TYPE

Matches miscellaneous.

IGNORECASE_TYPE

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 337

Chapter 16: Slick-C Macro Programming

Interacting with the Buffer


One of the most fundamental things you need to do in a Slick-C macro is interact with the buffer.
Obviously, all the commands weve looked at elsewhere in the book and in this chapter are accessible
to any Slick-C macro. There is no shortage of ways for a macro to move around the buffer and to move
and copy text. Sometimes a macro needs to be able to examine the text in the buffer, and macros often
need to be able to enter text themselves.
A macro can read text from the buffer using the primitive function get_text().The get_text() function
returns a chunk of text from the buffer. It takes two arguments: a character count and a seek position,
both of which are optional:
get_text(10, 8); // gets 10 characters from position 8
get_text(10);
// gets 10 characters from the cursor position
get_text();
// gets the character at the cursor position

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

To insert text, a macro can use the _insert_text() function:


_insert_text(;);

// inserts a semicolon at the cursor position

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 338

Part III: Advanced SlickEdit


may have unintended side effects. For example, find changes the search performed by find-next, and
it can change the selection too. Usually, a macro shouldnt affect these features unless that is its specific
purpose. Instead, you can invoke the lower-level search() function from macro code, which is not
available directly as a command. Invoking search() in your macro code is less disruptive to the users
environment because it doesnt affect the same settings that find does. In fact, you can study the implementation of find: It uses search() internally. The search() function is built in and is not implemented in Slick-C.
The search() function returns a status that indicates the success of the search. A status of 0 indicates a
successful search; other statuses indicate that nothing was found or that there was a problem with the
search criteria. To write a macro that does something for each match, follow this pattern in your code:
int status = search(string, options);
while (!status) {
// do something at the search match
status = repeat_search();
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 339

Chapter 16: Slick-C Macro Programming


There is a convenient utility function, get_match_text(), which is a shorthand for get_text() with
match_length():
message(Created date = get_match_text(1));

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 340

Part III: Advanced SlickEdit


One advantage of using a special temporary buffer rather than simply opening a new empty file is that
the temporary buffer is not displayed while your macro is running.
This snippet illustrates the use of the _create_temp_view(), _delete_temp_view(), and
activate_window() functions to work with a temporary buffer:
int temp_view_id;
int orig_view_id = _create_temp_view(temp_view_id);
// do something with the temporary buffer ...
_delete_temp_view(temp_view_id);
activate_window(orig_view_id);

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.

Listing Files and Directories


Weve already mentioned that I/O in Slick-C is different from that in most programming languages.
Rather than opening a file, reading its contents in some kind of loop, and then closing it, you simply
load the file into a buffer and work on it in the buffer.
Listing files and directories is similar. Rather than using special I/O functions to iterate through lists of
files and directories, SlickEdit provides the built-in function insert_file_list(), which simply inserts
names and attributes of files and directories into the buffer. You can then work with the list in the buffer
as required.
The insert_file_list() function takes a single string argument, which contains the filespec for files
to insert, but also can contain several additional options. Most of the options are single letters preceded
by + or -, to turn on or off certain features. These are documented in the online Help, and the more common ones are also shown in Table 16-8. In addition, the string argument can include -exclude with a
list of file patterns to exclude.

Table 16-8

340

Option

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.

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 341

Chapter 16: Slick-C Macro Programming


Table 16-8 (continued)
Option

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 342

Part III: Advanced SlickEdit


The main part of the function iterates through each line in the temporary buffer, adding the contents of
the line to the result array. Before an item is added to the result array, the function calls maybe_quote_
filename() on it to ensure that it is quoted if it contains spaces. This is one reason the macro wouldnt
work with additional data such as size, date, and attributes. They would be surrounded by quotes,
which would not be appropriate. If you need a version of wrox_list_files() that includes size, date,
and attributes, you can expand on this function, possibly using a struct to store the results.

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.

Useful Macro Files


Most of the supplied macro source deals with specific SlickEdit functionality. When you are interested in
a particular feature, it is usually not hard to find the source file(s) containing code pertaining to that feature. For example, CVS-related code is unsurprisingly located in cvs.e, cvsquery.e, and cvsutil.e.
The commands and functions supporting the Ruby language are in ruby.e.
There are several files that contain useful global declarations or general-purpose functions. Weve already
discussed most of these files and many of their declarations in this chapter. You may find it useful to
peruse some of these files in more detail, for example, to discover additional code not described in this
book. Table 16-9 lists some of the most useful general-purpose macro files in the supplied source.

342

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 343

Chapter 16: Slick-C Macro Programming


Table 16-9
File

Description

builtins.e

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.

main.e

Declares many macro variables, provides default values.

stdcmds.e

Defines many standard commands, e.g., undo, redo, nosplit-insert-line,


begin-line, top-of-buffer.

stdprocs.e

Defines many standard functions, e.g., abs(), strip_filename(),


maybe_quote_filename(), path_exists(), _create_temp_view(),
_delete_temp_view().

util.e

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.

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 344

Part III: Advanced SlickEdit

New name.

Flags.

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

344

Name

Event

Arguments

_actapp_

Application activated (such as


getting focus).

Whether getting focus.

_buffer_add_

New buffer opened.

Buffer ID, buffer name, buffer


flags.

_buffer_renamed_

Buffer renamed.

Buffer ID, buffer name, new


name, buffer flags.

_cbquit_

About to quit file.

Buffer ID, buffer name, filename,


buffer flags.

_cbquit2_

After quit file.

Buffer ID, buffer name, filename,


buffer flags.

_cbsave_

File saved.

(none)

_cbstop_process_

Stopping build.

(none)

_cd_

Directory changed.

New directory.

_diffOnExit_

End of DIFFzilla operation.

(none)

_diffOnStart_

Start of DIFFzilla operation.

(none)

_document_renamed_

Document name changed.

Buffer ID, old name, new name,


buffer flags.

_eventtab_modify_

Key bound.

Key binding table, key.

_gotfocus_

Received focus.

(none)

_lostfocus_

Lost focus.

(none)

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 345

Chapter 16: Slick-C Macro Programming


Table 16-10 (continued)
Name

Event

Arguments

_onexit__

Exit.

(none)

_postbuild_

Build completed.

Build arguments.

_prebuild_

Build about to start.

Build arg 1 (see source in compile.e).

_prjclose_

Closing project (but fired only


if not saving state during auto
restore see source in
wkspace.e).

(none)

_prjconfig_

Active configuration changed.

(none)

_prjedit_

Project properties edited.

(none)

_prjopen_

Opening project.

(none)

_prjupdate_

Project saved.

(none)

_project_close_

Closing project.

Project name.

_project_file_add_

File added to project.

Project name, filename.

_switchbuf_

Switching buffer.

Old buffer name, option, old


pos, old buffer ID.

_wkspace_close_

Closing workspace.

(none)

_workspace_file_add_

File added to workspace.

Project name, filename.

_workspace_opened_

Opening workspace.

(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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 346

Part III: Advanced SlickEdit


The function does three things:

It calls all callbacks whose names start with _buffer_renamed, passing the buffer ID, the old
buffer name, the new buffer name, and the buffer flags.

It changes the buffer name (p_buf_name) to the new name.

It resets the document name by calling docname(). (The document name is used when the
display name of a buffer is not a valid filename, e.g., for http:// files.)

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 347

Chapter 16: Slick-C Macro Programming

Example: Counting Duplicate Lines


SlickEdit has a nice command for removing adjacent duplicate lines in a selection: remove-duplicates.
Occasionally, as well as removing the duplicates you need to know how many there were. The macro
command below removes duplicates and appends the counts for each line to the end of the line:
_command void wrox_count_duplicates(_str ignore_case = )
name_info(,VSARG2_REQUIRES_EDITORCTL|VSARG2_REQUIRES_AB_SELECTION) {
if (_select_type() :!= LINE) {
message( Command needs a line mark );
return;
}
ignore_case = upcase(ignore_case) == I;
// initialize variables
int entry = 0;
_str key[];
int data[];
key[entry] = ;
data[entry] = 0;
int max_keylen = 0;
int max_datalen = 0;
// go through marked lines
filter_init();
for (;;) {
_str line;
int status = filter_get_string(line);
if (status) {
break;
}
boolean matched = ignore_case ?
strieq(key[entry], line) :
key[entry] :== line;
if (matched) {
// duplicate: increment count
data[entry]++;
if (length(data[entry]) > max_datalen) {
max_datalen++;
}
}
else {
// new entry: add to table, start count at 1
if (data[entry] > 0) {
entry++;
}
key[entry] = line;
if (length(line) > max_keylen) {
max_keylen = length(line);
}
data[entry] = 1;
}
}

347

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 348

Part III: Advanced SlickEdit


filter_restore_pos();
// delete the selection
delete_selection();
cursor_up();
// insert the aggregate (formatted neatly)
int i;
for (i = 0; i < key._length(); i++) {
insert_line(wrox_left(key[i], max_keylen) :+ :+
wrox_rightstr(data[i], max_datalen));
}
}

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

The result looks like this:


one
1
two
2
three 3
ten
10

Like SlickEdits remove-duplicates command, this command takes an optional string parameter
which, if I, causes the macro to compare lines case-insensitively.

Example: Inserting HTML End Tag


SlickEdit has considerable HTML and XML support these days, and more is added with every release.
For example, when you type a start tag such as <ul> or <li>, SlickEdit automatically adds the end tag,
usually in the correct place and indented to your preferences. However, for whatever reason, I still find

348

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 349

Chapter 16: Slick-C Macro Programming


that I often delete the end tags inserted by SlickEdit, then need to type them in again, perhaps in a different location. Some IDEs and other products automatically insert closing tags when you type the </ of a
closing tag, but SlickEdit doesnt do that (yet). Therefore, I have a macro I wrote some time ago thats
still useful:
static int wrox_optional_hmtl_tags:[] = {
base
=> 1,
basefont => 1,
bgsound => 1,
br
=> 1,
frame
=> 1,
hr
=> 1,
img
=> 1,
input
=> 1,
isindex => 1,
link
=> 1,
meta
=> 1,
nextid
=> 1,
param
=> 1,
plaintext=> 1,
spacer
=> 1,
wbr
=> 1
};
_command void wrox_insert_html_ending_tag() name_info(,MACRO_ARG2|MARK_ARG2) {
_str tagexp = <(/?(\:c|[0-9]|-|_|:)+)([^>]*)>;
int nesting = 0;
int status = 0;
int start_line = p_line;
int start_col = p_col;
push_bookmark();
status = search(tagexp, U<-); // search backwards for HTML/XML tag
if (!status && p_line == start_line &&
p_col == start_col) {
// search didnt move us
status = repeat_search();
// doesnt count, search again
}
_str nesting_stack[];
_str tag;
while (!status) {
tag = get_text(match_length(1), match_length(S1));
_str endchar = get_text(match_length(3), match_length(S3));
if (wrox_leftstr(tag, 1) == /) {
// end tag
nesting_stack[nesting++] =
wrox_rightstr(tag, length(tag) - 1);
// add it to nesting stack
}
else if (wrox_rightstr(endchar, 1) == /) { // self-contained tag like <tag/>
// ignore
}
else { // start tag
if (wrox_optional_hmtl_tags:[lowcase(tag)] == 1) { // end-tag is optional
if (nesting > 0 &&
tag == nesting_stack[nesting - 1]) {
// matched start: pop it
nesting--;
}

349

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 350

Part III: Advanced SlickEdit


}
else { // otherwise end-tag not optional
if (nesting == 0) {
// a start tag with zero nesting; were done
break;
}
else {
if (tag == nesting_stack[nesting - 1]) { // matched nested end-tag
nesting--;
}
else { // unmatched
message(Found unmatched tag < :+ tag :+ >);
return;
}
}
}
}
status = repeat_search();
} // end while
if (status) {
message(Couldnt find a tag.);
return;
}
int tag_line = p_line;
int tag_col = p_col;
pop_bookmark();
_str line;
get_line(line);
line = strip(line);
if (p_line != tag_line) { // match is on different line from cursor:
insert_line(); // add a new line for end tag
p_col = tag_col;
}
_insert_text(</ :+ tag :+ >); // insert the end tag
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 351

Chapter 16: Slick-C Macro Programming


</head>
<body>
<p>Paragraph.</p>
<p>Paragraph.
<img src=xxx>xxx
<table >
<tr>
<td>
<ul>
<li>one

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.

Example: Moving Lines Up and Down


I often find that I want to change the order of lines in the buffer. The usual way to do this is to use copy
and paste, or perhaps to mark a line selection and move it. These methods are a little awkward for reordering a lot of lines. The macros below can be used to move lines up or down conveniently in the buffer.
If there is a character or line selection, the macros move the selection; otherwise, they move the current
line. For a character selection, the macros first convert it to a line selection, using the wrox-to-lineselection command:
_command void wrox_to_line_selection() name_info(,) {
push_bookmark();
begin_select();
push_bookmark();

351

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 352

Part III: Advanced SlickEdit


end_select();
if (p_col == 1) {
cursor_up();
}
select_line();
pop_bookmark();
select_line();
pop_bookmark();
}

The move commands themselves are given below:


_command void wrox_move_line_up(_str commandline=1) name_info(,) {
int n = (int) commandline;
int i;
int orig_col = p_col;
if (_select_type() == CHAR) {
message(selection changed);
wrox_to_line_selection();
}
if (_select_type() == LINE) {
begin_select();
cursor_up(n + 1);
move_to_cursor();
}
else {
_str line;
get_line(line);
_delete_line();
cursor_up(n + 1);
insert_line(line);
}
p_col = orig_col; // restore column position
}
_command void wrox_move_line_down(_str commandline=1) {
int n = (int) commandline;
int i;
int orig_col = p_col;
if (_select_type() == CHAR) {
message(selection changed);
wrox_to_line_selection();
}
if (_select_type() == LINE) {
end_select();
cursor_down(n);
move_to_cursor();
}
else {
_str line;
get_line(line);
_delete_line();
cursor_down(n - 1);
insert_line(line);

352

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 353

Chapter 16: Slick-C Macro Programming


}
p_col = orig_col;

// restore column position

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.

Example: Callback Traces


The code in this example requires code in wrox_list_files.e and wrox_hashes.e to be loaded.
Above in the chapter, we covered SlickEdit callbacks and showed how you could add trace callbacks to
understand when callbacks are called. The trace callbacks followed a simple pattern:
void _switchbuf__trace() {
say(_switchbuf_ called);
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 354

Part III: Advanced SlickEdit


callbacks:[callback] = 1;
status = search(CALL_LIST_PATTERN, U@>);
}
_delete_temp_view(temp_view_id);
activate_window(orig_view_id);
}
return wrox_hash_keys(callbacks);
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 355

Chapter 16: Slick-C Macro Programming

Example: WROX Function Names


The code in this example requires code in wrox_list_files.e to be loaded.
Throughout this book, all the example macros have been contained in files with names beginning with
wrox_. The command and function names themselves (and even the global variables) also begin with
wrox_. This has been done to ensure that there is no clash with supplied Slick-C macro names. As

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 356

Part III: Advanced SlickEdit


_str short_name = get_text(match_length(1), match_length(S1));
if (find_index(short_name, WROX_TYPES)) { // check whether short name already
in use
message(short_name (filename) already exists!);
pop_bookmark();
return;
}
status = search(WROX_FUNCTION_NAME, U@>);
}
// if we get here all names in the file are OK
top();
deselect();
search(#include );
// skip down to first #include line
search($[ \t]*^, U>); // skip down to following blank line
select_line();
// start mark here
bottom();
select_line();
// mark to rest of file
activate_window(orig_view_id);
bottom();
push_bookmark();
copy_to_cursor();
// copy/append data into this file
deselect();
replace(WROX_FUNCTION_NAME, \1(, U*>); // remove wrox_ from function names
pop_bookmark();
replace(WROX_DEF, def \1=\2;, U*>);
// remove wrox_ from keyboard defs
insert_line();
_delete_temp_view(temp_view_id);
}
pop_bookmark();
message(Files processed: file_count);
}

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 357

Chapter 16: Slick-C Macro Programming

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 358

Part III: Advanced SlickEdit


}
boolean wrox_queens_ok(int row, int col) {
int size = wrox_queens_size();
return !(q_col[col] || q_diag1[col - row + size] || q_diag2[col + row]);
}
boolean wrox_queens_solve() {
int row = 0;
int col = 0;
int size = wrox_queens_size();
while (row >= 0 && row < size) {
while (col < size && !wrox_queens_ok(row, col)) {
col++;
}
if (col < size) {
wrox_queens_place(row, col);
row++;
col = 0;
}
else {
row--;
if (row >= 0) {
col = wrox_queens_unplace(row) + 1;
}
}
}
return row == size;
}
void wrox_queens_print() {
int size = wrox_queens_size();
int i;
for (i = 0; i < size; i++) {
insert_line(wrox_rightstr(*, wrox_queens_col(i) + 1));
}
}
_command void wrox_queens(int size=4) name_info(,VSARG2_REQUIRES_EDITORCTL) {
wrox_queens_init(size);
int start_time = (int) _time(B);
if (wrox_queens_solve()) {
int end_time = (int) _time(B);
wrox_queens_print();
int elapsed_seconds = (end_time - start_time) / 1000;
message(Board size size solved, took elapsed_seconds seconds.);
}
else {
message(Board size size not solved.);
}
}

358

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 359

Chapter 16: Slick-C Macro Programming

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

22150c16.qxd:WroxPro

9/25/07

1:44 AM

Page 360

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 361

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.

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 362

Part III: Advanced SlickEdit

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.

Example: Joining Lines


The WROX emulation binds the useful command join-line to Alt+J. The join-line command has
special handling for comments, to remove delimiters so that they flow correctly after joining lines. For
ordinary lines, the behavior is simpler. It removes any leading spaces from the line below and joins it to

362

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 363

Chapter 17: Customization


the current line. If the cursor is at or beyond the end of the current line, the line is joined at the cursor
position. Otherwise, it is joined at the end of the current line.
I find I often use join-line with data or text files, and in this case when I join lines, I need to make sure
the contents of the two lines are still separated by white space. To do this with the original join-line,
I need to move the cursor to one character after the end of the first line before invoking join-line.
Needless to say, this is inconvenient. A better solution is to write a wrapper for join-line:
_command void wrox_join_line_with_space() name_info(,VSARG2_REQUIRES_EDITORCTL) {
push_bookmark();
int orig_col = p_col;
end_line();
if (p_col > orig_col) {
cursor_right();
}
else {
p_col = orig_col;
}
join_line();
pop_bookmark();
}

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;

Example: Tabbing Behavior


In this example, well change the behavior of Tab and Shift+Tab. The normal behavior of the Tab key in
SlickEdit depends on the file type, the position of the cursor, and user extension settings. Generally, when
editing code, if the cursor is in the beginning part of the line (before the first non-whitespace), the Tab
key indents the line according to syntax rules. When the cursor is not in the leading whitespace, or for
files that are not source code, the Tab key adds space or tabs up to the next tab stop.
Rather than following arbitrary tab stops, I find a more useful behavior for the Tab (and Shift+Tab) keys
is to follow the positions of items in the line above. That is, the Tab key moves the cursor under the next
non-whitespace character on the line above, and the Shift+Tab key moves the cursor under the character
after the previous whitespace character on the line above.
This works well for typing data into columns, or even code where you have some items, for example,
array initializations, lined up in columns. Another example is when you have line comments starting in
the same column on several adjacent lines. Having Tab and Back-Tab configured to follow the fields above
makes it very quick to jump to the correct column for the next line comment. The example macros below
show how to achieve this.
These macros are not intended for text files using real tab characters. For such files, the relationship
between column positions on one line and another is complicated and depends on tab settings.
_command void wrox_tab_matchtabs() {
if (p_line < 2) { // no line above
ctab();

363

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 364

Part III: Advanced SlickEdit


return;
}
cursor_up();
_str line_above;
get_line(line_above);
cursor_down();
_str remainder_above = strip(substr(line_above, p_col), T);
if (length(remainder_above) <= 1) { // no more non-whitespace above
ctab();
return;
}
int first_space = pos([ \t], remainder_above, 1, U); // Unix regexp
if (first_space == 0) {
// no more spaces; skip to end
first_space = length(remainder_above);
}
int first_nonspace = pos([^ \t], remainder_above, first_space, U);
p_col += first_nonspace - 1;
}
_command void wrox_backtab_matchtabs() {
if (p_line < 2) { // no line above
cbacktab();
return;
}
cursor_up();
_str line_above;
get_line(line_above);
cursor_down();
_str remainder_above = substr(line_above, 1, p_col - 1);
if (length(strip(remainder_above)) <= 1) { // no more non-whitespace above
cbacktab();
return;
}
int last_nonspace =
lastpos([^ \t], remainder_above, p_col, U); // Unix regexp
if (last_nonspace == 0) { // all spaces; normal backtab
cbacktab();
return;
}
int last_space = lastpos([ \t], remainder_above, last_nonspace, U);
p_col = last_space + 1;
}

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 365

Chapter 17: Customization


macros are compatible with this behavior. Youll get the indenting behavior if it applies; otherwise,
youll get the tab-matching behavior of these macros.
The wrox_tab_matchtabs and wrox_backtab_matchtabs commands are inspired by the
matchtabs setting in the EPM editor, another descendent of the E line that SlickEdit came from. This
is reflected in their names.
By the way, all this customization of the Tab and Shift+Tab keys might leave you wondering how you
type in a tab character. When file formats require tab characters, you have to enter them. Makefiles are a
classic example. However, SlickEdit handles Makefiles specially via its Makefile mode, thus when you
type Tab on a blank line or after a make target, you get a tab character. To force a tab character in other
files, you can use quote-key (Ctrl+Q) followed by the Tab key.
Im of the school of thought that believes you shouldnt put tab characters into source code because they
cause more harm than good. Different editing tools treat tabs differently, and using tabs can make it hard
to share files across tools. Spaces are universal and unambiguous. Because tools such as SlickEdit indent
automatically, there is no extra typing overhead to using spaces. Obviously, if you think differently, you
can configure SlickEdit to use tab characters its up to you.

Custom Language Suppor t


SlickEdit supports a large number of languages out of the box. As of SlickEdit 12, there are about 70 modes
and 80 lexers defined. You can easily add color syntax highlighting and some other features for languages
not supported with the base product.

Example: Portable Game Notation Files


Lets start with a simple example. Portable Game Notation (PGN) is a file format used to represent chess
games. Its used for storing games and loading them into chess programs. An example of a file in PGN
format is shown here:
[Event F/S Return Match]
[Site Belgrade, Serbia JUG]
[Date 1992.11.04]
[Round 29]
[White Fischer, Robert J.]
[Black Spassky, Boris V.]
[Result 1/2-1/2]
1.e4 e5 2.Nf3 Nc6 3.Bb5 {This opening is called Ruy Lopez.} a6 4.Ba4 Nf6
5.O-O Be7 6.Re1 b5 7.Bb3 d6 8.c3 O-O 9. h3 Nb8 10.d4 Nbd7 11.c4 c6
12.cxb5 axb5 13.Nc3 Bb7 14.Bg5 b4 15.Nb1 h6 16.Bh4 c5 17.dxe5 Nxe4
18.Bxe7 Qxe7 19.exd6 Qf6 20.Nbd2 Nxd6 21.Nc4 Nxc4 22.Bxc4 Nb6 23.Ne5
Rae8 24.Bxf7+ Rxf7 25.Nxf7 Rxe1+ 26.Qxe1 Kxf7 27.Qe3 Qg5 28.Qxg5 hxg5
29.b3 Ke6 30.a3 Kd6 31.axb4 cxb4 32.Ra5 Nd5 33. f3 Bc8 34.Kf2 Bf5 35.Ra7
g6 36.Ra6+ Kc5 37.Ke1 Nf4 38.g3 Nxh3 39.Kd2 Kb5 40.Rd6 Kc5 41.Ra6 Nf2
42.g4 Bd3 43.Re6 1/2-1/2

You can find out more about this format at http://en.wikipedia.org/wiki/Portable_


game_notation.

365

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 366

Part III: Advanced SlickEdit


The file begins with specific tag pairs, giving keyword/value information about the game. Examples of
tags are Event, Site, and Date.
The game itself is specified as movetext, which consists of move number indicators and moves in algebraic notation.
Semicolons mark the remainder of a line as a comment. Braces can also be used to mark comments,
which can run to multiple lines, but cannot be nested.

Color Syntax Highlighting


We can get SlickEdit to display some of the elements of PGN files using color syntax highlighting. Well
create a mode for PGN files, and an associated lexer. Follow these steps:

1.

Invoke setupext (Tools Options File Extension Setup) to open the Extension Options dialog. SlickEdit displays the dialog.

2.
3.
4.

Click New to create a new extension. SlickEdit displays the New Extension dialog.

5.
6.
7.

Click OK. SlickEdit closes the New Extension dialog and creates the new mode.

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 the Advanced tab.


Click Color Coding. SlickEdit prompts you to confirm whether you want to start a new lexer for
this extension.

8.
9.
10.
11.
12.
13.
14.
15.
16.
17.

Click Yes. SlickEdit displays the Enter New Lexer Name dialog.

18.
19.
20.
21.

Click the Comments tab.

366

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 New Line comment.


Enter ; for Use delimiter.
Click New Multi-line comment.

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 367

Chapter 17: Customization


22.
23.
24.
25.

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.

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.

Example: Groovy Language


Lets do an example with a real programming language. The Groovy programming language is gaining
popularity as a dynamic language on the Java platform. Groovy combines the productivity and powerful
features of dynamic languages such as Ruby with the breadth and reach of the JVM platform.
You can find out more about Groovy at http://groovy.codehaus.org.
Heres an example of a Groovy script:
if (args.length == 0) {
println(I need a number.)
System.exit(-1)
}
size = Integer.parseInt(args[0])
Board b = new Board(size)
long start = new Date().getTime()
if (b.solve()) {
long elapsed = new Date().getTime() - start
for (i in 0..<size) {
int col = b.getCol(i)
for (j in 0..<col) {
print( )
}
println(*)
}
println( + elapsed/1000 + seconds.)
}

You can also define classes in Groovy, similarly to Java. Heres a partial example of a class:
class Board {
int size

367

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 368

Part III: Advanced SlickEdit


private
private
private
private

int[] pos
boolean[] col
boolean[] diag1
boolean[] diag2

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.

Color Syntax Highlighting


The procedure for setting up a Groovy mode and lexer is very similar to what we already covered for
PGN files. The main difference with Groovy is that there are a few more things to specify. Here, well
provide the steps to do it with the configuration GUI. Further on in the chapter, there is code that sets
up the configuration automatically.
To set up color syntax highlighting for Groovy, follow these steps:

368

1.

Invoke setupext (Tools Options File Extension Setup) to open the Extension Options
dialog. SlickEdit displays the dialog.

2.

Click New to create a new extension. SlickEdit displays the New Extension dialog.

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 369

Chapter 17: Customization


3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.

Enter groovy for the Extension.


Leave Refer to blank.
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 Groovy 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 keywords for Groovy, separated by spaces:

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.

Click OK. SlickEdit adds the tokens as keywords in the Groovy language.

19.

Click the checkbox for Search for end quote across multiple lines, for both double-quoted
strings and single-quoted strings.

20.
21.

Click the Language tab.

22.
23.
24.
25.
26.
27.
28.
29.

Click the Comments tab.

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 Color identifiers followed by ( as a function. This will result in
method names being highlighted as they are in Java.

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 370

Part III: Advanced SlickEdit


The result is partial support for Groovy syntax highlighting. Groovy, like Ruby, has powerful extended
string constructs. Unfortunately, most of these constructs are impossible to support with SlickEdits current customization features. It will require dedicated support in the editor, as it did for Ruby. However,
even this level of support is surprisingly useful and often sufficient for coding in Groovy.

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 371

Chapter 17: Customization


The regular expression used by these macros is ^ \:w. This matches any identifier starting on column 2.
This is a rather lame attempt at parsing Groovy source code, because Groovy places no such restrictions
on source code indentation. But I found that it worked pretty effectively with my own Groovy files. The
trouble with parsing Groovy more accurately is that a lot of syntax elements are optional. For example,
semicolons are optional at the ends of lines. Also, braces are used for both method definitions and for
closures, which are like blocks of code that can be passed around like objects. This makes parsing Groovy
with simple regular expressions quite difficult; thus we have to make do with an expedient heuristic. Of
course, the particular code above relies on my personal coding convention, which uses two spaces to
indent method names in a class. If your code style is different, you will have to make some changes.
The search options are -<UH@CO and +<UH@CO. The - and + parts instruct the search to be backward and forward, respectively. The < part makes the cursor end up at the beginning of the matched
text. The U indicates a UNIX-style regular expression. The H makes the search include hidden lines.
The @ prevents an error message appearing if nothing is found. Finally, the CO restricts the search
to matching text color coded as other, which excludes strings and comments.
The wrox-groovy-prev-proc has extra logic to cope with the common scenario where the cursor starts
at the beginning of a method.

Setting Up the Extension and Event Table


The key binding definitions bind the commands to Ctrl+Up and Ctrl+Down, in the groovy_keys event
table. This event table is not automatically created for the Groovy mode. By default the mode uses a
default event table called _ext_keys.
We can set up the event table when we define the extension, if we do it programmatically. So now well
switch approaches, and instead of doing the steps to set up the new extension and lexer through the
GUI, as just shown, well do it all through Slick-C.
The supplied macro source contains many examples of language extensions set up programmatically.
You can learn more about setting up extension-specific support by reading some of the supplied files.
For example, the file ada.e contains support for the Ada programming language.
Well use a single Slick-C module called wrox_groovy.e, which contains the navigation routines and
key bindings above. It also includes a defload() section, which is run at the time the module is loaded
(compiled). This routine does all the work necessary to set up the extension and lexer. (It also places the
necessary lines in the lexer definition for color coding support.) The defload() routine looks like this:
defload() {
_str setup_info=MN= :+ MODE_NAME :+
,TABS=+2,MA=1 74 1,KEYTAB=groovy-keys,WW=1,IWT=0,ST=0,;
_str compile_info=;
_str syntax_info=2 1 1 1 0 1 0;
_str be_info=({)|(});
int kt_index=0;
create_ext(kt_index,EXTENSION,,MODE_NAME,setup_info,compile_info,
syntax_info,be_info,,A-Za-z0-9_$,MODE_NAME);
// Add Groovy lexer data to user.vlx.
edit(maybe_quote_filename(get_env(VSLICKCONFIG) :+ user.vlx));
int status = search([Groovy]);

371

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 372

Part III: Advanced SlickEdit


if (!status) {
quit();
return;
// quit if file already has [Groovy] section
}
bottom_of_buffer();
insert_line();
insert_line([Groovy]);
insert_line(idchars=a-zA-Z 0-9_$);
insert_line(case-sensitive=y);
insert_line(styles=xhex dqbackslash dqmultiline sqmultiline idparenfunction);
insert_line(keywords= as assert boolean break case catch char class continue);
insert_line(keywords= def default do double else extends false finally float);
insert_line(keywords= for if implements import in instanceof int interface);
insert_line(keywords= long new null package property return short static);
insert_line(keywords= switch throw throws true try void while);
insert_line(linecomment=//);
file();
}

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 Menus and Dialogs


As well as the Slick-C programming language, SlickEdit also provides an entire GUI development
framework. You can customize virtually any GUI element in SlickEdit, and you can create your own.

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 373

Chapter 17: Customization


Before editing a supplied form with the Form Editor, its a good idea to back up the form. To back up the
_edit_form form, follow this procedure:

1.
2.

Open an empty file called edit_form_original.e.


Insert this line at the top:

#include slick.sh

3.

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 374

Part III: Advanced SlickEdit

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.

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.)

2.

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.

3.

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.

4.

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.

5.

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.

6.
7.
8.

Add 2,000 units to the width properties of the directory list control and the drive list control.

9.
10.

374

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.

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 375

Chapter 17: Customization

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.

Open an empty file called edit_form_large.e.


Insert this line at the top:

#include slick.sh

3.

Invoke insert-object (Macro Insert Form or Menu Source). SlickEdit displays the Insert
Form/Menu Source dialog.

4.
5.

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.

Creating a Pop-up Menu


The fastest way to invoke a SlickEdit command is through a key binding. However, there are many
commands and only so many keys. You can place commands that are used less often into menus. This
provides a reasonable middle ground between a single key press and typing the whole command on
the command line.
SlickEdit provides access to many of its commands through the main menu, and through context menus
in the editing pane and in various tool windows. When weve presented features in this book, weve
given the command name and any key binding or menu path to that command. The command name
is given so that you can look up the implementation in the supplied macro source or make use of the
command in your own macros. For using the command directly, you will usually either press a key it is
bound to, or invoke it via the menu.

375

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 376

Part III: Advanced SlickEdit


SlickEdit provides a menu editor that you can use to browse and edit the existing menus, or create your
own. To browse the definitions in the main menu, follow these steps:

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 377

Chapter 17: Customization


Well create a pop-up menu for several of the no-arg commands given as examples in this book. The following Slick-C code shows the menu definition:
_menu wrox_popup_menu {
WROX commands,,,,;
, , , , ;
// blank item to be replaced with divider
submenu &Selections, , Selections..., ncw;
&Save line selection,
wrox-save-line-sel,
, ,
Save line selection to bookmarks;
&Restore line selection, wrox-restore-line-sel, , ,
Restore line selection from bookmarks;
endsubmenu
submenu &Alignment, , Align..., ncw;
&Left with above, wrox-align-left-with-field-above, , ,
Left-align next field with next field above;
&Right with above, wrox-align-right-with-field-above, , ,
Right-align next field with next field above;
endsubmenu
submenu &Repeat, , Repeat..., ncw;
&Last macro n times, wrox-repeat-n-last-macro, , ,
Repeat last_macro n times;
endsubmenu
submenu &Other, , Other..., ncw;
Toggle &comment, wrox-toggle-comment, , ,
Toggle comment for line selection or current line;
&Execute current command, wrox-execute-current-command, , ,
Execute current command;
Count &duplicates, wrox-count-duplicates, , , Count duplicates;
endsubmenu
}

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

// put in separator line

377

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 378

Part III: Advanced SlickEdit


Finally, well bind the command to Ctrl+W with this code:
defeventtab default_keys;
def C-W=wrox_show_wrox_popup_menu;

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 379

Chapter 17: Customization


you experiment a lot, its even more important to have a quick way to restore the editor to your preferred
configuration. Fortunately, using Slick-C, its easy to create a script to restore most of your configuration
settings.
All personal configuration of SlickEdit is stored in the users configuration directory. Most of the configuration data are stored in the state file, which is vslick.sta on Windows and vslick.stu on UNIX.
This is a binary format file that contains data such as:

Compiled Slick-C code.

Menu, dialog, and other resources.

Global variable values.

Other settings.

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 380

Part III: Advanced SlickEdit

Its easy to experiment and restore the configuration to a known state at any time.

You can share configuration data more reliably with others.

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.

Loading Key Definitions and Code


Setting configuration data in SlickEdit is a one time job, in that they do not need to be set every time
SlickEdit starts or every time a module is loaded into memory and initialized. For this reason, well put
the configuration-setting code in one or more batch macros, rather than ordinary modules.
An example of a batch macro for configuration is shown below:
defmain() {
load(../Chapter02/wrox_emulation.e);
load(../Chapter02/wrox_utility.e);
load(../Chapter06/wrox_bookmark_select.e);
load(../Chapter08/wrox_next_prev_word.e);
load(../Chapter09/wrox_comments.e);
load(../Chapter10/wrox_align.e);
load(../Chapter10/wrox_benchmark.e);
load(../Chapter10/wrox_repeat.e);
load(../Chapter11/wrox_aliases.e);
load(../Chapter11/wrox_directories.e);
load(../Chapter12/wrox_url_mappings.e);
load(../Chapter16/wrox_assert.e);
load(../Chapter16/wrox_count_duplicates.e);
load(../Chapter16/wrox_execute.e);
load(../Chapter16/wrox_hashes.e);
load(../Chapter16/wrox_htmlend.e);
load(../Chapter16/wrox_list_files.e);
load(../Chapter16/wrox_move_line.e);
load(../Chapter16/wrox_names.e);
load(../Chapter16/wrox_strings.e);
load(wrox_join_line_with_space.e);
load(wrox_page_down_realign.e);
load(wrox_tabs_matchtab.e);
load(wrox_popup_menu.e);
load(wrox_show_context_menu.e);
load(forms/_edit_form_large.e);
load(forms/_open_form_large.e);
return 0;
}

380

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 381

Chapter 17: Customization


This example loads most of the macro files weve had so far in this book. You could run this batch macro
after installing SlickEdit, or with a fresh configuration directory, to load all the settings and macros in
these files. To run the macro, follow these steps:

1.

Use cd to change the working directory to the (drive and) directory where the
wrox_load_modules.e file is located.

2.

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 382

Part III: Advanced SlickEdit

General Configuration Settings


Many of the other settings are first encountered through the GUI dialogs. They can all be set programmatically, although there are a variety of different mechanisms used. In this section, we review some of
these mechanisms. Well include examples of many settings, but not all, by any means. See the section
Determining Programmatic Configuration below in the chapter to learn how to find out the programmatic interface for a given configuration setting.

Macro Variable Settings


The most straightforward configuration settings are controlled by macro variables. Many macro variable
configuration settings are documented in the online Help, and some are mentioned elsewhere in this
book. Some macro variable configuration settings are actually not available directly via the GUI, but
only via setting the macro variables.
You can set macro variables in a batch macro. The code below shows an example:
defmain() {
// Two character def_select_style corresponds to two settings in the config:
// Extend selection as cursor moves (C = yes, E = no)
// Inclusive character selection (I = yes, N = no)
// We change to EI because:
// E gives more flexible selection locking, and
// I is makes character selections easier to use
set_var(def_select_style EI); // CUA default is CN
// Leave selection after a copy, but not after a paste
set_var(def_deselect_copy 0); // CUA default is 1
//set_var(def_deselect_paste 1); // CUA default is 1
// CUA style: typing replaces basic (not locked) selection
//set_var(def_persistent_select D); // CUA is D
// ************************
// Cursor movement/wrapping
// ************************
// undo undoes cursor movement as well as changes
set_var(def_undo_with_cursor 1); // CUA default is 0
// allow cursor to move freely beyond the ends of lines
// Tools | Options | General, General Tab
set_var(def_click_past_end 1); // CUA default is 0
// do not wrap cursor at start/end of line
// Tools | Options | Redefine Common Keys (?)
set_var(def_cursorwrap 0); // CUA default is 1
// Tools | Options | Redefine Common Keys
set_var(def_linewrap 0);
set_var(def_restore_cursor 0);
set_var(def_updown_col 0);

382

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 383

Chapter 17: Customization


// *************
// Miscellaneous
// *************
set_var(def_fast_open 1);
set_var(def_alt_menu 0);
set_var(def_top_bottom_style 1);
set_var(def_toolbar_animate 0);

//
//
//
//

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

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 384

Part III: Advanced SlickEdit


Extension-Specific Settings
Extension-specific settings are set using the _setext() function. This function can take a wide variety
of different options, depending on which aspect of extension-specific settings you wish to change. The
batch macro below contains some code to change the indentation settings for C, Slick-C, Java, and
Ruby files:
defmain() {
_setext(c,
_setext(e,
_setext(java,
_setext(ruby,
}

options,2
options,2
options,2
options,2

1
1
1
1

1
1
1
1

0
0
0
0

4
4
4
1

1
1
1
0

1
0
1
0

1 0);
1 0);
1 0);
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.

Determining Programmatic Configuration


Some settings, such as those controlled by certain macro variables, are pretty well documented in the
online Help. Others, such as fonts, follow a simple pattern, and you can probably adapt the code above
to your own requirements easily.
For many other settings, you are probably wondering how you can determine what code to write to
update the setting. In this section, we review several techniques you can use to find out about how to
program SlickEdit configuration.

Using Macro Recording


A direct approach to finding out what Slick-C calls to make to achieve a certain configuration change is
to use macro recording. For example, suppose we start with a fresh SlickEdit configuration and want to
find out the Slick-C call to change the Open dialog to fast Open. Follow these steps:

1.
2.

384

Invoke record-macro-toggle (Ctrl+F11). SlickEdit begins recording a macro.


Open the General Options configuration dialog (Tools Options General).

22150c17.qxd:WroxPro

9/25/07

1:47 AM

Page 385

Chapter 17: Customization


3.
4.
5.
6.
7.

Click the More tab.


Click the checkbox for the Windows 3.1 style open dialog.
Click OK.
Invoke record-macro-toggle (Ctrl+F11). SlickEdit prompts you how to save the macro.
Click Cancel.

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.

Invoke record-macro-toggle (Ctrl+F11). SlickEdit begins recording a macro.

3.
4.
5.
6.
7.
8.

Uncheck the Cursor wrap option.

Open the Redefine Common Options configuration dialog (Tools Options Redefine
Common Keys).

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.

Now open lastmac.e. It contains these lines:


#include slick.sh
_command last_recorded_macro() name_info(,VSARG2_MARK|VSARG2_REQUIRES_EDITORCTL)
{
_macro(R,1);
execute(show -modal -mdi _rc_keys_form);
def_cursorwrap=0;
def_updown_col=0;
def_updown_screen_lines=1;
def_linewrap=0;
def_jmp_on_tab=1;

385

22150c17.qxd:WroxPro

9/25/07

1:48 AM

Page 386

Part III: Advanced SlickEdit


def_pull=1;
def_hack_tabs=0;
def_emulate_leading_tabs=0;
}

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

22150c17.qxd:WroxPro

9/25/07

1:48 AM

Page 387

Chapter 17: Customization


Reading Macro Source
One last approach to programmatic configuration is to study the supplied macro source. The file
config.e in the macros directory contains code for the General Options configuration dialog, among
others. Other configuration is handled in other modules. You can find the appropriate module by
studying the form code for the configuration dialog in which you are interested.
For example, suppose you want to find which Slick-C file contains code for the Redefine Common Keys
dialog. Follow these steps:

1.
2.

Open the Redefine Common Keys dialog (Tools Options Redefine Common Keys).

3.
4.

Close the Form Editor.

Press Ctrl+Shift+Space. SlickEdit displays the Form Editor. Note that the name of the form is
_rc_keys_form.

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

22150c17.qxd:WroxPro

9/25/07

1:48 AM

Page 388

Part III: Advanced SlickEdit


Thus, the Redefine Common Keys form is also handled in config.e. You can now navigate to references to _rc_keys_form. The important function is the event handler for the OK button, which is a
function called _ckok.lbutton_up():
_ckok.lbutton_up()
{
_macro(m,_macro(s));
def_cursorwrap = _cursorwrap.p_value!=0;
_macro_append(def_cursorwrap=_cursorwrap.p_value;);
def_updown_col = _updown_col.p_value;
_macro_append(def_updown_col=_updown_col.p_value;);
def_updown_screen_lines = ctlUpDownWithin.p_value!=0;
_macro_append(def_updown_screen_lines=ctlUpDownWithin.p_value;);
def_linewrap
= _linewrap.p_value!=0;
_macro_append(def_linewrap=_linewrap.p_value;);
def_jmp_on_tab = _jumpover_tabs.p_value!=0;
_macro_append(def_jmp_on_tab=_jumpover_tabs.p_value;);
def_pull
= _pullchars.p_value!=0;
_macro_append(def_pull=_pullchars.p_value;);
def_hack_tabs = _hacktabs.p_value!=0;
_macro_append(def_hack_tabs=_hacktabs.p_value;);
def_emulate_leading_tabs = ctlemulatetabs.p_value!=0;
_macro_append(def_emulate_leading_tabs=ctlemulatetabs.p_value;);
_config_modify_flags(CFGMODIFY_DEFVAR);
p_active_form._delete_window(1);
}

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

22150c17.qxd:WroxPro

9/25/07

1:48 AM

Page 389

Chapter 17: Customization

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

22150c17.qxd:WroxPro

9/25/07

1:48 AM

Page 390

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 391

Settings for
Different Emulations
This appendix contains several tables listing commands, key definitions, and other settings for
several different emulations. The tables are:

Command Keys by Category.

Key Commands.

Macro Variable Settings.

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.

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 392

Appendix A: Settings for Different Emulations

Command Keys by Categor y


Tables A-1 to A-10 list commands by category, showing key bindings for the commands. The categories are:

Debugging Commands.

Editing Commands.

File Commands.

Macro Commands.

Miscellaneous Commands.

Navigation Commands.

Project Commands.

Search Commands.

Toolbar Commands.

Window Commands.

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

CUA

SlickEdit

Visual C++ 6

Visual Studio

activate_autos

C+A+A;
C+M+A

C+A+A;
C+M+A

C+A+A;
C+M+A

C+A+A;
C+M+A;
C+A+V,A

activate_
breakpoints

C+A+B; C+M+B

C+A+B; C+M+B

C+A+B; C+M+B

C+A+B; C+M+B

activate_
exceptions

392

C+A+E

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 393

Appendix A: Settings for Different Emulations


Table A-1 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

activate_locals

C+A+L; C+M+L

C+A+L; C+M+L

C+A+L; C+M+L

C+A+L; C+M+L
C+A+V,L

activate_locals2
activate_members

C+A+M;
C+M+M

C+A+M;
C+M+M

C+A+M;
C+M+M

C+A+M;
C+M+M
C+A+V,T

activate_
members2
activate_memory

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

activate_
registers

A+5; M+5

A+5; M+5

A+5; M+5

A+5; C+A+G;
M+5

activate_threads

C+A+H;
C+M+H

C+A+H;
C+M+H

C+A+H;
C+M+H

C+A+H;
C+M+H

activate_
variables

A+4; C+A+V;
C+M+V; M+4

A+4; C+A+V;
C+M+V; M+4

A+4; C+A+V;
C+M+V; M+4

A+4; C+A+V;
C+M+V; M+4

activate_watch

A+3; C+A+W;
C+M+W; M+3

A+3; C+A+W;
C+M+W; M+3

A+3; C+A+W;
C+M+W; M+3

A+3; C+A+W, 1;
C+M+W; M+3

activate_watch2

C+A+W,2

activate_watch3

C+A+W,3

activate_watch4

C+A+W,4

debug_add_watch

C+A+Q

debug_
breakpoints

A+F9; M+F9

A+F9; M+F9

A+F9; M+F9

A+F9; M+F9

debug_clear_all_
breakpoints

C+S+F9

C+S+F9

C+S+F9

C+S+F9

debug_restart

C+S+F5

C+S+F5

C+S+F5

C+S+F5

debug_run_to_
cursor

C+F10

C+F10

C+F10

C+F10

continued

393

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 394

Appendix A: Settings for Different Emulations


Table A-1 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

debug_show_next_
statement

A+Pad-star;
M+Pad-star

A+Pad-star;
M+Pad-star

A+Pad-star;
M+Pad-star

A+Pad-star;
M+Pad-star

debug_step_into

F11

F11

F11

F11

debug_step_out

S+F11

S+F11

S+F11

S+F11

debug_step_over

F10

F10

F10

F10

debug_stop

S+F5

S+F5

S+F5

S+F5

debug_toggle_
breakpoint

F9

F9

C+B; F9

debug_toggle_
breakpoint_
enabled

C+F9

C+F9

C+F9

SlickEdit

Visual C++ 6

Visual Studio

A+A; M+A

A+A

A+A

Editing Commands
Table A-2
Command

CUA

adjust_block_
selection
append_cut

C+S+X

C+S+X

C+S+X

C+S+X

append_to_
clipboard

C+S+C

C+S+C

C+S+C

C+S+C

beautify

C+K,C+D

beautify_
selection

C+K,C+F

cap_selection

C+S+F2

C+S+A

C+S+A

cap_word

C+S+F1

cbacktab

S+TAB

S+TAB

S+TAB

C+Space

C+Space

A+Right;
C+Space

codehelp_
complete

394

C+S+A

C+Space

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 395

Appendix A: Settings for Different Emulations


Table A-2 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

comment

C+K,C+C

comment_erase

C+K,C+U

complete_more

C+S+Space

C+S+Space

complete_next

C+S+dot

C+S+dot

C+S+dot

C+S+dot

complete_prev

C+S+comma

C+S+comma

C+S+comma

C+S+comma

copy_to_
clipboard

C+C; C+Ins;
M+C

A+V; C+Ins;
M+V

C+C; C+Ins;
M+C

C+C; C+Ins;
M+C

A+C; M+C

A+C

A+C

A+K; C+X;
M+X; S+Del

A+K; C+X;
M+X; S+Del

C+L

C+L

A+L

A+L

delete_line

C+S+L

C+S+L

delete_prev_word

C+Backspace

C+Backspace

C+Del

C+Del

A+U

A+U

copy_to_cursor
copy_word

C+K

C+X,C+W
Tab

ctab
cut

C+X; M+X;
S+Del

A+K; M+K;
S+Del

cut_code_block

C+Del

C+Del

cut_end_line

C+E

C+E

cut_line

C+Backspace

C+Backspace

cut_sentence
cut_word

C+S+K

A+W; C+S+K;
M+W
C+D; DEL

delete_char

A+F4; M+F4

delete_tile
delete_word
deselect
fill_selection

C+U

A+U; M+U
A+F; M+F

continued

395

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 396

Appendix A: Settings for Different Emulations


Table A-2 (continued)
Command

CUA

Visual C++ 6

Visual Studio

insert_
blankline_above

C+Enter

insert_
blankline_below

C+S+Enter
Ins; C+X,C+O

Ins

Ins

join_line

A+J; M+J

A+J

A+J

keyin_buf_name

A+N; M+N

A+N

A+N

insert_toggle

Ins

keyin_enter

S+Enter

S+Enter

S+Enter

S+Enter

keyin_match_paren

keyin_space

S+Space

S+Space

S+Space

S+Space

linewrap_delete_
char

Del

Del

Del

linewrap_rubout

Backspace

Backspace

Backspace;
S+Backspace

Backspace

list_symbols

A+dot; M+dot

A+dot; M+dot

A+dot; C+A+T;
M+dot

A+dot; C+A+T;
M+dot

lowcase_selection

C+S+L

C+F4; C+S+L

C+U

C+U

C+F2

lowcase_word
maybe_complete

Space

Space

Space

Space

maybe_list_
matches

move_text_backtab

S+Tab

C+X,S+Tab

move_text_tab

Tab

C+X,Tab

C+M; Tab

Tab

A+M; M+M

move_to_cursor

396

SlickEdit

nosplit_insert_
line

C+Enter

C+Enter; Enter

C+Enter

nosplit_insert_
line_above

C+S+Enter

C+S+Enter

C+S+Enter

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 397

Appendix A: Settings for Different Emulations


Table A-2 (continued)
Command

CUA

C+V; M+V;
S+Ins

paste_replace_
word
redo

Visual C++ 6

Visual Studio

C+Y; S+Ins

C+V; M+V;
S+Ins

C+V; M+V;
S+Ins

C+S+Y

A+M+V

S+F9; C+X,R

C+S+Z; C+Y;
S+M+Z

A+S+Backspace;
C+S+Z; C+Y;
S+M+Z

C+A; M+A

C+A; M+A

A+O; M+O

overlay_block_
selection
paste

SlickEdit

C+Y; S+M+Z

reflow_paragraph

A+P; M+P

reflow_selection

C+X,C+P

select_all

C+A; M+A

select_block

C+B

A+B; M+B

C+B

select_char

F8

A+Z; M+Z

A+Z; F8

A+Z

select_line

C+L

A+L; M+L

C+F8

C+F8

select_matching_
brace

C+S+E

C+S+E

select_next_
condition

C+S+K

C+S+K

select_prev_
condition

C+S+J

C+S+J

select_whole_word

C+W

C+W
S+F7

shift_selection_
left

S+F7

S+F7

S+F7

shift_
selection_right

S+F8

S+F8

S+F8

split_insert_line

Enter

split_line
transpose_chars

Enter

Enter

A+S; M+S; C+X,S


C+T
continued

397

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 398

Appendix A: Settings for Different Emulations


Table A-2 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

transpose_lines

A+S+T

A+S+T

transpose_words

C+S+T

C+S+T

undo

A+Backspace;
C+Z; M+Z

A+Backspace;
F9;
M+Backspace

A+Backspace;
C+Z;
M+Backspace;
M+Z

M+Z

undo_cursor

S+Backspace;
S+F9

C+F9;
S+Backspace

S+F9

A+Backspace;
C+Z;
S+Backspace;
S+F9

unsurround

C+S+Del

C+S+Del

C+S+Del

C+S+Del

upcase_selection

C+S+U

C+F3; C+S+U

C+S+U

C+S+U

C+F1

upcase_word

File Commands
Table A-3

398

Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

close_all

A+M+W

A+M+W

A+M+W

A+M+W

close_buffer

S+M+W

S+M+W

S+M+W

S+M+W

file

F4

F4

gui_cd

C+D

gui_open

C+O; F7; M+O

C+O; M+O

C+O; M+O

gui_print

M+P

C+P; M+P

C+P; M+P

new

M+N

C+N; M+N

C+N; M+N

quit

F3

F3; C+X,K

safe_exit

A+F4; M+F4;
M+Q

A+X; M+X;
C+X,Ctrl+C

A+F4; A+X;
M+F4; M+Q

A+F4; A+X;
M+F4; M+Q

F7; C+X,C+F

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 399

Appendix A: Settings for Different Emulations


Table A-3 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

save

C+S; F2; M+S;


S+F12

F2; S+F12;
C+X,C+S

C+S; M+S

C+S; F2; M+S

C+S+S

save_all
save_as

S+M+S

S+M+S

S+M+S

S+M+S

SlickEdit

Visual C++ 6

Visual Studio

C+S+F12, 09;
C+S+F12, A-Z;
C+S+F12,
F1F12

C+S+F12, 09;
C+S+F12, A-Z;
C+S+F12,
F1F12

Macro Commands
Table A-4
Command

CUA

C+X,)

end_recording
execute_last_
macro_key

C+S+F12, 09;
C+S+F12, A-Z;
C+S+F12,
F1F12

C+S+F12, 09;
C+S+F12, A-Z;
C+S+F12,
F1F12
C+X,E

last_macro
load

F12

F12; C+X,C+L

C+F12

record_macro_
end_execute

C+F12

C+F12; C+T

C+S+P

C+S+P

record_macro_
toggle

C+F11

C+F11; C+R

C+S+R

C+S+R

Visual C++ 6

Visual Studio

A+F1; M+F1

A+F1; M+F1

C+X,(

start_recording

Miscellaneous Commands
Table A-5
Command

CUA

C+G

abort
api_index

SlickEdit

A+F1; M+F1

A+F1; M+F1

continued

399

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 400

Appendix A: Settings for Different Emulations


Table A-5 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

cmdline_toggle

Esc

C+A; Esc

Esc

Esc
C+M,C+O

collapse_to_
definitions
compare

F6

F6

F6

C+equals

C+equals

A+equals;
M+equals

F5

config
diff

F6

C+equals

C+equals
C+X,C+E

doc
execute_selection

A+equals;
M+equals

A+equals;
M+equals

A+equals;
M+equals

expand_alias

C+S+O

C+S+O

C+S+O

expand_extension_
alias

C+S+P

C+S+P

format_selection
function_
argument_help

A+comma;
M+comma

A+comma;
M+comma

A+F8; M+F8

A+F8

A+comma;
C+S+Space;
C+T; M+comma

A+comma;
C+S+Space;
M+comma
C+A+R

goto_url
help

F1; S+M+slash

F1; S+M+slash

F1; S+M+slash

hex

C+S+H

C+S+H

C+S+H
C+M,C+H

hide_selection

C+S+W

html_preview

400

F1; S+M+slash

javadoc_editor

C+S+D

C+S+D

C+S+D

list_buffers

C+S+B

C+S+B;
C+X,C+B

C+S+B

C+S+D

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 401

Appendix A: Settings for Different Emulations


Table A-5 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

list_clipboards

C+S+V

C+S+V;
C+X,C+Y

C+S+V

C+S+V

macos_font_config

M+T

M+T

M+T

macos_show_colors

S+M+C

S+M+C

S+M+C

C+D

C+D

S+M+C

maybe_active_
search_hist_list
plusminus

C+backslash

C+backslash

C+backslash

C+backslash;
C+M,C+M

quote_key

C+Q

C+Q

C+Q

C+Q

S+F6

S+F6

C+X,C+Z

resume
resync

S+F6

S+F6

show_all

C+M,C+P

show_selection

C+M,C+U

softwrap_toggle

C+R,C+R

start_process

C+S+M

stop_process

C+S+M;
C+X,C+M

C+S+M

C+S+M

C+C

C+Break

C+Break
C+M,C+L

toggle_all_
outlining

C+S+8

view_
specialchars_
toggle

C+S+8

C+R,C+W

view_
whitespace_toggle
wh

C+F1

wh2

C+F2

C+F1

C+F1

401

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 402

Appendix A: Settings for Different Emulations

Navigation Commands
Table A-6
Command

CUA

SlickEdit

Visual Studio

C+S+9

C+S+9

C+X,C+D

alias_cd
alt_gtbookmark
back

Back-ButtonDown

Back-ButtonDown

Back-ButtonDown

Back-ButtonDown

begin_line

M+Left

M+Left

M+Left

M+Left

begin_line_text_
toggle

Home

C+U; Home

Home

Home

A+Y; M+Y

A+Y

A+Y

begin_select
bottom_of_buffer

C+End;
M+Down

C+End;
M+Down;
C+X,C+J

C+End;
M+Down

C+End;
M+Down

bottom_of_window

C+PgDn

C+PgDn

C+PgDn

C+PgDn

C+S+F2

C+K,C+L

clear_bookmarks
cursor_down

Down

C+K; Down

Down

Down

cursor_error

A+1; M+1

A+1; M+1

A+1; C+S+G;
M+1

A+1; C+S+G;
M+1

cursor_left

Left

C+J; Left

Left

Left

cursor_right

Right

C+L; Right

Right

Right

cursor_up

Up

C+I; Up

Up

Up

end_line

End; M+Right

C+O; End;
M+Right

End; M+Right

End; M+Right

A+E; M+E

end_select
fast_scroll

Wheel-Down;
Wheel-Up

Wheel-Down;
Wheel-Up

Wheel-Down;
Wheel-Up

Wheel-Down;
Wheel-Up

find_matching_
paren

C+]

A+T; C+]; M+T

C+E; C+]

C+E; C+S+]; C+]

find_tag

402

Visual C++ 6

A+F12

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 403

Appendix A: Settings for Different Emulations


Table A-6 (continued)
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

forward

Forward-ButtonDown

Forward-ButtonDown

Forward-ButtonDown

Forward-ButtonDown

C+G

C+G

F2

C+K,C+N

gui_goto
gui_goto_line

C+J

list_errors

C+S+E

C+S+E

next_bookmark
next_buffer

C+N

C+B; F8
C+K

next_condition

C+S+Pad-minus

next_doc
next_error

C+S+Down

A+F10;
C+S+Down;
M+F10;
C+X,C+N

C+S+Down; F4

C+S+Down; F4;
F8

next_hotspot

C+[

C+[

C+[

C+[

next_paragraph

A+Down

A+Down

A+Down

A+Down

next_tag

C+Down

C+Down

next_window

C+F6; C+Tab

C+Tab; C+W;
C+X,O

C+F6; C+S+N;
C+Tab

C+F6; C+Tab

next_word

A+Right;
C+Right

A+Right;
C+Right

A+Right;
C+Right

A+Right;
C+Right

page_down

PgDn

C+N; PgDn

PgDn

PgDn

page_up

PgUp

C+P; PgUp

PgUp

PgUp

pop_bookmark

C+comma

C+comma;
C+X,C+H

C+comma;
C+Pad-star

C+comma;
C+Pad-star

S+F2

C+K,C+P

prev_bookmark
prev_buffer

C+P

A+F8; C+F8;
C+V; M+F8
continued

403

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 404

Appendix A: Settings for Different Emulations


Table A-6 (continued)
Command

CUA

SlickEdit

prev_condition

Visual C++ 6

Visual Studio

C+J

C+J
C+Pad-minus

prev_doc
prev_error

C+S+Up

C+S+Up

C+S+Up; S+F4

C+S+Up; S+F4;
S+F8

prev_hotspot

C+S+[

C+S+[

C+S+[

C+S+[

prev_paragraph

A+Up

A+Up

A+Up

A+Up

prev_tag

C+Up

C+Up

prev_window

C+S+F6;
C+S+Tab;
C+S+W

C+S+F6;
C+S+Tab;
C+S+W

C+S+F6;
C+S+Tab

C+S+F6;
C+S+Tab;
C+S+W

prev_word

A+Left; C+Left

A+Left; C+Left

A+Left; C+Left

A+Left; C+Left

push_ref

C+slash

C+slash

C+slash; S+F12

C+slash; S+F12

push_tag

C+dot

C+dot; C+H

C+dot; F12

C+dot; C+F12;
F12

scroll_down

S+F2

C+Down

C+Down

scroll_left

S+F3

scroll_page_down

C+Wheel-Down

C+Wheel-Down

C+Wheel-Down

C+Wheel-Down

scroll_page_up

C+Wheel-Up

C+Wheel-Up

C+Wheel-Up

C+Wheel-Up

C+Up

C+Up

scroll_right

S+F4

scroll_up

S+F1

A+F2; M+F2

set_bookmark

404

set_next_error

C+S+S

C+S+S; C+X,N

C+S+S

toggle_bookmark

C+S+J

C+S+J

C+F2

C+K,C+K

top_of_buffer

C+Home; M+Up

C+Home;
M+Up;
C+X,C+U

C+Home; M+Up

C+Home; M+Up

top_of_window

C+PgUp

C+PgUp

C+PgUp

C+PgUp

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 405

Appendix A: Settings for Different Emulations

Project Commands
Table A-7
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio
A+S+A

project_add_file
project_build

C+M

A+F5; C+M;
M+F5; C+X,M

F7

C+S+B

project_compile

S+F10

A+F6; C+F6;
M+F6; S+F10

C+F7; S+F10

C+F7; S+F10

project_debug

F5

F5

F5

A+F7; M+F7

A+F7

C+F5

C+F5

project_edit
project_execute

C+F5

C+F5

workspace_new

C+S+N

workspace_open

C+S+O

Search Commands
Table A-8
Command

CUA

find_in_files

C+S+F

find_next

C+G; M+G

C+F

C+Pad-plus; F3;
M+G

F3; M+G

find_prev

C+S+G; S+M+G

C+S+F; C+S+G;
S+M+G

C+Pad-minus;
C+S+F3; S+F3;
S+M+G

C+S+F3; S+F3;
S+M+G

gui_find

C+F; M+F

A+F3; C+F;
M+F; M+F3

C+F; M+F

gui_replace

C+R

C+H

C+H

i_search

C+I

C+I

C+I

C+F3

C+F3

quick_search

SlickEdit

Visual C++ 6

Visual Studio
C+S+F

C+S

continued

405

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 406

Appendix A: Settings for Different Emulations


Table A-8 (continued)
Command

CUA

replace_in_files

C+S+R

reverse_i_search

C+S+I

set_find

M+E

SlickEdit

Visual C++ 6

Visual Studio
C+S+H

C+S+I; C+X,C+R

C+S+I

C+S+I

M+E

M+E

toggle_so_
backwards

A+F3,B

toggle_so_
matchcase

A+F3,C

toggle_so_regex

A+F3,R

Toolbar Commands
Table A-9
Command

CUA

SlickEdit

Visual C++ 6

Visual Studio

activate_
bookmarks

C+S+N

C+S+N

A+S+F2

C+K,C+W
C+A+A

activate_build
activate_call_
stack

A+7; C+A+C;
C+M+C; M+7

A+7; C+A+C;
C+M+C; M+7

A+7; C+A+C;
C+M+C; M+7

C+A+O

activate_output
activate_output_
toolbar

406

A+7; C+A+C;
C+M+C; M+7

A+2; M+2

A+2

activate_
project_classes

C+A+J

activate_
project_files

C+A+L

activate_
project_toolbar

A+0; M+0

activate_tag_
properties_
toolbar

A+F12; M+F12

A+0

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 407

Appendix A: Settings for Different Emulations

Window Commands
Table A-10
Command

CUA

close_window

C+F4; M+W

create_tile

A+F3; M+F3

SlickEdit

Visual C++ 6

Visual Studio

C+F4; M+W

C+F4; M+W

A+F3; M+F3

M+F3
A+S+Enter

fullscreen
hsplit_window

C+H

C+X,2

iconize_all

A+M+M

A+M+M

iconize_window

A+M+M

A+M+M

M+M

M+M

M+M

maximize_mdi

A+F10; M+F10

A+F10; M+F10

A+F10; M+F10

move_edge

A+F2; M+F2

A+F2; M+F2

M+F2

move_mdi

A+F7; M+F7

A+F7; M+F7

M+F7

move_window

C+F7

C+F7
C+X,1

one_window
restore_mdi

A+F5; M+F5

size_mdi

A+F8; M+F8

size_window

C+F8

zoom_window

C+S+Z

A+F5; M+F5

A+F5; M+F5
M+F8

C+S+Z; C+Z

407

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 408

Appendix A: Settings for Different Emulations

Key Commands
Table A-11 lists the commands bound to keys in the different emulations.

Table A-11

408

Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

Space

maybe_
complete

maybe_
complete

maybe_
complete

maybe_
complete

C+Space

codehelp_
complete

codehelp_
complete

codehelp_
complete

codehelp_
complete

C+S+Space

complete_more

complete_more

function_
argument_help

function_
argument_help

S+Space

keyin_space

keyin_space

keyin_space

keyin_space

keyin_match_
paren

keyin_match_
paren

keyin_match_
paren

keyin_match_
paren

rexx_star

rexx_star

rexx_star

rexx_star

maybe_list_
matches

maybe_list_
matches

maybe_list_
matches

maybe_list_
matches

Back-Button-Down

back

back

back

back

Backspace

linewrap_
rubout

linewrap_
rubout

linewrap_
rubout

linewrap_
rubout

Del

linewrap_
delete_char

delete_char

linewrap_
delete_char

linewrap_
delete_char

Down

cursor_down

cursor_down

cursor_down

cursor_down

End

end_line

end_line

end_line

end_line

Enter

split_insert_
line

nosplit_
insert_line

split_insert_
line

split_insert_
line

Esc

cmdline_
toggle

cmdline_toggle

cmdline_
toggle

cmdline_
toggle

F1

help

help

help

help

F2

save

save

next_bookmark

save

F3

quit

quit

find_next

find_next

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 409

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

F4

file

file

next_error

next_error

F5

project_debug

config

project_debug

project_debug

F6

compare

compare

compare

compare

F7

gui_open

gui_open

project_build

F8

select_char

next_buffer

select_char

next_error

F9

debug_
toggle_
breakpoint

undo

debug_
toggle_
breakpoint

debug_
toggle_
breakpoint

F10

debug_step_
over

debug_step_
over

debug_step_
over

debug_step_
over

F11

debug_step_
into

debug_step_
into

debug_step_
into

debug_step_
into

F12

load

load

push_tag

push_tag

Forward-ButtonDown

forward

forward

forward

forward

Home

begin_line_
text_toggle

begin_line_
text_toggle

begin_line_
text_toggle

begin_line_
text_toggle

Ins

insert_toggle

insert_toggle

insert_toggle

insert_toggle

LButton-doubleclick

mou_select_
word

mou_select_
word

mou_select_
word

mou_select_
word

LButton-Down

mou_click

mou_click

mou_click

mou_click

LButton-triple-click

mou_select_
line

mou_select_
line

mou_select_
line

mou_select_
line

Left

cursor_left

cursor_left

cursor_left

cursor_left

MButton-Down

mou_paste

mou_paste

mou_paste

mou_paste

Mouse-Move

_mouse_move

_mouse_move

_mouse_move

_mouse_move

PgDn

page_down

page_down

page_down

page_down

PgUp

page_up

page_up

page_up

page_up

continued

409

22150bapp01.qxd:WroxPro

9/25/07

1:52 AM

Page 410

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

RButton-Down

mou_click_
menu_block

mou_click_
menu_block

mou_click_
menu_block

mou_click_
menu_block

Right

cursor_right

cursor_right

cursor_right

cursor_right

Tab

move_text_tab

ctab

move_text_tab

move_text_tab

Up

cursor_up

cursor_up

cursor_up

cursor_up

Wheel-Down

fast_scroll

fast_scroll

fast_scroll

fast_scroll

Wheel-Up

fast_scroll

fast_scroll

fast_scroll

fast_scroll

activate_
project_
toolbar

activate_
project_
toolbar

cursor_error

cursor_error

activate_
output_
toolbar

activate_
output_
toolbar

A+0

A+1

cursor_error

cursor_error

A+2

410

A+3

activate_
watch

activate_
watch

activate_
watch

activate_
watch

A+4

activate_
variables

activate_
variables

activate_
variables

activate_
variables

A+5

activate_
registers

activate_
registers

activate_
registers

activate_
registers

A+6

activate_
memory

activate_
memory

activate_
memory

activate_
memory

A+7

activate_
call_stack

activate_
call_stack

activate_
call_stack

activate_
call_stack

A+A

adjust_block_
selection

adjust_block_
selection

adjust_block_
selection

A+B

select_block

A+C

copy_to_
cursor

copy_to_
cursor

copy_to_
cursor

A+E

end_select

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 411

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

A+F

fill_
selection

A+J

join_line

join_line

join_line

A+K

cut

cut

cut

A+L

select_line

cut_sentence

cut_sentence

A+M

move_to_
cursor

A+N

keyin_buf_name

keyin_buf_name

keyin_buf_name

A+O

overlay_block_
selection

A+P

reflow_
paragraph

A+R

root_keydef

root_keydef

root_keydef

A+S

split_line

A+T

find_
matching_paren

A+U

deselect

deselect

deselect

A+V

copy_to_
clipboard

A+W

cut_word

A+X

safe_exit

safe_exit

safe_exit

A+Y

begin_select

begin_select

begin_select

A+Z

select_char

select_char

select_char

A+comma

function_
argument_help

function_
argument_help

function_
argument_help

function_
argument_help

A+dot

list_symbols

list_symbols

list_symbols

list_symbols

continued

411

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 412

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

A+equals

execute_
selection

execute_
selection

execute_
selection

execute_
selection

A+Backspace

undo

undo

undo

undo_cursor

A+Down

next_paragraph

next_paragraph

next_paragraph

next_paragraph

A+F1

api_index

api_index

api_index

api_index

A+F2

move_edge

move_edge

set_bookmark

A+F3

create_tile

create_tile

gui_find

A+F3,B

toggle_so_
backwards

A+F3,C

toggle_so_
matchcase

A+F3,R

toggle_so_
regex

A+F4

safe_exit

delete_tile

safe_exit

safe_exit

A+F5

restore_mdi

project_build

restore_mdi

restore_mdi

A+F6

project_
compile

A+F7

move_mdi

move_mdi

project_edit

project_edit

A+F8

size_mdi

prev_buffer

format_
selection

format_
selection

A+F9

debug_
breakpoints

debug_
breakpoints

debug_
breakpoints

debug_
breakpoints

A+F10

maximize_mdi

next_error

maximize_mdi

maximize_mdi

activate_tag_
properties_
toolbar

find_tag

A+F12

412

A+LButton-Down

mou_click_copy

mou_click_copy

mou_click_copy

mou_click_copy

A+Left

prev_word

prev_word

prev_word

prev_word

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 413

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

A+Pad-star

debug_show_
next_statement

debug_show_
next_statement

debug_show_
next_statement

debug_show_
next_statement

A+Right

next_word

next_word

next_word

codehelp_
complete

A+Up

prev_paragraph

prev_paragraph

prev_paragraph

prev_paragraph

A+M+M

iconize_all

iconize_all

iconize_all

iconize_all

A+M+V
A+M+W

paste_replace_
word
close_all

close_all

close_all

A+S+A

project_add_
file

A+S+T

transpose_
lines

A+S+Backspace
A+S+Down

close_all

transpose_
lines
redo

cua_select

cua_select

cua_select

A+S+Enter

cua_select
fullscreen

A+S+F2

activate_
bookmarks

A+S+Left

cua_select

cua_select

cua_select

cua_select

A+S+Right

cua_select

cua_select

cua_select

cua_select

A+S+Up

cua_select

cua_select

cua_select

cua_select

C+A

select_all

cmdline_
toggle

select_all

select_all

C+B

select_block

next_buffer

select_block

debug_toggle_
breakpoint

C+C

copy_to_
clipboard

stop_process

copy_to_
clipboard

copy_to_
clipboard

continued

413

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 414

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

C+D

gui_cd

delete_char

maybe_active_
search_hist_
list

maybe_active_
search_hist_
list

C+E

cut_end_line

cut_end_line

find_matching_
paren

find_matching_
paren

C+F

gui_find

find_next

gui_find

gui_find

C+G

find_next

abort

gui_goto

gui_goto

C+H

hsplit_window

push_tag

gui_replace

gui_replace

C+I

i_search

cursor_up

i_search

i_search

C+J

gui_goto_line

cursor_left

prev_
condition

prev_
condition

C+K

copy_word

cursor_down

next_condition

C+K,C+C

comment

C+K,C+D

beautify

C+K,C+F

beautify_
selection

C+K,C+K

toggle_
bookmark

C+K,C+L

clear_
bookmarks

C+K,C+N

next_bookmark

C+K,C+P

prev_bookmark

C+K,C+U

comment_erase

C+K,C+W

activate_
bookmarks

C+L

select_line

cursor_right

cut_line

C+M

project_build

project_build

move_text_tab

C+M,C+H

414

cut_line

hide_selection

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 415

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

C+M,C+L

toggle_all_
outlining

C+M,C+M

plusminus

C+M,C+O

collapse_to_
definitions

C+M,C+P

show_all

C+M,C+U

show_
selection

C+N

next_buffer

page_down

new

new

C+O

gui_open

end_line

gui_open

gui_open

C+P

prev_buffer

page_up

gui_print

gui_print

C+Q

quote_key

quote_key

quote_key

quote_key

C+R

gui_replace

record_macro_
toggle

C+R,C+R

softwrap_
toggle

C+R,C+W

view_
whitespace_
toggle

C+S

save

C+T

i_search

save

save

record_macro_
end_execute

function_
argument_help

transpose_
chars

C+U

deselect

begin_line_
text_toggle

lowcase_
selection

lowcase_
selection

C+V

paste

prev_buffer

paste

paste

next_window

select_whole_
word

select_whole_
word

cut

cut

C+W
C+X
C+X,(

cut
start_
recording

continued

415

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 416

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

416

CUA

SlickEdit

C+X,)

end_recording

C+X,1

one_window

C+X,2

hsplit_window

C+X,AZ

case_indirect

C+X,B

find_buffer

C+X,E

last_macro

C+X,K

quit

C+X,M

project_build

C+X,N

set_next_error

C+X,O

next_window

C+X,R

redo

C+X,S

split_line

C+X,Tab

move_text_tab

C+X,S+Tab

move_text_
backtab

C+X,C+B

list_buffers

C+X,C+C

safe_exit

C+X,C+D

alias_cd

C+X,C+E

dos

C+X,C+F

gui_open

C+X,C+H

pop_bookmark

C+X,C+J

bottom_of_
buffer

C+X,C+L

load

Visual C++ 6

Visual Studio

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 417

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

C+X,C+M

start_process

C+X,C+N

next_error

C+X,C+O

insert_toggle

C+X,C+P

reflow_
selection

C+X,C+R

reverse_i_
search

C+X,C+S

save

C+X,C+U

top_of_buffer

C+X,C+W

copy_word

C+X,C+X

nothing

C+X,C+Y

list_
clipboards

C+X,C+Z

resume

Visual C++ 6

Visual Studio

C+Y

redo

paste

redo

redo

C+Z

undo

zoom_window

undo

undo_cursor

C+comma

pop_bookmark

pop_bookmark

pop_bookmark

pop_bookmark

C+dot

push_tag

push_tag

push_tag

push_tag

C+slash

push_ref

push_ref

push_ref

push_ref

C+[

next_hotspot

next_hotspot

next_hotspot

next_hotspot

C+backslash

plusminus

plusminus

plusminus

plusminus

C+]

find_matching_
paren

find_matching_
paren

find_matching_
paren

find_matching_
paren

C+equals

diff

diff

diff

diff

C+Backspace

cut_line

cut_line

delete_prev_
word

delete_prev_
word

continued

417

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 418

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

C+Break

Visual Studio

stop_process

stop_process

C+Del

cut_code_block

cut_code_block

delete_word

delete_word

C+Down

next_tag

next_tag

scroll_down

scroll_down

C+End

bottom_of_
buffer

bottom_of_
buffer

bottom_of_
buffer

bottom_of_
buffer

C+Enter

nosplit_
insert_line

nosplit_
insert_line

nosplit_
insert_line

insert_
blankline_
above

C+F1

wh

upcase_word

wh

wh

C+F2

wh2

lowcase_word

toggle_
bookmark

upcase_
selection

quick_search

quick_search

C+F3

418

Visual C++ 6

C+F4

close_window

lowcase_
selection

close_window

close_window

C+F5

project_
execute

project_
execute

project_
execute

project_
execute

C+F6

next_window

project_
compile

next_window

next_window

C+F7

move_window

move_window

project_
compile

project_
compile

C+F8

size_window

prev_buffer

select_line

select_line

C+F9

debug_toggle_
breakpoint_
enabled

undo_cursor

debug_toggle_
breakpoint_
enabled

debug_toggle_
breakpoint_
enabled

C+F10

debug_run_to_
cursor

debug_run_to_
cursor

debug_run_to_
cursor

debug_run_to_
cursor

C+F11

record_macro_
toggle

record_macro_
toggle

C+F12

record_macro_
end_execute

record_macro_
end_execute

load

push_tag

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 419

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

C+Home

top_of_buffer

top_of_buffer

top_of_buffer

top_of_buffer

C+Ins

copy_to_
clipboard

copy_to_
clipboard

copy_to_
clipboard

copy_to_
clipboard

C+LButton-Down

mou_click_copy

mou_click_copy

mou_click_copy

mou_click_copy

C+Left

prev_word

prev_word

prev_word

prev_word

C+MButton-Down

mou_select_
word

mou_select_
word

C+Pad-minus

find_prev

prev_doc

C+Pad-plus

find_next

C+Pad-star

pop_bookmark

pop_bookmark

C+PgDn

bottom_of_
window

bottom_of_
window

bottom_of_
window

bottom_of_
window

C+PgUp

top_of_window

top_of_window

top_of_window

top_of_window

C+RButton-Down

mou_move_to_
cursor

mou_move_to_
cursor

mou_move_to_
cursor

mou_move_to_
cursor

C+Right

next_word

next_word

next_word

next_word

C+Tab

next_window

next_window

next_window

next_window

C+Up

prev_tag

prev_tag

scroll_up

scroll_up

C+Wheel-Down

scroll_page_
down

scroll_page_
down

scroll_page_
down

scroll_page_
down

C+Wheel-Up

scroll_page_up

scroll_page_up

scroll_page_up

scroll_page_up

C+S+Del

unsurround

unsurround

unsurround

unsurround

C+S+Down

next_error

next_error

next_error

next_error

C+S+End

cua_select

cua_select

cua_select

cua_select

C+S+Enter

nosplit_
insert_line_
above

nosplit_
insert_line_
above

nosplit_
insert_line_
above

insert_
blankline_
below

continued

419

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 420

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

C+S+F1

cap_word

C+S+F2

cap_selection

C+S+F3

Visual C++ 6

clear_
bookmarks
find_prev

find_prev

C+S+F5

debug_restart

debug_restart

debug_restart

debug_restart

C+S+F6

prev_window

prev_window

prev_window

prev_window

C+S+F9

debug_
clear_all_
breakpoints

debug_
clear_all_
breakpoints

debug_
clear_all_
breakpoints

debug_
clear_all_
breakpoints

C+S+F12,09

execute_last_
macro_key

C+S+F12,AZ

execute_last_
macro_key

C+S+F12,F1F12

execute_last_
macro_key

C+S+Home

cua_select

cua_select

cua_select

cua_select

C+S+Left

cua_select

cua_select

cua_select

cua_select

C+S+Pad-minus

420

Visual Studio

next_doc

C+S+RButton-Down

mou_copy_to_
cursor

mou_copy_to_
cursor

mou_copy_to_
cursor

mou_copy_to_
cursor

C+S+Right

cua_select

cua_select

cua_select

cua_select

C+S+Tab

prev_window

prev_window

prev_window

prev_window

C+S+Up

prev_error

prev_error

prev_error

prev_error

C+A+A

activate_autos

activate_autos

activate_autos

activate_build

C+A+B

activate_
breakpoints

activate_
breakpoints

activate_
breakpoints

activate_
breakpoints

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 421

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

C+A+C

activate_
call_stack

activate_
call_stack

activate_
call_stack

activate_
call_stack

C+A+E

activate_
exceptions

C+A+G

activate_
registers

C+A+H

activate_
threads

activate_
threads

activate_
threads

C+A+J

activate_
threads
activate_
project_
classes

C+A+L

activate_
locals

activate_
locals

activate_
locals

activate_
project_files

C+A+M

activate_
members

activate_
members

activate_
members

activate_
members

C+A+M,1

activate_
memory

C+A+M,2

activate_
memory

C+A+M,3

activate_
memory

C+A+M,4

activate_
memory

C+A+O

activate_
output

C+A+Q

debug_add_
watch

C+A+R

goto_url

C+A+T
C+A+V

list_symbols
activate_
variables

activate_
variables

list_symbols

activate_
variables

continued

421

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 422

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

C+A+V,A

activate_autos

C+A+V,L

activate_
locals2

C+A+V,T

acticate_
members2

C+A+W

activate_watch

activate_watch

activate_watch

C+A+W,1

activate_watch
activate_
watch2
activate_
watch3
activate_
watch4

422

C+M+A

activate_autos

activate_autos

activate_autos

activate_autos

C+M+B

activate_
breakpoints

activate_
breakpoints

activate_
breakpoints

activate_
breakpoints

C+M+C

activate_
call_stack

activate_
call_stack

activate_
call_stack

activate_
call_stack

C+M+H

activate_
threads

activate_
threads

activate_
threads

activate_
threads

C+M+L

activate_
locals

activate_
locals

activate_
locals

activate_
locals

C+M+M

activate_
members

activate_
members

activate_
members

activate_
members

C+M+V

activate_
variables

activate_
variables

activate_
variables

activate_
variables

C+M+W

activate_watch

activate_watch

activate_watch

activate_watch

C+S+8

view_
specialchars_
toggle

view_
specialchars_
toggle

C+S+9

alt_
gtbookmark

alt_
gtbookmark

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 423

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

C+S+A

Visual C++ 6

Visual Studio

cap_selection

cap_selection

C+S+B

list_buffers

list_buffers

list_buffers

project_build

C+S+C

append_to_
clipboard

append_to_
clipboard

append_to_
clipboard

append_to_
clipboard

C+S+D

javadoc_
editor

javadoc_
editor

javadoc_
editor

javadoc_
editor

C+S+E

list_errors

list_errors

select_
matching_brace

select_
matching_brace

C+S+F

find_in_files

find_prev

C+S+G

find_prev

find_prev

cursor_error

cursor_error

C+S+H

hex

hex

hex

replace_in_
files

C+S+I

reverse_i_
search

reverse_i_
search

reverse_i_
search

reverse_i_
search

C+S+J

toggle_
bookmark

toggle_
bookmark

select_prev_
condition

select_prev_
condition

C+S+K

cut_word

cut_word

select_next_
condition

select_next_
condition

C+S+L

lowcase_
selection

lowcase_
selection

delete_line

delete_line

C+S+M

start_process

start_process

start_process

start_process

C+S+N

activate_
bookmarks

activate_
bookmarks

next_window

workspace_new

C+S+O

expand_alias

expand_alias

expand_alias

workspace_open

C+S+P

expand_
extension_
alias

expand_
extension_
alias

record_macro_
end_execute

record_macro_
end_execute

C+S+R

replace_in_
files

record_macro_
toggle

record_macro_
toggle

C+S+S

set_next_error

set_next_error

save_all

set_next_error

find_in_files

continued

423

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 424

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

C+S+T
C+S+T,09

execute_last_
macro_key

C+S+T,AZ

execute_last_
macro_key

C+S+T,F1F12

execute_last_
macro_key

Visual C++ 6

Visual Studio

transpose_
words

transpose_
words

C+S+U

upcase_
selection

upcase_
selection

upcase_
selection

upcase_
selection

C+S+V

list_
clipboards

list_
clipboards

list_
clipboards

list_
clipboards

C+S+W

prev_window

prev_window

html_preview

prev_window

C+S+X

append_cut

append_cut

append_cut

append_cut

C+S+Y

paste_
replace_word

C+S+Z

zoom_window

zoom_window

redo

redo

C+S+comma

complete_prev

complete_prev

complete_prev

complete_prev

C+S+dot

complete_next

complete_next

complete_next

complete_next

C+S+[

prev_hotspot

prev_hotspot

prev_hotspot

prev_hotspot

C+S+]

find_
matching_paren

M+0

M+1

activate_
project_
toolbar
cursor_error

cursor_error

M+2

M+3

424

cursor_error

cursor_error

activate_
output_
toolbar
activate_watch

activate_watch

activate_watch

activate_watch

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 425

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

M+4

activate_
variables

activate_
variables

activate_
variables

activate_
variables

M+5

activate_
registers

activate_
registers

activate_
registers

activate_
registers

M+6

activate_
memory

activate_
memory

activate_
memory

activate_
memory

M+7

activate_
call_stack

activate_
call_stack

activate_
call_stack

activate_
call_stack

M+A

select_all

adjust_block_
selection

select_all

select_all

M+B

select_block

M+C

copy_to_
clipboard

copy_to_
cursor

copy_to_
clipboard

copy_to_
clipboard

M+E

set_find

end_select

set_find

set_find

M+F

gui_find

fill_
selection

gui_find

gui_find

M+G

find_next

find_next

find_next

M+J

join_line

M+K

cut

M+L

select_line

M+M

iconize_
window

move_to_
cursor

iconize_
window

iconize_
window

M+N

new

keyin_buf_name

new

new

M+O

gui_open

overlay_block_
selection

gui_open

gui_open

M+P

gui_print

reflow_
paragraph

gui_print

gui_print

M+Q

safe_exit

safe_exit

safe_exit

continued

425

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 426

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

M+R

Visual C++ 6

Visual Studio

root_keydef

M+S

save

split_line

save

save

M+T

macos_font_
config

find_matching_
paren

macos_font_
config

macos_font_
config

M+U

deselect

M+V

paste

copy_to_
clipboard

paste

paste

M+W

close_window

cut_word

close_window

close_window

M+X

cut

safe_exit

cut

cut

M+Y

begin_select

M+Z

undo

select_char

undo

undo

M+comma

function_
argument_help

function_
argument_help

function_
argument_help

function_
argument_help

M+dot

list_symbols

list_symbols

list_symbols

list_symbols

M+equals

execute_
selection

execute_
selection

execute_
selection

execute_
selection

undo

undo

M+Backspace

426

SlickEdit

M+Down

bottom_of_
buffer

bottom_of_
buffer

bottom_of_
buffer

bottom_of_
buffer

M+F1

api_index

api_index

api_index

api_index

M+F2

move_edge

move_edge

set_bookmark

move_edge

M+F3

create_tile

create_tile

gui_find

create_tile

M+F4

safe_exit

delete_tile

safe_exit

safe_exit

M+F5

restore_mdi

project_build

restore_mdi

restore_mdi

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 427

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

M+F6

SlickEdit

Visual C++ 6

Visual Studio

project_
compile

M+F7

move_mdi

move_mdi

project_edit

move_mdi

M+F8

size_mdi

prev_buffer

format_
selection

size_mdi

M+F9

debug_
breakpoints

debug_
breakpoints

debug_
breakpoints

debug_
breakpoints

M+F10

maximize_mdi

next_error

maximize_mdi

maximize_mdi

M+F12

activate_tag_
properties_
toolbar

M+Left

begin_line

begin_line

begin_line

begin_line

M+Pad-star

debug_show_
next_statement

debug_show_
next_statement

debug_show_
next_statement

debug_show_
next_statement

M+Right

end_line

end_line

end_line

end_line

M+Up

top_of_buffer

top_of_buffer

top_of_buffer

top_of_buffer

S+Backspace

undo_cursor

undo_cursor

linewrap_
rubout

undo_cursor

S+Del

cut

cut

cut

cut

S+Down

cua_select

cua_select

cua_select

cua_select

S+End

cua_select

cua_select

cua_select

cua_select

S+Enter

keyin_enter

keyin_enter

keyin_enter

keyin_enter

S+F1

scroll_up

S+F2

scroll_down

prev_bookmark

S+F3

scroll_left

find_prev

find_prev

S+F4

scroll_right

prev_error

prev_error

debug_stop

debug_stop

debug_stop

S+F5

debug_stop

continued

427

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 428

Appendix A: Settings for Different Emulations


Table A-11 (continued)

428

Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

S+F6

resync

resync

resync

resync

S+F7

shift_
selection_left

shift_
selection_left

shift_
selection_left

shift_
selection_left

S+F8

shift_
selection_
right

shift_
selection_
right

shift_
selection_
right

prev_error

S+F9

undo_cursor

redo

undo_cursor

undo_cursor

S+F10

project_
compile

project_
compile

project_
compile

project_
compile

S+F11

debug_step_out

debug_step_out

debug_step_out

debug_step_out

S+F12

save

save

push_ref

push_ref

S+Home

cua_select

cua_select

cua_select

cua_select

S+Ins

paste

paste

paste

paste

S+LButton-Down

mou_extend_
selection

mou_extend_
selection

mou_extend_
selection

mou_extend_
selection

S+Left

cua_select

cua_select

cua_select

cua_select

S+PgDn

cua_select

cua_select

cua_select

cua_select

S+PgUp

cua_select

cua_select

cua_select

cua_select

S+Right

cua_select

cua_select

cua_select

cua_select

S+Tab

move_text_
backtab

cbacktab

cbacktab

cbacktab

S+Up

cua_select

cua_select

cua_select

cua_select

S+M+C

macos_show_
colors

macos_show_
colors

macos_show_
colors

macos_show_
colors

S+M+G

find_prev

find_prev

find_prev

find_prev

S+M+S

save_as

save_as

save_as

save_as

S+M+W

close_buffer

close_buffer

close_buffer

close_buffer

S+M+Z

redo

redo

redo

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 429

Appendix A: Settings for Different Emulations


Table A-11 (continued)
Key

CUA

SlickEdit

Visual C++ 6

Visual Studio

S+M+/

help

help

help

help

S+M+Down

cua_select

cua_select

cua_select

cua_select

S+M+End

cua_select

cua_select

cua_select

cua_select

S+M+Home

cua_select

cua_select

cua_select

cua_select

S+M+Left

cua_select

cua_select

cua_select

cua_select

S+M+Right

cua_select

cua_select

cua_select

cua_select

S+M+Up

cua_select

cua_select

cua_select

cua_select

Macro Variable Settings


Table A-12 lists macro variable settings for the different emulations.

Table A-12
Variable

CUA

SlickEdit

Visual C++ 6

Visual Studio

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

continued

429

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 430

Appendix A: Settings for Different Emulations


Table A-12 (continued)

430

Variable

CUA

SlickEdit

Visual C++ 6

Visual Studio

def_from_cursor

def_gui

def_hack_tabs

def_ispf_flags

def_jmp_on_tab

def_keys

windows-keys

vcpp-keys

vsnet-keys

def_leave_
selected

def_line_insert

def_linewrap

def_list_binary_
files

true

true

true

true

def_modal_tab

def_next_word_
style

def_one_file

+w

+w

+w

def_persistent_
select

def_preplace

def_process_tab_
output

def_pull

def_restore_
cursor

def_scursor_style

def_select_style

CN

EI

CN

CN

def_switchbuf_cd

false

false

false

false

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 431

Appendix A: Settings for Different Emulations


Table A-12 (continued)
Variable

CUA

SlickEdit

Visual C++ 6

Visual Studio

def_top_bottom_
style

def_updown_col

def_updown_
screen_lines

true

true

true

true

def_vcpp_bookmark

def_vcpp_word

def_word_continue

false

false

false

false

def_word_delim

WROX Emulation Key Commands


Table A-13 lists the key bindings defined in the WROX emulation, and in other macros presented in this
book. These bindings are defined on top of the CUA emulation.

Table A-13
Key

WROX

Alt+A

adjust-block-selection

Alt+B

select-block

Alt+C

copy-to-cursor

Alt+D

cut

Alt+E

end-select

Alt+F

fill-selection

Alt+J

join-line

Alt+L

select-line

Alt+M

move-to-cursor

Alt+N

keyin-buf-name

continued

431

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 432

Appendix A: Settings for Different Emulations


Table A-13 (continued)

432

Key

WROX

Alt+O

overlay-block-selection

Alt+P

reflow-paragraph

Alt+Q

what-is

Alt+Shift+Q

where-is

Alt+R

root-keydef

Alt+S

split-line

Alt+U

deselect

Alt+V

copy-to-clipboard

Alt+W

cut-word

Alt+X

safe-exit

Alt+Y

begin-select

Alt+Z

select-char

Alt+quote

duplicate-line

Ctrl+semicolon

push-bookmark

Ctrl+F3

quick-search

Ctrl+Shift+F2

quick-reverse-search

Shift+F1

scroll-up

Shift+F2

scroll-down

Shift+F3

scroll-left

Shift+F4

scroll-right

Tab

ctab

Shift+Tab

cbacktab

Ctrl+Shift+0
Ctrl+Shift+9

alt-bookmark

Ctrl+0 Ctrl+9

alt-gtbookmark

22150bapp01.qxd:WroxPro

9/25/07

1:53 AM

Page 433

Appendix A: Settings for Different Emulations


Table A-13 (continued)
Key

WROX

Alt+Home

center-line

Alt+PgUp

line-to-top

Alt+PgDn

line-to-bottom

Alt+T,K

activate-bookmarks

Alt+T,B

activate-build

Alt+T,A

activate-call-stack

Alt+T,C

activate-tbclass

Alt+T,D

activate-defs

Alt+T,H

activate-deltasave

Alt+T,L

activate-files-files

Alt+T,P

activate-files-project

Alt+T,W

activate-files-workspace

Alt+T,F

activate-find-symbol

Alt+T,T

activate-ftp

Alt+T,O

activate-open

Alt+T,U

activate-output

Alt+T,V

activate-preview

Alt+T,J

activate-projects

Alt+T,R

activate-references

Alt+T,X

activate-regex-evaluator

Alt+T,S

activate-search

Alt+T,Y

activate-symbols-browser

F5

config

Alt+Shift+A

wrox-make-anchor (Chapter 1)

continued

433

22150bapp01.qxd:WroxPro

9/25/07

1:54 AM

Page 434

Appendix A: Settings for Different Emulations


Table A-13 (continued)

434

Key

WROX

Alt+Left

prev-word

Ctrl+Left

wrox-prev-whitespace-word (Chapter 6)

Alt+Right

next-word

Ctrl+Right

wrox-next-whitespace-word (Chapter 6)

Ctrl+Shift+slash

wrox-toggle-comment (Chapter 9)

Alt+Enter

wrox-start-of-next-line (Chapter 10)

Alt+Shift+L

wrox-align-left-with-field-above (Chapter 10)

Alt+Shift+R

wrox-align-right-with-field-above (Chapter 10)

Alt+Shift+equals

wrox-execute-current-command (Chapter 16)

Alt+slash

wrox-insert-html-ending-tag (Chapter 16)

Alt+Up

wrox-move-line-up (Chapter 16)

Alt+Down

wrox-move-line-down (Chapter 16)

Tab

wrox-tab-matchtabs (Chapter 17)

Shift+Tab

wrox-backtab-matchtabs (Chapter 17)

Shift+F10

wrox-show-context-menu (Chapter 17)

Ctrl+W

wrox-show-wrox-popup-menu (Chapter 17)

PgDn

wrox-page-down-realign (Chapter 17)

Alt+J

wrox-join-line-with-space (Chapter 17)

22150bapp02.qxd:WroxPro

9/25/07

1:56 AM

Page 435

Regular Expression Syntax


Table B-1 shows the complete syntax for regular expression features in the three variants supported by SlickEdit. Chapter 7 contains a shorter version of this table. Chapter 7 also contains
explanations for some of the items in this table.

Table B-1
Definition

UNIX

SlickEdit

Brief

Match beginning of line.

%
<

Match end of line.

$
>

Match any character except newline.

Maximal match of zero or more occurrences of X.

X*

X@

X\:@

Maximal match of one or more occurrences of X.

X+

X#

X\:+

Maximal match of zero or one occurrences of X.

X?

X:0,1

X\:0,1

Match exactly n1 occurrences of X.

X{n1}
X{n1}?

X:n1

X\:n1
X\:n1?

Maximal match of at least n1 occurrences of X.

X{n1,}

X:n1,

X\:n1,

Maximal match of at least 0 occurrences but not


more than n2 occurrences of X.

X{,n2}

X:0,n2

X\:,n2

continued

22150bapp02.qxd:WroxPro

9/25/07

1:56 AM

Page 436

Appendix B: Regular Expression Syntax


Table B-1 (continued)

436

Definition

UNIX

SlickEdit

Brief

Maximal match of at least n1 occurrences but not


more than n2 occurrences of X.

X{n1,n2}

X:n1,n2

X\:n1,n2

Maximal match of zero or more of any character


except newline.

.*

?@

X\:*

Minimal match of zero or more occurrences of X.

X*?

X*

X\:0,?

Minimal match of one or more occurrences of X.

X+?

X+

X+

Minimal match of zero or one occurrences of X.

X??

X:*0,1

X\:0,1?

Minimal match of at least n1 occurrences of X.

X{n1,}?

X:*n1,

X\:n1,?

Minimal match of at least 0 occurrences but not


more than n2 occurrences of X.

X{,n2}?

X:*0,n2

X\:,n2?

Minimal match of at least n1 occurrences but not


more than n2 occurrences of X.

X{n1,n2}?

X:*n1,n2

X\:n1,n2?

Minimal match of zero or more of any character


except newline.

.*?

?*

Search fails if expression X is matched.

(?!X)

~X

Matches X or Y.

X|Y

X|Y

X|Y

Matches subexpression X but does not define a


tagged expression.

(?:X)

(X)

\(X\)

Matches subexpression X and specifies a new


tagged expression. No more tagged expressions
are defined once an explicit tagged expression
number is specified as shown below. See Chapter 7.

(X)

{X}

{X}

Matches subexpression X and specifies to use


tagged expression number d, where 0 d 9. No
more tagged expressions are defined by the
subexpression syntax (X) once this subexpression syntax is used.

(?dX)

{#dX}

{@dX}

Matches any one of the characters specified by


charset. A hyphen (-) character may be used to
specify ranges.

[charset]

[charset]

[charset]

Matches any character not specified by charset. A


hyphen (-) character may be used to specify
ranges.

[^charset]

[~charset]
[^charset]

[~charset]

22150bapp02.qxd:WroxPro

9/25/07

1:56 AM

Page 437

Appendix B: Regular Expression Syntax


Table B-1 (continued)
Definition

UNIX

SlickEdit

Brief

Character set subtraction. Matches all characters in charset1 except the characters in
charset2.

[charset1[charset2]]

[charset1[charset2]]

[charset1[charset2]]

Character set intersection. Matches all characters in charset1 that are also in charset2.

[charset1&
[charset2]]

[charset1&
[charset2]]

[charset1&
[charset2]]

Matches up to 31-bit Unicode hexadecimal


character specified by hhhh.

\x{hhhh}

\x{hhhh}

\x{hhhh}

(Only valid in character set) Matches


characters in UnicodeCategorySpec, where
UnicodeCategorySpec uses the standard
general categories specified by the
Unicode Consortium.

\p{Unicode
CategorySpec]

\p{Unicode
CategorySpec]

\p{Unicode
CategorySpec]

(Only valid in character set) Matches characters not in UnicodeCategorySpec.

\P{Unicode
CategorySpec]

\P{Unicode
CategorySpec]

\P{Unicode
CategorySpec]

(Only valid in character set) Matches


characters in UnicodeIsBlockSpec, where
UnicodeIsBlockSpec is one of the standard
character blocks specified by the Unicode
Consortium.

\p{UnicodeIs
BlockSpec]

\p{UnicodeIs
BlockSpec]

\p{UnicodeIs
BlockSpec]

(Only valid in character set) Matches characters not in UnicodeIsBlockSpec.

\P{UnicodeIs
BlockSpec]

\P{UnicodeIs
BlockSpec]

\P{UnicodeIs
BlockSpec]

Matches hexadecimal character hh, where


0 hh 0xff.

\xhh

\xhh

\xhh

Matches decimal character nnn, where


0 nnn 255.

\dnnn

\nnn

\dnnn

Defines a back reference to tagged expression number d. See Chapter 7.

\d

\gd

\d

Specifies cursor position if match is found.


See Chapter 7.

\c

\c

\c

Matches newline character sequence. Useful


for matching multiline search strings. What
this matches depends on whether the buffer
is a DOS (ASCII 13,10 or just ASCII 10), UNIX
(ASCII 10), Macintosh (ASCII 13), or userdefined ASCII file.

\n

\n

\n

continued

437

22150bapp02.qxd:WroxPro

9/25/07

1:56 AM

Page 438

Appendix B: Regular Expression Syntax


Table B-1 (continued)
Definition

UNIX

SlickEdit

Brief

Matches carriage return (ASCII 13).

\r

\r

\r

Matches tab character.

\t

\t

\t

\b

\b

Matches backspace character.


Matches form feed character.

\f

\f

\f

Matches any 2-byte DBCS character. This escape


is only valid in a match set ([...\od...]).
[^\od] matches any single byte character
excluding end-of-line characters. When used to
search Unicode text, this escape does nothing.

\od

\od

\od

Turns on multiline matching. This enhances the


match character set, or matches any character
primitives to support matching end-of-line characters. For example, \om.+ matches the rest of
the buffer.

\om

\om

\om

Turns off multiline matching (default). You can


still use \n to create regular expressions that match
one or more lines. However, expressions like .+
will not match multiple lines. This is much safer
and usually faster than using the \om option.

\ol

\ol

\ol

Declares character after slash to be literal.

\char

\char

\char

Matches predefined expression corresponding


to char.

\:char

:char

\:char

See Table B-2.

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

438

Description

Character

Matches an alphanumeric character.

Matches an alphabetic character.

22150bapp02.qxd:WroxPro

9/25/07

1:56 AM

Page 439

Appendix B: Regular Expression Syntax


Table B-2 (continued)
Description

Character

Matches blanks.

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.

439

22150bapp02.qxd:WroxPro

9/25/07

1:56 AM

Page 440

22150bapp03.qxd:WroxPro

9/25/07

1:57 AM

Page 441

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

Event

Arguments

_actapp_

Application activated (such


as getting focus).

Whether getting focus.

_b4wrst_

Before writing state file.

_buffer_add_

New buffer opened.

Buffer ID, buffer name, buffer


flags.

_buffer_renamed_

Before buffer renamed.

Buffer ID, buffer name, new


name, buffer flags.

_cbmdibufferhidden_

MDI buffer hidden.


continued

22150bapp03.qxd:WroxPro

9/25/07

1:57 AM

Page 442

Appendix C: SlickEdit Callbacks


Table C-1 (continued)

442

Name

Event

Arguments

_cbmdibuffer_unhidden_

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.

_cbquit_

Before file closed.

Buffer ID, buffer name, filename,


buffer flags.

_cbquit2_

After file closed.

Buffer ID, buffer name, filename,


buffer flags.

_cbsave_

File saved.

_cbstop_process_

Stopping build.

_cd_

Directory changed.

_diffOnExit_

End of DIFFzilla operation.

_diffOnStart_

Start of DIFFzilla operation.

_document_renamed_

Filename or buffer name


changed.

Buffer ID, old name, new name,


buffer flags.

_eventtab_modify_

Key bound.

Key binding table, key.

_ftpQBusy_

FTP busy.

_ftpQIdle_

FTP idle.

_lexer_updated_

Color coding lexer changed.

_lostfocus_

Lost focus.

_MenuAddFileHist_

Adding filename to File History


on File Menu.

Filename.

_MenuAddWorkspaceHist_

Adding workspace filename to


Project History on Project Menu.

Filename.

New directory.

Lexer name as stored in


.vlx file.

22150bapp03.qxd:WroxPro

9/25/07

1:57 AM

Page 443

Appendix C: SlickEdit Callbacks


Table C-1 (continued)
Name

Event

Arguments

_on_load_module_

Before loading module.

Module name.

_on_popup_

Before an editor window popup/context menu is displayed.

Menu name, menu handle.

_on_popup2_

Before any pop-up menu is


displayed.

Menu name, menu handle.

_on_unload_module_

Before unloading module.

Module name.

_postbuild_

Build completed.

Build arguments.

_prebuild_

Build about to start.

Build arg.

_prjclose_

Called after _project_name is


set to blank, when closing project.

_prjconfig_

Active project configuration


changed.

_prjedit_

Project properties edited.

_prjopen_

Opening project.

_prjupdate_

Project saved.

_project_file_add_

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).

_sr_

Save/restore.

_srg_

Save/restore global.

_switchbuf_

Switching buffer.

_vi_switchmode_

Switching mode in vi emulation.

_wkspace_close_

Closing workspace.

_workspace_file_add_

File added to workspace.

Project name, filename.

_workspace_open_

Before workspace opened.

Workspace filename.

_workspace_opened_

After workspace opened.

Handle to open project.

Project name, filename.

Old buffer name, option, old


pos, old buffer ID.

443

22150bapp03.qxd:WroxPro

9/25/07

1:57 AM

Page 444

22150bapp04.qxd:WroxPro

9/25/07

2:00 AM

Page 445

Whats on the CD-ROM


This appendix provides you with information on the contents of the CD that accompanies this
book. For the latest and greatest information, please refer to the ReadMe file located at the root of
the CD. Here is what you will find:

System Requirements.

Using the CD with Windows, Linux, UNIX, and Macintosh.

Whats on the CD.

Troubleshooting.

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.

22150bapp04.qxd:WroxPro

9/25/07

2:00 AM

Page 446

Appendix D: Whats on the CD-ROM


For AIX 5 and later:

At least 256 MB of total RAM installed on your computer.

250 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:

446

At least 256 MB of total RAM installed on your computer.

190 MB disk space.

A CD-ROM drive.

X11 for Mac OS X.

22150bapp04.qxd:WroxPro

9/25/07

2:00 AM

Page 447

Appendix D: Whats on the CD-ROM

Using the CD with Windows


To access the content from the CD, follow these steps:

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).

Using the CD with Linux and UNIX


To install the items from the CD to your hard drive, follow these steps:

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.

Command-line instructions: At the command prompt, type:

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

22150bapp04.qxd:WroxPro

9/25/07

2:00 AM

Page 448

Appendix D: Whats on the CD-ROM

5.
6.

Solaris Sparc <cdrom>/SlickEdit/solaris/sparc.

Solaris x86 <cdrom>/SlickEdit/solaris/x86.

Start the installation at the prompt: ./vsinst.


To remove the CD from your CD-ROM drive, follow these steps:

a.

Command line instructions: At the command prompt, type:

umount /mnt/cdrom.

b.

Graphical: Right-click on the CD-ROM icon on the desktop, and choose UMount
CD-ROM. This mounts your CD-ROM.

Using the CD with the Mac OS


To install the items from the CD to your hard drive, follow these steps:

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

22150bapp04.qxd:WroxPro

9/25/07

2:00 AM

Page 449

Appendix D: Whats on the CD-ROM

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

22150bapp04.qxd:WroxPro

9/25/07

2:00 AM

Page 450

9/25/07

2:01 AM

Page 451

Index

22150bindex.qxd:WroxPro

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

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 452

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

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

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

9/25/07

2:01 AM

Page 453

code editing
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 454

code editing (continued)


code editing (continued)
SlickEdit in-memory representations, 255
syntax assistance, suppressing, 185
See also Context Tagging
color syntax, search with, 144
color syntax highlighting, 173, 175177,
366367
Color Coding Setup dialog settings, 176177
color schemes, 176
Groovy, 368370
lexer settings, 174
program elements, 175176
screen elements, 176
search of, 135
columns, 202204
block editing, 208213
enter data, block insert mode, 203204
filling data, 203
navigation to, commands, 124
command(s), 192196
and arguments, 1011
basic functions, 9
binding to keys, 1114
color, changing, 176
command arguments, 328330
command keys, 392407
hyphens versus underscores in, 9, 328
invoking, 10
key commands, listing of, 408429
Slick-C, 11, 328330, 332
SlickEdit, 11
command keys
debugging, 392394
editing, 394398
file, 398399
macro, 399
navigation, 402404
project, 405
search, 405406
toolbar, 406
window, 407
command-line, 1011
commands, types entered on, 11
dos commands, use of, 11

454

history on, 11
message area as, 8
operating system, 11
search and replace 141146
selective display, 149
toggle to edit buffer, 10
comments
functions of, 192
JavaDoc comments, 195
line comments, 192194
multiline comments, 192, 194
settings, 195196
commit sets, 279282, 285
adding files to, 281282
creating, 280
Common User Access (CUA) emulation. See CUA
(Common User Access) emulation
comparison, 259266
DIFFzilla settings, 266
directories, 265
running standalone, 266
sections within file, 262265
two files, 260261
compile errors, navigation among, 53
compiler(s)
default compiler, 96
definiton and tag database, creating, 9698
selecting, 97
unlisted, new definition, creating, 9798
Compiler groups, contents of, 89
complete-more, 167, 188
complete-next, 167, 190
complete-prev, 166, 190
Concurrent Version System (CVS), 271293
accessing, 272
branches and tags, 282283
browse history, 283284
changes, committing, 278
changes, review of, 275277
checking out module, 275
commit sets, group changes with, 279282
Concurrent Version System (CVS), 271272
existing project, checking, 274275
files, adding to, 277

9/25/07

2:01 AM

Page 455

Courier New
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 456

CUA (Common User Access) emulation


CUA (Common User Access) emulation, 1920
Alt key combinations, 21
command keys, listing of, 392407
key commands, listing of, 408429
macro variable settings, listing of, 429431
stream model, 26
Current Context toolbar, 35
cursor
block selections, 201
color, changing, 176
current line, box around, 24
cursor wrap, 27
navigation commands, 120
selection, 156, 161
tab characters, jump over, 27
undo-cursor, 152
cursor-down, 120
cursor-down n, 124
cursor-error command, to open files, 119
cursor-left, 120
cursor-left n, 124
cursor-right, 124
cursor-right n, 124
cursor-up, 120
cursor-up n, 124
customization
dialogs, 372375
keyboard, 362365
language support, 365372
menus, 375378
programmatic configuration, 378388
custom projects, 7072
definitions, location for storage, 71
project template files, 71
Slick-C macro, 7172
XML file, editing, 71
cut, 154, 201
cut and paste, clipboard, 154155
cut-end-line, 153
cut-line, 153
CxxTest, 5458
downloading/installing, 57
running tests, 5960

456

test runner, 5758


test suites, 5457
CygWin
bash shell, single quotes as, 96
installing, 47

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

9/25/07

2:01 AM

Page 457

errors
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 458

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

F
Fast Open Dialog, 114115
file(s)
add file, 45
browse history, 283284, 291
command keys, 398399

458

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

9/25/07

2:01 AM

Page 459

GNU C/C++ project


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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 460

GNU C/C++ project (continued)


GNU C/C++ project (continued)
driver program, 4849
executing project, 53
files for, 4748
GNU C Options dialog, 53
target configurations, 60
unit tests, 5460
goto-bookmark, 128
goto-col n, 124
Go to definition, troubleshooting, 105106, 109
goto-line n, 124
goto-parent, 120
Go to Reference, troubleshooting, 107, 109
grep
Find and Replace tool window, 136
options, 85
search for symbols, 85
Groovy, 367372
color syntax highlighting, 368370
event tables, 371372
extension, defining, 371
information source on, 367
navigation, 370371
gui-enumerate, 205
gui-find, 132133
keyboard shortcut, 132
gui-make-tags, 92, 96, 100, 101, 109
gui-open, 114
gui-replace, 132133
keyboard shortcut, 132
gui-set-var, 2223
gui-sort, 204

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

Hex Source Window, 25


hidden lines, search through, 143
hide-all-comments, 146, 147
hide-code-book, 146
hide-dotnet-regions, 146, 147
hide-selection, 146
history
browsing, CVS, 283284
browsing, Subversion, 291
on command line, 11
Home key, settings, 29
hotspots
aliases, syntax expansion, 237238
if( ), 181
hsplit-window, 34
HTML
end tag, inserting, macro for, 348351
html-mode, 174
indentation, 180
JavaScript within, 191
HTTP resources, downloading of, 258
hyphens, in commands, 9

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

9/25/07

2:01 AM

Page 461

libraries
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

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

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

461

Index

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 462

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

462

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

9/25/07

2:01 AM

Page 463

next-buff-tab
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 464

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

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

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

9/25/07

2:01 AM

Page 465

quick-search
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 466

quick-search (continued)
quick-search (continued)
keyboard shortcut, 131
use of, 132
quote-key, 185

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

466

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

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

9/25/07

2:01 AM

Page 467

Slick-C
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 468

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

468

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

9/25/07

2:01 AM

Page 469

tag databases
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

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 470

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

470

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

9/25/07

2:01 AM

Page 471

window(s)
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

V
variable(s)
global, 330
macro, 2223, 330331

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

471

Index

22150bindex.qxd:WroxPro

22150bindex.qxd:WroxPro

9/25/07

2:01 AM

Page 472

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

472

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

22150badvert.qxd:WroxPro

9/25/07

2:03 AM

Page 473

Programmer to Programmer

TM

Take your library


wherever you go.
Now you can access more than 200 complete Wrox books
online, wherever you happen to be! Every diagram, description,
screen capture, and code sample is available with your
subscription to the Wrox Reference Library. For answers when
and where you need them, go to wrox.books24x7.com and
subscribe today!

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

You might also like