emacs inside of screen is made difficult because both want to use C-A for something important. C-O (AFAIK so far) isn't too useful for my use of emacs, so I use that for screen now:
screen -e^Oo emacs
screen -r
$HOME directory, plus the /Applications directory. There's probably other stuff that should be snarfed (like /Library), but I didn't on my last backup, and doing a restore from scratch seemed to work OK. Here's a quick outline of backing up to the external firewire drive called "Wikkit":
% sudo mkdir /Volumes/Wikkit/backup
% cd /Users
% sudo hfstar cf - bork | (cd /Volumes/Wikkit/backup; sudo hfstar xf -)
To Restore:
% cd /Users
% sudo mv bork bork-orig
% cd /Volumes/Wikkit/backup
% sudo hfstar cf - bork | (cd /Users; sudo hfstar xf -)
Some folks have had success with psync, but we haven't used it yet.
~/.inputrc file:
set completion-ignore-case On
Then when you type ls /appli in the shell you'll get ls /Applications/ like you ought to!
% ~/bin/rename.pl 's/.oop$/.ack/' *.oop
To tack on an extension to all files, do something like
% ~/bin/rename.pl 's/(.*)/$1.jpg/' *
% perl -pi -e 's/\r/\n/g' mealcsv.csv
tr '\r' '\n' < macfile.txt > unixfile.txt
# svc -d /service/whatever - Bring the server down
# svc -u /service/whatever - Start the server up and leave it in keepalive mode.
# svc -o /service/whatever - Start the server up once. Do not restart it if it stops.
# svc -t /service/whatever - Stop and immediately restart the server.
# svc -k /service/whatever - Sends the server a KILL signal. This is like KILL -9. If svc -t fails to fully kill the process, use this option.
(Thanks to the OpenACS documentation)
% cd /Users/bork/Library/Screen\ Savers
or you can surround it with quotes:
% cd "/Users/bork/Library/Screen Savers"
Note that tilde expansion (~/Library) is suppressed if you use the quotes.
% screen -r
There is a screen on:
8395.pts-0.vikki (Multi, attached)
You can boot off that other loser by using:
% screen -d 8395.pts-0.vikkiand then doing
screen-r again
% du -sk dir_name
To see how much each of a directory's contents consume, use
% du -sk dir_name/* | sort -n
to get a list ordered by size.
% cd directory
% find . -name "*.h" -exec grep NSDoWhatIMean {} ; -print{} construct. Also make sure there's a space after the {} and ;
-h flag:
% grep -h chicken ~/Documents/ircLogs/FreeNode/2007*/#macsb*
% sw_vers
ProductName: Mac OS X ProductVersion: 10.3.7 BuildVersion: 7S215
% ps -eo "%p %P %c"
% find . -type f -perm +06000 -print
(or use find / to start looking from the root directory.)
% grep -c "fix me" *.m
% curl -O http://borkware.com/quickies/files/fullscreensaver.tar.gz
-l (dash ell) flag to grep. If a file contains the expression, the name of the file (rather than the matching line) is displayed.
e.g. to open all the files that contain 'rzolf'
% grep -l rzolf *.ham | xargs open
-e option to the rescue:
% grep -e -H filename
% hdiutil mount diskimage.dmg
LANG environment variable to be en_US to make it happier.
% rm -- -i-am-a-bad-file
% perl -pi.bak -e 's/OLDSTRING/NEWSTRING/g' *.html
% find . -type f -name "*.html" -exec grep Spoon {} ; -print
% sudo sh -c "tar cf - * | (cd /mirror4/web; tar xf -)"
% xmllint -noout kipple.xml
Handy for a quick check after hand-editing a file.
% gcc -v --help
ls -l:
% ls -l ~/junk/SnapshotRepository.sparseimage -rw-r--r--@ 1 markd markd 135270400 Jul 24 20:38 /Users/markd/junk/SnapshotRepository.sparseimageThat means there's some extended attributes. use
ls -l@ to see them:
% ls -l@ ~/junk/SnapshotRepository.sparseimage -rw-r--r--@ 1 markd markd 135270400 Jul 24 20:38 /Users/markd/junk/SnapshotRepository.sparseimage com.apple.diskimages.fsck 20
% tail -f /var/tmp/console.log
% unzip -l snorgle.zip
ppid option with the -o flag:
% ps -axo user,pid,ppid,vsz,tt,state,start,time,command
^t is the hotkey, doing ^t ^g will toggle the visible bell on and off.
% find . \( -name "*.jpg" -or -name "*.gif" \) -exec do_something_with {} ;
% find . -name "*.jpg" -exec convert -verbose -geometry 150x150 {} {} ;
% identify filename.jpg
If you want to be studly, you can use -format to tailor
the output
% identify -format "insert into bw_graphics values (generate_primary_key(), '/images/llamas/%f', %w, %h);" *.jpg
generates a sql insert statement for each image.
nm outputs a three-column format. I needed to get the set of defined symbols (in particular those that start with __, in tracking down a C++ linking problem), which is the third column. awk is good for that. Use $N to get the nth column (zero-index). This pipeline did the trick:
nm ./oopack.o | awk '{print $2}' | sort | grep __
(Thanks to DougEDoug for the pointer)
% awk '{ for (f=1; f <= NF; f++) { if (f != 1 && f != 9) printf("%s ", $f);} printf("
");}' < ook.txt
Or you can put this at the end of a pipeline instead of directing a text file into the command. (courtesy of DougEDoug)
% tar cf - ./stuff | ssh theOtherMachine "tar xf -"
% cd /Users/bork/development/cool\ stuff/neat\ things
The other is to use shell completion to put in the backslashes for you. In
the above path, if you type
% cd /Users/bork/development/cool[tab], it'll expand
"cool stuff" for you.
cp -R is generally unsafe to copy directories with since it will copy through symbolic links rather than just copying the link (newer cp's have an -H flag that will work around this). The classic unix way of doing things like this is a push-pull tar:
% tar cf - dir-name | (cd /destination-dir; tar xf -)
In English: tar out through a pipe into a subshell that's changed directories, feeding that pipe into the tar extraction. If you run both sides of the pipeline as root (via sudo), the file owners and permissions will be preserved (which cp won't do)
% find . -name "*.yuck" -print | xargs tar rvf oop.tar
% ssh-keygen -t rsa
% scp ~/.ssh/id_rsa.pub gitdown.com:
% cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
mv: rename build/ to oopack: Is a directorywhen using
mv or ln on the command line, that's a Darwin error. To correct the problem, remove the trailing slash from the directory name.
% sudo tcpdump -Atq -s 0 -i en1
-i en1 will display traffic on your airport card. Use en0 (or nothing, for most systems) for built-in ethernettage.
You can add a host line to limit output to a particular host
% sudo tcpdump -Atq -s 0 -i en1 host zombo.com(thanks to Dan Jalkut for this one)
touch. You can specify a specific date or time using the format [[CC]YY]MMDDhhmm[.SS]]. Here's an example with alternating bolds to make it easier to read:
% touch -t 200703141536 snork.waffle % ls -l snork.waffle -rw-r--r-- 1 markd markd 298 Mar 14 15:36 snork.waffle
% hdid ram://size
where size is the size in bytes. the system will round that number up or down as it sees fit.
% sw_vers -productVersion 10.5.1
/usr/bin/drutil info to get a listing of the kinds of media your drive supports. For example, on the 17" iLamp:
% drutil info
Vendor Product Rev
PIONEER DVD-RW DVR-104 A227
Interconnect: ATAPI
SupportLevel: Apple Shipping
Cache: 2000k
CD-Write: -R, -RW, BUFE, Test, IndexPts, ISRC
DVD-Write: -R, -RW, BUFE, Test
Strategies: CD-TAO, CD-SAO, DVD-DAO
chflags in Mac OS X works like chattr over in Linux-land. So to make a file immutable (can't change it, even if you're the superuser), you can sudo chflags uchg file-name(s). To undo it, do sudo chflags nouchg file-name(s)
# niutil -create . /machines/tower # niutil -createprop . /machines/tower ip_address 10.0.1.155 # niutil niutil -createprop . /machines/tower serves ./local
/System/Library/StartupItems/SystemTuning/SystemTuningtweak some values, like
sysctl -w kern.sysv.shmmax=167772160 # bytes: 160 megs sysctl -w kern.sysv.shmmin=1 sysctl -w kern.sysv.shmmni=32 sysctl -w kern.sysv.shmseg=8 sysctl -w kern.sysv.shmall=65536 # 4k pages: 256 megsSave, and restart your system.
On some Panther seeds, you may need to add these things to /etc/rc
/etc/rc, but you want to be able to back out your changes. You also want to preserve the original timestamp of the file. That way if you back out your change, someone else coming along doesn't have to figure out "why did /etc/rc change yesterday, it doesn't look any different?" Here's how:
% sudo mv rc rc-orig
% sudo cp rc-orig rc
% sudo vi rc
% sudo mv rc-orig rcThereby undoing your changes, and not messing up the timestamp of the original file.
(mucho thankos to Louis Bertrand for this one)
cc1obj: error: type '<built-in>' does not have a known size(void), a typo that should have been (void *).
@executable_path/../blah. Sometimes you get a library from someone else (or something generated by a gigantic configure script) and need to change the install name. The install_name_tool will do that for you. Say I had a library, libbork.dylib, that will end up being placed side-by-side with the executable of a cocoa app, this is how I would fix it:
% install_name_tool -id @executable_path/libbork.dylib ./libbork.dylib
In Interface Builder 2: If you hold down the control key while resizing, though, the contents obey their spring configurations and will resize accordingly. Makes the process a whole lot easier.
In Interface Builder 3: If you hold down command while resizing, the contents obey their spring configurations and will resize accordingly. (This avoids the annoying process of resizing each widget within the windows afterwards.) Holding option while resizing will display the pixel values of the padding. Holding command-option while dragging displays both.
(muchos thankos to Quinn Taylor at the BYU CocoaHeads for the IB3 update)
% gcc -E -dM -x c /dev/null
(thanks to xmath on #macdev for this one)
% otool -L /path/to/application.app/Contents/MacOS/application
The problem is, if I include the usefulStuff.c in my plugin and my test harness, there are two copies of the static variables, and the test harness can't control the plugin. If I don't include usefulStuff.c in the plugin I get link errors. If I don't declare as weak linked the functions I use, I'll get errors when the final program loads the plugin. Sucks to be me.
Here's one way of doing it (which is kinda hacky, but after spending a day inside of the ld man page, and other pain, the fact it works is good enough for me for right now).
In the source file for the plugin that uses stuff from usefulStuff:
Declare the function to be weak:
extern void BWDebugLog (int blah, char *blah) __attribute__((weak_import));(you can also do this in your header files. In this case, I didn't want to touch the header)
Before you use the function, make sure it's not NULL. Note there's no trailing () after the function name.
if (BWDebugLog != NULL) {
BWDebugLog (23, "stuff");
}
In the Xcode project for the plugin
Add the flags -flat_namespace and -undefined dynamic_lookup to the "Other Linker Flags" (a.k.a. OTHER_LDFLAGS). The flat namespace lets the symbols be found in the test harness when the plugin is loaded. The undefined dynamic_lookup means to suppress warnings about undefined symbols. This could conceivably mask errors, but it's no worse than ZeroLink.
In the Xcode project for the test harness
Add usefulStuff.c, and turn on the "Preserve Private External Symbols" checkbox (a.k.a -keep_private_externs). That turns the symbol BWDebugLog (and others) into exported symbols that'll be visible to the plugin. Otherwise the plugin will never get past that != NULL check earlier.
Once all that's done, my plugin loads into the test harness and can get controlled. It can be loaded into the Real App without undefined symbol errors.
BWNagType.h:23: `BWConcreteType' defined as wrong kind of tag
In this particular case, I had a type I had declared with:
@class BWConcreteType;
and later on I had decided to turn it into an enum:
typedef enum BWConcreteType { ... } BWConcreteType;
without removing the previous @class declaration. So be on the look out for conflicting types for the same symbol.
xcodebuild. We've got a rant about cocoa development in emacs, which includes a discussion of pbxbuild, the predecessor to xcodebuild. Some of the arguments have changed over the years. I usually run it like: % xcodebuild -configuration "Debug" -target "My Groovy App"If you have one target, or have a default target, you can leave out the
-target argument.
% defaults write com.borkware.snongflozzle ookook -array thing1 thing2 thing3
[self performSelector: @selector(whatever) withObject: nil afterDelay: 0];
The selector gets posted after a sub event loop finishes. You can use this for finding out when a live slider is done being manipulated, for instance
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
gridType = [defaults objectForKey: @"gridType"];
Will have the value of "flarn" whether you do something like
% defaults write com.borkware.BorkStitch gridType flarnor
% ./build/Debug/BorkStitch.app/Contents/MacOS/BorkStitch -gridType flarn
void giveSomeLove ()
{
// give the app some love so it'll update the window
[[NSRunLoop currentRunLoop] runUntilDate: [NSDate distantPast]];
} // giveSomeLove
unsigned index;
for (index = [indexSet firstIndex];
index != NSNotFound; index = [indexSet indexGreaterThanIndex: index]) {
...
}
(courtesy of mikeash)
if ([NSBundle loadNibNamed: @"theNibName.nib" owner: self]) {
... life is happy
} else {
... couldn't load the nib
}
NSRect selectionRect = ...;
NSValue *value;
value = [NSValue valueWithRect: selectionRect];
% find . -name "*.h" -print -exec cat {} \; > ~/moby-file.h
static void *tempCopyOf(void *data, UInt32 size) {
void *buffer = NULL;
if (data) {
buffer = malloc(size);
if (buffer) {
bcopy(data, buffer, size);
[NSData dataWithBytesNoCopy: buffer length: size freeWhenDone: YES];
}
}
return (buffer);
}
This works in a AutoReleased environment but it is long winded.
static void *tempCopyOf(void *data, NSUInteger size)
{
void *buffer = NULL;
if (data) {
buffer = [[NSMutableData dataWithCapacity: size] mutableData];
bcopy(data, buffer, size);
}
return buffer;
}
You can choose to check the buffer is not null but this avoids the more complicated malloc then alloc call of earlier.
NSString *filename = @"/this/is/my/file/path";
NSData *data;
data = [NSData dataWithContentsOfFile: filename];
In this case, the selector being called takes two arguments, one of which is an object, the other is an NSTimeInterval. The atIndex: jazz starts with 2 so that the self parameter and the selector can be passed to the method.
NSMethodSignature *signature = [target_ methodSignatureForSelector:selector_];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:selector_];
[invocation setTarget:target_];
[invocation setArgument:&self
atIndex:2];
[invocation setArgument:&lastWait_
atIndex:3];
[invocation invoke];
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setPrompt: @"Stuff for the Choose Button"];
[panel beginSheetForDirectory: nil
file: nil
types: [NSArray arrayWithObject: @"buf"] // or other file types
modalForWindow: window
modalDelegate: self
didEndSelector: @selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo: nil];
and the didEndSelector implementation looks kinda like this:
- (void) openPanelDidEnd: (NSOpenPanel *) sheet
returnCode: (int) returnCode
contextInfo: (void *) context
{
if (returnCode == NSOKButton) {
NSArray *fileNames = [sheet filenames];
NSLog (@"wooOOooot! %@", [fileNames objectAtIndex: 0]);
}
} // openPanelDidEnd
Localizable.string, your NSLocalizedString() call will not look up the strings in the file. To verify the file, do something like this:
% pl < Localizable.strings
% gcc -E -dM - </dev/null
// NSLog() writes out entirely too much stuff. Most of the time I'm
// not interested in the program name, process ID, and current time
// down to the subsecond level.
// This takes an NSString with printf-style format, and outputs it.
// regular old printf can't be used instead because it doesn't
// support the '%@' format option.
void QuietLog (NSString *format, ...) {
va_list argList;
va_start (argList, format);
printf ("%s\n", [[NSString stringWithFormat: format, argList] UTF8String]);
va_end (argList);
} // QuietLog
(Thanks to Quinn Taylor for a shorter version)
# pmset lidwake 0
NSString *pathString = ... whatever ...;
FSRef ref;
status = FSPathMakeRef ((const UInt8 *)[pathString fileSystemRepresentation],
&ref, NULL);
if (status != noErr) {
NSLog (@"bummer. couldn't make FSREf from path '%@'",
pathString);
}
% /Developer/Tools/DeRez -useDF ./blarg.rsrc /Developer/SDKs/MacOSX10.4u.sdk/Developer/Headers/FlatCarbon/MacTypes.r > oopack2And the reverse process is like:
% /Developer/Tools/Rez -o blah.rsrc -useDF /Developer/SDKs/MacOSX10.4u.sdk/Developer/Headers/FlatCarbon/MacTypes.r oopack2
% cat /System/Library/Frameworks/Foundation.framework/Headers/*.h > ~/moby % cat /System/Library/Frameworks/AppKit.framework/Headers/*.h >> ~/moby % chmod 444 ~/moby
- (void) snorgWaffle: (NSString *) start, ... {
va_list argList;
va_start (argList, start);
NSString *string = start;
while (string != nil) {
NSLog (@"Done did saw string '%@'", string);
string = va_arg (argList, NSString *);
}
va_end (argList);
} // snorgWaffle
and can be called like
[self snorgWaffle:@"red", @"planet", @"zeitgeist", nil];
printf ("hello %.*s\n", 5, "there is no good going on");
NSLog (@"hello %.*s\n", 5, "there is no good going on");
results in
hello there 2007-05-04 09:14:15.575 printf[4914] hello there
Similarly, something like printf ("hello %*.*s\n", 10, 5, "florgsnorgle"); will right-justify 'florg' in a field of 10 characters.
(Thanks to TVL for this goodie)
int AmIBeingDebugged(void)
{
int mib[4];
struct kinfo_proc info;
size_t size;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = getpid();
size = sizeof(info);
info.kp_proc.p_flag = 0;
sysctl(mib,4,&info,&size,NULL,0);
return ((info.kp_proc.p_flag & P_TRACED) == P_TRACED);
}
#define StopIfInDebugger() __asm__ volatile ("twnei %0,0" : : "r" (AmIBeingDebugged()))
(courtesy of arwyn on #macdev. Useful uses: controlling voluminous console output when running in gdb, or if running non-debugged, an assert routine that generates stack trace and logs it when not-being debugged, but just traps into the debugger at the point of failure when being debugged)
gdb There are two ways to enable core files:
% limit coredumpsize unlimited.cshrc. I don't know what to do for bash)
struct rlimit corelimit = { RLIM_INFINITY, RLIM_INFINITY };
setrlimit (RLIMIT_CORE, &corelimit);
You may need to also add#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
Core files seem to be getting dumped into /cores, rather than the directory the program was run from.
/System/Library/Frameworks/Foundation.framework/Headers/NSDebug.h. Lots of low-level unsupported APIs for mucking around with gory technical details.
% defaults write com.apple.CrashReporter DialogType none
Turn turn it back on, replace none with prompt to get the original behavior. See for details.
fprintf
% gdb build/Debug/Snorkfizzle.app/Contents/MacOS/Snorkfizzle (gdb) set env NSZombieEnabled=YES (gdb) fb -[_NSZombie methodSignatureForSelector:] (gdb) runThen exercise your app and trip the error.
(gdb) thread apply all where
(gdb) fb -[NSTextView drawRect:]
b objc_msgSend comm silent printf "%c[%s %s]\n", $r3&&((id)$r3)->isa->info&2?'+':'-', $r3?((id)$r3)->isa->name:"nil", $r4 cont end b objc_msgSend_rtp comm silent printf "%c[%s %s]\n", $r3&&((id)$r3)->isa->info&2?'+':'-', $r3?((id)$r3)->isa->name:"nil", $r4 cont endAnd you'll get some output like this:
-[NSTableColumn _bindingAdaptor] +[NSBinder binderClassesForObject:] +[NSBinder _allBinderClasses] +[NSDisplayPatternTitleBinder isUsableWithObject:] +[NSBox self](courtesy of Rob Mayoff)
Borkdoku(11062,0xcec0600) malloc: *** error for object 0xd109010: incorrect checksum for freed object - object was probably modified after being freed, break at szone_error to debugWhich is fine and dandy, but it lies. I've never gotten
szone_error to actually do anything. Try breaking on malloc_printf instead.
2007-05-05 17:18:00.702 QueenStitcher[2804:117] *** Assertion failure in -[NSColorWell setColor:], NSColorWell.m:497, u suk l0s3r, and then the runloop happily runs again, giving you no clue where the problem is. I tell gdb to always break on Cocoa exceptions:
fb -[NSException raise] fb objc_exception_throw()For maximal enjoyment, add these two lines to your
~/.gdbinit file, so they'll get set no matter how you invoke gdb (no need to add these to every single project, for instance).
I've been told VoiceOver uses exceptions heavily, so if you're doing VoiceOver development, these breaks may cause you pain.
'bork'. You can have gdb print them out if you need to look at one or two of them:
(gdb) print/T 1936746868 $4 = 'spit'(thanks to Daniel Jalkut for the print/T trick)
(gdb) po *(int*)($ebp+8)
(gdb) handle SIGTRAP nostop
The signal still goes to your program. Another handy option is 'ignore' to prevent it coming to the program. Also there is 'print' to print a message go on.
$r3 and go up from there. For Objective-C method sends, $r3 has 'self', and $r4 has the name of the method. Subsequent arguments are in $5 and so on.
(gdb) print (char*) $r4 $5 = 0x90874160 "drawRect:" (gdb) po $r5 <BWStitchView: 0x1a6670>
(gdb) print (int)[theObject retainCount]
If you're expecting to have an excessively high number of retains, you can use (unsigned int) in the cast. I find (int) a skootch faster to type.
.gdbinit and then you can use wchar_print:
define wchar_print
echo "
set $i = 0
while (1 == 1)
set $c = (char)(($arg0)[$i++])
if ($c == '\0')
loop_break
end
printf "%c", $c
end
echo "
end
document wchar_print
wchar_print <wstr>
Print ASCII part of <wstr>, which is a wide character string of type wchar_t*.
end
info selectors will show you all of the selectors in the application's symbol table. info functions will show you all of the functions. You can supply regular expressions to limit the output.
libgmalloc puts guard pages at the end of malloc'd blocks of memory, letting you catch buffer overruns. (This will hugely inflate your program's working set, and may lead to swapping) To turn on libgmalloc in gdb, do this:
(gdb) set env DYLD_INSERT_LIBRARIES /usr/lib/libgmalloc.dylib
(gdb) call (void)[textField setStringValue: @"Bork"]
(gdb) call (id) objc_getClass("NSBundle")
$1 = (struct objc_object *) 0xa0a051d8
gdb) call (id)[$1 bundleWithPath:@"/blah/blah/PoseAsClassBundle.bundle"]
$2 = (struct objc_object *) 0x51467e0
(gdb) call (BOOL)[$2 load]
Reading symbols for shared libraries . done
.emacs file:(global-set-key "C-Z" nil)
#define DONT_REOPEN_PTY
(setq c-default-style "bsd"
c-basic-offset 4)
deletechar into backward-delete-char-untabify causes backspace in incremental search to cancel the search, which is annoying.
One option is to set the TERM env var to rxvt:
% setenv TERM rxvtBefore cranking up screen.
C-x ( : start recording keyboard macroC-x ) : stop recording keyboard macroC-x e : replay current keyboard macro
.emacs file. This will make spaces the indent character, and use 4 spaces per indent level, for C, C++, and Objective C:
(setq c-mode-hook
(function (lambda ()
(setq indent-tabs-mode nil)
(setq c-indent-level 4))))
(setq objc-mode-hook
(function (lambda ()
(setq indent-tabs-mode nil)
(setq c-indent-level 4))))
(setq c++-mode-hook
(function (lambda ()
(setq indent-tabs-mode nil)
(setq c-indent-level 4))))
!$). M-x dirs will tell the shell buffer to figure out what the current working directory is.
M-x narrow-to-region
Hides everything not in the current region.
$Id: $ tags for CVS are nice, but it can be a pain when you're doing lots of checkins and have to re-load the file each time. You can either execute M-x revert-bufer or bind that to a key, or else use a trick by doing C-x C-v which invokes find-alternate-file, but just so happens to have the current buffer name, so you just have to do C-x C-v RET
uuidgen, for instance:
C-U M-! ret uuidgen ret
C-U 0 C-L(you can put in another number besides zero to scroll the line with the cursor to that particular line in the buffer)
/* For the emacs weenies in the crowd. Local Variables: c-basic-offset: 2 End: */
M-x column-number-mode
C-X C-Q
(setq comint-highlight-input nil)
(global-font-lock-mode -1)
(setq search-highlight nil)
You may also need to
(setq isearch-lazy-highlight nil)
To turn off underlining of matching results. Only some OS X installs need this setting.
(setq comint-scroll-show-maximum-output nil)
C-U C-_
M-x widen
C-Q C-J (control-Q control-J) each time you want to include a carriage return. e.g. to double-space everything
M-x replace-string RET C-Q C-J RET C-Q C-J C-Q C-J RET
Or to put "bloogie " at the beginning of every line
M-x replace-string RET C-Q C-J RET C-Q C-J b l o o g i e SPACE RET
.el files take a long time to load.
You can compile them into .elc files by using:% emacs -batch -f batch-byte-compile filename.el
[NSApp beginSheet: saveSheet
modalForWindow: window
modalDelegate: self
didEndSelector: @selector(saveSheetDidEnd:returnCode:contextInfo:)
contextInfo: NULL];
In the controls in the sheet, use something like
[NSApp endSheet: saveSheet returnCode: NSOKButton];To invoke the
didEndSelector. Inside of that method, you can check the return code and decide what to do:
- (void) saveSheetDidEnd: (NSWindow *) sheet
returnCode: (int) returnCode
contextInfo: (void *) contextInfo
{
if (returnCode == NSOKButton) {
// ...
} else if (returnCode == NSCancelButton) {
// ...
} else {
// ...
}
[sheet close];
} // saveSheetDidEnd
setFrame: for a window, you have to account for the height of the title bar. In the Classic days it was 16 pixels. In Aqua-land, it's currently 22 pixels. But that's not safe to use, so try this instead:
- (float) titleBarHeight
{
NSRect frame = NSMakeRect (0, 0, 100, 100);
NSRect contentRect;
contentRect = [NSWindow contentRectForFrameRect: frame
styleMask: NSTitledWindowMask];
return (frame.size.height - contentRect.size.height);
} // titleBarHeight
Rainer Brockerhoff points out that this might miss any system-suppled window decorations at the bottom of the window. There aren't any now, but Mac OS X 10.37 Sabertooth might, so you may want to take into account the y positions of the original rectangle and the newly calculated content rect.
window method, that will force the nib file to be loaded. Something like this:
+ (BWInspector *) sharedInspector
{
static BWInspector *s_inspector;
if (s_inspector == nil) {
s_inspector = [[BWInspector alloc]
initWithWindowNibName: @"BWInspector"];
assert (s_inspector != nil);
// force loading of nib
(void) [s_inspector window];
}
return (s_inspector);
} // sharedInspector
[sheet close] in addition to your [NSApp endSheet: sheet returnCode:23]
[panel setHidesOnDeactivate: NO];
setFrame:display:animate: to resize a window, and have the window animate between the two sizes. Remember that Cocoa uses a bottom-left origin, which is a pain when dealing with windows. You want the window's top left to be the same between the old and new sizes, so you have to dink with the origin as well as the size:
float delta = ... how much to make the window bigger or smaller ...;
NSRect frame = [window frame];
frame.origin.y -= delta;
frame.size.height += delta;
[window setFrame: frame
display: YES
animate: YES];
NSViewAnimation lets you resize a window and cross-fade some views in one operation. (note I've had problems with the window size getting a couple of pixels off using this. Hopefully either I'm doing something dumb, or Apple fixes a bug). This code resizes the window, and changes the view that lives inside of a box. This is like how the Pages inspector works (except Pages doesn't do the gratuitous animation effect)
NSRect newWindowFrame = ... the new window size;
NSDictionary *windowResize;
windowResize = [NSDictionary dictionaryWithObjectsAndKeys:
window, NSViewAnimationTargetKey,
[NSValue valueWithRect: newWindowFrame],
NSViewAnimationEndFrameKey,
nil];
NSDictionary *oldFadeOut = nil;
if (oldView != nil) {
oldFadeOut = [NSDictionary dictionaryWithObjectsAndKeys:
oldView, NSViewAnimationTargetKey,
NSViewAnimationFadeOutEffect,
NSViewAnimationEffectKey, nil];
}
NSDictionary *newFadeIn;
newFadeIn = [NSDictionary dictionaryWithObjectsAndKeys:
newView, NSViewAnimationTargetKey,
NSViewAnimationFadeInEffect,
NSViewAnimationEffectKey, nil];
NSArray *animations;
animations = [NSArray arrayWithObjects:
windowResize, newFadeIn, oldFadeOut, nil];
NSViewAnimation *animation;
animation = [[NSViewAnimation alloc]
initWithViewAnimations: animations];
[animation setAnimationBlockingMode: NSAnimationBlocking];
[animation setDuration: 0.5]; // or however long you want it for
[animation startAnimation]; // because it's blocking, once it returns, we're done
[animation release];
// I am the very modal of a modern major general. int blah = [NSApp runModalForWindow:[self window]];and then elsewhere, like in your OK or cancel button
[NSApp stopModalWithCode:NSOKButton];
NSWindowController:
@interface BWInspector : NSWindowController
{
// ivars, IBOutlets, etc
}
// IBActions, etc
+ (BWInspector *) sharedInspector;
@end // BWInspector
Then make a nib file with the window, the controls, and other fun stuff you want. This one lives in English.lproj/BWInspector.nib
Then in that class method load the window:
+ (BWInspector *) sharedInspector
{
static BWInspector *g_inspector;
if (g_inspector == nil) {
g_inspector = [[BWInspector alloc]
initWithWindowNibName: @"BWInspector"];
assert (g_inspector != nil); // or other error handling
[g_inspector showWindow: self];
}
return (g_inspector);
} // sharedInspector
That will load the nib file, set up the connections and then open the window for display
@implementation NSView (BWYellowView)
- (void) drawRect: (NSRect) rect
{
NSColor *transparentYellow;
rect = [self bounds];
transparentYellow = [NSColor colorWithCalibratedRed: 1.0
green: 1.0
blue: 0.0
alpha: 0.333];
[transparentYellow set];
[NSBezierPath fillRect: rect];
} // rect
@end // BWYellowView
I have no idea how you colorize the titlebar.
NSWindow and override sendEvent:
- (void) sendEvent: (NSEvent *) anEvent
{
if ([anEvent type] == NSKeyDown) {
[someOtherWindow sendEvent: anEvent];
} else {
[super sendEvent: anEvent];
}
} // sendEvent
It's up to you to figure out what "someOtherWindow" is, whether it's a delegate or an instance variable that holds the other window.
static void *tempCopyOf(void *data,UInt32 size) {
void *buffer = NULL;
if (data) {
buffer = malloc(size);
if (buffer) {
bcopy(data,buffer,size);
[NSData dataWithBytesNoCopy: buffer length: size freeWhenDone: YES];
}
}
return (buffer);
}
You can get really fancy and assign buffer to calloc(1, size) if you want to give it "pass NULL to get a zero-filled buffer back" semantics.
Also note this doesn't play well with garbage collection - caveat nerdor. (Thanks to Ken Ferry for that note)
poseAsClass: to hook yourself into the matrix during the +load method:
@interface BorkSpellChecker : NSSpellChecker
{
}
@end // BorkSpellChecker
@implementation BorkSpellChecker
+ (void) load
{
NSLog (@"posing");
[self poseAsClass: [NSSpellChecker class]];
} // load
- (void) ignoreWord: (NSString *) word inSpellDocumentWithTag: (int) tag
{
NSLog (@"ignore word: %@ intag: %d",
word, tag);
[super ignoreWord: word
inSpellDocumentWithTag: tag];
} // ignoreWord
Open up Internet Connect, select your VPN icon in the toolbar, and choose options from the Connect menu. Uncheck "Disconnect when switching user accounts".
if ([event modifierFlags] & NSShiftKeyMask) {
constrain = YES;
}
If you need to check them outside of your mouseDown, dip into carbon:
NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil];
- (void) keyDown: (NSEvent *) event
{
NSString *characters;
characters = [event characters];
unichar character;
character = [characters characterAtIndex: 0];
if (character == NSRightArrowFunctionKey) {
[self moveSelectedBlockBy: 1];
} else if (character == NSLeftArrowFunctionKey) {
[self moveSelectedBlockBy: -1];
} ... and look at whatever other keys you want
}
NSView's viewWithTag: to find it.
[self lockFocus];
NSBitmapImageRep *bits;
bits = [[NSBitmapImageRep alloc]
initWithFocusedViewRect: [self bounds]];
[self unlockFocus];
Then you can add it to an NSImage or save it to a file, or whatever.
If you want to retain the vectoritude of the drawing, you can use [self dataWithPDFInsideRect: [self bounds]], and then make an NSPDFImageRep. Avoid the NSEPSImageRep since it makes a trip through NSPDFImageRep along with a slow PS to PDF conversion. (Thanks to Peter Hosey for the PDF hint)
NSEventTrackingRunLoopMode, such as you wanting to use an NSNotificationQueue to coalesce updates for your own mouse tracking code. I've been sticking a call to this in my mouseDown: handler for the cases when I want the secondary run loop
- (void) runEventTrackingRunLoop
{
NSEventType eventType = NSLeftMouseDown;
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask
| NSLeftMouseDraggedMask | NSMouseMovedMask;
while (eventType != NSLeftMouseUp) {
NSEvent *event;
event = [NSApp nextEventMatchingMask: eventMask
untilDate: [NSDate distantFuture]
inMode: NSEventTrackingRunLoopMode
dequeue: YES];
eventType = [event type];
if (eventType == NSLeftMouseDragged) {
[self mouseDragged: event];
}
}
} // runEventTrackingRunLoop
(and thanks to Rainer Brockerhof for pointing out a no-op line of code from the original version of this)
@interface Blah : NSView
{
NSPoint grabOrigin;
NSPoint scrollOrigin;
}
@end // Blah
...
@implementation Blah
...
- (void) mouseDown: (NSEvent *) event
{
// deal in window coordinates. there is a scrolling problem
// if using view coordinates because view coordinates
// can get transformed
grabOrigin = [event locationInWindow];
NSClipView *contentView;
contentView = (NSClipView*)[layerView superview];
scrollOrigin = [contentView bounds].origin;
} // mouseDown
- (void) mouseDragged: (NSEvent *) event
{
NSPoint mousePoint;
mousePoint = [event locationInWindow];
float deltaX, deltaY;
deltaX = grabOrigin.x - mousePoint.x;
deltaY = mousePoint.y - grabOrigin.y;
NSPoint newOrigin;
newOrigin = NSMakePoint (scrollOrigin.x + deltaX,
scrollOrigin.y + deltaY);
[layerView scrollPoint: newOrigin];
} // mouseDragged
...
@end // Blah
You can be fancy and check for the option key by look at [event modifierFlags] and looking for NSAlternateKeyMask, and also use the NSCursor open/closedHandCursor.
- (void) keyDown: (NSEvent *) event
{
NSString *chars = [event characters];
unichar character = [chars characterAtIndex: 0];
if (character == 27) {
NSLog (@"ESCAPE!");
}
} // keyDown
NSDeleteCharacter in the event's character string:
- (void) keyDown: (NSEvent *) event
{
NSString *chars = [event characters];
unichar character = [chars characterAtIndex: 0];
if (character == NSDeleteCharacter) {
NSLog (@"Delete!");
}
} // keyDown
flagsChanged: (NSEvent *) event and look at the event there. (flagsChanged: comes from NSResponder, so any responder in the responder chain can react to it)
-[NSView setCursor:] call (drat!) You can get something similar by adding this to your NSView subclass:
- (void) resetCursorRects
{
[super resetCursorRects];
[self addCursorRect: [self bounds]
cursor: [NSCursor crosshairCursor]];
} // resetCursorRects
Set it "permanently" via
% defaults write com.apple.TextEdit NSShowAllViews YES(or whatever your application identifier is), or use the one-shot version:
/Developer/Applications/Xcode.app/Contents/MacOS/Xcode -NSShowAllViews YES
- (BOOL) _hasEditableCell
{
return (YES);
} // _hasEditableCell
This workaround is necessary at least for Mac OS X 10.1.*.
environment method
Growl.framework into your application bundle.
Pick a class to be the contact point with Growl. Your AppController class is a good place. Import <Growl/Growl.h>
Set the delegate to the GrowlApplicationBridge:
[GrowlApplicationBridge setGrowlDelegate: self];
Doing this will eventually have the registrationDictionaryForGrowl delegate message called. Return a dictionary with two arrays (Which can be the same). These are the names of the alerts you will be posting. These are human-readable, so you'll want to use a localized string (which I've already set in the global variable here:
- (NSDictionary *) registrationDictionaryForGrowl
{
NSArray *notifications;
notifications = [NSArray arrayWithObject: g_timesUpString];
NSDictionary *dict;
dict = [NSDictionary dictionaryWithObjectsAndKeys:
notifications, GROWL_NOTIFICATIONS_ALL,
notifications, GROWL_NOTIFICATIONS_DEFAULT, nil];
return (dict);
} // registrationDictionaryForGrowl
And use this to post a notification:
[GrowlApplicationBridge notifyWithTitle: @"Woop! Time has expired!"
description: @"You have been waiting for 37 minutes"
notificationName: g_timesUpString
iconData: nil
priority: 0
isSticky: NO
clickContext: nil];
Consult the SDK documentation for more explanations of the features, but they are pretty self-explanitory.
float blah = FixedToFloat(someFixedvalue);other goodies in
FixMath.h
~/Library/Application Support/Chimera/Profiles/default/xyz.slt/prefs.js file:
user_pref("browser.urlbar.autocomplete.enabled", false);
NSString has a couple of convenience functions for print out basic structures like NSRect and NSSize:
NSStringFromRect (someNSRect);
NSStringFromPoint (someNSPoint);
NSStringFromSize (someNSSize);
NSSearchPathForDirectoriesInDomains is how you find the location of things like Library directories, or User directories, and the like (this is the NSSearchPathDirectory). The NSSearchPathDomainMask is what domains to find things in. For instance for a NSLibraryDirectory, a NSUserDomainMask will give you the path to ~/Library, NSSystemDomainMask will give you the path to /System/Library, and so on.
The directories inside of Library, like "Preferences" and "Application Support" are in English in the file system, and the Finder presents localized versions to the user. If you need ~/Library/Application Support/Borkware, you can construct it like
NSMutableString *path;
path = [[NSMutableString alloc] init];
// find /User/user-name/Library
NSArray *directories;
directories = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory,
NSUserDomainMask, YES);
// if you had more than one user domain, you would walk directories and
// work with each path
[path appendString: [directories objectAtIndex: 0]];
[path appendString: @"/Application Support"];
[path appendString: @"/Borkware"];
NSUserName() or NSFullUserName().
Thanks to Peter Hosey for letting us know about a better API for getting these.
logo.jpg)
logo.jpg that's on the thingie drive
logo.jpg file/Developer/Tools/SetFile -a V /Volumes/thingie/logo.jpg
Image->Convert Image will let you compress the image. As a side-effect of the compressed format, this makes the image read-only.
~/.MacOSX/environment.plist. Make the root a Dictionary, and add the key/value pairs (all strings) to it. Don't forget to logout and back in.
% sudo mdutil -i off /
#importint main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; [pool release]; } // main
And you can compile it on the command line with:
cc -o test -framework Foundation file-name.m
% /usr/bin/mdimport -d2 ../Book.pdf >& oopack.txtAnd edit out the little bit of extra metadata output.
ld: multiple definitions of symbol OpenSP::Text::~Text [in-charge]() Entity.lo definition of OpenSP::Text::~Text [in-charge]() in section (__TEXT,__text) Group.lo definition of OpenSP::Text::~Text [in-charge]() in section (__TEXT,__text) ld: multiple definitions of symbol OpenSP::Text::~Text [not-in-charge]() Entity.lo definition of OpenSP::Text::~Text [not-in-charge]() in section (__TEXT,__text) Group.lo definition of OpenSP::Text::~Text [not-in-charge]() in section (__TEXT,__text) Param.lo definition of OpenSP::Text::~Text [in-charge]() in section (__TEXT,__text) Param.lo definition of OpenSP::Text::~Text [not-in-charge]() in section (__TEXT,__text)These are caused by the class in question (Text) not having an explicit destructor declared, so the compiler is creating one for us in each of the files. In Text.cxx, add
Text::~Text() { }
and in Text.h, add~Text();to the Text class. (I got it to compile and link, so I didn't go back to check to see if just sticking
~Text() {} in Text.h would work.)
gcc -dynamiclib -o .libs/libogrove.0.0.1.dylib Node.lo LocNode.lo -lm -lc -install_name /usr/local/lib/libogrove.0.dylib ld: Undefined symbols: vtable for __cxxabiv1::__class_type_info vtable for __cxxabiv1::__si_class_type_info operator delete(void*) operator new(unsigned long) ___cxa_pure_virtual ___gxx_personality_v0 /usr/bin/libtool: internal link edit command failedThe link line needs to have "-lstdc++" added to the end. For OpenJade, edit the libtool script and add
-lstdc++ to the end archive_cmds line. (but leave it inside the last closing double-quote)
lsregister tool that lives in /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support
% defaults write com.apple.mail PreferPlainText -bool TRUE
~/Library/Screen Savers folder? If so, you can make a symbolic link that points to your screen saver bundle, and that will automatically get used whenever you engage the screen saver engine. e.g.
% cd ~/Library/Screen Savers % ln -s ~/Projects/MonkeySaver/build/Debug/MonkeySaver.saver .
NSBundle *bundle;
NSString *path;
bundle = [NSBundle bundleForClass: [self class]];
path = [bundle pathForResource: @"atomsymbol" ofType: @"jpg"];
image = [[NSImage alloc] initWithContentsOfFile: path];
Targets pane in Project Builder
Build Settings tab
Product Name under General Settings
~/Library/Preferences/ByHost directory. The name of the file is the name that you pass to defaultsForModuleWithName:, followed by
.someBigNumber.plist.
So, on my machine,
userPrefs = [ScreenSaverDefaults defaultsForModuleWithName: @"BWDrip"];creates a file
/Users/bork/Library/Preferences/ByHost/BWDrip.0003931024a6.plist
% /System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &
(all one command)
- (void) handleTimer: (NSTimer *) timer
{
do some work here...
} // handleTimer
NSTimer *timer;
timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: @selector(handleTimer:)
userInfo: nil
repeats: YES];
applicationShouldTerminate: message, you're likely to want to returnNSTerminateLater so that you can first gracefully shut down the connection before quitting.
There is a gotcha: returning NSTerminateLater stops the main runloop, so your NSTimers will stop working from that point on. Thus, if you were depending on a timer firing to finish up your shut-down process, you'll never see it, and you'll hang. The solution is to return NSTerminateCancel, then do whatever you need to do and then terminate yourself manually. (Thanks to Larry Gerndt for this one!)
defaults = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat: 25.0], @"density",
[NSNumber numberWithFloat: 40.0], @"rate",
nil];
% cvs admin -kb filename
cvswrappers file provided in the devtools. The easiest thing to do is to copy it to your homedir and prepend a dot:
% cp /Developer/Tools/cvswrappers ~/.cvswrappers
You can also add the contents of that fike to your repository.
.pbproj files aren't handled by the cvswrappers by default. You'll need to add a line like this:
*.pbproj -k 'b' -f '/Developer/Tools/cvs-unwrap %s' -t '/Developer/Tools/cvs-wrap %s %s' -m 'COPY'
% cvs checkout -D "3 days ago" blork
Or via a date (month/day/year)
% cvs checkout -D "10/17/2002" fnord
or recently in time
% cvs diff -D "1 hour ago" ook.blah
% cvs update -d [whatever]
-d option. Otherwise CVS will just ignore any directories added in the branch.
% cvs update -Ad #switch to the trunk (if you haven't already) % cvs update -d -j branch_name [resolve conflicts] % cvs commit -m "whatever"
(Courtesy of Jeremy Stein)
% find . -type d -print | grep -v CVS | xargs cvs add % find . -type f -print | grep -v CVS | xargs cvs addThe first adds the directories, the second adds the files. Filenames with spaces in them won't be added, and it won't do the Right Thing with
-kb for binary files.
% cvs log -r1.2:1.5 multiprocessing.txt
NSURL *url;
NSData *data;
NSString *blork;
url = [NSURL URLWithString: @"http://borkware.com/hacks/random"];
data = [url resourceDataUsingCache: NO];
blork = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
NSURL *url;
NSData *data;
NSImage *blork;
url = [NSURL URLWithString: @"http://borkware.com/hacks/random-pic"];
data = [url resourceDataUsingCache: NO];
blork = [[NSImage alloc] initWithData: data];
float domain[2] = { 0.0, 1.0 }; // 1-in function
float range[8] = { 0.0, 1.0, // N-out, RGBA
0.0, 1.0,
0.0, 1.0,
0.0, 1.0 };
CGFunctionCallbacks callbacks = { 0, evaluate, NULL };
CGFunctionRef shaderFunction;
shaderFunction = CGFunctionCreate (self, // info / rock / context
1, // # of inputs for domain
domain, // domain
4, // # of inputs for range
range, // range
&callbacks);
CGColorSpaceRef deviceRGB;
deviceRGB = CGColorSpaceCreateDeviceRGB ();
CGShadingRef shader;
shader = CGShadingCreateAxial (deviceRGB, // colorspace
cgpoint(start), // start of axis
cgpoint(end), // end of axis
shaderFunction, // shader, 1-n, n-out
NO, // extend start
NO); // extend end
CGContextSaveGState (context); {
NSRect bounds = [self bounds];
CGContextClipToRect (context, cgrect(bounds));
CGContextDrawShading (context, shader);
} CGContextRestoreGState (context);
[self drawSpotAt: start size: 4];
[self drawSpotAt: end size: 4];
CGFunctionRelease (shaderFunction);
CGColorSpaceRelease (deviceRGB);
CGShadingRelease (shader);
And the evaluator function is given an array of inputs and outputs. Use the in value(s) (which run from your domain's start-to-finish values) to generate the out values (which should be in the range's start-to-finish values):
static void evaluate (void *info, const float *in, float *out)
{
float thing;
thing = in[0];
out[0] = thing;
out[1] = thing;
out[2] = thing;
out[3] = 1.0;
} // evaluate
NSString *blah = @"Placeholder Pane";
NSSize size = [blah sizeWithAttributes: nil];
NSPoint startPoint;
startPoint.x = bounds.origin.x + bounds.size.width / 2 - size.width / 2;
startPoint.y = bounds.origin.y + bounds.size.height / 2 - size.height / 2;
[blah drawAtPoint: startPoint
withAttributes: nil];
#define cgrect(nsrect) (*(CGRect *)&(nsrect))
- (void) drawRect: (NSRect) rect
{
NSRect bounds = [self bounds];
NSGraphicsContext *cocoaContext = [NSGraphicsContext currentContext];
CGContextRef context = (CGContextRef)[cocoaContext graphicsPort];
CGContextSetLineWidth (context, 5.0);
CGContextBeginPath(context); {
CGContextAddRect (context, cgrect(bounds));
CGContextSetRGBFillColor (context, 1.0, 0.9, 0.8, 1.0);
} CGContextFillPath(context);
} // drawRect
- (NSImage *) captureScreenImageWithFrame: (NSRect) frame
{
// Fetch a graphics port of the screen
CGrafPtr screenPort = CreateNewPort ();
Rect screenRect;
GetPortBounds (screenPort, &screenRect);
// Make a temporary window as a receptacle
NSWindow *grabWindow = [[NSWindow alloc] initWithContentRect: frame
styleMask: NSBorderlessWindowMask
backing: NSBackingStoreRetained
defer: NO
screen: nil];
CGrafPtr windowPort = GetWindowPort ([grabWindow windowRef]);
Rect windowRect;
GetPortBounds (windowPort, &windowRect);
SetPort (windowPort);
// Copy the screen to the temporary window
CopyBits (GetPortBitMapForCopyBits(screenPort),
GetPortBitMapForCopyBits(windowPort),
&screenRect,
&windowRect,
srcCopy,
NULL);
// Get the contents of the temporary window into an NSImage
NSView *grabContentView = [grabWindow contentView];
[grabContentView lockFocus];
NSBitmapImageRep *screenRep;
screenRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect: frame];
[grabContentView unlockFocus];
NSImage *screenImage = [[NSImage alloc] initWithSize: frame.size];
[screenImage addRepresentation: screenRep];
// Clean up
[grabWindow close];
DisposePort(screenPort);
return (screenImage);
} // captureScreenImageWithFrame
- (void) makeLayerInContext: (CGContextRef) enclosingContext
{
layer = CGLayerCreateWithContext (enclosingContext, CGSizeMake(100, 100),
NULL); // options - unused in Tiger
CGContextRef context;
context = CGLayerGetContext (layer);
// .. and do your drawing
} // makeLayer
And then to draw the layer at a particular point (like replicating it a bunch of different points as done here):
for (i = 0; i < pointCount; i++) {
CGContextDrawLayerAtPoint (context, locations[i], layer);
}
- (NSBezierPath *) makePathFromString: (NSString *) string
forFont: (NSFont *) font
{
NSTextView *textview;
textview = [[NSTextView alloc] init];
[textview setString: string];
[textview setFont: font];
NSLayoutManager *layoutManager;
layoutManager = [textview layoutManager];
NSRange range;
range = [layoutManager glyphRangeForCharacterRange:
NSMakeRange (0, [string length])
actualCharacterRange: NULL];
NSGlyph *glyphs;
glyphs = (NSGlyph *) malloc (sizeof(NSGlyph)
* (range.length * 2));
[layoutManager getGlyphs: glyphs range: range];
NSBezierPath *path;
path = [NSBezierPath bezierPath];
[path moveToPoint: NSMakePoint (20.0, 20.0)];
[path appendBezierPathWithGlyphs: glyphs
count: range.length inFont: font];
free (glyphs);
[textview release];
return (path);
} // makePathFromString
To make editing end, you need to subclass NSTableView and add code to catch the textDidEndEditing delegate notification, massage the text movement value to be something other than the return and tab text movement, and then let NSTableView handle things.
// make return and tab only end editing, and not cause other cells to edit
- (void) textDidEndEditing: (NSNotification *) notification
{
NSDictionary *userInfo = [notification userInfo];
int textMovement = [[userInfo valueForKey:@"NSTextMovement"] intValue];
if (textMovement == NSReturnTextMovement
|| textMovement == NSTabTextMovement
|| textMovement == NSBacktabTextMovement) {
NSMutableDictionary *newInfo;
newInfo = [NSMutableDictionary dictionaryWithDictionary: userInfo];
[newInfo setObject: [NSNumber numberWithInt: NSIllegalTextMovement]
forKey: @"NSTextMovement"];
notification =
[NSNotification notificationWithName: [notification name]
object: [notification object]
userInfo: newInfo];
}
[super textDidEndEditing: notification];
[[self window] makeFirstResponder:self];
} // textDidEndEditing
(Thanks to Steven Jacowski for a tweak that ends editing on clicks on different cells)
NSTableViewDropAbove- (NSDragOperation) tableView: (NSTableView*) tableView
validateDrop: (id ) info
proposedRow: (int) row
proposedDropOperation: (NSTableViewDropOperation) op
{
int result = NSDragOperationNone;
if (op == NSTableViewDropAbove) {
result = NSDragOperationMove;
}
return (result);
} // validateDrop
NSTableView's -setDoubleAction: method, and supply it a standard IBAction-style method selector.
You may need to also do -setTarget:. double-clicks get sent if the column isn't editable, so you may need to grab the column and do a -setEditable: NO on it.
- (BOOL) tableView: (NSTableView *) view
writeRows: (NSArray *) rows
toPasteboard: (NSPasteboard *) pboard
in your table view data source (and don't forget to hook up the datasource if you use bindings to populate the tableview)
- (void) textDidEndEditing: (NSNotification *) notification
{
NSDictionary *userInfo;
userInfo = [notification userInfo];
NSNumber *textMovement;
textMovement = [userInfo objectForKey: @"NSTextMovement"];
int movementCode;
movementCode = [textMovement intValue];
// see if this a 'pressed-return' instance
if (movementCode == NSReturnTextMovement) {
// hijack the notification and pass a different textMovement
// value
textMovement = [NSNumber numberWithInt: NSIllegalTextMovement];
NSDictionary *newUserInfo;
newUserInfo = [NSDictionary dictionaryWithObject: textMovement
forKey: @"NSTextMovement"];
notification = [NSNotification notificationWithName:
[notification name]
object: [notification object]
userInfo: newUserInfo];
}
[super textDidEndEditing: notification];
} // textDidEndEditing
mouseDownInHeaderOfTableColumn or didClickTableColumn:
NSImage *indicatorImage;
if (sortAscending) {
sort your data ascending
indicatorImage = [NSImage imageNamed: @"NSAscendingSortIndicator"];
} else {
sort your data descending
indicatorImage = [NSImage imageNamed: @"NSDescendingSortIndicator"];
}
sortAscending = !sortAscending;
[tableView setIndicatorImage: indicatorImage
inTableColumn: tableColumn];
[tableView reloadData];
- (void) tableViewSelectionDidChange: (NSNotification *) notification
{
int row;
row = [tableView selectedRow];
if (row == -1) {
do stuff for the no-rows-selected case
} else {
do stuff for the selected row
}
} // tableViewSelectionDidChange
If you have more than one tableview, the notification's object is the tableview that had the selection change.
-setDropRow:dropOperation:, like so:
- (NSDragOperation) tableView: (NSTableView *) view
validateDrop: (id ) info
proposedRow: (int) row
proposedDropOperation: (NSTableViewDropOperation) op
{
// have the table highlight on-row / between-row correctly
[view setDropRow: row
dropOperation: op];
// or use whatever drag operation is appropriate
NSDragOperation dragOp = NSDragOperationCopy;
return (dragOp);
} // validateDrop
and in the acceptDrop method, look at the operation:
- (BOOL) tableView: (NSTableView *) view
acceptDrop: (id ) info
row: (int) row
dropOperation: (NSTableViewDropOperation) op
{
if (op == NSTableViewDropOn) {
// replace existing
} else if (op == NSTableViewDropAbove) {
// add new
} else {
NSLog (@"unexpected operation (%d) in %s",
op, __FUNCTION__);
}
// documentation doesn't actually say what this signifies
return (YES);
} // acceptDrop
- (int) numberOfRowsInTableView: (NSTableView *) tableView
- (id) tableView: (NSTableView *) tableView
objectValueForTableColumn: (NSTableColumn *) tableColumn
row: (int) row
% createlang plpgsql template1
alter table pfo_survey_response_2006 add column section text
% pg_dump databasename > db.out
pg_hba.conf, you can connect to the database, logged in as an ordinary person, by doing
% psql -U nsadmin opeancs
% createdb database-name
psql=# create user bork with password 'bork';
You can also do this for a passwordless user:
% crateuser bork
psql=# select to_timestamp('10:45am', 'HH12:MIam')::timetz::time;
to_timestamp
--------------
10:45:00
(1 row)
limit" statement:
select stuff from some_table where stuff.blah > 12 limit 5
% psql database-name user-name
% psql -h tower borkdb nettest
% pg_ctl -D /usr/local/pgsql/data -l /tmp/pgsql.log start
insert into blah (id, stuff)
values (nextval('sequence_name'), 'stuff');
% psql -d databasename -f db.out
% psql -l
random() function.
select stuff.src, stuff.width, stuff.height from
(select src, width, height,
random()
from bw_eyes
order by 4) stuff
limit 1
This selects a random row from bw_eyes and returns the interesting data from it. This query is used on the quickies pages to randomly select an image of eyes staring back.
select current_timestamp()::date - entry_date::date as days_old from kb_nuggets;
wplug-oacs=# \pset pager
Pager usage is off.
select blah from whatever where date-column > (current_timestamp - 21) to get all the blahs from whatever in the last 21 days. This doesn't work in newer versions of Postgresql. Instead, you need to use a time interval:select to_char (whenx, 'fmDD fmMonth YYYY') as pretty_when, text from blog where whenx > (current_timestamp - interval '21 days') order by whenx desc
shared_buffers in your postgresql.conf, and get an error similar to this:
IpcMemoryCreate: shmget(key=5432001, size=266371072, 03600) failed:
Invalid argument
This error usually means that PostgreSQL's request for a shared memory
segment exceeded your kernel's SHMMAX parameter.
You should increase your the shmmax parameters using tips in the Unix administration quickies.
- Darwin Website (Darwin->General)
[permalink]
Since I can never remember this, it's at developer.apple.com/darwin.
- Darwin's CVSROOT string (Darwin->CVS)
[permalink]
for read-only checkouts:
setenv CVSROOT :pserver:username@anoncvs.opensource.apple.com:/cvs/Darwin
- Appending to the end of a textview (NSTextView->General)
[permalink]
NSRange range;
range = NSMakeRange ([[textView string] length], 0);
[textView replaceCharactersInRange: range withString: string];
And Peter Hosey provided a one-liner that may suit your needs better:
[[[textView textStorage] mutableString] appendString: string];
- Deleting the selected text (NSTextView->General)
[permalink]
[textView delete: nil]
- Determining the paragraph style at a particular point (NSTextView->General)
[permalink]
- (NSParagraphStyle *) paragraphStyleInTextView: (NSTextView *) textView
atIndex: (int) index
{
NSTextStorage *storage = [textView textStorage];
NSDictionary *attributes;
NSRange effectiveRange;
attributes = [storage attributesAtIndex: index
effectiveRange: &effectiveRange];
NSParagraphStyle *style;
style = [attributes valueForKey: NSParagraphStyleAttributeName];
return (style);
} // paragraphStyleInTextView
- Finding the span of a paragraph (NSTextView->General)
[permalink]
The NSString paragraphRangeForRange: method gives you the span of a paragraph. If you're using the text architecture, you need to get the string from the text storage. This chunklet shows the paragraph span for the current selection:
NSRange selectedRange = [textview selectedRange];
NSTextStorage *storage = [textview textStorage];
effectiveRange = [[storage string] paragraphRangeForRange: selectedRange];
- Forcing validation of pending text field entries (NSTextView->General)
[permalink]
[window makeFirstResponder: window]
- Moving insertion point to the end (NSTextView->General)
[permalink]
NSRange range = { [[textView string] length], 0 };
[textView setSelectedRange: range];
- Moving insertion point to the start (NSTextView->General)
[permalink]
NSRange zeroRange = { 0, 0 };
[textView setSelectedRange: zeroRange];
- Replacing NSTextView's contents with an attributed string (NSTextView->General)
[permalink]
[[textView textStorage] setAttributedString: theNewString];
- Restricting typed in text to just digits (NSTextView->General)
[permalink]
Create a subclass of NSNumberFormatter, add this method, and hook up the formatter to your text fields.
- (BOOL) isPartialStringValid: (NSString **) partialStringPtr
proposedSelectedRange: (NSRangePointer) proposedSelRangePtr
originalString: (NSString *) origString
originalSelectedRange: (NSRange) origSelRange
errorDescription: (NSString **) error
{
NSCharacterSet *nonDigits;
NSRange newStuff;
NSString *newStuffString;
nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
newStuff = NSMakeRange(origSelRange.location,
proposedSelRangePtr->location
- origSelRange.location);
newStuffString = [*partialStringPtr substringWithRange: newStuff];
if ([newStuffString rangeOfCharacterFromSet: nonDigits
options: NSLiteralSearch].location != NSNotFound) {
*error = @"Input is not an integer";
return (NO);
} else {
*error = nil;
return (YES);
}
} // isPartialStringValid
- Scrolling to the end of a textview (NSTextView->General)
[permalink]
NSRange range;
range = NSMakeRange ([[textView string] length], 0);
[textView scrollRangeToVisible: range];
I've heard that scrollRangeToVisible is O(N) for the length of the text. So be on