module Hledger.UI.Editor (
endPosition
,runEditor
,runIadd
)
where
import Control.Applicative ((<|>))
import Data.List (intercalate)
import Data.Maybe (catMaybes)
import Data.Bifunctor (bimap)
import Safe
import System.Environment
import System.Exit
import System.FilePath
import System.Process
import Hledger
type TextPosition = (Int, Maybe Int)
endPosition :: Maybe TextPosition
endPosition :: Maybe TextPosition
endPosition = forall a. a -> Maybe a
Just (-Int
1, forall a. Maybe a
Nothing)
runIadd :: FilePath -> IO ExitCode
runIadd :: FilePath -> IO ExitCode
runIadd FilePath
f = FilePath -> IO ProcessHandle
runCommand (FilePath
"hledger-iadd -f " forall a. [a] -> [a] -> [a]
++ FilePath
f) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ProcessHandle -> IO ExitCode
waitForProcess
runEditor :: Maybe TextPosition -> FilePath -> IO ExitCode
runEditor :: Maybe TextPosition -> FilePath -> IO ExitCode
runEditor Maybe TextPosition
mpos FilePath
f = Maybe TextPosition -> FilePath -> IO FilePath
editFileAtPositionCommand Maybe TextPosition
mpos FilePath
f forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= FilePath -> IO ProcessHandle
runCommand forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ProcessHandle -> IO ExitCode
waitForProcess
editFileAtPositionCommand :: Maybe TextPosition -> FilePath -> IO String
editFileAtPositionCommand :: Maybe TextPosition -> FilePath -> IO FilePath
editFileAtPositionCommand Maybe TextPosition
mpos FilePath
f = do
FilePath
cmd <- IO FilePath
getEditCommand
let editor :: FilePath
editor = FilePath -> FilePath
lowercase forall a b. (a -> b) -> a -> b
$ FilePath -> FilePath
takeBaseName forall a b. (a -> b) -> a -> b
$ forall a. a -> [a] -> a
headDef FilePath
"" forall a b. (a -> b) -> a -> b
$ FilePath -> [FilePath]
words' FilePath
cmd
f' :: FilePath
f' = FilePath -> FilePath
singleQuoteIfNeeded FilePath
f
mpos' :: Maybe (FilePath, Maybe FilePath)
mpos' = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap forall a. Show a => a -> FilePath
show (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Show a => a -> FilePath
show) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe TextPosition
mpos
join :: [a] -> [Maybe [a]] -> [a]
join [a]
sep = forall a. [a] -> [[a]] -> [a]
intercalate [a]
sep forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Maybe a] -> [a]
catMaybes
args :: [FilePath]
args = case FilePath
editor of
FilePath
"emacs" -> case Maybe (FilePath, Maybe FilePath)
mpos' of
Maybe (FilePath, Maybe FilePath)
Nothing -> [FilePath
f']
Just (Char
'-' : FilePath
_, Maybe FilePath
_) -> [FilePath
f', FilePath
"-f", FilePath
"end-of-buffer"]
Just (FilePath
l, Maybe FilePath
mc) -> [Char
'+' forall a. a -> [a] -> [a]
: forall {a}. [a] -> [Maybe [a]] -> [a]
join FilePath
":" [forall a. a -> Maybe a
Just FilePath
l, Maybe FilePath
mc], FilePath
f']
FilePath
e | FilePath
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath
"emacsclient", FilePath
"nano"] -> case Maybe (FilePath, Maybe FilePath)
mpos' of
Maybe (FilePath, Maybe FilePath)
Nothing -> [FilePath
f']
Just (Char
'-' : FilePath
_, Maybe FilePath
_) -> [FilePath
f']
Just (FilePath
l, Maybe FilePath
mc) -> [Char
'+' forall a. a -> [a] -> [a]
: forall {a}. [a] -> [Maybe [a]] -> [a]
join FilePath
":" [forall a. a -> Maybe a
Just FilePath
l, Maybe FilePath
mc], FilePath
f']
FilePath
"vscode" -> case Maybe (FilePath, Maybe FilePath)
mpos' of
Maybe (FilePath, Maybe FilePath)
Nothing -> [FilePath
f']
Just (Char
'-' : FilePath
_, Maybe FilePath
_) -> [FilePath
f']
Just (FilePath
l, Maybe FilePath
mc) -> [FilePath
"--goto", forall {a}. [a] -> [Maybe [a]] -> [a]
join FilePath
":" [forall a. a -> Maybe a
Just FilePath
f', forall a. a -> Maybe a
Just FilePath
l, Maybe FilePath
mc]]
FilePath
"kak" -> case Maybe (FilePath, Maybe FilePath)
mpos' of
Maybe (FilePath, Maybe FilePath)
Nothing -> [FilePath
f']
Just (Char
'-' : FilePath
_, Maybe FilePath
_) -> [FilePath
"+:", FilePath
f']
Just (FilePath
l, Maybe FilePath
mc) -> [Char
'+' forall a. a -> [a] -> [a]
: forall {a}. [a] -> [Maybe [a]] -> [a]
join FilePath
":" [forall a. a -> Maybe a
Just FilePath
l, Maybe FilePath
mc], FilePath
f']
FilePath
e | FilePath
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath
"vi", FilePath
"vim", FilePath
"view", FilePath
"nvim", FilePath
"evim", FilePath
"eview",
FilePath
"gvim", FilePath
"gview", FilePath
"rvim", FilePath
"rview",
FilePath
"rgvim", FilePath
"rgview", FilePath
"ex"] -> case Maybe (FilePath, Maybe FilePath)
mpos' of
Maybe (FilePath, Maybe FilePath)
Nothing -> [FilePath
f']
Just (Char
'-' : FilePath
_, Maybe FilePath
_) -> [FilePath
"+", FilePath
f']
Just (FilePath
l, Maybe FilePath
_) -> [Char
'+' forall a. a -> [a] -> [a]
: FilePath
l, FilePath
f']
FilePath
_ -> [FilePath
f']
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [FilePath] -> FilePath
unwords forall a b. (a -> b) -> a -> b
$ FilePath
cmdforall a. a -> [a] -> [a]
:[FilePath]
args
getEditCommand :: IO String
getEditCommand :: IO FilePath
getEditCommand = do
Maybe FilePath
hledger_ui_editor_env <- FilePath -> IO (Maybe FilePath)
lookupEnv FilePath
"HLEDGER_UI_EDITOR"
Maybe FilePath
editor_env <- FilePath -> IO (Maybe FilePath)
lookupEnv FilePath
"EDITOR"
let Just FilePath
cmd = Maybe FilePath
hledger_ui_editor_env forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe FilePath
editor_env forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall a. a -> Maybe a
Just FilePath
"emacsclient -a '' -nw"
forall (m :: * -> *) a. Monad m => a -> m a
return FilePath
cmd