Skip to content

Commit

Permalink
Option to automatically chmod .ghci files that GHCi ignores
Browse files Browse the repository at this point in the history
.ghci files are a convenience facility. GHCi decides out of security
concerns that it will simply ignore convenience files. For an
interactive application, this is pretty stupid. The better approach
is the approach that Emacs takes, which is to prompt the user and
allow them to decide conveniently.

This patch collects all files that GHCi warns that it has ignored into
a list, the user is given a message like this:

GHCi is ignoring: /home/chris/foo (run M-x haskell-process-unignore)
GHCi is ignoring: /home/chris/foo/.ghci (run M-x haskell-process-unignore)

When they run `M-x haskell-process-unignore', they get:

Set permissions? /home/chris/foo/.ghci (y, n, v: stop and view file) y
Permissions command: chmod 700 /home/chris/foo/.ghci

This allows the user to edit the permissions command per file, if
desired, or they can just hit RET. They also have the option to stop
this procedure and view the file first.

At the end, it prompts the user to restart the process for the
changes (if any) to take effect.

This is not portable to Windows. There apparently is some command for
Windows for setting permissions but it's difficult to know how
reliable it is and I don't have a Windows machine to test on. Instead,
I include a note in the function for Windows-using Emacs hackers to
further extend it.

@hvr might be of interest.
  • Loading branch information
chrisdone committed Jan 28, 2014
1 parent 55408fc commit 1834c3b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
69 changes: 69 additions & 0 deletions haskell-process.el
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
;; FIXME: haskell-process shouldn't depend on haskell-interactive-mode to avoid module-dep cycles
(declare-function haskell-interactive-mode-echo "haskell-interactive-mode" (session message &optional mode))
(declare-function haskell-interactive-mode-compile-error "haskell-interactive-mode" (session message))
(declare-function haskell-interactive-mode-compile-warning "haskell-interactive-mode" (session message))
(declare-function haskell-interactive-mode-insert "haskell-interactive-mode" (session message))
(declare-function haskell-interactive-mode-reset-error "haskell-interactive-mode" (session))
(declare-function haskell-interactive-show-load-message "haskell-interactive-mode" (session type module-name file-name echo))
Expand Down Expand Up @@ -991,6 +992,21 @@ now."
(haskell-process-send-string process "Prelude.putStrLn \"\"")
(haskell-process-send-string process ":set -v1"))

:live (lambda (process buffer)
(when (haskell-process-consume
process
"^\*\*\* WARNING: \\(.+\\) is writable by someone else, IGNORING!$")
(let ((path (match-string 1 buffer)))
(haskell-session-modify
(haskell-process-session process)
'ignored-files
(lambda (files)
(remove-duplicates (cons path files) :test 'string=)))
(haskell-interactive-mode-compile-warning
(haskell-process-session process)
(format "GHCi is ignoring: %s (run M-x haskell-process-unignore)"
path)))))

:complete (lambda (process _)
(haskell-interactive-mode-echo
(haskell-process-session process)
Expand Down Expand Up @@ -1257,6 +1273,59 @@ Returns nil if queue is empty."
(haskell-process-set process 'command-queue (cdr queue))
(car queue))))

(defun haskell-process-unignore ()
"Unignore any files that were specified as being ignored by the
inferior GHCi process."
(interactive)
(let ((session (haskell-session))
(changed nil))
(if (null (haskell-session-get session
'ignored-files))
(message "Nothing to unignore!")
(loop for file in (haskell-session-get session
'ignored-files)
do (case (read-key
(propertize (format "Set permissions? %s (y, n, v: stop and view file)"
file)
'face 'minibuffer-prompt))
(?y
(haskell-process-unignore-file session file)
(setq changed t))
(?v
(find-file file)
(return))))
(when (and changed
(y-or-n-p "Restart GHCi process now? "))
(haskell-process-restart)))))

(defun haskell-process-unignore-file (session file)
"
Note to Windows Emacs hackers:
chmod is how to change the mode of files in POSIX
systems. This will not work on your operating
system.
There is a command a bit like chmod called \"Calcs\"
that you can try using here:
http://technet.microsoft.com/en-us/library/bb490872.aspx
If it works, you can submit a patch to this
function and remove this comment.
"
(shell-command (read-from-minibuffer "Permissions command: "
(concat "chmod 700 "
file)))
(haskell-session-modify
(haskell-session)
'ignored-files
(lambda (files)
(remove-if (lambda (path)
(string= path file))
files))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Accessing commands -- using cl 'defstruct'
(defstruct haskell-command
Expand Down
8 changes: 8 additions & 0 deletions haskell-session.el
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,14 @@ If DONTCREATE is non-nil don't create a new session."
set-dir)
(haskell-session-cabal-dir s))))))

(defun haskell-session-modify (session key update)
"Update the value at KEY in SESSION with UPDATE."
(haskell-session-set
session
key
(funcall update
(haskell-session-get session key))))

(defun haskell-session-get (session key)
"Get the SESSION's KEY value.
Returns nil if KEY not set."
Expand Down

0 comments on commit 1834c3b

Please sign in to comment.