Re: [Sawfish] sawinlist : provides emacs functions for listing and manipulating x-windows managed by sawfish

[ Thread Index | Date Index | More lists.tuxfamily.org/sawfish Archives ]


Here it is. I've just included the two files inline as I was not sure what you meant by your gzip suggestion (don't know how to post gzip). I have found in other lists that posting source code sometimes results in redundant linefeeds, but for emacs source that *may* not matter. However, since I see the sawfish listserv thoughtfully translated my email addr to xxx's, I'll put it here again in not-too-hard-to-understand form - if you want the gzip file, post here or send email to in the next line, remove underscore and change (word1 word2) to at-sign||word1.word2 (omit ||)
john_lumby(hotmail com)


In this package:
----------------

sawinlist.el     the emacs functions that interface with sawfish  (using sawfish-client command)
;;-----------------
;;; sawinlist.el --- functions for listing and manipulating x-windows managed by sawfish

;; Copyright (C) 2011 by the author: John Lumby johnlumby@xxxxxxxxxxx

;; This file may be used in conjunction with GNU Emacs.

;; Both this file and GNU Emacs are free software; you may redistribute them and/or modify
;; them under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; Both this file and GNU Emacs are distributed in the hope that they will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

(provide 'sawinlist)

(defun sawinlist-raise (this-point)
 "raise the sawfish window whose name is the string at or near point;
a Ctl-g<windowid>  sequence,  if present for disambiguation,
may be removed prior to selecting the line,  to cause selection of most recent with that name"
  (let
    (
      tempoint nextpoint temp len curchar index nextindx window-name
       cur-is-ctl-g prev-was-ctl-g
       escape-type ; values "["<=>  octal sequence,  "<"<=>  window-id
;;     (coding-system-for-read 'no-conversion)
;;     (coding-system-for-write 'no-conversion)
      (coding-system-for-read 'undecided)
      (coding-system-for-write 'iso-latin-1)
      (cur-line-num 0) ; line number of current line counted backwards from the last as 0
      windownum        ; window-id of window on this line according to sawinlist-window-ids
      override-window-id ;  window-id (printable) from override in line in buffer
    )
;;   count lines backwards from last to current point
   (goto-char (point-max))
   (backward-char)
   (beginning-of-line)
   (while (>  (point) this-point)
     (setq cur-line-num (1+ cur-line-num))
     (forward-line -1)
   )
   (goto-char this-point)
   (setq tempoint (progn (beginning-of-line) (point)))
   (setq nextpoint (progn (end-of-line) (point)))
;  window-name is from start of line to end,  minus any appended window-id
   (setq temp (buffer-substring-no-properties tempoint nextpoint))
;  quote backslash and double-quote, and convert the \C-G sequences back to control chars
   (setq index 0)
   (setq len (length temp))
   (setq window-name "")
   (setq override-window-id nil)
   (setq prev-was-ctl-g nil)
   (setq escape-type nil)
;   crawl through characters
       (while (<  index len)
     (setq nextindx (1+ index))
     (setq curchar (substring temp index nextindx))
     (setq cur-is-ctl-g (string= curchar ""))
     (cond
      (cur-is-ctl-g                            ; start of a \C-G sequence - merely remember
       (setq prev-was-ctl-g t)
       (setq escape-type nil))                 ; next char determines escape-type
      ((and prev-was-ctl-g (not cur-is-ctl-g) (not escape-type)) ; continuation of a \C-G sequence - identify escape type
        (if (or
              (string= curchar "[")               ; octal sequence
                  (string= curchar "<"))              ; window-id of non-unique window name
               (setq escape-type curchar) )
            (setq prev-was-ctl-g nil)
      )
      (escape-type ; prev char was the escape type,  current is start of sequence
           (cond
         ( (string= escape-type "[")               ; octal sequence
               (setq nextindx (+ index 3))
               (setq window-name (concat window-name (car (read-from-string (concat "\"\\" (substring temp index nextindx) "\"")))))
               (setq nextindx (1+ nextindx))           ; for the terminating "]"
         )
             ( (string= escape-type "<")               ; window-id of non-unique window name
;;     in this case, set override-window-id to force selection by window-id
           (if (string-match "\\([0-9]+\\)>" temp index)
           (setq override-window-id (match-string-no-properties 1 temp)))
               (setq nextindx len)                     ; and exclude this from the true window-name
             )
           )
       (setq escape-type nil)
         )
     (t
;;   not a \C-G sequence - take the character as is or quoted
       (setq prev-was-ctl-g nil)
           (if (or (string= curchar "\\")
                   (string= curchar "\"")
               )
;   quote the character
             (setq window-name (concat window-name "\\")))
           (setq window-name (concat window-name curchar))
     ))
     (setq index nextindx)
       )
       (setq windownum (aref sawinlist-window-ids cur-line-num)) ;  save this before refresh
;;     always refresh
       (sawinlist-build)
;;     (message window-name)
;;     if an override window-id of non-unique window name was found,  then get window using that window id.
;;     otherwise,  the following or clause first tries to find the window by name, and then if that fails, by window id.
;;     reason why not to use window id first is that, when there are multiple windows with same name,
;;     (and assuming that the user deleted the Ctl-g<windowid>  sequence at the end of the name so that this function does not see it),
;;     empirically, sawfish always finds the one we want (most recent) whereas use of window id would not.
;;     however, where an app continually changes its name, such as Lotus Notes, mozilla, etc,
;;     we want to locate that window based on id
;;     be careful with formatting of the windownum  -   we want an integer but it may be stored as a float with .0 as fractional part
;; (message (concat "(let ((chosen-window " (cond (override-window-id (concat "(get-window-by-id " override-window-id ")")) (t (concat "(or (get-window-by-name \"" window-name "\") (get-window-by-id " (format "%.0f" windownum) "))"))) ")) (if (window-iconified-p chosen-window) (uniconify-window chosen-window)) (activate-window chosen-window))"))
   (call-process "sawfish-client" nil nil nil "-e" (concat "(let ((chosen-window " (cond (override-window-id (concat "(get-window-by-id " override-window-id ")")) (t (concat "(or (get-window-by-name \"" window-name "\") (get-window-by-id " (format "%.0f" windownum) "))"))) ")) (if (window-iconified-p chosen-window) (uniconify-window chosen-window)) (activate-window chosen-window))"))
))

(defun sawinlist-raise-from-kbd (this-point)
 "raise the sawfish window whose name is the string at or near point"
 (interactive "d")
  (save-excursion
  (sawinlist-raise this-point)
))

(defun sawinlist-raise-from-mouse (eventp)
  "raise the sawfish window whose name is the string at or near mouse position"
  (interactive "e")
  (mouse-set-point eventp)
  (save-excursion
    (let ( (this-point (point)) )
;; as a convenience, treat right-click at end of buffer as request to refresh it
      (if (= this-point (point-max))
      (sawinlist-build)
;;     else
      (sawinlist-raise this-point)
      )
)))

(defun sawinlist-build ()
 "build list of sawfish windows in *SAWINLIST* buffer
for manipulation by user - e.g. to raise and lower windows"
;;  the following returns the window list
;;  bash -c 'sawfish-client -e "(let ((winlist (managed-windows)) tcar tcdr (repout \"\`\") temp) (setq tcdr winlist) (while (setq tcar (car tcdr)) (setq tcdr (cdr tcdr)) (setq temp (prin1-to-string (window-name tcar))) (setq repout (concat repout (substring temp 1 (1- (length temp))) \"\`\"))) (princ repout))" | tr "\`" "\n"'
;; and the following raises a named window
;; sawfish-client -e '(activate-window (get-window-by-name "labvm"))'
;; and the following renames a named window
;; sawfish-client -e "(set-x-property (get-window-by-name \"lumby@lumbyrnt:~\") 'WM_NAME \"redpine-screen\" 'STRING 8)"
;; and the following deletes a named window
;; sawfish-client -e '(delete-window (get-window-by-name "Smile!"))'
;;
;; quoting is tricky:   there are up to three levels of nesting of quoting:
;;     level      where                                                       what quoted
;; .     1    inside a lisp string                                                  \ "
;; .      2   inside the shell command (string attached to -c)                      \ " ` $
;; .       3  inside a lisp string inside sawfish-client parmstring                 \ "
;;
;; transparency schemes:
;; two transparency schemes are used:
;;   .  sawfish ==>>  this program           :    printable-ascii char whose value is in symbol transp-char
;;   .  this program ==>>  *SAWINLIST* buffer  :    non-printable control char Ctl-G
;; details of each are given where deployed.    the rationale for these choices and why they are different is :
;;   .  sawfish ==>>  this program
;;       we *must* use a printable-ascii since non-printable chars are translated into quoted octal sequences before we receive them;
;;       note that this character is internal to this program and its use for control sequences is not visible to the user.
;;   .  this program ==>>  *SAWINLIST* buffer
;;       we *prefer* to use a non-printable-ascii since the chosen character is visible to the user
;;       and non-printable is less likely to appear as itself in a name,   i.e. results in less confusion when displayed.
;;
 (interactive)
  (save-excursion
  (let
    (
     (transp-char "`") ; printable-ascii char used to delimit control sequences in data sawfish ==>>  this program - see above and below
     (cbuf (current-buffer))
     (sawbuf (get-buffer-create "*SAWINLIST*"))
     sawfish-string ;  the string passed to sawfish -e
     temp ix replacement tempoint windowid windownum (winid-list (list))
;    (coding-system-for-read 'no-conversion)
;    (coding-system-for-write 'no-conversion)
     (coding-system-for-read 'undecided)
     (coding-system-for-write 'iso-latin-1)
     window-name prev_name
     start-of-windowid-section end-of-windowid-section predecessor-windowid
     current-repeated-name ; indicates whether this window name is a repetition of its predecessor
     prev-repeated-name    ; prev value of current-repeated-name : indicates whether the previous window name was a repetition of its predecessor (cur - 2)
    )
;; (call-process "bash" nil "*SAWINLIST*" nil "-c" "sawfish-client -e \"(let ((junk \\\"junkword\\\") temp) (princ junk))\"")
   (switch-to-buffer sawbuf)
   (erase-buffer)
;; in the following:
;; the sawfish lambda builds the list of names using a transparent control char,  default back-tick :
;;    single transp-char in name is replaced by two transp-chars
;;    names are separated by sequence forward-slash transp-char forward-slash, which is replaced by newline in the bash one-line-command
;;    any name ending in "- [- a-zA-Z0-9_.:]+" will have this suffix prepended as prefix, on assumption that it is a constant,
;;               separated by sequence blank transp-char blank
;;    window-id integer is appended to each name separated by asterisk transp-char asterisk
;; none of these sequences is a part of any other sequence regardless of neighbouring characters
;;
;; the purpose of the if not string= test is to exclude the name of the current window since we are already in it
;;
;;

(setq sawfish-string (concat "(let ((winlist (managed-windows)) tcar tcdr (repout \"/" transp-char "/\")
     temp index previndx nextindx curchar len dashpos transtr)
  (setq tcdr winlist)
  (while (setq tcar (car tcdr))
   (setq tcdr (cdr tcdr))
   (setq temp (prin1-to-string (window-name tcar) t))
   (setq temp (substring temp 1 (1- (length temp))))
;        (princ temp)
   (cond
;        ignore current window
     ((string= temp \"" (or (cdr (assoc 'title (frame-parameters (selected-frame)))) (cdr (assoc 'name (frame-parameters (selected-frame))))) "\"))
     (t
       (setq index 0)
       (setq dashpos nil)
       (setq transtr \"\")
       (setq len (length temp))
;   crawl through characters
       (while (<  index len)
;        (princ index)
     (setq nextindx (1+ index))
     (setq curchar (substring temp index nextindx))
     (setq transtr (concat transtr curchar))
     (cond
       ((string= curchar \"-\")
          (if (and (>  index 1) (<  index (- len 4))
               (string= (substring temp previndx index) \" \")
               (string= (substring temp nextindx (1+ nextindx)) \" \")
          )
;   found candidate dash
          (setq dashpos index)))
;   check if valid suffix character ...
       ((string-match \"[ a-zA-Z0-9_.:]\" curchar))
;   ... if not ...
       (t
           (setq dashpos nil)
           (if (string= curchar \"" transp-char "\")
;   repeat the transp-char
           (setq transtr (concat transtr curchar)))
       )
     )
     (setq previndx index)
     (setq index nextindx)
       )
       (if (and dashpos (<  (- len dashpos) 44))
;   prepend the dash suffix
       (setq transtr (concat (substring temp (+ dashpos 2)) \" " transp-char " \" transtr)))
;   append the window-id as well
       (setq repout (concat repout transtr \"*" transp-char "*\" (prin1-to-string (window-id tcar) t) \"/" transp-char "/\"))))
  )
  repout
)"))

;; (call-process "echo" nil "*SAWINLIST*" nil sawfish-string) ; to debug
(call-process "sawfish-client" nil "*SAWINLIST*" nil "-e" sawfish-string)
;;
;; post-processing
;;
;; any non-printable characters in original window names appear as a doubly-quoted octal-read-syntax
;; these are unambiguously distinguished from a clear sequence of such characters (e.g. \\253)
;; because, fortunately, original backslashes appear as a sequence of four backslashes (don't know why ...)
;; so the non-printables are distinguishable by leading with a pair of backslashes NOT preceded by backslash;
;; also note we don't want any clear linefeeds to be translated back to clear linefeeds since our name parsing and sorting relies on one name per line;
;; replace each octal-read-syntax character by :
;;  . if in range 000-037 ( the control chars , including \C-G)  \C-g[octal-sequence] (control-G followed by octal-read-syntax in square-brackets)
;;       (note - the above range includes linefeed - 012 )
;;  . otherwise    the single character
;;
;; note - for reason given below, this works inside emacs started with no .emacs profile but not in my heavily customized emacs -
;;        although the resulting translation is made, sawfish does not find the window -
;;        it seems that in the customized emacs, the special characters are translated once more
;;        with some kind of special leading character
;;        at some point before being sent to sawfish in sawinlist-raise.
;;        explanation found - relating to coding system used for writing to / reading from subprocesses:
;;        although both emacs's had enable-multibyte-characters t nonascii-insert-offset 0
;;        .   customized emacs - had default-process-coding-system (mule-utf-8 . mule-utf-8)
;;        . uncustomized emacs - had default-process-coding-system (undecided . iso-latin-1)
;;        I don't know why these defaults were different, but
;;        setting both coding-system-for-read and coding-system-for-write as for uncustomized emacs makes it work!
;;        I also am NOT sure that this will correctly handle all character sets appearing in window titles ...
;;
   (goto-char (point-min))
   (while (re-search-forward "\\(^\\|[^\\]\\)\\(\\\\\\\\[0-7][0-7][0-7]\\)" nil t)
;;   (match-string-no-properties 2) is the octal sequence including two leading backslashes
     (setq temp (substring (match-string-no-properties 2) 1)) ; octal sequence including one leading backslash
     (setq ix (car (read-from-string (concat "?" temp)))) ; numeric value
     (cond
      ((<  ix 32)
       (setq replacement (concat "[" (substring temp 1) "]")))
      (t
       (setq replacement (car (read-from-string (concat "\"" temp "\""))))) ; character value as a string - default replacement
     )
     (replace-match replacement t t nil 2)
;; back up behind last replacement char in case another sequence follows immediately
;; (note the matching regexp includes one character or line-start preceding the octal sequence)
     (backward-char)
   )
;;
;; replace each transparent linefeed sequence by a single linefeed
   (goto-char (point-min))
   (while (search-forward (concat "/" transp-char "/") nil t)
     (replace-match "\n" t t nil)
   )
;; delete each line containing only single double-quote
   (goto-char (point-min))
   (while (re-search-forward "^\"$" nil t)
     (delete-region (1- (point)) (1+ (point)))
   )
;; sort the buffer
;; note that the window-ids are still present but at the end of lines so we may use sort-lines
   (goto-char (point-min))
   (sort-lines nil (point-min) (point-max))
;; save window ids in our persistent defvar - format is a vector of window-ids in linenumber sequence
;; if window name key is unique, remove window id
;; otherwise, for any sequence of repeated lines (identical window name key,  i.e. non-unique window names) :
;;      IF   that name is valid (there is still a window of that name)
;;      THEN leave the window-id in place
;;           (changing the transp-char sequence into the sequence Ctl-G<windowid>
;;            to make it disambiguable by sawinlist-raise)
   (makunbound 'sawinlist-window-ids)
   (goto-char (point-min))
   (setq prev-name "")
   (setq prev-repeated-name nil)
   (while (re-search-forward (concat "\\(\\*" transp-char "\\*\\)\\([0-9]+\\)") nil t)
     (setq windowid (match-string-no-properties 2))
     (setq windownum (string-to-number windowid))
     (setq start-of-windowid-section (match-beginning 0))
     (setq end-of-windowid-section (match-end 0))
;;   always delete the windowid section  -
;;   the corresponding ctl-G sequence will be inserted on next loop if needed
     (delete-region start-of-windowid-section end-of-windowid-section)
     (setq tempoint (point)) ; end of current window-name
     (beginning-of-line)
     (setq window-name (buffer-substring (point) start-of-windowid-section))
     (cond
      ((string= window-name prev-name)
       (setq current-repeated-name t)
      )
      (t  ; else different
       (setq current-repeated-name nil)
       (setq prev-name window-name)
      )
     )
;;   save its windowid
     (setq winid-list (cons windownum winid-list))
;;   insert window-id sequence at end of predecessor unless its name was distinct from its predecessor and ours
     (cond
       ( (or prev-repeated-name current-repeated-name)
         (forward-line -1)
         (end-of-line)
         (insert (concat "<" (format "%d" predecessor-windowid)">"))
         (forward-line 1)
         (end-of-line)
       )
     )
     (setq prev-repeated-name current-repeated-name)
     (setq predecessor-windowid windownum)
   )
   (cond
     ( prev-repeated-name
       (end-of-line)
       (insert (concat "<" (format "%.0f" predecessor-windowid)">"))
     )
   )
   (defvar sawinlist-window-ids (vconcat winid-list) "vector of sawinlist window ids")
;;
;; replace each sequence of three backslashes followed by double-quote by a single double-quote
   (goto-char (point-min))
   (while (search-forward "\\\\\\\"" nil t)
     (replace-match "\"" t t nil)
   )
;; replace each sequence of four backslashes by a single backslash
   (goto-char (point-min))
   (while (search-forward "\\\\\\\\" nil t)
     (replace-match "\\" t t nil)
   )
;;
;; chop off the prepended dash-suffices
   (goto-char (point-min))
   (while (re-search-forward (concat "^.* " transp-char " ") nil t)
     (replace-match "" t t nil)
   )
;; replace each sequence of two transp-chars by a single transp-char
   (goto-char (point-min))
   (while (search-forward (concat transp-char transp-char) nil t)
     (replace-match transp-char t t nil)
   )

)))


;;----------------


sawlist.el       example of user's own load file to run in the emacs frame to initialise the sawinlist

;;----------------

;;   example of an emacs load file to initialise a sawinlist frame
(require 'sawinlist)
(defvar sawin_keymap (copy-keymap (current-global-map))) ;; keymap to be in effect in our buffer

;;   frame-related user customizations --- change anything in the following
;;   local keymap bindings
(define-key sawin_keymap [(control ?3)] 'sawinlist-raise-from-kbd)
(define-key sawin_keymap [(control ?4)] 'sawinlist-build)
(define-key sawin_keymap [f8] 'toggle-truncate-lines)
(define-key sawin_keymap [mouse-3] 'mouse-set-point) ; to prevent altering selection
(define-key sawin_keymap [down-mouse-3] 'sawinlist-raise-from-mouse)
(define-key sawin_keymap "\C-xc" 'dired)
(define-key sawin_keymap "\C-x\C-c" 'dired)
(define-prefix-command 'Ctl-z); define Ctl-z to be a symbolic prefix key
(define-key sawin_keymap "\C-z" 'Ctl-z); define ctl-z to be the prev'ly def'd prefix key
(define-prefix-command 'Ctl-z-Ctl-x)
(define-key sawin_keymap "\C-z\C-x" 'Ctl-z-Ctl-x)
(define-key sawin_keymap "\C-z\C-x\C-c" 'save-buffers-kill-emacs)

;;   load this file into a buffer in case we want to modify it on the fly
(if (file-readable-p load-file-name)
  (find-file load-file-name))

;; odds and ends to make the frame appear as we wish
; (set-frame-height (selected-frame) 64)
; (set-frame-width (selected-frame) 18)
; (set-default-font "6x13")
; (modify-frame-parameters (selected-frame) (list '(mouse-color . "black")))
; (modify-frame-parameters (selected-frame) (list '(background-color . "#E0EDED")))
; (modify-frame-parameters (selected-frame) (list '(foreground-color . "#751503")))
; the above are commented out since usually best to set them from the emacs command line
(modify-frame-parameters (selected-frame) '((menu-bar-lines . 0)))
(tool-bar-mode -1)
;;   frame-related user customizations ---  change anything in the above

;; preferably do not change the next part
;; build the list in the current buffer and set buffer name
(sawinlist-build)
(set-buffer "*SAWINLIST*") ;; preferably dont change this name,  as it is hard-coded in sawinlist.el
(if (and (boundp 'sawin_keymap) (keymapp sawin_keymap)) ;; check in case user changed the suggested defvar
  (use-local-map sawin_keymap))
;; preferably do not change the above part

;;   buffer-related user customizations  ---  change anything in the following block
;;   faces and some content that must be run after the terminal-specific init
(set-face-font 'modeline "-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1")
(set-face-background 'default "#E0EDED")
(set-face-foreground 'default "#751503")
(progn (face-set-after-frame-default (selected-frame)) (set-face-background 'default (cdr (assoc 'background-color (frame-parameters (selected-frame))))) (set-face-background 'fringe (cdr (assoc 'background-color (frame-parameters (selected-frame))))) (set-face-foreground 'default (cdr (assoc 'foreground-color (frame-parameters (selected-frame))))))
(goto-char (point-max))
;;    insert text of some emacs functions that we might want to modify and run into the buffer
(insert "\n(progn (modify-frame-parameters (selected-frame) '((menu-bar-lines . 0)))\n(set-default-font \"6x13\")\n(set-face-font 'modeline \"-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1\")\n (face-set-after-frame-default (selected-frame)) (set-face-background 'default (cdr (assoc 'background-color (frame-parameters (selected-frame))))) (set-face-background 'fringe (cdr (assoc 'background-color (frame-parameters (selected-frame))))) (set-face-foreground 'default (cdr (assoc 'foreground-color (frame-parameters (selected-frame)))))\n(modify-frame-parameters (selected-frame) (list (cons 'vertical-scroll-bars nil)))\n(server-start))")
;; maybe we want to start a shell???  for example ...
;; (let ((explicit-shell-file-name "/bin/bash") (explicit-bash-args (list "-i"))) (shell "*XSET*"))
;; (sleep-for 1)
;; (set-buffer "*XSET*")
;; (goto-char (point-max))
;; (insert "export LANG=C DISPLAY=:0;for keycode in 10 11 12 13 14 15 16 17 18 19 22 24 25 26 27 28 29 30 31 32 33 38 39 40 41 42 43 44 45 46 52 53 54 55 56 57 58 65 75 76 98 99 100 102 104 105 107;do xset r ${keycode};done;xset r rate 450 40")
;;   buffer-related user customizations  ---  change anything in the above    block


;;----------------

and the readme again :


sawinlist
---------

Copyright (C) 2011 by the author: John Lumby johnlumby@xxxxxxxxxxx
Refer to license in sawinlist.el before using this package

Overview:
--------

sawinlist provides emacs functions for listing and manipulating x-windows managed by sawfish.

The idea is simple  -
   An emacs buffer containing a list of all the current desktop's windows,
allowing some window-manager-like manipulation of those windows from the emacs buffer.
   For example,   right-click a window name to raise it.

The obvious question - why would I want this when sawfish provides a perfectly good menu? Because an emacs buffer provides facilities which make it an even better menu : . can be permanently displayed if desired ("nailed-down") or iconified
     .   can be resized easily (since it is itself a window)
. can use cut'n'paste etc inside it - in fact, can do any emacs'y thing inside it.

In this package:
----------------

sawinlist.el the emacs functions that interface with sawfish (using sawfish-client command) sawlist.el example of user's own load file to run in the emacs frame to initialise the sawinlist
sawinlist.readme this file

Installation and Operation:
--------------------------

  .   put sawinlist.el somewhere in your emacs load-path
  .   put sawlist.el anywhere that can be accessed (e.g. in your home)
  .   customize sawlist.el as desired (see instructions in example)
  .   verify that the sawfish-client command is available
          and works in your environment  -  try running this command:
sawfish-client -e "(let ((winlist (managed-windows)) tcar tcdr (repout \"\`\") temp) (setq tcdr winlist) (while (setq tcar (car tcdr)) (setq tcdr (cdr tcdr)) (setq temp (prin1-to-string (window-name tcar))) (setq repout (concat repout (substring temp 1 (1- (length temp))) \"\`\"))) (princ repout))" | tr "\`" "\n"
          it should return a list of all windows managed by sawfish
          (sawinlist.el uses this command to build its list)
  .   start the emacs frame by running an emacs command such as
emacs --geometry=26x64+6+6 --name=sawinlist --title=sawinlist -ms "#146a2b" -cr red -fn "6x13" -bg "#E0EDED" -fg "#751503" -q -load sawlist.el </dev/null & (where all the options except for the -load sawlist.el are optional and whatever you wish)
  .   if you used the example's key bindings,  then :
      .   right-clicking at the end of the buffer refreshes it
====>>>>> N.B. do this first if there are any emacs forms in the buffer - nothing happens if the buffer content is not a valid list of window names!
      .   right-clicking on any window-name line raises it


Miscellaneous notes:
--------------------

1. window names are displayed one per line, sorted alphabetically on their names; Exception to sort-sequence - any name ending in "- [- a-zA-Z0-9_.:]+" (dash, space, stuff) will have this suffix prepended as prefix to the sort key (only for sorting purposes). This is in order to try to keep those windows from jumping around in the buffer, since in many cases, especially web browsers, the name changes frequently but the suffix remains constant,
      e.g. "sawfish - Google Search - Google Chrome"
2. any non-printable characters in range octal 000-037 (i.e. the ascii control characters)
      in a window name will appear as the sequence ^G[octal-sequence]
      (control-G followed by octal-read-syntax in square-brackets)
      note that this includes ^G itself and ^J (linefeed)
3. if a subset of windows all have the same name, the suffix ^G<windowid> is appended to disambiguate, where <windowid> is angle-bracket followed by sawfish's internal window id followed by angle-bracket.
      In this case,   there is a feature which may sometimes be useful -
the ^G<windowid> suffix may be removed (by simply editing the name in the buffer) *before* right-clicking, in which case sawinlist will select the most recently created with that name. 4. Bug/feature - the window list is refreshed only when you click in the sawinlist window, not continuously. So sawinlist does not "notice" new/changed windows until after the next click. However, if a window name changes and you then click on the (old) name, then provided there is no new window with the old name, sawinlist will still raise the correct window, as it first tries to find the window by name, and then if that fails, by window id, which remains unchanged. 5. The only window-manger currently (July 2011) implemented is "raise" (activate-window sawfish function);
      others could easily be implemented if desired.


On 07/30/11 01:01, Teika Kazura wrote:
On Tue, 26 Jul 2011 21:07:51 -0400, John Lumby wrote:
I saw there is a web app on the wiki page for uploading sawfish scripts,  but this is an emacs library, not a sawfish script.
However I would guess it belongs more to sawfish than to emacs.
Is there some more generic upload capability on the wiki?    (And is this the right place to ask that?)
Sorry for inconvenience. Our wiki doesn't allow it, so please post it
here. You can make the wiki page, and put a pointer to the cdoe
in the mailing list archives, which are listed here:
  http://sawfish.wikia.com/wiki/Community

If you post it in a plain text, many of archives show it inline,
following the message text, so it may be better to gzip for download
sake.

Thanks a lot.

Teika (Teika kazura)
I���LL===


---
--
Sawfish ML


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/