;; ;; toggle-exec-on-current-file - does what it says it does ;; ;; Copyright (c) 2010, Dorian Taylor ;; All rights reserved. ;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions ;; are met: ;; * Redistributions of source code must retain the above ;; copyright notice, this list of conditions and the following ;; disclaimer. ;; * Redistributions in binary form must reproduce the above ;; copyright notice, this list of conditions and the following ;; disclaimer in the documentation and/or other materials ;; provided with the distribution. ;; * Neither the name of Dorian Taylor nor the names of his ;; contributors may be used to endorse or promote products ;; derived from this software without specific prior written ;; permission. ;; ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ;; FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DORIAN ;; TAYLOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ;; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY ;; OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE ;; USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH ;; DAMAGE. ; map to C-x ! (defun toggle-exec-on-current-file () "Sets the executable bit on or off for the current file, based on the current state of the read bits. Note this will clobber executable bits where there are no read bits when setting the toggle to 'off' (but then how often does it make sense to execute a file you can't read?). Does nothing if the current buffer is not mapped to an existing file." (interactive) ;; XXX: should this operate on a symlink or the real file? (let ((bfn (buffer-file-name))) (if (and (stringp bfn) (file-exists-p bfn)) (let* ((mode (file-modes bfn)) ;; right shifting by two bits gives whatever masked with 0111 (read-bits (lsh (logand mode #o444) -2)) (exec-bits (logand mode #o111))) (if (= exec-bits 0) (progn ; adds executable bits where the read bits already exist (set-file-modes bfn (logior mode read-bits)) (message (format "%s is now executable" bfn))) (progn ; removes all executable bits (set-file-modes bfn (logand mode (lognot #o111))) (message (format "%s is no longer executable" bfn))))) (message "Current buffer is not a file."))))