dmenu-search (empty) → 0.1.0.0
raw patch · 6 files changed
+197/−0 lines, 6 filesdep +basedep +containersdep +directorybuild-type:Customsetup-changedbinary-added
Dependencies added: base, containers, directory, dmenu, lens, mtl, process, transformers
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- dmenu-search.cabal +57/−0
- doc/dmenu-search-1.png binary
- doc/dmenu-search-2.png binary
- src/Main.hs +108/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
@@ -0,0 +1,57 @@+name:+ dmenu-search+version:+ 0.1.0.0+synopsis:+ dmenu script for searching the web with customizable search engines.+description:+ See README.md file.+homepage:+ https://github.com/m0rphism/haskell-dmenu-search+bug-reports:+ https://github.com/m0rphism/haskell-dmenu-search/issues+license:+ BSD3+license-file:+ LICENSE+author:+ Hannes Saffrich+maintainer:+ Hannes Saffrich <m0rphism@zankapfel.org>+copyright:+ 2016 Hannes Saffrich+category:+ System+build-type:+ Custom+cabal-version:+ >=1.10+extra-doc-files:+ doc/*.png+stability:+ Beta+tested-with:+ GHC == 8.0.1++executable dmenu-search+ hs-source-dirs:+ src+ default-language:+ Haskell2010+ main-is:+ Main.hs+ build-depends:+ base >= 4.8 && < 5,+ containers >= 0.5.7 && < 0.6,+ lens >= 4.10 && < 4.16,+ mtl >= 2.2 && < 2.3,+ transformers >= 0.5 && < 0.6,+ process >= 1.4 && < 1.5,+ directory >= 1.2.6 && < 1.3,+ dmenu >= 0.3.1 && < 0.4+ ghc-options:+ -Wall -threaded -O2 -fno-warn-partial-type-signatures++source-repository head+ type: git+ location: https://github.com/m0rphism/haskell-dmenu-search.git
binary file changed (absent → 17400 bytes)
binary file changed (absent → 3125 bytes)
+ src/Main.hs view
@@ -0,0 +1,108 @@+{-# LANGUAGE UnicodeSyntax, LambdaCase, FlexibleContexts, TemplateHaskell #-}++import Control.Lens+import Control.Monad.IO.Class+import Control.Monad.State.Strict+import System.Environment+import System.Exit+import System.Process+import qualified DMenu++data Opts = Opts+ { _optsBrowser :: String+ , _optsEngines :: [(String, String)] -- ^ [(EngineName, EngineURLPrefix)]+ }++makeLenses ''Opts++pairs :: [a] → Either String [(a, a)]+pairs = \case+ [] → Right []+ x:y:xs → ((x,y):) <$> pairs xs+ _ → Left "Found search engine name without URL prefix."++parseEngines :: String -> Either String [(String, String)]+parseEngines es = pairs relevantLines+ where+ isEmptyLine = all (`elem` [' ', '\t'])+ relevantLines = filter (not . isEmptyLine) (lines es)++-- | Parse the command line arguments+readArgs+ :: [String] -- ^ Arguments from 'getArgs'+ -> IO Opts+readArgs args =+ execStateT (go $ words $ unwords args) (Opts "chromium -new-window" [])+ where+ go []+ = pure ()+ go (a:as)+ | a == "--"+ = pure () -- All arguments after "--" are passed to dmenu later.+ | a `elem` ["-b", "--browser"]+ , browser : as' ← as+ = do optsBrowser .= browser; go as'+ | a `elem` ["-e", "--engine"]+ , (name : urlPrefix : as') ← as+ = do optsEngines %= (++[(name, urlPrefix)]); go as'+ | a `elem` ["-E", "--engine-file"]+ , (filePath : as') ← as+ = liftIO (parseEngines <$> readFile filePath) >>= \case+ Left err → liftIO $ putStrLn $ "Failed to parse config file `"+ ++ filePath ++ "`: " ++ err+ Right es → do optsEngines %= (++es); go as'+ | a `elem` ["-h", "--help"]+ = liftIO $ do putStrLn usage; exitFailure+ | a == ""+ = go as+ go _+ = liftIO $ do putStrLn usage; exitFailure++main :: IO ()+main = do+ opts ← readArgs =<< getArgs+ let cfg1 = do DMenu.prompt .= "search with"; DMenu.forwardExtraArgs+ let cfg2 = do DMenu.prompt .= "search for"; DMenu.forwardExtraArgs+ DMenu.selectWith cfg1 fst (opts^.optsEngines) >>= \case+ Right (_, urlPrefix) →+ DMenu.select cfg2 [] >>= \case+ Right query →+ callCommand $ (opts^.optsBrowser) ++ " " ++ show (urlPrefix ++ query)+ _→ pure ()+ _ → pure ()++usage :: String+usage = unlines+ [ "USAGE"+ , " dmenu-search [OPTIONS] [-- DMENUOPTIONS]"+ , ""+ , " Let's the user choose a search engine and enter a search string by"+ , " spawning two subsequent dmenu processes, and opens the resulting"+ , " URL in a browser."+ , ""+ , " All arguments, after the first `--` argument, are directly passed to dmenu."+ , ""+ , "OPTIONS"+ , " -b, --browser CMD"+ , " Shell command to open url in browser. Default: `chromium -new-window`"+ , ""+ , " -e, --engine NAME URLPREFIX"+ , " Add a search engine, e.g."+ , ""+ , " -e google https://www.google.com/search?q="+ , " -e github https://github.com/search?q="+ , ""+ , " -E, --engine-file PATH"+ , " Add search engines from a file."+ , ""+ , " The following shows example content of an engine file:"+ , ""+ , " google"+ , " https://www.google.com/search?q="+ , ""+ , " github"+ , " https://github.com/search?q="+ , ""+ , " -h, --help"+ , " Display this message."+ ]