From 23695180860d25765394c4681ef9e919cfcd583b Mon Sep 17 00:00:00 2001 From: Mateusz Kowalczyk Date: Fri, 24 Oct 2014 20:53:06 +0100 Subject: [PATCH] Allow vim to close dired &c buffers In general it can now close more stuff Fixes #649 --- CHANGELOG | 1 + yi/src/library/Yi/File.hs | 18 +++++++++++++++++- yi/src/library/Yi/Keymap/Emacs/Utils.hs | 12 ------------ .../library/Yi/Keymap/Vim/Ex/Commands/Quit.hs | 19 +++++++------------ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 19f2d7cc1..610e7dc34 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,7 @@ * Fix eolPoint' when on last, empty line (#667, #662) * More intuitive justOneSep (emacs M-SPC) (#665) * Closer behaviour to emacs C-x 0 (#642) + * Allow vim to close dired &c buffers (#649) 0.10.0 ------ diff --git a/yi/src/library/Yi/File.hs b/yi/src/library/Yi/File.hs index 8ed2f4ed9..12acdc081 100644 --- a/yi/src/library/Yi/File.hs +++ b/yi/src/library/Yi/File.hs @@ -23,9 +23,11 @@ module Yi.File ( revertE, -- :: YiM () -- * Helper functions - setFileName + setFileName, + deservesSave ) where +import Control.Applicative import Control.Lens hiding (act) import Control.Monad (void) import Control.Monad.Base @@ -151,3 +153,17 @@ setFileName :: BufferRef -> FilePath -> YiM () setFileName b filename = do cfn <- liftBase $ userToCanonPath filename withGivenBuffer b $ assign identA $ FileBuffer cfn + +-- | Checks if the given buffer deserves a save: whether it's a file +-- buffer and whether it's pointing at a file rather than a directory. +deservesSave :: FBuffer -> YiM Bool +deservesSave b + | isUnchangedBuffer b = return False + | otherwise = isFileBuffer b + +-- | Is there a proper file associated with the buffer? +-- In other words, does it make sense to offer to save it? +isFileBuffer :: FBuffer -> YiM Bool +isFileBuffer b = case b ^. identA of + MemBuffer _ -> return False + FileBuffer fn -> not <$> liftBase (doesDirectoryExist fn) diff --git a/yi/src/library/Yi/Keymap/Emacs/Utils.hs b/yi/src/library/Yi/Keymap/Emacs/Utils.hs index eb91efff9..c43c0b14c 100644 --- a/yi/src/library/Yi/Keymap/Emacs/Utils.hs +++ b/yi/src/library/Yi/Keymap/Emacs/Utils.hs @@ -98,18 +98,6 @@ askSaveEditor = askIndividualSave False =<< getModifiedBuffers getModifiedBuffers :: YiM [FBuffer] getModifiedBuffers = filterM deservesSave =<< gets bufferSet -deservesSave :: FBuffer -> YiM Bool -deservesSave b - | isUnchangedBuffer b = return False - | otherwise = isFileBuffer b - --- | Is there a proper file associated with the buffer? --- In other words, does it make sense to offer to save it? -isFileBuffer :: (Functor m, MonadBase IO m) => FBuffer -> m Bool -isFileBuffer b = case b ^. identA of - MemBuffer _ -> return False - FileBuffer fn -> not <$> liftBase (doesDirectoryExist fn) - -------------------------------------------------- -- Takes in a list of buffers which have been identified -- as modified since their last save. diff --git a/yi/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs b/yi/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs index cc8a9b58f..362f1cb55 100644 --- a/yi/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs +++ b/yi/src/library/Yi/Keymap/Vim/Ex/Commands/Quit.hs @@ -20,6 +20,7 @@ import Control.Monad import Data.Foldable (find) import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.PointedList.Circular as PL +import Data.Maybe import Data.Monoid import qualified Data.Text as T import qualified Text.ParserCombinators.Parsec as P @@ -71,7 +72,7 @@ action True True True = saveAndQuitAllE quitWindowE :: YiM () quitWindowE = do - nw <- withCurrentBuffer needsAWindowB + nw <- gets currentBuffer >>= needsSaving ws <- withEditor $ use currentWindowA >>= windowsOnBufferE . bufkey if length ws == 1 && nw then errorEditor "No write since last change (add ! to override)" @@ -85,14 +86,13 @@ quitWindowE = do quitAllE :: YiM () quitAllE = do - a :| as <- readEditor bufferStack - let needsWindow b = (b,) <$> withEditor (withGivenBuffer b needsAWindowB) - bs <- mapM needsWindow (a:as) + let needsWindow b = (b,) <$> deservesSave b + bs <- readEditor bufferSet >>= mapM needsWindow -- Vim only shows the first modified buffer in the error. case find snd bs of Nothing -> quitEditor Just (b, _) -> do - bufferName <- withEditor $ withGivenBuffer b $ gets file + bufferName <- withEditor $ withGivenBuffer (bkey b) $ gets file errorEditor $ "No write since last change for buffer " <> showT bufferName <> " (add ! to override)" @@ -100,10 +100,5 @@ quitAllE = do saveAndQuitAllE :: YiM () saveAndQuitAllE = Common.forAllBuffers fwriteBufferE >> quitEditor -needsAWindowB :: BufferM Bool -needsAWindowB = do - isWorthless <- gets (^. identA) >>= return . \case - MemBuffer _ -> True - FileBuffer _ -> False - canClose <- gets isUnchangedBuffer - return (not (isWorthless || canClose)) +needsSaving :: BufferRef -> YiM Bool +needsSaving = findBuffer >=> maybe (return False) deservesSave