anchor.diff:  			   0)
   	      new-mode 'normal)
   	(setf new-mode 'search))
  -    (list new-mode selected () ())))
  +    (list new-mode selected)))
  +
  +(defun open-file-with-command (path command)
  +  "write the current path, close Lightning, and execute the command"
  +  (tb-shutdown)
  +  (write-path (to-string *lightning-path-file*) (to-string path))
  +  (trivial-shell:shell-command (to-string command))
  +  (exit))
   
   (defun action (filename path)
     "do something with a filename that the user selected"
     (when (dir-p filename)
  -    (cd filename)
  -    (list *default-mode* 0 nil nil))
  +    (cd filename))
     (when (file-p filename)
  -    (command path (append *editor* (list #\space) filename))))
  -
  -(defun command (path command)
  -  "write the current path, close Lightning, and execute the command"
  -  (tb-shutdown)
  -  (write-path *lightning-path-file* path)
  -  (trivial-shell:shell-command (to-string command))
  -  (exit))
  +    (open-file-with-command path (append *editor* (list #\space) filename))))
   
   (defun lightning ()
     (let ((mode *default-mode*)
   	(selected-files ())
   	(search-buffer ())
  -	(selected 0)
  -	(files ())
  +	(selected-index 0)
  +	(all-files ())
   	(char-range (get-char-range)))
  -    ;(tb-init)
  +    (tb-init)
       (loop
  -       (let ((normal-files ())
  -	     (dot-files ()))
  -	 (tb-clear)
  -	 (setf files (mapcar #'to-list (sort (mapcar #'to-string (ls)) #'string<)))
  -	 (mapcar (lambda (f) (if (eq (nth 0 f) #\.)
  -				 (setf dot-files (append dot-files (list f)))
  -				 (setf normal-files (append normal-files (list f))))) files)
  -	 (setf files (append normal-files dot-files))
  -	 (if (eq mode 'search)
  -	     (setf selected-files (select-files-in-search-buffer files search-buffer)))
  -	 (print (mapcar #'to-string selected-files))
  -	 (return)))
  -    ))
  -#|
  -    while True:
  -        files = normalfiles + dotfiles
  -        if mode == SEARCH:
  -            selectedFiles = selectFilesOnsearchBuffer(files, searchBuffer)
  -        drawFileList(t, 1, t.height() - 1, mode, selected, selectedFiles)
  -        if mode == SEARCH:
  -            if len(selectedFiles) == 1 and len(searchBuffer):
  -                mode, selected, selectedFiles, searchBuffer = action(selectedFiles[0], os.path.realpath('.'))
  -                continue
  -            writeText(t, 0, t.height() - 1, searchBuffer, termbox.WHITE, 0)
  -        if mode == SEARCH:
  -            modeText = "search"
  -        elif mode == NORMAL:
  -            modeText = "normal"
  -        writeText(t, 0, 0, modeText + ": ", termbox.WHITE, 0)
  -        writeText(t, len(modeText) + 2, 0, os.path.realpath('.'), termbox.WHITE, 0)
  -        t.present()
  -
  -        event = t.poll_event()
  -        letter, keycode = event[1], event[2]
  -        if letter == ',':
  -            os.chdir('..')
  -            searchBuffer = ''
  -            selected = 0
  -        elif keycode == termbox.KEY_SPACE:
  -            mode, selected, searchBuffer, selectedFiles = switchMode(mode, selected, selectedFiles)
  -        elif keycode == termbox.KEY_ESC:
  -            break
  -        elif letter == ';':
  -            command(os.path.realpath('.'), 'true')
  -        elif mode == NORMAL:
  -            if letter == 'k':
  -                selected = selected - 1 % len(files)
  -            elif letter == 'j':
  -                selected = selected + 1 % len(files)
  -            elif letter == '\'':
  -                mode, selected, selectedFiles, searchBuffer = action(files[selected], os.path.realpath('.'))
  -            elif letter == 'q':
  -                break
  -            elif letter == 'v':
  -                command(os.path.realpath('.'), editor + ' ' + files[selected])
  -            elif letter == 'n':
  -                command(os.path.realpath('.'), 'nautilus ' + os.path.realpath('.') + ' > /dev/null 2>&1')
  -            elif letter == 't':
  -                command(os.path.realpath('.'), 'tmux > /dev/null')
  -            elif letter == 'T':
  -                command(os.path.realpath('.'), 'tmux > /dev/null')
  -        elif mode == SEARCH:
  -            if letter:
  -                if letter in charRange:
  -                    searchBuffer = searchBuffer + letter
  -                elif letter == '-':
  -                    searchBuffer = searchBuffer[:-1]
  -            if keycode == termbox.KEY_ENTER:
  -                mode, selected, selectedFiles, searchBuffer = action(selectedFiles[0], os.path.realpath('.'))
  -
  -    t.close()
  -    print os.path.realpath('.')# }}}
  -
  -|#
  +					; sort files
  +       (setf all-files (mapcar #'to-list (sort (mapcar #'to-string (ls)) #'string<)))
  +
  +					; if we're in search mode, only show files that match the buffer
  +       (if (and (eq mode 'search) search-buffer)
  +	   (setf selected-files (select-files-in-search-buffer all-files search-buffer)))
  +
  +					; clear
  +       (tb-clear)
  +
  +					; draw file list, search string, mode, and current directory
  +       (draw-file-list 1 (1- (tb-height)) mode selected-files selected-index all-files)
  +       (if (eq mode 'search)
  +	   (write-text 0 (1- (tb-height)) search-buffer))
  +       (write-text 0 0 (append (to-list (string mode)) (to-list ": ") *current-directory*))
  +       (tb-present)
  +
  +					; get and process input
  +       (cond
  +	 ((and (eq mode 'search) (= (length selected-files) 1) (plusp (length search-buffer)))
  +	  (action (nth 0 selected-files) *current-directory*)
  +	  (setf mode *default-mode*
  +		selected-files ()
  +		selected-index 0
  +		search-buffer ()))
  +	 (t
  +	  (plus-c:c-let ((event (:struct (tb-event)) :free t))
  +	    (tb-poll-event event)
  +	    (let ((letter (code-char (event :ch)))
  +		  (keycode (event :key)))
  +	      (cond
  +					; go up one directory
  +		((eq letter #\.)
  +		 (cd (to-list ".."))
  +		 (setf search-buffer ()
  +		       selected-index 0))
  +					; switch modes
  +		((eq keycode (tb-const "TB_KEY_SPACE"))
  +		 (let ((result (switch-mode mode selected-index selected-files all-files)))
  +		   (setf mode (nth 0 result)
  +			 selected-index (nth 1 result)
  +			 selected-files ()
  +			 search-buffer ())))
  +					; quit instantly
  +		((eq keycode (tb-const "TB_KEY_ESC"))
  +		 (return))
  +					; quit to the current directory
  +		((eq letter #\;)
  +		 (open-file-with-command *current-directory* (to-list "true")))
  +					; normal-mode-specific commands
  +		((eq mode 'normal)
  +		 (cond
  +					; move up one item
  +		   ((eq letter #\k)
  +		    (setf selected-index (mod (1- selected-index) (length all-files))))
  +					; move down one item
  +		   ((eq letter #\j)
  +		    (setf selected-index (mod (1+ selected-index) (length all-files))))
  +					; open the current item
  +		   ((eq letter #\')
  +		    (action (nth selected-index all-files) *current-directory*)
  +		    (setf mode *default-mode*
  +			  selected-files ()
  +			  selected-index 0
  +			  search-buffer ()))
  +		   ((eq letter #\v)
  +		    (open-file-with-command *current-directory* (append *editor* (list #\space) (list (nth selected-index all-files)))))))
  +		((eq mode 'search)
  +		 (cond
  +		   (letter
  +		    (cond
  +		      ((member letter char-range)
  +		       (setf search-buffer (append search-buffer (list letter))))
  +		      ((eq letter #\-)
  +		       (setf search-buffer (butlast search-buffer)))))
  +		   ((eq keycode (tb-const "TB_KEY_ENTER"))
  +		    (action (nth 0 selected-files) *current-directory*))))))))))))
  +
  +(lightning)
  
positive.code: 	  (nconc chars (list (code-char i)))))
      chars))
  
  (defun filename-clean (filename)
    "convert a raw filename to a simplified one that can be searched for"
    (let ((acceptable-chars (get-char-range)))
      (remove-if-not (lambda (item) (member item acceptable-chars)) (to-list (string-downcase (to-string filename))))))
  
  (defun select-files-in-search-buffer (files search-buffer)
    "return a list of selected files by comparing simplified filenames with the search buffer"
    (remove-if-not (lambda (file) (equal search-buffer (subseq (filename-clean file) 0 (length search-buffer)))) files))
  
  (defun get-file-colors (mode selected-files selected this-file file-list)
    (cond
      ((and (eq mode 'search) (member this-file selected-files) *show-deselected-files*)
       (cons (tb-const "TB_BLACK") (tb-const "TB_WHITE")))
      ((and (eq mode 'normal) (eq this-file (nth selected file-list)))
       (cons (tb-const "TB_BLACK") (tb-const "TB_WHITE")))
      (t
       (cons (tb-const "TB_WHITE") 0))))
  
  (defun show-this-file-p (this-file selected-files)
    (or *show-deselected-files* (member this-file selected-files :test #'equal) (null selected-files)))
  
negative.code:     (with-standard-io-syntax
        (print path out))))
  
  (defun draw-file-list (ystart yend mode selected-files selected-index file-list)
    "draw the list of selected file-list onto the screen"
    (let ((x 0)
  	(width 1)
  	(y ystart))
      (dolist (f file-list)
        (if (= y yend)
  	  (setf y ystart
  		x (+ x width)
  		width 1))
        (when (show-this-file-p f selected-files)
  	(if (dir-p f)
  	    (setf f (to-string (append (coerce f 'list) (list #\/)))))
  	(setf width (max width (+ (length (coerce f 'list)) 1)))
  	(write-text x y f (get-file-colors mode selected-files selected-index f file-list))
  	(incf y)))))
  
  (defun switch-mode (prev-mode selected selected-files files)
    "switch the mode to either search or normal and do associated setup for each mode"
  