summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mercouris <john@mercouris.email>2017-09-10 01:43:27 -0500
committerJohn Mercouris <john@mercouris.email>2017-09-10 01:43:27 -0500
commitb3e0cc34c0b3cc5bf4abcbc81d13d65fbdb99edc (patch)
tree4078ad0478524882b5d07c7d7cac54931e356f20
parent2be7dbdffb769383527531da459e5604f9af72e5 (diff)
parenta4b9d89962bceb258f50c58d73464f6ed4489f3c (diff)
Merge branch 'minibuffer-completion'0.01
-rw-r--r--next/README.org3
-rw-r--r--next/dependencies.lisp1
-rw-r--r--next/lisp/base.lisp2
-rw-r--r--next/lisp/buffer.lisp14
-rw-r--r--next/lisp/completion.lisp30
-rw-r--r--next/lisp/document-mode.lisp1
-rw-r--r--next/lisp/keymap.lisp1
-rw-r--r--next/lisp/minibuffer.lisp25
-rw-r--r--next/lisp/package.lisp2
-rw-r--r--next/next.asd5
10 files changed, 66 insertions, 18 deletions
diff --git a/next/README.org b/next/README.org
index 55cd16f66..508ed094b 100644
--- a/next/README.org
+++ b/next/README.org
@@ -338,7 +338,8 @@ CLOSED: [2017-09-05 Tue 00:58]
The user will be able to invoke the key binding C-x b to bring up
a menu in the Minibuffer in which they will be able to select a new buffer
to bring to focus.
-**** TODO Minibuffer Completion
+**** DONE Minibuffer Completion
+CLOSED: [2017-09-10 Sun 01:42]
Switch buffer should demonstrate an example of minibuffer completion
candidates
*** DONE Compilation OSX
diff --git a/next/dependencies.lisp b/next/dependencies.lisp
index d7288701b..f7e374b70 100644
--- a/next/dependencies.lisp
+++ b/next/dependencies.lisp
@@ -1 +1,2 @@
(ql:quickload :cl-strings)
+(ql:quickload :cl-string-match)
diff --git a/next/lisp/base.lisp b/next/lisp/base.lisp
index 95fddb9e6..20ae2450c 100644
--- a/next/lisp/base.lisp
+++ b/next/lisp/base.lisp
@@ -8,7 +8,7 @@
(defparameter *root-layout* (qnew "QGridLayout"))
(defparameter *stack-layout* (qnew "QStackedLayout"))
-(setf *minibuffer* (generate-new-buffer "mini-buffer" (minibuffer-mode) nil))
+(setf *minibuffer* (generate-new-buffer "minibuffer" (minibuffer-mode) nil))
(setf *active-buffer* (generate-new-buffer "default" (document-mode)))
;; Used by QT to capture key presses
diff --git a/next/lisp/buffer.lisp b/next/lisp/buffer.lisp
index 3957c95ff..928fe5a26 100644
--- a/next/lisp/buffer.lisp
+++ b/next/lisp/buffer.lisp
@@ -22,9 +22,6 @@
(|addWidget| *stack-layout* (buffer-view new-buffer)))
new-buffer))
-(defun set-major-mode (mode buffer)
- (setf (buffer-mode buffer) mode))
-
(defun set-active-buffer (buffer)
(setf *active-buffer* buffer))
@@ -32,10 +29,15 @@
(set-active-buffer buffer)
(|setCurrentWidget| *stack-layout* (buffer-view *active-buffer*)))
-(defun switch-buffer (index)
- (set-visible-active-buffer (nth (parse-integer index) *buffers*)))
+(defun switch-buffer (input)
+ (loop for buffer in *buffers* do
+ (if (equalp (buffer-name buffer) input)
+ (set-visible-active-buffer buffer))))
+
+(defun switch-buffer-complete (input)
+ (fuzzy-match input (mapcar #'buffer-name *buffers*)))
(defun switch-buffer-read ()
- (input #'switch-buffer))
+ (input #'switch-buffer #'switch-buffer-complete))
(define-key global-map (kbd "C-b") #'switch-buffer-read)
diff --git a/next/lisp/completion.lisp b/next/lisp/completion.lisp
new file mode 100644
index 000000000..b736f04a7
--- /dev/null
+++ b/next/lisp/completion.lisp
@@ -0,0 +1,30 @@
+;;;; completion.lisp --- completion matchers
+
+;;;; completion matchers are functions that accept an input string and
+;;;; a list of strings, and given some logic, return an ordered list
+;;;; of strings matched based on probability
+;;;;
+;;;; as an example, consider the possible implementation
+;;;; "fuzzy_matcher" with input string "so str" and a list of strings:
+;;;; "some string", "strike" we would expect the return to be "some
+;;;; string", "strike", because it is more probable that the user is
+;;;; looking for "some string"
+
+(in-package :next)
+
+
+(defun fuzzy-match (string string-list)
+ (let ((regex
+ (with-output-to-string (stream)
+ (loop for char across string do
+ (princ #\. stream)
+ (princ #\* stream)
+ (princ char stream))
+ ;; match any set of chars after final char
+ (princ #\. stream)
+ (princ #\* stream)))
+ (results nil))
+ (loop for element in string-list do
+ (when (match-re regex element)
+ (push element results)))
+ results))
diff --git a/next/lisp/document-mode.lisp b/next/lisp/document-mode.lisp
index 7539b3ad0..22c0e0bee 100644
--- a/next/lisp/document-mode.lisp
+++ b/next/lisp/document-mode.lisp
@@ -22,6 +22,7 @@
(set-url-read)))
(defun set-url-buffer (input-url buffer)
+ (setf (buffer-name buffer) input-url)
(qlet ((url (qnew "QUrl(QString)" input-url)))
(|setUrl| (buffer-view buffer) url)))
diff --git a/next/lisp/keymap.lisp b/next/lisp/keymap.lisp
index abe8a7eeb..fd7d943bd 100644
--- a/next/lisp/keymap.lisp
+++ b/next/lisp/keymap.lisp
@@ -92,7 +92,6 @@
(return-from consume-key-sequence t))))
;; If we make it to this point, key did not exist
;; in any of the keymaps, print a message and clear stack
- (print "Key Undefined")
(setf *key-sequence-stack* ())
(return-from consume-key-sequence nil)))
diff --git a/next/lisp/minibuffer.lisp b/next/lisp/minibuffer.lisp
index bfec04ba2..81d0d46c9 100644
--- a/next/lisp/minibuffer.lisp
+++ b/next/lisp/minibuffer.lisp
@@ -10,15 +10,20 @@
"A variable to store the minibuffer prompt")
(defparameter *minibuffer-input* (qnew "QLineEdit")
"A variable to store the current minibuffer input")
-(defparameter *minibuffer-completion* (qnew "QListWidget")
+(defparameter *minibuffer-completion-function* nil
+ "A variable to store the function used to generate completion candidates")
+(defparameter *minibuffer-completion-model* (qnew "QStringListModel")
+ " A variable to store the model which updates the QListView")
+(defparameter *minibuffer-completion* (qnew "QListView")
"A variable to store the current minibuffer completion candidates")
(defparameter *minibuffer-callback* nil
"A variable to store the function upon completion of the minibuffer read")
(defparameter *minibuffer-callback-buffer* nil
"A variable to store the buffer which originally requested the minibuffer read")
-(defun input (callback-function)
+(defun input (callback-function &optional completion-function)
(setf *minibuffer-callback* callback-function)
+ (setf *minibuffer-completion-function* completion-function)
(setf *minibuffer-callback-buffer* *active-buffer*)
(|show| (buffer-view *minibuffer*))
(|setFocus| *minibuffer-input*)
@@ -26,12 +31,14 @@
(defun return-input ()
(set-active-buffer *minibuffer-callback-buffer*)
- (funcall *minibuffer-callback* (|text| *minibuffer-input*))
+ (if *minibuffer-completion-function*
+ (progn
+ (funcall *minibuffer-callback*
+ (nth 0 (funcall *minibuffer-completion-function* (|text| *minibuffer-input*)))))
+ (funcall *minibuffer-callback* (|text| *minibuffer-input*)))
(|setText| *minibuffer-input* "")
(|hide| (buffer-view *minibuffer*)))
-(define-key minibuffer-mode-map (kbd "Return") #'return-input)
-
(defun minibuffer-mode ()
"Base mode for input"
(let ((widget (qnew "QWidget")) (layout (qnew "QGridLayout")))
@@ -39,8 +46,9 @@
(|addWidget| layout *minibuffer-input* 0 1 1 15)
(|addWidget| layout *minibuffer-completion* 1 1 1 15)
(|setLayout| widget layout)
+ (|setModel| *minibuffer-completion* *minibuffer-completion-model*)
(make-mode
- :name "Minibuffer-Mode"
+ :name "minibuffer"
:keymap minibuffer-mode-map
:view widget)))
@@ -48,4 +56,9 @@
(defun update-candidates (obj event)
(declare (ignore obj)) ; supress unused warnings
(declare (ignore event)) ; supress unused warnings
+ (when *minibuffer-completion-function*
+ (let ((candidates (funcall *minibuffer-completion-function* (|text| *minibuffer-input*))))
+ (|setStringList| *minibuffer-completion-model* candidates)))
nil)
+
+(define-key minibuffer-mode-map (kbd "Return") #'return-input)
diff --git a/next/lisp/package.lisp b/next/lisp/package.lisp
index 1cd76ae7b..c09929833 100644
--- a/next/lisp/package.lisp
+++ b/next/lisp/package.lisp
@@ -3,6 +3,6 @@
(in-package :cl-user)
(defpackage :next
- (:use :common-lisp :eql :cl-strings)
+ (:use :common-lisp :eql :cl-strings :cl-string-match)
(:export
#:start))
diff --git a/next/next.asd b/next/next.asd
index c560ad117..9e606e9ff 100644
--- a/next/next.asd
+++ b/next/next.asd
@@ -2,11 +2,12 @@
;;;; next.asd
(defsystem :next
:serial t
- :depends-on (:cl-strings)
+ :depends-on (:cl-strings :cl-string-match)
:components ((:file "lisp/package")
(:file "lisp/qt")
(:file "lisp/keymap")
- (:file "lisp/document-mode")
(:file "lisp/minibuffer")
(:file "lisp/buffer")
+ (:file "lisp/document-mode")
+ (:file "lisp/completion")
(:file "lisp/base")))