kanban.el
 
(stackeffect )
2013-10-12: kanban-fill: a generalized version of kanban-zero and kanban-todo stackeffect

kanban-fill: a generalized version of kanban-zero and kanban-todo

diff --git a/kanban.el b/kanban.el
--- a/kanban.el
+++ b/kanban.el
@@ -170,6 +170,30 @@ Gets the ROW and COLUMN via TBLFM ($# an
         ""
       elem)))
 
+(defun kanban--normalize-whitespace (elem)
+"Return ELEM with sequences of spaces reduced to 1 space"
+(replace-regexp-in-string "\\W\\W+" " " elem))
+
+(defun kanban--member-of-table (elem &optional skipcol)
+"Check if ELEM is in some table field
+ignoring all elements of column SKIPCOL.
+
+If SKIPCOL is not set column 1 will be ignored."
+(if (org-at-table-p)
+  (let ((row 2)
+      (skipcol (or skipcol 1))
+      col result field)
+    (while (and (not result) (<= row (length org-table-dlines)))
+    (setq col (if (= 1 skipcol) 2 1))
+    (while (and (not result) (<= col org-table-current-ncol))
+      (setq field (org-table-get row col))
+      (if (and field elem)
+      (setq result (or result (equal (kanban--normalize-whitespace elem) (kanban--normalize-whitespace field)))))
+      (setq col (1+ col))
+      (if (= col skipcol) (setq col (1+ col))))
+    (setq row (1+ row)))
+    result)))
+
 ; Fill the first column with TODO items, except if they exist in other cels
 ;;;###autoload
 (defun kanban-todo (row cels &optional match scope)
@@ -216,6 +240,51 @@ Gets the ROW and all other CELS via TBLF
      elem))) ; otherwise use the element.
 
 
+(defun kanban-fill (&optional match scope)
+  "Kanban TODO item grabber. Fills the current row of the kanban
+table with org-mode TODO entries, if they are not in another cell
+of the table. This allows you to set the state manually and just
+use org-mode to supply new TODO entries.
+
+Can get a string as MATCH to select only entries with a matching tag, as well as a list of org-mode files as the SCOPE to search for tasks.
+
+Only not already present TODO states will be filled into empty
+fields starting from the current field. All fields above the current
+one are left untouched."
+  (let* ((ofc (org-table-get nil nil)) ; remember old field content
+         (row (org-table-current-dline))
+         (startrow row)
+         (col (org-table-current-column)) ; and current column
+         (srcfile (buffer-file-name))
+         (todo (kanban--get-todo-of-current-col))
+         (maxrow (length (delete nil org-table-dlines)))
+         (elems (delete nil (org-map-entries
+                             '(kanban--todo-links-function srcfile)
+                                        ; select the TODO state via the matcher: just match the TODO.
+                             (if match
+                                 (concat match "+TODO=\"" todo "\"")
+                               (concat "+TODO=\"" todo "\""))
+                                        ; read all agenda files
+                             (if scope
+                                 scope
+                               'agenda))))
+         (elem t))
+    (save-excursion
+      (while (and elem (<= row maxrow))
+        (setq elem (pop elems))
+        (while (and elem (kanban--member-of-table elem 0)) 
+          (setq elem (pop elems)))
+        (while (and elem (<= row maxrow) (not (equal "" (org-table-get row col))))
+          (if (= row maxrow)
+              (setq elem nil) ; stop search
+            (setq row (1+ row)))) ; skip non empty rows
+        (when (and elem (equal "" (org-table-get row col)))
+          (if (= row startrow) (setq ofc elem))
+          (save-excursion
+            (if (org-table-goto-line row)
+                (org-table-get-field col elem))))))
+    (org-table-goto-column col)
+    ofc))
 
 ;; An example for auto-updating kanban tables from duply.han
 ;; I use the double-dash to mark this as "private" function