From 1cad1ccc8b0b2543b104172009f33f45ee9a1929 Mon Sep 17 00:00:00 2001 From: Bar Magal Date: Fri, 13 Feb 2015 16:59:59 +0200 Subject: [PATCH] New fallback behavior, small fixes and updated version to 1.1 --- README.rst | 3 ++ purpose-prefix-overload.el | 10 +++--- purpose-switch.el | 37 ++++++++++++++----- purpose.el | 74 +++++++++++++++++++------------------- 4 files changed, 72 insertions(+), 52 deletions(-) diff --git a/README.rst b/README.rst index f7e870a..a3287a1 100644 --- a/README.rst +++ b/README.rst @@ -2,6 +2,9 @@ Purpose ======= +IMPORTANT: this README is not accurate for version 1.1. The README will +be updated shortly (together with the project's wiki). + Purpose is a plugin for Emacs which introduces the concept of a "purpose" for windows and buffers. By setting purposes for your windows and for your buffers, Purpose helps you maintain a consistent window diff --git a/purpose-prefix-overload.el b/purpose-prefix-overload.el index 79a637d..fcf969a 100644 --- a/purpose-prefix-overload.el +++ b/purpose-prefix-overload.el @@ -8,14 +8,14 @@ ;; key-binding for several commands (overloading). The correct command ;; is chosen by considering the prefix argument. ;; -;; For example, this binds `purpose-find-file' and `find-file' to C-x -;; C-f: +;; For example, this binds `ido-find-file' and +;; `find-file-without-purpose' to C-x C-f: ;; (def-prefix-overload purpose-find-file-overload -;; '(purpose-find-file find-file)) +;; '(ido-find-file find-file-without-purpose)) ;; (define-key purpose-mode-map (kbd "C-x C-f") ;; #'purpose-find-file-overload) -;; To call `purpose-find-file', the user presses C-x C-f. To call -;; `find-file', the user presses C-u C-x C-f. +;; To call `ido-find-file', the user presses C-x C-f. To call +;; `find-file-without-purpose', the user presses C-u C-x C-f. ;;; Code: diff --git a/purpose-switch.el b/purpose-switch.el index 7c51fa3..52e7c22 100644 --- a/purpose-switch.el +++ b/purpose-switch.el @@ -15,10 +15,15 @@ "Names of buffers for which the default `display-buffer' behavior should not be overridden. This is a list of names.") -(defvar purpose-display-buffer-hook nil - "Hook to run after displaying a buffer with a purpose-aware function. -That means after `purpose-switch-buffer', `purpose-pop-buffer' and -`purpose--action-function'.") +(defvar purpose-display-fallback 'pop-up-frame + "Fallback action to use when `purpose--action-function' couldn't +display a buffer. +This should be either `pop-up-window' for displaying the buffer in a new +window, `pop-up-frame' for displaying the buffer in a new frame, or nil +for signalling an error.") + +(defvar purpose-select-buffer-hook nil + "Hook to run after selecting a buffer with `purpose-select-buffer'.") (defvar purpose--active-p nil "When nil, Purpose's advices and `purpose--action-function' are not @@ -338,12 +343,17 @@ This function doesn't raise the new frame." (purpose--change-buffer buffer window 'reuse alist) window)))) +(defalias 'purpose-display-pop-up-window #'display-buffer-pop-up-window) + (defun purpose-display-maybe-pop-up-window (buffer alist) "Display BUFFER in a new window, if possible. The display is possible if `pop-up-windows' is non-nil. The display is done with `display-buffer-pop-up-window'." (when pop-up-windows - (display-buffer-pop-up-window buffer alist))) + ;; (display-buffer-pop-up-window buffer alist) + (purpose-display-pop-up-window buffer alist))) + +(defalias 'purpose-display-pop-up-frame #'display-buffer-pop-up-frame) (defun purpose-display-maybe-pop-up-frame (buffer alist) "Display BUFFER in a new frame, if possible. @@ -355,7 +365,8 @@ The display is done with `display-buffer-pop-up-frame'." (when (if (eq pop-up-frames 'graphic-only) (display-graphic-p) pop-up-frames) - (display-buffer-pop-up-frame buffer alist))) + ;; (display-buffer-pop-up-frame buffer alist) + (purpose-display-pop-up-frame))) @@ -404,12 +415,20 @@ If ALIST is nil, it is ignored and `purpose--alist' is used instead." ;; ;; `raise-frame'? `window--maybe-raise-frame'? ;; (select-frame-set-input-focus (window-frame new-window))) ;; (select-window new-window)) - (error "No window available")))))) + (cond ((eql purpose-display-fallback 'pop-up-frame) + (message "trying fallback: purpose-display-pop-up-frame") + (purpose-display-pop-up-frame buffer alist)) + ((eql purpose-display-fallback 'pop-up-window) + (message "trying fallback: purpose-display-pop-up-window") + (purpose-display-pop-up-window buffer alist)) + (t + (error "No window available")))))))) (defun purpose-select-buffer (buffer-or-name &optional action-order norecord) "Display buffer BUFFER-OR-NAME in window and then select that window. ACTION-ORDER is used as the `action-order' entry in -`purpose--action-function''s alist." +`purpose--action-function''s alist. +This function runs hook `purpose-select-buffer-hook' when its done." (let* ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)) (purpose--alist (purpose-alist-set 'action-order action-order @@ -424,7 +443,7 @@ ACTION-ORDER is used as the `action-order' entry in (unless (eq new-frame old-frame) (select-frame-set-input-focus new-frame norecord)) (select-window new-window norecord)) - (run-hooks purpose-display-buffer-hook) + (run-hooks purpose-select-buffer-hook) buffer)) diff --git a/purpose.el b/purpose.el index b6fc5e6..ddd1cb2 100644 --- a/purpose.el +++ b/purpose.el @@ -2,10 +2,10 @@ ;; Author: Bar Magal (2015) ;; Package: purpose -;; Version: 1.0.50 +;; Version: 1.1 ;; Keywords: frames ;; Homepage: https://github.com/bmag/emacs-purpose -;; Package-Requires: ((emacs "24.3") (let-alist "1.0.3")) +;; Package-Requires: ((emacs "24.4") (let-alist "1.0.3")) ;;; Commentary: @@ -14,6 +14,9 @@ ;; layout easily. Purpose is intended to help both regular users and ;; developers who want Emacs to have a more IDE-like behavior. +;; Note: Currently Purpose is supported for Emacs 24.4 and newer. The +;; main reason is because it uses `advice-add' and `advice-remove'. + ;; Typical Usage (Regular User) ;; 1. Turn Purpose on (`purpose-mode'). ;; 2. Configure which purposes you want your windows to have (see @@ -22,64 +25,59 @@ ;; you want to dedicate to a specific purpose (so it won't be used ;; for other purposes), you shuld dedicate with ;; `purpose-toggle-window-purpose-dedicated'. -;; 4. Use purpose-aware commands instead of your regular commands when -;; you need to change buffers (e.g. `purpose-switch-buffer' instead -;; of `switch-to-buffer'). This will open your buffers in the correct -;; windows. +;; 4. Purpose uses advice, so Emacs uses purpose-aware commands instead +;; of the original commands when you need to change buffers. (e.g. +;; `purpose-switch-buffer' instead of `switch-to-buffer'). This will +;; open your buffers in the correct windows. ;; - To save your layout, or load a previously saved layout, use -;; `purpose-save-layout' and `purpose-load-layout'. You can load a -;; saved layout and skip phases 1 and 2, of course. - -;; Purpose-Aware commands that replace common commands: -;; `purpose-switch-buffer': instead of `switch-to-buffer' -;; `purpose-pop-buffer': instead of `pop-to-buffer' -;; `purpose-find-file': instead of `find-file' -;; `purpose-find-file-other-window': instead of `find-file-other-window' +;; `purpose-save-window-layout', `purpose-load-window-layout', +;; `purpose-save-frame-layout' and `purpose-load-frame-layout'. You +;; can load a saved layout and skip phases 1 and 2, of course. ;; Important Features: ;; - Configurable: Configure how Purpose decides what's your buffer's ;; purpose. Note that the window's purpose is determined by its ;; buffer. ;; - Persistent Window Layout: You can save and load your window layout -;; between sessions by using `purpose-save-layout' and -;; `purpose-load-layout'. -;; - Purpose-Aware Buffer Switching: Commands for switching buffers -;; without ruining your layout. The main ones are -;; `purpose-switch-buffer', `purpose-pop-buffer' and -;; `purpose-find-file'. Also, purpose-aware switching is supported -;; for any function that uses `display-buffer' internally -;; (`switch-to-buffer' doesn't). See purpose-switch.el for more. +;; between sessions by using `purpose-save-window-layout', +;; `purpose-load-window-layout', `purpose-save-frame-layout' and +;; `purpose-load-frame-layout'. +;; - Purpose-Aware Buffer Switching: Purpose uses advices (overrides) +;; `display-buffer-overriding-action' in order to make Emacs' buffer +;; switching functions "purpose-aware". ;; - Developer-Friendly: Purpose has hooks and an API that should make ;; it easy for developers to use it as a part of more sophisticated ;; plugins. If it isn't, your input is welcome. ;; Developer Usage (informal API): -;; - `purpose-set-layout', `purpose-load-layout': use this to set a -;; window layout that suits your plugin. -;; - `purpose-get-layout' or `purpose-save-layout': use this to save a -;; layout so you can add it to your plugin later. +;; - `purpose-set-window-layout', `purpose-load-window-layout': use this +;; to set a window layout that suits your plugin. - +;; - `purpose-get-window-layout' or `purpose-save-window-layout': use +;; this to save a layout so you can add it to your plugin later. +;; - Functions for changing frame layout (similar to window layout) ;; - `purpose-get-extra-window-params-function': use this if you want to ;; save additional window parameters that make sense for your plugin, -;; when `purpose-get-layout' is called. +;; when `purpose-get-window-layout' is called. ;; - `purpose-set-window-properties-functions': use this hook if you ;; want to set extra properties for new windows, when -;; `purpose-set-layout' is called. +;; `purpose-set-window-layout' is called. ;; - `set-configuration', `add-configuration': use these to change the ;; purpose configuration to suit your plugin's needs. -;; - `with-action-function-inactive': use this macro if you need -;; `display-buffer' to ignore purposes (original behavior) while -;; executing some piece of code. -;; - `purpose-display-buffer-hook': use this if you want to run some -;; code every time a buffer is displayed. +;; - `purpose-select-buffer-hook': use this if you want to run some +;; code every time a buffer is selected. +;; - `without-purpose': use this macro if you need to ignore purposes +;; while executing some piece of code. +;; - `without-purpose-command': use this macro to create a command that +;; ignores purposes. ;;; Installation: ;; Download Purpose's source files and put them in your `load-path'. -;; - Note: Purpose is not yet on any package repository. Once it will be -;; there, you could download it with Emacs' package manager. For now, -;; you have to do it manually. -;; Add these lines to your init file: +;; Purpoes is available from MELPA, so the best way to do this is +;; with Emacs' package manager. +;; Next, add these lines to your init file: ;; (require 'purpose) ;; (purpose-mode) +;; And that's all. ;;; Code: @@ -89,7 +87,7 @@ (require 'purpose-switch) (require 'purpose-prefix-overload) -(defconst purpose-version "1.0.50" +(defconst purpose-version "1.1" "Purpose's version.")