Skip to content

Commit

Permalink
double-click support for opening entries
Browse files Browse the repository at this point in the history
  • Loading branch information
pasqu4le committed Apr 27, 2018
1 parent fe2fe53 commit c6acf7d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 5 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Clifm is a small file manager written in Haskell with a terminal-based interface
> Note: this is still an experiment. Directory navigation will do no harm, but double-check before starting operations on your file system. I take no responsibility for what you do with this software.
## Installation
> Note: You may need to install `ncurses` on your system before using clifm
For ArchLinux the binary from [the latest github release](https://github.com/pasqu4le/clifm/releases/latest) should work.
For other Linux distro the binary may work as well, or you can build from source.

Expand All @@ -25,7 +27,7 @@ $ cabal install
## Features
Clifm is a [brick](https://github.com/jtdaugherty/brick) application, that in turn builds upon [vty](https://github.com/jtdaugherty/vty). As such it supports a large number of terminals, but not on Windows, handles windows resizing and more.

If your terminal supports a mouse you can use it to change Tab/Pane, click a button on the bottom or change your selection, but only using the keyboard you can perform every possible action. This is the list of all the keybindings:
If your terminal supports a mouse you can use it to change Tab/Pane, click a button on the bottom, change your selection or open it (double-click), but only using the keyboard you can perform every possible action. This is the list of all the keybindings:

#### Bottom menu
- L: open Se**l**ection menu
Expand Down
2 changes: 1 addition & 1 deletion clifm.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name: clifm
-- PVP summary: +-+------- breaking API changes
-- | | +----- non-breaking API additions
-- | | | +--- code changes with no API change
version: 0.4.0.0
version: 0.4.1.0

-- A short (one-line) description of the package.
synopsis: Command Line Interface File Manager
Expand Down
23 changes: 20 additions & 3 deletions src/Widgets/Manager.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import qualified Widgets.Prompt as Prompt

import System.Process (callCommand)
import Control.Exception (try, SomeException)
import Control.Monad.IO.Class (liftIO)
import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime)
import Brick.Main (continue, halt, suspendAndResume)
import Brick.Widgets.Core ((<+>), str, hBox, vBox, vLimit, withBorderStyle)
import Brick.Types (Widget, BrickEvent(..), EventM, Next, ViewportType(..), Location(..))
Expand All @@ -24,6 +26,7 @@ data State = State {paneZipper :: PaneZipper,
lastPaneName :: PaneName,
bottomMenu :: Menu.Menu,
prompt :: Maybe Prompt.Prompt,
lastClickedEntry :: Maybe (PaneName, Int, UTCTime),
editorCommand :: String,
eventChan :: BChan (ThreadEvent Tab.Tab)
}
Expand All @@ -33,7 +36,7 @@ type PaneZipper = PointedList Pane.Pane
makeState :: FilePath -> String -> BChan (ThreadEvent Tab.Tab) -> IO State
makeState path editCom eChan = do
pane <- Pane.make 0 path
return $ State (singleton pane) 0 Menu.make Nothing editCom eChan
return $ State (singleton pane) 0 Menu.make Nothing Nothing editCom eChan

-- rendering functions
drawUi :: State -> [Widget Name]
Expand Down Expand Up @@ -90,8 +93,8 @@ handleMain (VtyEvent ev) = case ev of
EvKey KRight [] -> nextPane
_ -> updateCurrentPane (Pane.handleEvent ev)
handleMain (MouseUp name _ (Location pos)) = case name of
EntryList {pnName = pName} -> updateCurrentPane (Pane.moveTabToRow $ snd pos) . focusOnPane pName
Label {pnName = pName, labelNum = n} -> updateCurrentPane (Pane.updateTabZipper (Pane.moveToNth n)) . focusOnPane pName
EntryList {pnName = pName} -> clickedEntry pName (snd pos)
Label {pnName = pName, labelNum = n} -> updateCurrentPane (Pane.moveToNthTab n) . focusOnPane pName
Button {keyBind = key, withCtrl = b} -> handleMain . VtyEvent $ EvKey key [MCtrl | b]
_ -> continue
handleMain _ = continue
Expand Down Expand Up @@ -122,6 +125,20 @@ openPrompt func state = continue $ state {prompt = Just $ func tab pName}
openPromptWithClip :: (Menu.Clipboard -> Tab.Tab -> PaneName -> Prompt.Prompt) -> State -> EventM Name (Next State)
openPromptWithClip func state = openPrompt (func . Menu.clipboard $ bottomMenu state) state

clickedEntry :: PaneName -> Int -> State -> EventM Name (Next State)
clickedEntry pName row state = do
currTime <- liftIO $ getCurrentTime
let clicked = (pName, row, currTime)
doubleClick = isDoubleClick (lastClickedEntry state) clicked
if doubleClick then openEntry $ state {lastClickedEntry = Nothing}
else updateCurrentPane (Pane.moveTabToRow row) . focusOnPane pName $ state {lastClickedEntry = Just clicked}

isDoubleClick :: Maybe (PaneName, Int, UTCTime) -> (PaneName, Int, UTCTime) -> Bool
isDoubleClick lastClick (nPane, nRow, nTime) = case lastClick of
Nothing -> False
Just (pPane, pRow, pTime) -> and [pPane == nPane, pRow == nRow, isSmallDiff]
where isSmallDiff = toRational (diffUTCTime nTime pTime) <= toRational 0.2

openEntry :: State -> EventM Name (Next State)
openEntry state = case Pane.selectedEntry $ currentPane state of
Just Entry.Dir {} -> openDirEntry False state
Expand Down
3 changes: 3 additions & 0 deletions src/Widgets/Pane.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ openDirEntry inNew pane = case selectedEntry pane of
replaceCurrentTab :: Tab.Tab -> Pane -> EventM Name Pane
replaceCurrentTab tab = updateTabZipper (replace tab)

moveToNthTab :: Int -> Pane -> EventM Name Pane
moveToNthTab n = updateTabZipper (moveToNth n)

-- tab and tabZipper utility functions
selectedEntry :: Pane -> Maybe Entry.Entry
selectedEntry = Tab.selectedEntry . currentTab
Expand Down

0 comments on commit c6acf7d

Please sign in to comment.