(defun lispdoc ()
"searches lispdoc.com for SYMBOL, which is by default the symbol
currently under the curser"
(interactive)
(let* ((word-at-point (word-at-point))
(symbol-at-point (symbol-at-point))
(default (symbol-name symbol-at-point))
(inp (read-from-minibuffer
(if (or word-at-point symbol-at-point)
(concat "Symbol (default " default "): ")
"Symbol (no default): "))))
(if (and (string= inp "") (not word-at-point) (not
symbol-at-point))
(message "you didn't enter a symbol!")
(let ((search-type (read-from-minibuffer
"full-text (f) or basic (b) search (default b)? ")))
(browse-url (concat "http://lispdoc.com?q="
(if (string= inp "")
default
inp)
"&search="
(if (string-equal search-type "f")
"full+text+search"
"basic+search")))))))
;;;======================================================================
;;; scratch buffer function to immediately go to the scratch buffer
;;; from anywhere else
;;;======================================================================
(defun scratch ()
(interactive)
(switch-to-buffer "*scratch*")
(lisp-interaction-mode)
(if current-prefix-arg
(delete-region (point-min) (point-max))
(goto-char (point-max))))
;;;======================================================================
;;; From: lawrence mitchell <wence-at-gmx.li>
;;; Find the function under the point in the elisp manual
;;;
;;; C-h TAB runs the command info-lookup-symbol
;;; which is an interactive autoloaded Lisp function in `info-look'.
;;; [Arg list not available until function definition is loaded.]
;;;
;;; Display the definition of SYMBOL, as found in the relevant manual.
;;; When this command is called interactively, it reads SYMBOL from the minibuffer.
;;; In the minibuffer, use M-n to yank the default argument value
;;; into the minibuffer so you can edit it.
;;; The default symbol is the one found at point.
;;;
;;; With prefix arg a query for the symbol help mode is offered.
;;;======================================================================
(defun find-function-in-elisp-manual (function)
(interactive
(let ((fn (function-called-at-point))
(enable-recursive-minibuffers t)
val)
(setq val
(completing-read
(if fn
(format "Find function (default %s): " fn)
"Find function: ")
obarray 'fboundp t nil nil (symbol-name fn)))
(list (if (equal val "")
fn
val))))
(Info-goto-node "(elisp)Index")
(condition-case err
(progn
(search-forward (concat "* "function":"))
(Info-follow-nearest-node))
(error (message "`%s' not found" function))))
;;;======================================================================
;;; Functions to insert the date, the time, and the date and time at
;;; point. Useful for keeping records and automatically creating
;;; program headers
;;;======================================================================
(defvar insert-time-format "%H:%M"
"*Format for \\[insert-time] (c-h f 'format-time-string' for info on how to format).")
(defvar insert-date-format "%d %b %Y"
"*Format for \\[insert-date] (c-h f 'format-time-string' for info on how to format).")
(defun insert-time ()
"Insert the current time according to the variable \"insert-time-format\"."
(interactive "*")
(insert (concat (format-time-string insert-time-format (current-time)) " ")))
(defun insert-date ()
"Insert the current date according to the variable \"insert-date-format\"."
(interactive "*")
(insert (concat (format-time-string insert-date-format (current-time))" ")))
(defun insert-date-time ()
"Insert the current date according to the variable \"insert-date-format\", then a space, then the current time according to the variable \"insert-time-format\"."
(interactive "*")
(progn
(insert-date)
(insert " ")
(insert-time)))
(defun insert-current-file-name ()
(interactive)
(insert (file-name-nondirectory (buffer-file-name (current-buffer)) "\/")))
(defun insert-current-path ()
(interactive)
(insert (buffer-file-name (current-buffer))))
;;;======================================================================
;;; this function prints an ascii table in a new buffer 4 columns
;;;======================================================================
(defun ascii-table (&optional extended)
"Print the ascii table (up to char 127). Given an optional argument, print up to char 255."
(interactive "P")
(defvar col)
(defvar limit)
(setq limit 255)
(if (null extended)
(setq limit 127))
(setq col (/ (+ 1 limit) 4))
(switch-to-buffer "*ASCII*")
(erase-buffer)
(insert (format "ASCII characters up to %d. (00 is NULL character)\n\n" limit))
(insert " DEC OCT HEX CHAR\t\t DEC OCT HEX CHAR\t\t DEC OCT HEX CHAR\t\t DEC OCT HEX CHAR\n")
(insert " ----------------\t\t ----------------\t\t ----------------\t\t ----------------\n")
(let ((i 0) (right 0) (tab-width 4))
(while (< i col)
(setq col2 (+ i col))
(setq col3 (+ i (* col 2)))
(setq col4 (+ i (* col 3)))
; special condition to insert a <TAB> instead of an actual tab
(cond
((= i 9)
(insert (format "%4d%4o%4x <TAB>\t\t%4d%4o%4x%4c\t\t%4d%4o%4x%4c\t\t%4d%4o%4x%4c\n"
i i i col2 col2 col2 col2 col3 col3 col3 col3 col4 col4 col4 col4)))
; special conditon to insert a <LF> instead of an actual line feed
((= i 10)
(insert (format "%4d%4o%4x <LF>\t\t%4d%4o%4x%4c\t\t%4d%4o%4x%4c\t\t%4d%4o%4x%4c\n"
i i i col2 col2 col2 col2 col3 col3 col3 col3 col4 col4 col4 col4)))
(t
; insert the actual character
(insert (format "%4d%4o%4x%4c>\t\t%4d%4o%4x%4c\t\t%4d%4o%4x%4c\t\t%4d%4o%4x%4c\n"
i i i i col2 col2 col2 col2 col3 col3 col3 col3 col4 col4 col4 col4))))
(setq i (+ i 1))))
(beginning-of-buffer)
(local-set-key "q" (quote bury-buffer)))
(defun explorer ()
"Launch the windows explorer in the current directory"
(interactive)
(w32-shell-execute
"open"
"explorer"
(concat "/e, " (convert-standard-filename default-directory))))
(defun cmd ()
"Launch the NT Command console"
(interactive)
(w32-shell-execute
"open"
"cmd"))
(defun tomcat ()
"launch tomcat in debug mode."
(interactive)
(let* ((cwd (getenv "CATALINA_HOME"))
(tcat (concat cwd "/bin/startdbg.bat")))
(find-file tcat)
(w32-shell-execute
"open"
tcat)
(kill-buffer (get-file-buffer tcat))))
(defun dbg-tomcat ()
"launch a debug console for tomcat."
(interactive)
(let ((dbg (concat (getenv "JAVA_HOME") "/bin/jdb.exe")))
(w32-shell-execute
nil
dbg
"-attach jdbconn")))
(defun run-cmd (cmd)
(interactive "sCommand: ")
(start-process cmd "*scratch*" "cmd" (concat "/c " cmd))
(switch-to-buffer "*scratch*"))
(defun replace-all (string to-string)
(interactive (progn (setq string (read-from-minibuffer "Replace string: "))
(setq to-string (read-from-minibuffer
(format "Replace %s with: " string)))
(list string to-string)))
"Replaces string with to-string in all buffers"
(let ((buffs (buffer-list))
(current-buffer (current-buffer)))
(while (car buffs)
(switch-to-buffer (buffer-name (car buffs)))
(let ((pos (point)))
(goto-char 0)
(query-replace string to-string)
(goto-char pos))
(setq buffs (cdr buffs)))
(switch-to-buffer current-buffer)))
;;overlay bookmarks
(defun filter (fn lst)
(let ((acc nil))
(dolist (x lst)
(let ((val (funcall fn x)))
(if val (push val acc))))
(nreverse acc)))
(defun setOverlayBookmark ()
(interactive)
(let*
((pnt (line-beginning-position))
(ovrly (make-overlay pnt (line-end-position))))
(overlay-put ovrly 'face 'highlight)
(overlay-put ovrly 'pointHistory t)
ovrly))
(defun overlayBookmarkFilterFunc (ovrly) (and (overlay-get ovrly 'pointHistory) ovrly))
(defun overlayBookmarkFilterStartsFunc (ovrly) (and (overlay-get ovrly 'pointHistory) (overlay-start ovrly)))
(defun nextOverlayBookmark ()
(interactive)
(let*((pnt (line-end-position))
(ovrly_starts (or (filter 'overlayBookmarkFilterStartsFunc (overlays-in pnt (point-max)))
(filter 'overlayBookmarkFilterStartsFunc (overlays-in (point-min) pnt)))))
(if ovrly_starts
(goto-char (reduce (lambda (a b) (if (< a b) a b)) ovrly_starts))
(message "no items in history"))))
(defun clearOverlayBookmarks ()
(interactive)
(let
((ovrlys (filter 'overlayBookmarkFilterFunc (overlays-in (point-min) (point-max)))))
(mapcar 'delete-overlay ovrlys)
(message "cleared point history")))
(defun toggleOverlayBookmark ()
(interactive)
(let
((ovrlys (filter 'overlayBookmarkFilterFunc (overlays-in (line-beginning-position) (line-end-position)))))
(if ovrlys
(mapcar 'delete-overlay ovrlys)
(setOverlayBookmark))))
(defun overlayBookmarkRefresh ()
"stretches the overlays from the beginning to end of a line"
(interactive)
(let
((ovrlys (filter 'overlayBookmarkFilterFunc (overlays-in (point-min) (point-max))))
(lf (lambda (tmp) (save-excursion
(goto-char (overlay-start tmp))
(move-overlay tmp (overlay-start tmp) (line-end-position))))))
(if ovrlys
(mapcar lf ovrlys)
(setPointHistory))))
;; eshell/bmk - version 0.1.2
(defun pcomplete/eshell-mode/bmk ()
"Completion for `bmk'"
(pcomplete-here (bookmark-all-names)))
(defun eshell/bmk (&rest args)
"Integration between EShell and bookmarks. For usage, execute without arguments."
(setq args (eshell-flatten-list args))
(let ((bookmark (car args))
filename name)
(cond
((eq nil args)
(format "Usage: bmk BOOKMARK to change directory pointed to by BOOKMARK
or bmk . BOOKMARK to bookmark current directory in BOOKMARK.
Completion is available."))
((string= "." bookmark)
;; Store current path in EShell as a bookmark
(if (setq name (car (cdr args)))
(progn
(bookmark-set name)
(bookmark-set-filename name (eshell/pwd))
(format "Saved current directory in bookmark %s" name))
(error "You must enter a bookmark name")))
(t
;; Assume the user wants to go to the path pointed out by a bookmark.
(if (setq filename (cdr (car (bookmark-get-bookmark-record bookmark))))
(if (file-directory-p filename)
(eshell/cd filename)
;; TODO: Handle this better and offer to go to directory
;; where the file is located.
(error "Bookmark %s points to %s which is not a directory"
bookmark filename)))))))
(defun eshell/start (FILE)
"Invoke (w32-shell-execute \"Open\" FILE) and substitute slashes for backslashes"
(w32-shell-execute "Open" (substitute ?\\ ?/ (expand-file-name FILE))))
(defun setenv-from-list (env strlst)
"Set an environment variable using the contents of a list."
(setenv env (join "; " strlst)))
(defun join-strings (sep &rest strngs)
"join a bunch of strings with sep concatinated after each string."
(let ((rslt ""))
(dolist (str strngs)
(setq rslt (concat rslt str sep)))
rslt))
(defun join (sep strlst)
"join a list of strings with sep between each."
(let ((rslt ""))
(dolist (str strlst)
(setq rslt (concat rslt str sep)))
rslt))
(defun join-ba (before after strlst)
"join a list of strings with before and after pre/post pended to each string."
(let ((rslt ""))
(dolist (str strlst)
(setq rslt (concat rslt (format "%s%s%s" before str after))))
rslt))
;;setup load paths
(defun setup-load-paths (edir subdirlst)
"Setup load paths. edir is the elisp directory path and subdirlst is a list of subdirectories."
(mapcar (lambda (subdir) (add-to-list 'load-path (concat edir subdir)))
subdirlst)
(add-to-list 'load-path edir))
(defun copy-to-scratch ()
"copies selected text to the scratch buffer."
(interactive)
(let ((txt (buffer-substring (region-beginning) (region-end))))
(save-current-buffer
(set-buffer "*scratch*")
(insert txt "\n"))))
(defun search-all-buffers (srch-str &optional match-buffers)
"Search across all open buffers."
(interactive "sSearch String: \nsMatch Buffers: ")
(let (buffer-re)
(if (stringp match-buffers)
(setq buffer-re match-buffers)
(setq buffer-re "."))
(multi-occur-in-matching-buffers buffer-re srch-str t)))
(defun todo ()
"Find all todo items in all buffers."
(interactive)
(multi-occur-in-matching-buffers "." "TODO: " t))
(defun multi-find-file (root-dir name-regx)
"Find multiple files starting in root-dir and descending directories."
(interactive "sDirectory to search from: \nsMatch files Regx: ")
;(message (concat "root-dir: " root-dir))
;(message (concat "name-regx: " name-regx))
(if (and (and (stringp root-dir) (> (length root-dir) 0))
(and (stringp name-regx) (> (length name-regx) 0)))
(let ((files-to-open nil)
(subdirs nil)
(names-list nil))
(setq names-list (directory-files root-dir t))
(unless names-list (message "names-list is nil."))
(dolist (name names-list)
;(message (concat "file name: " name))
(cond
((file-directory-p name) (unless (string-match "[.]+$" name) (setq subdirs (cons name subdirs))))
((string-match name-regx (file-name-nondirectory name)) (setq files-to-open (cons name files-to-open)))
))
(dolist (item files-to-open)
;(message (concat "opening file " item))
(find-file-other-window item))
(setq file-to-open nil)
(setq names-list nil)
(dolist (item subdirs)
;(message "dropping into subdirectory.")
(multi-find-file item name-regx)))
(message "Need values for root-dir and name-regx.")))
Monday, September 17, 2007
elisp functions for emacs
Tuesday, May 08, 2007
Tuesday, May 01, 2007
Lets see how long this lasts
The HD-DVD key. Fighting censorship.
09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
Monday, January 15, 2007
Real life project management using Scrum
| Dody Gunawinata, founder of Silverkey Technologies, explaining real life project management using Scrum. | |
Scrum Tuning: Lessons learned from Scrum implementation at Google
| Google Tech Talks December 7, 2006 ABSTRACT Adwords introduced a Scrum implementation at Google in small steps with remarkable success. As presented at the Agile 2006 conference this exemplifies a great way to start up Scrum teams. The inventor and Co-Creator of Scrum will use this approach in building the Google Scrum implementation to describe some of the subtle aspects of Scrum along with suggested next steps that can help in distributing and scaling Scrum in a "Googly way". | |
Scrum et al.
| Google Tech Talks September 5, 2006 Ken Schwaber co-developed the Agile process, Scrum. He is a founder of the Agile Alliance and Scrum Alliance, and signatory to the Agile Manifesto. Ken has been a software developer for over thirty years. He is an active advocate and evangelist for Agile processes. ABSTRACT Scrum is an amazingly simple process that causes many, many changes when it is implemented. This seminar presents the basic framework of Scrum and some of the implementation issues associated with it. | |
Tuesday, April 18, 2006
Getting Started with Common Lisp, part 2
Thursday, April 06, 2006
Getting Started with Common Lisp, part 1
Lisp is a significantly different environment than any of the other languages I have learned. It's not the syntax that is the real issue. Once you get used to prefix notation and how the libraries work, you really start to appreciate the language. If you get emacs setup correctly then Lisp syntax is actually easier than the more common languages. The bug hurdle in my adjustment to Lisp was getting used to working with the repl, learning about application images, learning how to work with SLIME and learning the primary library and application management system, which is called ASDF. Once you learn how to install ASDF, getting and installing libraries becomes simple, somewhat like CPAN or Python's easyInstall. The next few posts will be about how I overcame each of these hurdles and learning to appreciate Lisp and the Lisp way.
Wednesday, March 08, 2006
Lisp in Python
Monday, February 13, 2006
Sunday, January 22, 2006
Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajax
Read more at www-128.ibm.com/develop...
Mastering Ajax, Part 1: Introduction to Ajax
Yet another excellent Developer Works article. A nice intro to Ajax. Covers the basics of using the XMLHttpRequest object, including cross browser issues.
Read more at www-128.ibm.com/develop...
Wednesday, January 11, 2006
Tuesday, January 10, 2006
Wednesday, November 09, 2005
Planner Mode for EMACS
In the past I have used a variety of contact management/calendaring software including Outlook and Evolution but they are big and bulky and get in the way. They are also overly complicated and it is hard to associate notes with a given piece of information.
Wednesday, September 21, 2005
Thursday, August 18, 2005
Very Interesting Lisp Primer
Monday, August 08, 2005
Find 'hidden' resources in extension DLL's
Identifying the problem
The problem is that MFC assumes that all of the applications' resources reside in the main executable. There are two ways to solve this problem. The first method is to let MFC hunt for the correct resource using AfxFindResourceHandle. The second method revolves around treating the extension DLL like a separate resource DLL.
However, there are significant disadvantages to both methods. The main disadvantage with the first method, which uses AfxFindResourceHandle, is that there can’t be any duplicate resource IDs in any of your applications DLL’s. Also, this method is slower.Both occur because AfxFindResourceHandle searches the entire link chain in the application and returns the first module with a matching resource.
The primary disadvantage with the second method is that you have to explicitly get a handle to the target module; and since loading each kind of resource uses different functions, you end up with code that is almost identical for each kind of resource.
Ask MFC politely for the resource
To have MFC do all the heavy lifting, call AfxFindResourceHandle, like this:
HINSTANCE hInst;
HANDLE hIcon;
hInst = AfxFindResourceHandle(MAKEINTRESOURCE(IDI_YOURICONHERE),
RT_GROUP_ICON);
hIcon = FindResource(hInst, MAKEINTRESOURCE(IDI_YOURICONHERE),
RT_GROUP_ICON);
This will work fine--until someone adds an icon with a duplicate ID to the code base. There is one advantage to this method of loading a resource: You don’t have to know which module the resource resides in.
When something can go wrong, it will.
Being a firm believer in Murphy’s Law; I like to be as explicit as possible. So I prefer the second method of loading resources in my extension DLL’s. Although it requires a little more investment upfront, it pays off when your code goes into maintenance mode. Basically, for each kind of resource you use in your extension DLL, you’ll write a function like this:
CString LoadResString(UINT ResID, CString strModuleName)
{
TCHAR szBuffer[256];
//The module handle can be obtained in a variety of ways the
//following is the most
//straight forward
HMODULE mod = ::GetModuleHandle(strModuleName);
ASSERT(mod);
if (!mod){
AfxMessageBox(_T("GetModuleHandle failed in LoadResString."));
RaiseException(1814, 0, 0, NULL);
}
//This is where the resource actually gets loaded and will be
//different in each function
int count = LoadString(mod, ResID, szBuffer, 255);
ASSERT(count);
if (!count){
AfxMessageBox(_T("LoadString failed in LoadResString."));
RaiseException(1814, 0, 0, NULL);
}
CString rslt(szBuffer);
return rslt;
}
MFC extension DLL’s are a nice feature but because of all the legacy code that Microsoft has to support we are stuck with some “interesting” features like this problem with MFC not looking in the extension DLL for resources first. It’s an easy problem to overcome but it can give you a headache the first time you encounter it. It doesn’t help that you have to know what the problem is before you can find the answer in the documentation.
Note: Technically, there is a third method for specifying which module to load resources from. I chose not to examine it in this article because it's an even less explicit than the AfxFindResourceHandle method.
Friday, August 05, 2005
Marking an ActiveX object safe for scripting
_reg_catids_ = ["{7DD95801-9882-11CF-9FA9-00AA006C42C4}"]
Now the class won't cause Internet Exporer to prompt for permission to load the component. I wonder why there is such a spyware problem? :0
Thursday, August 04, 2005
Event logging the .NET way
The System.Diagnostics name space contains (among other things) the event logging API. The two classes we'll focus on for reading and writing to the event log in .NET are the EventLog and the EventLogEntry classes.
Write to the event log
Writing to the event log in .NET follows the same basic procedure as using the Win32 API. First, open the event log.
//The period means this machine
EventLog log = new EventLog(“Application”, “.”, “MySource”);
Then write the event:
log.WriteEntry(“Test message”, EventLogEntryType.Information);
Read from the event log
Reading the event log the Win32 way requires you to open the log with the OpenEventLog function and retrieve a handle to the Event Log. Then you have to retrieve the EVENTLOGRECORD structure with the ReadEventLog function.
The EVENTLOGRECORD structure has both static and dynamic fields. In order to access the dynamic fields of the structure such as the message and the source, you have to treat the structure like a byte array. To make things inconsistent, you access the static fields with the dot operator like normal. Although it’s not difficult, it can be error-prone, and if you miscount bytes, you'll get access violations or bad data.
Reading the event log the .NET way is much improved. Instead of dealing with an EVENTLOGRECORD structure, you get to deal with a much safer and easier EventLogEntry class. When you create an EventLog instance pointing at a specific log, the Entries property (which is an instance of the EventLogEntryCollection class) automatically fills with EventLogEntries. You can use the following code to access the Entries collection:
foreach EventLogEntry entry in eventLog.Entries{
Console.WriteLine(entry.Source);
Console.WriteLine(entry.Message);
}
Create a custom event log
You can also create a custom event log by calling the static method CreateEventSource of the EventLog class. For example:
//Check to make sure that the source that will
//be associated with the new log doesn’t exist.
//SourceExists is also a static method
if (!EventLog.SourceExists(“MySource”){
//If MyNewLog does not exist it will be created.
EventLog.CreateEventSource(“MySource”, “MyNewLog”);
}
As the above code indicates, you can check to see if a source is registered. If the source name already exists, you could overwrite someone else’s source, creating havoc.
Compare the previous code to what you would have to do to create a custom event log with the Win32 API:
Create a message file.
Compile it using the message compiler.(Be sure to include the created resource into the resources of the message synch DLL or Executable.)
Register the message synch (which is about 100 lines of code) in the event system by creating the requisite registry entries.
Take a look at the keys under HKLM\System\CurrentControlSet\Services\EventLog in the registry.
Open and retrieve a handle to an event log.
Now you can write the custom event log.
Conclusion
As you can see, event logging the .NET way is quite easy. The only drawback is that your application has to be running on a version of Windows based on Windows NT. But since Windows XP is the new consumer OS, this issue will soon be moot.