diff --git a/CHANGELOG.md b/CHANGELOG.md index 28872f8..d2cad47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Icon for files modified outside emacs (from Font Awesome). +- Icon for files that are being modified by another user (from Font Awesome). ## [0.3.0] diff --git a/mode-icons.el b/mode-icons.el index 5f8b443..4853980 100644 --- a/mode-icons.el +++ b/mode-icons.el @@ -209,6 +209,7 @@ This was stole/modified from `c-save-buffer-state'" (save #xf0c7 FontAwesome) (saved "" nil) (modified-outside #xf071 FontAwesome) + (steal #xf21b FontAwesome) (apple #xf179 FontAwesome) (win #xf17a FontAwesome) ;; FIXME: use lsb_release to determine Linux variant and choose appropriate icon @@ -235,6 +236,7 @@ without the extension. And the third being the type of icon." (const :tag "Saved" saved) (const :tag "Save" save) (const :tag "Modified Outside Emacs" modified-outside) + (const :tag "Locked By Someone Else" steal) (const :tag "Apple" apple) (const :tag "Windows" win) (const :tag "Unix" unix)) @@ -307,38 +309,59 @@ the icon." 'local-map '(keymap (mode-line keymap - (mouse-1 . mode-icons-save-or-revert-buffer) + (mouse-1 . mode-icons-save-steal-or-revert-buffer) (mouse-3 . mode-line-toggle-modified))) 'help-echo 'mode-icons-modified-help-echo) "List of text propeties to apply to read-only buffer indicator." :type '(repeat sexp) :group 'mode-icons) -(defun mode-icons-save-or-revert-buffer (event) +(defun mode-icons-ask-user-about-lock (_file _other-user) + "Automatically steals lock." + t) + +(defun mode-icons-save-steal-or-revert-buffer (event) "Save buffer OR revert file from mode line. Use EVENT to determine location." (interactive "e") (with-selected-window (posn-window (event-start event)) - (if (not (or (and (buffer-file-name) (file-remote-p buffer-file-name)) - (verify-visited-file-modtime (current-buffer)))) - (revert-buffer t t) - (call-interactively (key-binding (where-is-internal 'save-buffer global-map t)))) + (let* ((bfn (buffer-file-name)) + (revert-p (not (or (and bfn (file-remote-p buffer-file-name)) + (verify-visited-file-modtime (current-buffer))))) + (steal-p (and (not (or (and bfn (file-remote-p buffer-file-name)) + (member (file-locked-p bfn) '(nil t))))))) + (cond + (revert-p (revert-buffer t t)) + (steal-p + (message "To steal or ignore lock, start editing the file.")) + (t (call-interactively (key-binding (where-is-internal 'save-buffer global-map t)))))) (force-mode-line-update))) (defun mode-icons-modified-help-echo (window _object _point) "Return help text specifying WINDOW's buffer modification status." - (format "Buffer is %s\nmouse-1: %s Buffer\nmouse-3: Toggle modification state" - (cond - ((not (or (and (buffer-file-name) (file-remote-p buffer-file-name)) - (verify-visited-file-modtime (current-buffer)))) - "modified outside of emacs!") - ((buffer-modified-p (window-buffer window)) - "modified") - (t "unmodified")) - (if (not (or (and (buffer-file-name) (file-remote-p buffer-file-name)) - (verify-visited-file-modtime (current-buffer)))) - "Revert" - "Save"))) + (let* ((bfn (buffer-file-name)) + (revert-p (not (or (and bfn (file-remote-p buffer-file-name)) + (verify-visited-file-modtime (current-buffer))))) + (steal-p (and (not (or (and bfn (file-remote-p buffer-file-name)) + (member (file-locked-p bfn) '(nil t)))))) + (mod-p (buffer-modified-p (window-buffer window)))) + (format "Buffer is %s\nmouse-1: %s Buffer\nmouse-3: Toggle modification state" + (cond + (steal-p + "locked for editing by another user.") + (revert-p + "modified outside of emacs!") + ((buffer-modified-p (window-buffer window)) + "modified") + (t "unmodified")) + (cond + (steal-p + "Echo about lock status of") + (revert-p + "Revert") + (mod-p + "Save") + (t ""))))) (defcustom mode-icons-read-only-text-properties '('mouse-face 'mode-line-highlight 'local-map @@ -396,8 +419,7 @@ everywhere else." MODE should be a string, the name of the mode to propertize. ICON-SPEC should be a specification from `mode-icons'." (mode-icons-save-buffer-state ;; Otherwise may cause issues with trasient mark mode - (let (tmp) - (cond + (cond ((and (stringp mode) (get-text-property 0 'mode-icons-p mode)) mode) ((not (nth 1 icon-spec)) @@ -419,7 +441,7 @@ ICON-SPEC should be a specification from `mode-icons'." (nth 1 icon-spec))) (put-text-property (point-min) (point-max) 'mode-icons-p t) (buffer-string))) - (t (propertize (format "%s" mode) 'display (mode-icons-get-icon-display (nth 1 icon-spec) (nth 2 icon-spec)) 'mode-icons-p t)))))) + (t (propertize (format "%s" mode) 'display (mode-icons-get-icon-display (nth 1 icon-spec) (nth 2 icon-spec)) 'mode-icons-p t))))) (defun mode-icons-get-icon-spec (mode) "Get icon spec for MODE based on regular expression." @@ -574,29 +596,39 @@ ICON-SPEC should be a specification from `mode-icons'." (defun mode-icons--modified-status () "Get modified status icon." (eval `(propertize - ,(let ((mod (or (and (not (or (and (buffer-file-name) (file-remote-p buffer-file-name)) - (verify-visited-file-modtime (current-buffer)))) - "!") - (format-mode-line "%1+"))) - icon-spec) - (setq mod (or (cond - ((char-equal ?! (aref mod 0)) - (if (setq icon-spec (mode-icons-get-icon-spec 'modified-outside)) - (mode-icons-propertize-mode 'modified-outside icon-spec) - mod)) - ((char-equal ?* (aref mod 0)) - (if (setq icon-spec (mode-icons-get-icon-spec 'save)) - (mode-icons-propertize-mode 'save icon-spec) - mod)) - (t - (if (setq icon-spec (mode-icons-get-icon-spec 'saved)) - (mode-icons-propertize-mode 'saved icon-spec) - mod))) - "")) - (when (and mode-icons-modified-status-space - (not (string= mod ""))) - (setq mod (concat mod " "))) - mod) + ,(or (ignore-errors + (let* ((bfn (buffer-file-name)) + (nice-file-p (and (file-remote-p bfn))) + (mod (or (and (not (or nice-file-p (verify-visited-file-modtime (current-buffer)))) + "!") + (and (not (or nice-file-p (member (file-locked-p bfn) '(nil t)))) + "s") + (format-mode-line "%1+"))) + icon-spec) + (setq mod (or (cond + ((not (stringp mod)) "") + ((char-equal ?s (aref mod 0)) + (if (setq icon-spec (mode-icons-get-icon-spec 'steal)) + (mode-icons-propertize-mode 'steal icon-spec) + mod)) + ((char-equal ?! (aref mod 0)) + (if (setq icon-spec (mode-icons-get-icon-spec 'modified-outside)) + (mode-icons-propertize-mode 'modified-outside icon-spec) + mod)) + ((char-equal ?* (aref mod 0)) + (if (setq icon-spec (mode-icons-get-icon-spec 'save)) + (mode-icons-propertize-mode 'save icon-spec) + mod)) + (t + (if (setq icon-spec (mode-icons-get-icon-spec 'saved)) + (mode-icons-propertize-mode 'saved icon-spec) + mod))) + "")) + (when (and mode-icons-modified-status-space + (stringp mod) + (not (string= mod ""))) + (setq mod (concat mod " "))) + mod)) "") ,@mode-icons-modified-text-properties))) ;; Based on rich-minority by Artur Malabarba