stumpwm-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[STUMP] Patch


From: Manuel Giraud
Subject: [STUMP] Patch
Date: Tue, 14 Dec 2004 17:59:17 +0100
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Hi,

This patch compiles an old one plus other features:
   - Cursor in the input window;
   - Cleaner (but not so clean) input window's keybindings;
   - Bug correction in the sample-stumpwmrc;
   - Remove dumb message when renumbering.

---8<-------------------------------------------
Index: core.lisp
===================================================================
RCS file: /cvsroot/stumpwm/stumpwm/core.lisp,v
retrieving revision 1.9
diff -u -r1.9 core.lisp
--- core.lisp   1 Dec 2004 01:18:20 -0000       1.9
+++ core.lisp   14 Dec 2004 17:59:32 -0000
@@ -363,6 +363,14 @@
                        :background
                        (xlib:screen-black-pixel (screen-number screen))))
 
+(defun create-cursor-gcontext (screen)
+  (xlib:create-gcontext :drawable (screen-message-window screen)
+                       :font (screen-font screen)
+                       :foreground
+                       (xlib:screen-white-pixel (screen-number screen))
+                       :background 
+                       (xlib:alloc-color (xlib:screen-default-colormap 
(screen-number screen)) *cursor-color*)))
+
 (defun max-width (font l)
   "Return the width of the longest string in L using FONT."
   (loop for i in l
Index: input.lisp
===================================================================
RCS file: /cvsroot/stumpwm/stumpwm/input.lisp,v
retrieving revision 1.5
diff -u -r1.5 input.lisp
--- input.lisp  1 Dec 2004 01:18:20 -0000       1.5
+++ input.lisp  14 Dec 2004 17:59:32 -0000
@@ -75,8 +75,9 @@
 
 (defun read-one-line (screen prompt &optional (initial-input ""))
   "Read a line of input through stumpwm and return it."
-  (labels ((key-loop ()
-            (let ((input (coerce initial-input 'list)))
+  (let* ((content (coerce initial-input 'list))
+        (input (make-buffer :content content :index (length content))))
+    (labels ((key-loop ()
               (do ((key (read-key) (read-key)))
                   (nil)
                 (multiple-value-bind (inp ret) (process-input screen prompt 
input
@@ -86,13 +87,13 @@
                     ('done
                      (return (values input 'done)))
                     ('abort
-                     (return (values input 'abort)))))))))
-    (setup-input-window screen prompt initial-input)
-    (multiple-value-bind (input ret) (key-loop)
-      (shutdown-input-window screen)
-      (unless (eq ret 'abort)
-       ;; Return the input bucket as a string
-       (concatenate 'string input)))))
+                     (return (values input 'abort))))))))
+      (setup-input-window screen prompt input)
+      (multiple-value-bind (input ret) (key-loop)
+       (shutdown-input-window screen)
+       (unless (eq ret 'abort)
+         ;; Return the input bucket as a string
+         (concatenate 'string (buffer-content input)))))))
 
 (defun read-one-char (screen)
   "Read a single character."
@@ -106,14 +107,22 @@
 (defun draw-input-bucket (screen prompt input)
   "Draw to the screen's input window the contents of input."
   (let* ((gcontext (create-message-window-gcontext screen))
+        (cursor-gcontext (create-cursor-gcontext screen))
         (win (screen-input-window screen))
         (prompt-width (xlib:text-width (screen-font screen) prompt))
+        (content (buffer-content input))
+        (index (buffer-index input))
+        (before-chunk (subseq content 0 index))
+        (cursor-chunk (subseq content index (min (length content) (1+ index))))
+        (after-chunk (subseq content (min (length content) (1+ index))))
+        (before-width (xlib:text-width (screen-font screen) before-chunk))
+        (cursor-width (xlib:text-width (screen-font screen) cursor-chunk))
         (width (+ prompt-width
-                  (max 100 (xlib:text-width (screen-font screen) input))))
-       (screen-width (xlib:drawable-width (xlib:screen-root (screen-number 
screen)))))
+                  (max 100 (xlib:text-width (screen-font screen) content))))
+        (screen-width (xlib:drawable-width (xlib:screen-root (screen-number 
screen)))))
     (xlib:clear-area win :x (+ *message-window-padding*
                               prompt-width
-                              (xlib:text-width (screen-font screen) input)))
+                              (xlib:text-width (screen-font screen) content)))
     (xlib:with-state (win)
                     (setf (xlib:drawable-x win) (- screen-width width
                                                    (* 
(xlib:drawable-border-width win) 2)
@@ -123,10 +132,79 @@
                            *message-window-padding*
                            (xlib:font-ascent (screen-font screen))
                            prompt)
+    ;; Before cursor
     (xlib:draw-image-glyphs win gcontext
                            (+ *message-window-padding* prompt-width)
                            (xlib:font-ascent (screen-font screen))
-                           input)))
+                           before-chunk)
+    ;; Cursor
+    (xlib:draw-image-glyphs win cursor-gcontext
+                           (+ *message-window-padding* prompt-width 
before-width)
+                           (xlib:font-ascent (screen-font screen))
+                           (or cursor-chunk " "))
+    ;; After cursor
+    (xlib:draw-image-glyphs win gcontext
+                           (+ *message-window-padding* prompt-width 
before-width cursor-width)
+                           (xlib:font-ascent (screen-font screen))
+                           after-chunk)))
+
+
+;; Simple buffer with index management
+(defstruct buffer content index)
+
+(defun goto-end (buffer)
+  "Set index to the end of buffer."
+  (setf (buffer-index buffer) (length (buffer-content buffer))))
+
+(defun goto-start (buffer)
+  "Set index to the beginning of buffer."
+  (setf (buffer-index buffer) 0))
+
+(defun move-left (buffer)
+  "Move left :-)"
+  (setf (buffer-index buffer) (max 0 (1- (buffer-index buffer)))))
+
+(defun move-right (buffer)
+  "Move right :-)"
+  (setf (buffer-index buffer) (min (length (buffer-content buffer)) (1+ 
(buffer-index buffer)))))
+
+(defun insert-and-move (buffer obj)
+  "Insert obj and increment index."
+  (setf (buffer-content buffer)
+       (concatenate 'list 
+                    (subseq (buffer-content buffer) 0 (buffer-index buffer)) 
+                    (list obj)
+                    (subseq (buffer-content buffer) (buffer-index buffer))))
+  (incf (buffer-index buffer)))
+
+(defun deinsert-and-move (buffer)
+  "Remove one object of buffer and decrement index."
+  (setf (buffer-content buffer)
+       (concatenate 'list 
+                    (subseq (buffer-content buffer) 0 (max 0 (1- (buffer-index 
buffer))))
+                    (subseq (buffer-content buffer) (buffer-index buffer))))
+  (setf (buffer-index buffer) (max 0 (1- (buffer-index buffer)))))
+
+(defun deinsert-forward (buffer)
+  (setf (buffer-content buffer)
+       (concatenate 'list 
+                    (subseq (buffer-content buffer) 0 (buffer-index buffer))
+                    (subseq (buffer-content buffer) (1+ (buffer-index 
buffer))))))
+
+;; XXX Might be merge with 'set-key-binding' and hash table as an argument.
+(defun set-input-key-binding (key mod cmd)
+  "Bind KEY to the function FN."
+  (setf (gethash (list key mod) *input-key-bindings*) cmd))
+
+(defun set-default-input-bindings ()
+  (set-input-key-binding #\Return '() #'(lambda (inp) (values inp 'done)))
+  (set-input-key-binding #\Backspace '() #'(lambda (inp) (deinsert-and-move 
inp) (values inp nil)))
+  (set-input-key-binding #\g '(:control) #'(lambda (inp) (values inp 'abort)))
+  (set-input-key-binding #\a '(:control) #'(lambda (inp) (goto-start inp) 
(values inp nil)))
+  (set-input-key-binding #\e '(:control) #'(lambda (inp) (goto-end inp) 
(values inp nil)))
+  (set-input-key-binding #\b '(:control) #'(lambda (inp) (move-left inp) 
(values inp nil)))
+  (set-input-key-binding #\f '(:control) #'(lambda (inp) (move-right inp) 
(values inp nil)))
+  (set-input-key-binding #\d '(:control) #'(lambda (inp) (deinsert-forward 
inp) (values inp nil))))
 
 (defun process-input (screen prompt input code state)
   "Process the key (code and state), given the current input
@@ -135,24 +213,15 @@
              "Call the appropriate function based on the key
 pressed. Return 'done when the use has signalled the finish of his
 input (pressing Return), nil otherwise."
-             (cond ((eq (xlib:keycode->keysym *display* code 0)
-                        (char->keysym #\Return))
-                    (values inp 'done))
-                   ((eq (xlib:keycode->keysym *display* code 0)
-                        (char->keysym #\Backspace))
-                    (if (cdr inp)
-                        (rplacd (last inp 2) '())
-                      (setf inp nil))
-                    (values inp nil))
-                   ((and (eq (xlib:keycode->keysym *display* code 0)
-                             (char->keysym #\g))
-                         (member :control (xlib:make-state-keys state)))
-                    (values inp 'abort))
-                   (t (let* ((mods (xlib:make-state-keys state))
-                             (ch (keycode->character code mods)))
-                        (if (and (characterp ch) (char>= ch #\Space) (char<= 
ch #\~))
-                            (setf inp (conc1 inp ch)))
-                        (values inp nil))))))
+             (let* ((mods (xlib:make-state-keys state))
+                    (ch (keycode->character code mods)))
+               (multiple-value-bind (fn present-p) (gethash (list ch mods) 
*input-key-bindings*)
+                 (if present-p
+                     (funcall fn inp)
+                   (progn
+                     (when (and (characterp ch) (char>= ch #\Space) (char<= ch 
#\~))
+                       (insert-and-move inp ch))
+                     (values inp nil)))))))
     (multiple-value-bind (inp ret) (process-key input code state)
       (case ret
        ('done
Index: primitives.lisp
===================================================================
RCS file: /cvsroot/stumpwm/stumpwm/primitives.lisp,v
retrieving revision 1.6
diff -u -r1.6 primitives.lisp
--- primitives.lisp     1 Dec 2004 01:18:20 -0000       1.6
+++ primitives.lisp     14 Dec 2004 17:59:32 -0000
@@ -75,6 +75,9 @@
 (defvar *font-name* "9x15bold"
   "The name of the font to use when stumpwm displays messages.")
 
+(defvar *cursor-color* "blue"
+  "Input window cursor color.")
+
 (defvar *prefix-key* #\t
   "The key to use as the prefix key")
 
@@ -97,6 +100,8 @@
 (defvar *key-bindings* (make-hash-table :test 'equal)
   "An alist of keysym function pairs.")
 
+(defvar *input-key-bindings* (make-hash-table :test 'equal))
+
 ;; FIXME: This variable is set only once but it needs to be set after
 ;; the display is opened. So should it have +'s around it even though
 ;; it's defined as a variable?
Index: sample-stumpwmrc.lisp
===================================================================
RCS file: /cvsroot/stumpwm/stumpwm/sample-stumpwmrc.lisp,v
retrieving revision 1.3
diff -u -r1.3 sample-stumpwmrc.lisp
--- sample-stumpwmrc.lisp       1 Dec 2004 01:39:27 -0000       1.3
+++ sample-stumpwmrc.lisp       14 Dec 2004 17:59:32 -0000
@@ -24,8 +24,8 @@
 (defmacro make-web-jump (name prefix)
   `(define-stumpwm-command ,name (screen (search :rest ,(concatenate 'string 
name " search: ")))
      (declare (ignorable screen))
-     (substitute #\+ #\Space search)
-     (run-shell-command (concatenate 'string ,prefix search))))
+     (let ((search (substitute #\+ #\Space search)))
+       (run-shell-command (concatenate 'string ,prefix search)))))
 
 (make-web-jump "google" "firefox http://www.google.fr/search?q=";)
 (make-web-jump "imdb" "firefox http://www.imdb.com/find?q=";)
Index: stumpwm.lisp
===================================================================
RCS file: /cvsroot/stumpwm/stumpwm/stumpwm.lisp,v
retrieving revision 1.22
diff -u -r1.22 stumpwm.lisp
--- stumpwm.lisp        1 Dec 2004 01:18:20 -0000       1.22
+++ stumpwm.lisp        14 Dec 2004 17:59:32 -0000
@@ -110,6 +110,7 @@
        (focus-frame (first *screen-list*) (screen-current-frame (first 
*screen-list*)))
        ;; Setup the default key bindings. FIXME: should this be in the hook?
        (set-default-bindings)
+       (set-default-input-bindings)
        (echo-string (first *screen-list*) "Welcome to The Stump Window 
Manager!")
        ;; Load rc file
        (multiple-value-bind (success err rc) (load-rc-file)
Index: user.lisp
===================================================================
RCS file: /cvsroot/stumpwm/stumpwm/user.lisp,v
retrieving revision 1.11
diff -u -r1.11 user.lisp
--- user.lisp   1 Dec 2004 03:49:56 -0000       1.11
+++ user.lisp   14 Dec 2004 17:59:32 -0000
@@ -375,8 +375,7 @@
          (setf (window-number screen win) nf)
          (setf (window-number screen (screen-current-window screen)) nt))
       ;; Just give the window the number
-      (setf (window-number screen (screen-current-window screen)) nt)))
-  (echo-string screen "Number expected"))
+      (setf (window-number screen (screen-current-window screen)) nt))))
 
 (define-stumpwm-command "number" (screen (n :number "Number: "))
   (renumber screen n))
---8<-------------------------------------------

-- 
Manuel Giraud (CNRS/CETP)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]