Remove `exwm-worspace-number'
No longer fill initial workspace list, nor limit the number of workspaces to `exwm-worspace-number'. Users are free to create as many as they like by hitting 'C-x 5 2' or running `make-frame'. The initial workspace list can be set up by creating frames in a configuration file. For example, to start up with 4 workspaces: (dolist (i 3) (make-frame)) The interactive workspace switcher is improved to support selecting workspaces with a many-digits position. * exwm-workspace.el (exwm-workspace-number): Remove variable, as we no longer have a fixed number of workspaces. (exwm-workspace--switch-map) (exwm-workspace--switch-map-nth-prefix) (exwm-workspace--switch-map-select-nth): Improve support for selecting workspaces with multiple-digit positions (e.g. workspace number 12). (exwm-workspace--add-frame-as-workspace, exwm-workspace--init): Remove limit on number of workspaces. (exwm-workspace--init): Stop creating workspaces at startup. * exwm-config.el (exwm-config-default): Bind keys to namespaces 0-9 in the default configuration.
This commit is contained in:
parent
0fbc725de1
commit
d0797d03de
2 changed files with 64 additions and 37 deletions
|
@ -39,7 +39,7 @@
|
||||||
;; 's-w': Switch workspace
|
;; 's-w': Switch workspace
|
||||||
(exwm-input-set-key (kbd "s-w") #'exwm-workspace-switch)
|
(exwm-input-set-key (kbd "s-w") #'exwm-workspace-switch)
|
||||||
;; 's-N': Switch to certain workspace
|
;; 's-N': Switch to certain workspace
|
||||||
(dotimes (i exwm-workspace-number)
|
(dotimes (i 10)
|
||||||
(exwm-input-set-key (kbd (format "s-%d" i))
|
(exwm-input-set-key (kbd (format "s-%d" i))
|
||||||
`(lambda () (interactive) (exwm-workspace-switch ,i))))
|
`(lambda () (interactive) (exwm-workspace-switch ,i))))
|
||||||
;; 's-&': Launch application
|
;; 's-&': Launch application
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
(require 'exwm-core)
|
(require 'exwm-core)
|
||||||
|
|
||||||
(defvar exwm-workspace-number 4 "Number of workspaces (1 ~ 10).")
|
|
||||||
(defvar exwm-workspace--list nil "List of all workspaces (Emacs frames).")
|
(defvar exwm-workspace--list nil "List of all workspaces (Emacs frames).")
|
||||||
(defvar exwm-workspace--current nil "Current active workspace.")
|
(defvar exwm-workspace--current nil "Current active workspace.")
|
||||||
(defvar exwm-workspace-current-index 0 "Index of current active workspace.")
|
(defvar exwm-workspace-current-index 0 "Index of current active workspace.")
|
||||||
|
@ -63,12 +62,7 @@ NIL if FRAME is not a workspace"
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map [t] (lambda () (interactive)))
|
(define-key map [t] (lambda () (interactive)))
|
||||||
(dotimes (i 10)
|
(dotimes (i 10)
|
||||||
(define-key map (int-to-string i)
|
(define-key map (int-to-string i) #'exwm-workspace--switch-map-nth-prefix))
|
||||||
`(lambda ()
|
|
||||||
(interactive)
|
|
||||||
(when (< ,i (exwm-workspace--count))
|
|
||||||
(goto-history-element ,(1+ i))
|
|
||||||
(exit-minibuffer)))))
|
|
||||||
(define-key map "\C-a" (lambda () (interactive) (goto-history-element 1)))
|
(define-key map "\C-a" (lambda () (interactive) (goto-history-element 1)))
|
||||||
(define-key map "\C-e" (lambda ()
|
(define-key map "\C-e" (lambda ()
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -318,6 +312,48 @@ Value nil means to use the default position which is fixed at bottom, while
|
||||||
:stack-mode xcb:StackMode:Above))
|
:stack-mode xcb:StackMode:Above))
|
||||||
(set-frame-width exwm-workspace--minibuffer width nil t)))
|
(set-frame-width exwm-workspace--minibuffer width nil t)))
|
||||||
|
|
||||||
|
(defun exwm-workspace--switch-map-nth-prefix (&optional prefix-digits)
|
||||||
|
"Allow selecting a workspace by number.
|
||||||
|
|
||||||
|
PREFIX-DIGITS is a list of the digits introduced so far."
|
||||||
|
(interactive)
|
||||||
|
(let* ((ev (this-command-keys-vector))
|
||||||
|
(off (1- (length ev)))
|
||||||
|
(k (elt ev off))
|
||||||
|
;; 0 is ASCII 48.
|
||||||
|
(d (- k 48))
|
||||||
|
;; Convert prefix-digits to number. For example, '(2 1) to 120.
|
||||||
|
(o 1)
|
||||||
|
(pn (apply #'+ (mapcar (lambda (x)
|
||||||
|
(setq o (* 10 o))
|
||||||
|
(* o x))
|
||||||
|
prefix-digits)))
|
||||||
|
(n (+ pn d))
|
||||||
|
(num-workspaces (exwm-workspace--count)))
|
||||||
|
(if (= (length prefix-digits) ; Go ahead if there are enough
|
||||||
|
(floor (log num-workspaces 10))) ; digits to select any workspace.
|
||||||
|
(exwm-workspace--switch-map-select-nth n)
|
||||||
|
(set-transient-map
|
||||||
|
(let ((map (make-sparse-keymap))
|
||||||
|
(cmd `(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(exwm-workspace--switch-map-nth-prefix ',(cons d prefix-digits))
|
||||||
|
)))
|
||||||
|
(dotimes (i 10)
|
||||||
|
(define-key map (int-to-string i) cmd))
|
||||||
|
;; Accept
|
||||||
|
(define-key map [return]
|
||||||
|
`(lambda ()
|
||||||
|
(interactive)
|
||||||
|
(exwm-workspace--switch-map-select-nth ,n)))
|
||||||
|
map)))))
|
||||||
|
|
||||||
|
(defun exwm-workspace--switch-map-select-nth (n)
|
||||||
|
"Select Nth workspace."
|
||||||
|
(interactive)
|
||||||
|
(goto-history-element (1+ n))
|
||||||
|
(exit-minibuffer))
|
||||||
|
|
||||||
(defvar exwm-workspace-switch-hook nil
|
(defvar exwm-workspace-switch-hook nil
|
||||||
"Normal hook run after switching workspace.")
|
"Normal hook run after switching workspace.")
|
||||||
|
|
||||||
|
@ -854,9 +890,6 @@ before it."
|
||||||
(defun exwm-workspace--add-frame-as-workspace (frame)
|
(defun exwm-workspace--add-frame-as-workspace (frame)
|
||||||
"Configure frame FRAME to be treated as a workspace."
|
"Configure frame FRAME to be treated as a workspace."
|
||||||
(cond
|
(cond
|
||||||
((>= (exwm-workspace--count) exwm-workspace-number)
|
|
||||||
(delete-frame frame)
|
|
||||||
(user-error "[EXWM] Too many workspaces: maximum is %d" exwm-workspace-number))
|
|
||||||
((exwm-workspace--workspace-p frame)
|
((exwm-workspace--workspace-p frame)
|
||||||
(exwm--log "Frame `%s' is already a workspace" frame))
|
(exwm--log "Frame `%s' is already a workspace" frame))
|
||||||
((not (display-graphic-p frame))
|
((not (display-graphic-p frame))
|
||||||
|
@ -1010,31 +1043,23 @@ applied to all subsequently created X frames."
|
||||||
|
|
||||||
(defun exwm-workspace--init ()
|
(defun exwm-workspace--init ()
|
||||||
"Initialize workspace module."
|
"Initialize workspace module."
|
||||||
(cl-assert (and (< 0 exwm-workspace-number) (>= 10 exwm-workspace-number)))
|
|
||||||
;; Prevent unexpected exit
|
;; Prevent unexpected exit
|
||||||
(setq confirm-kill-emacs #'exwm-workspace--confirm-kill-emacs)
|
(setq confirm-kill-emacs #'exwm-workspace--confirm-kill-emacs)
|
||||||
(let ((initial-workspaces (frame-list)))
|
(let ((initial-workspaces (frame-list)))
|
||||||
(if (not (exwm-workspace--minibuffer-own-frame-p))
|
(if (not (exwm-workspace--minibuffer-own-frame-p))
|
||||||
;; Initialize workspaces with minibuffers.
|
;; Initialize workspaces with minibuffers.
|
||||||
(progn
|
(when (< 1 (length initial-workspaces))
|
||||||
(when (< 1 (exwm-workspace--count))
|
;; Exclude the initial frame.
|
||||||
;; Exclude the initial frame.
|
(dolist (i initial-workspaces)
|
||||||
(dolist (i initial-workspaces)
|
(unless (frame-parameter i 'window-id)
|
||||||
(unless (frame-parameter i 'window-id)
|
(setq initial-workspaces (delq i initial-workspaces))))
|
||||||
(setq initial-workspaces (delq i initial-workspaces))))
|
(setq exwm-workspace--client
|
||||||
(cl-assert (= 1 (length initial-workspaces)))
|
(frame-parameter (car exwm-workspace--list) 'client))
|
||||||
(setq exwm-workspace--client
|
(let ((f (car initial-workspaces)))
|
||||||
(frame-parameter (car exwm-workspace--list) 'client))
|
;; Remove the possible internal border.
|
||||||
(let ((f (car initial-workspaces)))
|
(set-frame-parameter f 'internal-border-width 0)
|
||||||
;; Remove the possible internal border.
|
;; Prevent user from deleting the first frame by accident.
|
||||||
(set-frame-parameter f 'internal-border-width 0)
|
(set-frame-parameter f 'client nil)))
|
||||||
;; Prevent user from deleting this frame by accident.
|
|
||||||
(set-frame-parameter f 'client nil)))
|
|
||||||
;; Create remaining frames.
|
|
||||||
(dotimes (_ (1- exwm-workspace-number))
|
|
||||||
(nconc initial-workspaces
|
|
||||||
(list (make-frame '((window-system . x)
|
|
||||||
(internal-border-width . 0)))))))
|
|
||||||
;; Initialize workspaces without minibuffers.
|
;; Initialize workspaces without minibuffers.
|
||||||
(setq exwm-workspace--minibuffer
|
(setq exwm-workspace--minibuffer
|
||||||
(make-frame '((window-system . x) (minibuffer . only)
|
(make-frame '((window-system . x) (minibuffer . only)
|
||||||
|
@ -1092,12 +1117,14 @@ applied to all subsequently created X frames."
|
||||||
(setq exwm-workspace--timer
|
(setq exwm-workspace--timer
|
||||||
(run-with-idle-timer 0 t #'exwm-workspace--on-echo-area-dirty))
|
(run-with-idle-timer 0 t #'exwm-workspace--on-echo-area-dirty))
|
||||||
(add-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
|
(add-hook 'echo-area-clear-hook #'exwm-workspace--on-echo-area-clear)
|
||||||
;; Create workspace frames.
|
;; Recreate frames with the external minibuffer set.
|
||||||
(dotimes (_ exwm-workspace-number)
|
(setq initial-workspaces
|
||||||
(push (make-frame `((window-system . x)
|
(mapcar
|
||||||
(internal-border-width . 0)
|
(lambda (_)
|
||||||
(client . nil)))
|
(make-frame `((window-system . x)
|
||||||
exwm-workspace--list))
|
(internal-border-width . 0)
|
||||||
|
(client . nil))))
|
||||||
|
initial-workspaces))
|
||||||
;; The default behavior of `display-buffer' (indirectly called by
|
;; The default behavior of `display-buffer' (indirectly called by
|
||||||
;; `minibuffer-completion-help') is not correct here.
|
;; `minibuffer-completion-help') is not correct here.
|
||||||
(cl-pushnew '(exwm-workspace--display-buffer) display-buffer-alist
|
(cl-pushnew '(exwm-workspace--display-buffer) display-buffer-alist
|
||||||
|
|
Loading…
Reference in a new issue