diff --git a/exwm-x/exwmx-appconfig b/exwm-x/exwmx-appconfig index b018374..2adedbb 100644 --- a/exwm-x/exwmx-appconfig +++ b/exwm-x/exwmx-appconfig @@ -1,17 +1,8 @@ -(:command "firefox" :alias "Navigator" :pretty-name "firefox3" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "8ae6552419703180476fa4387f9cf8b9") +(:command "steam" :alias "steamwebhelper" :pretty-name "steam" :paste-key "C-v" :class "steam" :instance "steamwebhelper" :title "Steam" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "5cae6843e6081ff23f80b1a7c8821595") +(:command "pcmanfm" :alias "pcmanfm" :pretty-name "pcmanfm" :paste-key "C-v" :class "Pcmanfm" :instance "pcmanfm" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "50e978cd291dcc11f145ca5835193ae1") +(:command "firefox" :alias "Navigator" :pretty-name "firefox" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c2bee0373d986f9561845a4e1ae0374d") (:command "firefox" :alias "Navigator" :pretty-name "firefox1" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "15f370a4572c4a0b89c8146f0c6c5ffe") -(:command firefox :alias "Navigator" :pretty-name "firefox" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c2bee0373d986f9561845a4e1ae0374d") -(:command "discord" :alias "discord" :pretty-name "discord" :paste-key "C-v" :class "discord" :instance "discord" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "4ad4943e4fc9da6b8421dbd655ac09ec") -(:command "clementine" :alias "clementine" :pretty-name "clementine" :paste-key "C-v" :class "Clementine" :instance "clementine" :title "Takeshi Abo - First leap" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "6d1a0cd2fd349b32c844ad096ceaa529") -(:command "VirtualBox Machine" :alias "VirtualBox Machine" :pretty-name "VirtualBox Machine" :paste-key "C-v" :class "VirtualBox Machine" :instance "VirtualBox Machine" :title "Windows 7 [Running] - Oracle VM VirtualBox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "9032cdf6364297438c1892d892122db3") -(:command "qutebrowser" :alias "qutebrowser" :pretty-name "qutebrowser" :paste-key "C-v" :class "qutebrowser" :instance "qutebrowser" :title "DuckDuckGo — Privacy, simplified. - qutebrowser" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "5a90ddb8976a59d030137fc4414e2918") -(:command "emacs" :alias "emacs" :pretty-name "emacs" :paste-key "C-v" :class "Emacs" :instance "emacs" :title "emacs@ArchLinuvo" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys t :ignore-simulation-keys nil :eval nil :key "d174de6e20bb093cb298146666b92ac1") -(:command "Navigator" :alias "Navigator" :pretty-name "Navigator" :paste-key "C-v" :class "Firefox" :instance "Navigator" :title "mkropat/jumpapp: A run-or-raise application switcher for any X11 desktop - Mozilla Firefox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "b5686ca42c47fd5dec0b9efe8739ce94") -(:command "work" :alias "work" :pretty-name "work" :paste-key "C-v" :class "Firefox" :instance "work" :title "Pocket: Log In - Mozilla Firefox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "ca58c8720d794df8d0b88c6dceea8c69") -(:command "steam" :alias "Steam" :pretty-name "Steam" :paste-key "C-v" :class "Steam" :instance "Steam" :title "Steam" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "a68f5a036e9cd3dd4c8ae09a73f8d3db") -(:command "mgtv" :alias "mgtv" :pretty-name "mgtv" :paste-key "C-v" :class "mgtv" :instance "mgtv" :title "哆啦A梦第二季 第70集 - 视频在线观看 - 哆啦A梦 第二季 - 芒果TV - Mozilla Firefox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "618647de63882e1c4e7209cd22bea289") -(:command "lutris" :alias "lutris" :pretty-name "lutris" :paste-key "C-v" :class "Lutris" :instance "lutris" :title "Lutris" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "d5f5f739289cc9c6286881ecd659d2a5") -(:command "pcmanfm" :alias nil :pretty-name "pcmanfm" :paste-key "C-v" :class "Pcmanfm" :instance "pcmanfm" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "50e978cd291dcc11f145ca5835193ae1") -(:command "firefox" :alias "Navigator" :pretty-name "firefox" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "61fd33ff3615b1e582accf4eba6ff1ee") -(:command firefox :alias "Navigator" :pretty-name "youtube" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c1d685634c050571eb12fba803934e74") -(:command "firefox" :alias "Navigator" :pretty-name "firefox2" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "83cf4fcff6f07dd334aabe6207f087b0") +(:command "firefox" :alias "Navigator" :pretty-name "firefox2" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "61fd33ff3615b1e582accf4eba6ff1ee") +(:command "firefox" :alias "Navigator" :pretty-name "firefox3" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "8ae6552419703180476fa4387f9cf8b9") +(:command "firefox" :alias "Navigator" :pretty-name "youtube" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c1d685634c050571eb12fba803934e74") +(:command "discord" :alias "discord" :pretty-name "discord" :paste-key "C-v" :class "discord" :instance "discord" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "08b13f35d50cd2e97ed836ad38b6bead") diff --git a/lisp/exwm-tagging/exwm-tag.el b/lisp/exwm-tagging/exwm-tag.el index 02558e4..31c4a23 100644 --- a/lisp/exwm-tagging/exwm-tag.el +++ b/lisp/exwm-tagging/exwm-tag.el @@ -32,30 +32,40 @@ (interactive) (shell-command "~/Github/my-projects/i3lock-fancy/i3lock-fancy & disown")) -(defun exwmx-name-buffer (name) - (interactive - (list - (completing-read "Name: " - (mapcar (lambda (a) (plist-get a :pretty-name)) - (exwmx-appconfig--get-all-appconfigs))))) - (cl-labels ((name-pretty (buffer name) - (with-current-buffer buffer - (exwm-workspace-rename-buffer name) - (setq-local exwmx-pretty-name name)))) - (if (equal name (buffer-name)) - (setq-local exwmx-pretty-name name) - (let ((obuffer (get-buffer name))) - (if (not obuffer) - (name-pretty (current-buffer) name) - (when (y-or-n-p (format "Already a buffer named \"%s\". Would you like to swap?" name)) - (let ((oname (completing-read "Name of other buffer: " - (mapcar (lambda (a) (plist-get a :instance)) - (exwmx-appconfig--get-all-appconfigs))))) - (name-pretty (current-buffer) - "This is a stupid name that no one would ever choose for a buffer, hopefully") - (name-pretty obuffer oname) - (name-pretty (current-buffer) - name)))))))) +(defun exwmx-prompt-pretty-name (prompt appconfigs) + (completing-read + prompt + (mapcar (lambda (a) (plist-get a :pretty-name)) + appconfigs))) + +(defun exwmx-name-buffer (&optional name buffer appconfigs) + (interactive) + (setq appconfigs (or appconfigs (exwmx-appconfig--get-all-appconfigs)) + buffer (or buffer (current-buffer)) + name (or name (exwmx-prompt-pretty-name "Name: " appconfigs))) + (with-current-buffer buffer + (cl-labels ((name-pretty (buffer name) + (with-current-buffer buffer + (exwm-workspace-rename-buffer name) + (setq-local exwmx-pretty-name name)) + name)) + (if (equal name (buffer-name)) + (setq-local exwmx-pretty-name name) + (let ((obuffer (get-buffer name))) + (if (not obuffer) + (name-pretty (current-buffer) name) + (if (not (y-or-n-p (format "Already a buffer named \"%s\". Would you like to swap?" name))) + exwmx-pretty-name + (let ((oname (exwmx-prompt-pretty-name + "Name of other buffer: " + (remove-if #'(lambda (x) + (string= name (plist-get x :pretty-name))) + appconfigs)))) + (name-pretty (current-buffer) + "This is a stupid name that no one would ever choose for a buffer, hopefully") + (name-pretty obuffer oname) + (name-pretty (current-buffer) + name))))))))) ;; Add these hooks in a suitable place (e.g., as done in exwm-config-default) @@ -91,16 +101,25 @@ (define-prefix-command '*firefox-map*) (define-key *root-map* (kbd "f") '*firefox-map*) +(defmacro quickrun-firefox (command tag) + (let ((name-gensym (intern (format "quickrun-comm-%s" + (or tag command))))) + `(defun ,name-gensym () + (interactive) + (if (zerop (length (exwmx-find-buffers '(:class "firefox")))) + (exwmx/launch-firefox-windows) + (my/exwmx-quickrun ,command nil '(:pretty-name ,tag)))))) + (define-key *firefox-map* (kbd "c") (quickrun-lambda "google-chrome-stable" "chrome")) -(define-key *firefox-map* (kbd "f") (quickrun-lambda "firefox" "firefox")) -(define-key *firefox-map* (kbd "1") (quickrun-lambda "firefox" "firefox1")) -(define-key *firefox-map* (kbd "2") (quickrun-lambda "firefox" "firefox2")) -(define-key *firefox-map* (kbd "3") (quickrun-lambda "firefox" "firefox3")) -(define-key *firefox-map* (kbd "4") (quickrun-lambda "firefox" "firefox4")) -(define-key *firefox-map* (kbd "d") (quickrun-lambda "firefox" "development")) -(define-key *firefox-map* (kbd "s") (quickrun-lambda "firefox" "school")) -(define-key *firefox-map* (kbd "w") (quickrun-lambda "firefox" "work")) -(define-key *firefox-map* (kbd "y") (quickrun-lambda "firefox" "youtube")) +(define-key *firefox-map* (kbd "f") (quickrun-firefox "firefox" "firefox")) +(define-key *firefox-map* (kbd "1") (quickrun-firefox "firefox" "firefox1")) +(define-key *firefox-map* (kbd "2") (quickrun-firefox "firefox" "firefox2")) +(define-key *firefox-map* (kbd "3") (quickrun-firefox "firefox" "firefox3")) +(define-key *firefox-map* (kbd "4") (quickrun-firefox "firefox" "firefox4")) +(define-key *firefox-map* (kbd "d") (quickrun-firefox "firefox" "development")) +(define-key *firefox-map* (kbd "s") (quickrun-firefox "firefox" "school")) +(define-key *firefox-map* (kbd "w") (quickrun-firefox "firefox" "work")) +(define-key *firefox-map* (kbd "y") (quickrun-firefox "firefox" "youtube")) ;; Musics (define-prefix-command '*music-map*) diff --git a/lisp/exwm-tagging/my-exwmx-quickrun-2.el b/lisp/exwm-tagging/my-exwmx-quickrun-2.el index 2cfa2d3..26fce8b 100644 --- a/lisp/exwm-tagging/my-exwmx-quickrun-2.el +++ b/lisp/exwm-tagging/my-exwmx-quickrun-2.el @@ -101,7 +101,28 @@ or use `exwmx-appconfig-ignore' ignore." (or (not title) (exwmx--string-match-p instance exwm-title)) (or (not pretty) (exwmx--string-match-p (format "^%s$" pretty) exwmx-pretty-name)))))) -(defun exwmx-find-buffer (appconfig) +(defun exwmx-buffer-match-alist (alist buffer) + (cl-assert + (eq 'exwm-mode + (with-current-buffer buffer + major-mode))) + (with-current-buffer buffer + (-every + (lambda (rule) + (let* ((key (nth 0 rule)) + (search-string (nth 1 rule)) + (test-function (or (nth 2 rule) #'equal)) + (prop-value + (pcase key + (:class exwm-class-name) + (:instance exwm-instance-name) + (:title exwm-title) + (:pretty-name exwmx-pretty-name)))) + (and (functionp test-function) + (funcall test-function search-string prop-value)))) + alist))) + +(defun exwmx-find-buffer (appconfig &optional alist) (let ((current (current-buffer)) (buffers (buffer-list)) (result '())) @@ -109,7 +130,9 @@ or use `exwmx-appconfig-ignore' ignore." (let ((buffer (pop buffers))) (when (and (eq 'exwm-mode (with-current-buffer buffer major-mode)) - (exwmx-buffer-match-p appconfig buffer)) + (if alist + (exwmx-buffer-match-alist appconfig buffer) + (exwmx-buffer-match-p appconfig buffer))) (push buffer result)))) (setq result (reverse result)) ;; If two more buffers are found, switch between these buffer. @@ -118,7 +141,19 @@ or use `exwmx-appconfig-ignore' ignore." (cadr result) (car result)))) -(exwmx-find-buffer '(:pretty-name "firefox")) +(defun exwmx-find-buffers (appconfig &optional alist) + (let ((current (current-buffer)) + (buffers (buffer-list)) + (result '())) + (while buffers + (let ((buffer (pop buffers))) + (when (and (eq 'exwm-mode (with-current-buffer buffer + major-mode)) + (if alist + (exwmx-buffer-match-alist appconfig buffer) + (exwmx-buffer-match-p appconfig buffer))) + (push buffer result)))) + (reverse result))) (defun exwmx-select-window () (if (= 1 (length (window-list))) @@ -129,7 +164,7 @@ or use `exwmx-appconfig-ignore' ignore." until (= c index) finally return win)))) -(defun my/exwmx-quickrun (command &optional search-alias ruler) +(defun my/exwmx-quickrun (command &optional search-alias ruler no-manage) "Run `command' to launch an application, if application's window is found, just switch to this window, when `search-alias' is t, `command' will be regard as an appconfig alias and search it from `exwmx-appconfig-file', by default, @@ -171,8 +206,9 @@ and :title or just a key list." (let ((exwm-layout-show-all-buffers nil)) (exwm-workspace-switch-to-buffer buffer)) (when cmd - (exwmx-register-x-window - matched-appconfig (exwmx-select-window)) + (when (not no-manage) + (exwmx-register-x-window + matched-appconfig (exwmx-select-window))) (exwmx-shell-command cmd))))) (defmacro quickrun-lambda (cmd name) @@ -252,26 +288,89 @@ and :title or just a key list." `((:class ,exwm-class-name)))) (defun exwmx-manage-x-window () - (if-let* ((appconfigs (exwmx-appconfig-candidates)) - (matched-config - (-any (lambda (c) (and (gethash c exwmx/destination-windows) - c)) - appconfigs)) - (name (plist-get matched-config :pretty-name)) - (window (gethash matched-config exwmx/destination-windows))) - (unwind-protect - (progn - (exwm-workspace-rename-buffer name) - (when (and (window-live-p window) - (not (eq window (selected-window)))) - (let ((curr (current-buffer))) - (save-selected-window - (previous-buffer) - (window--display-buffer curr window 'reuse nil))))) - (setq-local exwmx-pretty-name name) - (remhash matched-config exwmx/destination-windows)) - (exwm-workspace-rename-buffer - (or exwm-class-name exwm-instance-name exwm-title)))) + (when (not (member #'exwmx/add-firefox-buffers exwm-manage-finish-hook)) + (if-let* ((appconfigs (exwmx-appconfig-candidates)) + (matched-config + (-any (lambda (c) (and (gethash c exwmx/destination-windows) + c)) + appconfigs)) + (name (plist-get matched-config :pretty-name)) + (window (gethash matched-config exwmx/destination-windows))) + (unwind-protect + (progn + (exwm-workspace-rename-buffer name) + (when (and (window-live-p window) + (not (eq window (selected-window)))) + (let ((curr (current-buffer))) + (save-selected-window + (previous-buffer) + (window--display-buffer curr window 'reuse nil))))) + (setq-local exwmx-pretty-name name) + (remhash matched-config exwmx/destination-windows)) + (exwm-workspace-rename-buffer + (or exwm-class-name exwm-instance-name exwm-title))))) + +(defvar exwmx/firefox-buffers nil) +(defvar exwmx/buffer-name-timer nil) + +(defun exwmx/launch-firefox-windows () + (interactive) + (unless (zerop (length (exwmx-find-buffers '(:class "firefox")))) + (user-error "Firefox already launched")) + (add-hook 'exwm-manage-finish-hook #'exwmx/add-firefox-buffers) + (my/exwmx-quickrun "firefox" nil nil t)) + +(defun exwmx/add-firefox-buffers () + (push (current-buffer) exwmx/firefox-buffers) + (when (timerp exwmx/buffer-name-timer) + (cancel-timer exwmx/buffer-name-timer)) + (setq exwmx/buffer-name-timer + (run-at-time 3 nil #'exwmx/rename-firefox-windows))) + +;; (setq exwm-manage-finish-hook +;; (delq #'exwmx/add-firefox-buffers exwm-manage-finish-hook)) + +(defun display-buffers-split-vertically (lob) + (delete-other-windows) + (let ((last (car (last lob)))) + (dolist (b lob) + (display-buffer-same-window b nil) + (unless (eq b last) + (select-window (split-window-vertically))))) + (balance-windows)) + +(defun exwmx/rename-firefox-windows () + (unwind-protect + (save-window-excursion + (let ((appconfigs (exwmx-appconfig--search-all '((:class "firefox"))))) + (when-let ((b (exwmx-find-buffer '((:title "YouTube" string-match-p)) t))) + (when (member b exwmx/firefox-buffers) + (exwmx-name-buffer "youtube" b ) + (setq exwmx/firefox-buffers + (delete b exwmx/firefox-buffers)) + (setq appconfigs + (remove-if #'(lambda (x) + (string= "youtube" (plist-get x :pretty-name))) + appconfigs)))) + (if (= 1 (length exwmx/firefox-buffers)) + (exwmx-name-buffer "firefox" (car exwmx/firefox-buffers)) + (delete-other-windows) + (let ((last (car (last exwmx/firefox-buffers)))) + (display-buffers-split-vertically exwmx/firefox-buffers) + (dolist (b exwmx/firefox-buffers) + (let ((win (get-buffer-window b))) + (select-window win) + (--> + (funcall-interactively #'exwmx-name-buffer nil b appconfigs) + (setq appconfigs + (remove-if #'(lambda (x) + (string= it + (plist-get x :pretty-name))) + appconfigs))) + (unless (eq b last) + (delete-window win)))))))) + (remove-hook 'exwm-manage-finish-hook #'exwmx/add-firefox-buffers) + (setq exwmx/firefox-buffers nil))) (add-hook 'exwm-manage-finish-hook 'exwmx-manage-x-window)