From d151e478e2b69d404bc410a60c91e591310d948a Mon Sep 17 00:00:00 2001 From: Junji Hashimoto Date: Tue, 12 Jun 2018 13:00:26 +0900 Subject: [PATCH 1/3] Move Hclip to yi-core Add disable-hclip function --- yi-core/src/Yi/Clip.hs | 46 +++++++++++++++++++ yi-core/src/Yi/Config/Default.hs | 1 + yi-core/src/Yi/Config/Simple.hs | 3 +- yi-core/src/Yi/Types.hs | 5 +- yi-core/yi-core.cabal | 2 + .../src/Yi/Keymap/Emacs/KillRing.hs | 6 +-- yi-keymap-emacs/yi-keymap-emacs.cabal | 1 - .../src/Yi/Keymap/Vim/Ex/Commands/Copy.hs | 4 +- yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs | 7 ++- yi-keymap-vim/yi-keymap-vim.cabal | 2 - 10 files changed, 63 insertions(+), 14 deletions(-) create mode 100644 yi-core/src/Yi/Clip.hs diff --git a/yi-core/src/Yi/Clip.hs b/yi-core/src/Yi/Clip.hs new file mode 100644 index 000000000..9479b585b --- /dev/null +++ b/yi-core/src/Yi/Clip.hs @@ -0,0 +1,46 @@ +{-# OPTIONS_HADDOCK show-extensions #-} + +-- | +-- Module : Yi.Clip +-- License : GPL-2 +-- Maintainer : yi-devel@googlegroups.com +-- Stability : experimental +-- Portability : portable +-- +-- A proxy of clipboard. + +module Yi.Clip ( setClipboard + , getClipboard + ) + where + +import qualified System.Hclip as H (getClipboard, setClipboard) +import Data.IORef +import System.IO.Unsafe + +import Yi.Types (configDisableSystemClipboard, askCfg) +import Yi.Utils (io) +import Yi.Keymap (YiM) + +clipboard :: IORef String +clipboard = unsafePerformIO $ newIORef "" + +getClipboard' :: IO String +getClipboard' = readIORef clipboard + +setClipboard' :: String -> IO () +setClipboard' = writeIORef clipboard + +getClipboard :: YiM String +getClipboard = do + config <- askCfg + if configDisableSystemClipboard config + then io getClipboard' + else io H.getClipboard + +setClipboard :: String -> YiM () +setClipboard text = do + config <- askCfg + if configDisableSystemClipboard config + then io $ setClipboard' text + else io $ H.setClipboard text diff --git a/yi-core/src/Yi/Config/Default.hs b/yi-core/src/Yi/Config/Default.hs index f56d759cc..8ba0cbd99 100644 --- a/yi-core/src/Yi/Config/Default.hs +++ b/yi-core/src/Yi/Config/Default.hs @@ -108,6 +108,7 @@ defaultConfig = , bufferUpdateHandler = mempty , layoutManagers = [hPairNStack 1, vPairNStack 1, tall, wide] , configVars = mempty + , configDisableSystemClipboard = False } nilKeymap :: Keymap diff --git a/yi-core/src/Yi/Config/Simple.hs b/yi-core/src/Yi/Config/Simple.hs index 2287455fc..2d1cef5e3 100644 --- a/yi-core/src/Yi/Config/Simple.hs +++ b/yi-core/src/Yi/Config/Simple.hs @@ -148,7 +148,8 @@ import Yi.Config(Config, UIConfig, startFrontEndA, configUIA, CursorStyle(..), configLeftSideScrollBarA, configAutoHideScrollBarA, configAutoHideTabBarA, configLineWrapA, configWindowFillA, configThemeA, - layoutManagersA, configVarsA, configLineNumbersA + layoutManagersA, configVarsA, configLineNumbersA, + configDisableSystemClipboardA ) diff --git a/yi-core/src/Yi/Types.hs b/yi-core/src/Yi/Types.hs index 7697cc3ca..25cbd8fc1 100644 --- a/yi-core/src/Yi/Types.hs +++ b/yi-core/src/Yi/Types.hs @@ -434,8 +434,11 @@ data Config = Config {startFrontEnd :: UIBoot, bufferUpdateHandler :: !(S.Seq (S.Seq Update -> BufferM ())), layoutManagers :: ![AnyLayoutManager], -- ^ List of layout managers for 'cycleLayoutManagersNext' - configVars :: !ConfigState.DynamicState + configVars :: !ConfigState.DynamicState, -- ^ Custom configuration, containing the 'YiConfigVariable's. Configure with 'configVariableA'. + configDisableSystemClipboard :: !Bool + -- ^ Set to 'True' not to use system clipboard. + -- When vty-mode, system clipboard is not available in some environments. } diff --git a/yi-core/yi-core.cabal b/yi-core/yi-core.cabal index 5183bbcbd..8ae59f0ee 100644 --- a/yi-core/yi-core.cabal +++ b/yi-core/yi-core.cabal @@ -54,6 +54,7 @@ library , yi-language >= 0.17 , yi-rope >= 0.10 , exceptions + , Hclip if flag(hint) cpp-options: -DHINT build-depends: @@ -74,6 +75,7 @@ library Yi.Buffer.Region Yi.Buffer.TextUnit Yi.Buffer.Undo + Yi.Clip Yi.Command Yi.Command.Help Yi.Completion diff --git a/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs b/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs index deffc64d9..08602b121 100644 --- a/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs +++ b/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs @@ -19,10 +19,10 @@ import Yi.Buffer import Yi.Editor (EditorM, killringA, withCurrentBuffer) import Yi.Keymap (YiM) import Yi.KillRing (Killring (_krContents), krKilled, krPut) +import Yi.Clip (getClipboard, setClipboard) import qualified Yi.Rope as R (YiString, fromString, toString) import Yi.Types (withEditor) import Yi.Utils (io) -import System.Hclip (getClipboard, setClipboard) uses :: forall a b f s. MonadState s f => Getting a s a -> (a -> b) -> f b uses l f = f <$> use l @@ -32,7 +32,7 @@ uses l f = f <$> use l -- | Adds system clipboard's contents on top of the killring if not already there clipboardToKillring :: YiM () clipboardToKillring = do - text <- fmap R.fromString $ io getClipboard + text <- fmap R.fromString $ getClipboard withEditor $ do text' <- killringGet when (text' /= text) $ killringPut Forward text @@ -41,7 +41,7 @@ clipboardToKillring = do killringToClipboard :: YiM () killringToClipboard = do text <- withEditor killringGet - io . setClipboard $ R.toString text + setClipboard $ R.toString text -- This is like @kill-region-or-backward-word@. killRegionB :: BufferM () diff --git a/yi-keymap-emacs/yi-keymap-emacs.cabal b/yi-keymap-emacs/yi-keymap-emacs.cabal index 2243cba58..7f88a6427 100644 --- a/yi-keymap-emacs/yi-keymap-emacs.cabal +++ b/yi-keymap-emacs/yi-keymap-emacs.cabal @@ -21,7 +21,6 @@ library base >= 4.8 && < 5 , containers , filepath - , Hclip , microlens-platform , mtl , oo-prototypes diff --git a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs index e7ddd6971..d9b915299 100644 --- a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs +++ b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs @@ -23,7 +23,7 @@ import Yi.Types (YiM, BufferM) import Yi.Rope (toString) import Yi.Buffer.Region (readRegionB, Region) import Control.Monad.Base (liftBase) -import System.Hclip (setClipboard) +import Yi.Clip (setClipboard) import Yi.Core (errorEditor) parse :: EventString -> Maybe ExCommand @@ -38,5 +38,5 @@ parse = Common.parse $ do copy :: Maybe (BufferM Region) -> YiM () copy maybeGetRegion = case maybeGetRegion of Nothing -> errorEditor "Cannot copy: No region" - Just getRegion -> liftBase . setClipboard . toString + Just getRegion -> setClipboard . toString =<< withCurrentBuffer (readRegionB =<< getRegion) diff --git a/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs b/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs index fd076f2a5..85b3b0191 100644 --- a/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs +++ b/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs @@ -50,7 +50,7 @@ import Yi.Monad (whenM) import Yi.Rope (YiString, countNewLines, last) import qualified Yi.Rope as R (replicateChar, snoc, toString, fromString) import Yi.Utils (io) -import System.Hclip (getClipboard, setClipboard) +import Yi.Clip (getClipboard, setClipboard) -- 'mkBindingE' and 'mkBindingY' are helper functions for bindings -- where VimState mutation is not dependent on action performed @@ -208,11 +208,10 @@ addNewLineIfNecessary rope = pasteFromClipboard :: YiM () pasteFromClipboard = do - text <- fmap R.fromString $ io getClipboard + text <- fmap R.fromString $ getClipboard withCurrentBuffer $ insertRopeWithStyleB text Inclusive exportRegisterToClipboard :: RegisterName -> YiM () exportRegisterToClipboard name = do mbr <- withEditor $ getRegisterE name - io . setClipboard $ maybe "" (R.toString . regContent) mbr - \ No newline at end of file + setClipboard $ maybe "" (R.toString . regContent) mbr diff --git a/yi-keymap-vim/yi-keymap-vim.cabal b/yi-keymap-vim/yi-keymap-vim.cabal index 6109256ff..de3414c07 100644 --- a/yi-keymap-vim/yi-keymap-vim.cabal +++ b/yi-keymap-vim/yi-keymap-vim.cabal @@ -56,7 +56,6 @@ library , data-default , directory , filepath - , Hclip , microlens-platform , mtl , oo-prototypes @@ -141,7 +140,6 @@ test-suite spec , data-default , directory , filepath - , Hclip , microlens-platform , mtl , oo-prototypes From d6528c550da846665583fe13800a1909a6cd8e49 Mon Sep 17 00:00:00 2001 From: Junji Hashimoto Date: Tue, 19 Jun 2018 17:47:11 +0900 Subject: [PATCH 2/3] Use YiString for clipboard --- yi-core/src/Yi/Clip.hs | 16 +++++++++------- yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs | 6 +++--- .../src/Yi/Keymap/Vim/Ex/Commands/Copy.hs | 2 +- yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/yi-core/src/Yi/Clip.hs b/yi-core/src/Yi/Clip.hs index 9479b585b..3ac757a9d 100644 --- a/yi-core/src/Yi/Clip.hs +++ b/yi-core/src/Yi/Clip.hs @@ -1,4 +1,5 @@ {-# OPTIONS_HADDOCK show-extensions #-} +{-# LANGUAGE OverloadedStrings #-} -- | -- Module : Yi.Clip @@ -21,26 +22,27 @@ import System.IO.Unsafe import Yi.Types (configDisableSystemClipboard, askCfg) import Yi.Utils (io) import Yi.Keymap (YiM) +import qualified Yi.Rope as R (YiString, fromString, toString) -clipboard :: IORef String +clipboard :: IORef R.YiString clipboard = unsafePerformIO $ newIORef "" -getClipboard' :: IO String +getClipboard' :: IO R.YiString getClipboard' = readIORef clipboard -setClipboard' :: String -> IO () +setClipboard' :: R.YiString -> IO () setClipboard' = writeIORef clipboard -getClipboard :: YiM String +getClipboard :: YiM R.YiString getClipboard = do config <- askCfg if configDisableSystemClipboard config then io getClipboard' - else io H.getClipboard + else io $ fmap R.fromString $ H.getClipboard -setClipboard :: String -> YiM () +setClipboard :: R.YiString -> YiM () setClipboard text = do config <- askCfg if configDisableSystemClipboard config then io $ setClipboard' text - else io $ H.setClipboard text + else io $ H.setClipboard $ R.toString text diff --git a/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs b/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs index 08602b121..eeb6c7624 100644 --- a/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs +++ b/yi-keymap-emacs/src/Yi/Keymap/Emacs/KillRing.hs @@ -20,7 +20,7 @@ import Yi.Editor (EditorM, killringA, withCurrentBuffer) import Yi.Keymap (YiM) import Yi.KillRing (Killring (_krContents), krKilled, krPut) import Yi.Clip (getClipboard, setClipboard) -import qualified Yi.Rope as R (YiString, fromString, toString) +import qualified Yi.Rope as R (YiString) import Yi.Types (withEditor) import Yi.Utils (io) @@ -32,7 +32,7 @@ uses l f = f <$> use l -- | Adds system clipboard's contents on top of the killring if not already there clipboardToKillring :: YiM () clipboardToKillring = do - text <- fmap R.fromString $ getClipboard + text <- getClipboard withEditor $ do text' <- killringGet when (text' /= text) $ killringPut Forward text @@ -41,7 +41,7 @@ clipboardToKillring = do killringToClipboard :: YiM () killringToClipboard = do text <- withEditor killringGet - setClipboard $ R.toString text + setClipboard text -- This is like @kill-region-or-backward-word@. killRegionB :: BufferM () diff --git a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs index d9b915299..449d779bd 100644 --- a/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs +++ b/yi-keymap-vim/src/Yi/Keymap/Vim/Ex/Commands/Copy.hs @@ -38,5 +38,5 @@ parse = Common.parse $ do copy :: Maybe (BufferM Region) -> YiM () copy maybeGetRegion = case maybeGetRegion of Nothing -> errorEditor "Cannot copy: No region" - Just getRegion -> setClipboard . toString + Just getRegion -> setClipboard =<< withCurrentBuffer (readRegionB =<< getRegion) diff --git a/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs b/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs index 85b3b0191..fb9478c8f 100644 --- a/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs +++ b/yi-keymap-vim/src/Yi/Keymap/Vim/Utils.hs @@ -208,10 +208,10 @@ addNewLineIfNecessary rope = pasteFromClipboard :: YiM () pasteFromClipboard = do - text <- fmap R.fromString $ getClipboard + text <- getClipboard withCurrentBuffer $ insertRopeWithStyleB text Inclusive exportRegisterToClipboard :: RegisterName -> YiM () exportRegisterToClipboard name = do mbr <- withEditor $ getRegisterE name - setClipboard $ maybe "" (R.toString . regContent) mbr + setClipboard $ maybe "" regContent mbr From dce2db83a0554c855bc49040354876c44b31ffb6 Mon Sep 17 00:00:00 2001 From: Junji Hashimoto Date: Tue, 19 Jun 2018 17:57:18 +0900 Subject: [PATCH 3/3] Add comment for IOREF --- yi-core/src/Yi/Clip.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/yi-core/src/Yi/Clip.hs b/yi-core/src/Yi/Clip.hs index 3ac757a9d..07ab50b46 100644 --- a/yi-core/src/Yi/Clip.hs +++ b/yi-core/src/Yi/Clip.hs @@ -24,6 +24,10 @@ import Yi.Utils (io) import Yi.Keymap (YiM) import qualified Yi.Rope as R (YiString, fromString, toString) + +-- | +-- This is just used for emulating system clipbord. +-- Do not release this IORef variable outside this module. clipboard :: IORef R.YiString clipboard = unsafePerformIO $ newIORef ""