hascard 0.1.1.0 → 0.1.2.0
raw patch · 6 files changed
+48/−24 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- ChangeLog.md +9/−0
- README.md +12/−1
- app/Main.hs +2/−1
- hascard.cabal +2/−2
- src/Parser.hs +3/−3
- src/UI/FileBrowser.hs +20/−17
ChangeLog.md view
@@ -1,5 +1,14 @@ # Changelog for hascard +## 0.1.2.0+New:+- Directories are now hidden by default, and can be shown by pressing 'h' in the filebrowser+++Fixed bugs:+- Parsing now succeeds even if the text file does not end with ---+- When passing a file via the CLI, the absolute path is saved instead of the relative one, preventing issues with the 'recently selected files'+ ## 0.1.1.0 New: - Add nix build support (by @srid)
README.md view
@@ -5,16 +5,24 @@ ## Contents - [Installation](#installation)+- [Usage](#usage) - [Cards](#cards)+ - [Definition](#definition)+ - [Multiple choice](#multiple-choice)+ - [Multiple answer](#multiple-answer)+ - [Open question](#open-question) - [Miscellaneous info](#miscellaneous-info) ## Installation+Installation on Windows is not possible sadly, aside from WSL. This is because hascard depends on vty which only supports unix operating systems (this includes MacOS). ### Binary The binary used on my system is available under [releases](https://github.com/Yvee1/hascard/releases/). If you run debian with the x86-64 architecture that binary should work for you too. To be able to run it from any directory, it has to be added to the PATH. This can be done by copying it to e.g. the `/usr/local/bin` directory. ### Snapcraft Hascard is also on [snapcraft](https://snapcraft.io/hascard). Installation instructions are on that site. If you already have snap installed you can just install hascard via `sudo snap install hascard`. By default snap applications are isolated from the system and run in a sandbox. This means that hascard does not have permission to read or write any files on the system aside from those under `%HOME/snap/hascard`. To be able to read cards also in other directories under the home directory, hascard makes use of the `home` interface which might need to be enabled manually using `sudo snap connect hascard:home :home`. +**Note**: The installation with snapcraft does not work with all terminals, [known issues are with alacritty and st](https://github.com/Yvee1/hascard/issues/3), because of problems with terminfo that I do not know how to solve. With me, this did not happen with the other installation methods so try those if you have a somewhat non-standard terminal. If anyone knows what the problem might be, let me know!+ ### Install from source Another option is to build hascard and install it from source. For this you can use the Haskell build tool called [stack](https://docs.haskellstack.org/en/stable/README/#how-to-install), or [nix](https://nixos.org/). Then for example clone this repository somewhere: ```@@ -23,6 +31,9 @@ ``` and do `stack install hascard` or `nix-build` respectively. +## Usage+Simply run `hascard` to open the main application. Menu navigation can be done with the arrow keys or with the 'j' and 'k' keys. The controls for the different cards can be found at the bottom of the screen by default. This, and a couple other things, can be changed in the settings menu. Currently there is no functionality for making cards inside the hascard application itself, but they can easily be written in your favorite text editor since the syntax is human-friendly. Instead of selecting a deck of flashcards via the built-in filebrowser, it's also possible to run `hascard [FILE.txt]` where FILE is the text file with cards.+ ## Cards Decks of cards are written in `.txt` files. Cards are seperated with a line containing three dashes `---`. For examples, see the [`/cards`](https://github.com/Yvee1/hascard/tree/master/cards) directory. In this section the 4 different cards are listed, with the syntax and how it is represented in the application. @@ -73,4 +84,4 @@  ## Miscellaneous info-Written in Haskell, UI built with [brick](https://github.com/jtdaugherty/brick) and parsing of cards done with [parsec](https://github.com/haskell/parsec). Recordings of the terminal were made using [terminalizer](https://github.com/faressoft/terminalizer).+Written in Haskell, UI built with [brick](https://github.com/jtdaugherty/brick) and parsing of cards done with [parsec](https://github.com/haskell/parsec). Recordings of the terminal were made using [terminalizer](https://github.com/faressoft/terminalizer). The filebrowser widget was mostly copied from the brick [filebrowser demo program](https://github.com/jtdaugherty/brick/blob/master/programs/FileBrowserDemo.hs).
app/Main.hs view
@@ -8,6 +8,7 @@ import Paths_hascard (version) import Parser import Options.Applicative+import System.Directory (makeAbsolute) import System.Process (runCommand) import System.FilePath (takeExtension) @@ -52,4 +53,4 @@ Left exc -> putStrLn (displayException exc) Right val -> case parseCards val of Left parseError -> print parseError- Right result -> addRecent textfile *> runCardsUI result $> ()+ Right result -> (makeAbsolute textfile >>= addRecent) *> runCardsUI result $> ()
hascard.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 6a57f1e9b67613bc9c711646e3e9db7e237814e8d4b3baf027cb4827af79f38c+-- hash: b0ef7eaa1b6c53ffbbff8d10a8ea1a4e49ab9dc738a36e190346b422ff795ba3 name: hascard-version: 0.1.1.0+version: 0.1.2.0 synopsis: A TUI for reviewing notes using 'flashcards' written with markdown-like syntax. description: Hascard is a text-based user interface for reviewing notes using flashcards. Cards are written in markdown-like syntax. Please see the README file on GitHub at <https://github.com/Yvee1/hascard#readme> for more information. category: Application
src/Parser.hs view
@@ -33,7 +33,7 @@ pChoice = do kind <- oneOf "*-" space- text <- manyTill anyChar $ lookAhead (try (try choicePrefix <|> seperator))+ text <- manyTill anyChar $ lookAhead (try (try choicePrefix <|> seperator <|> (eof >> return []))) return (kind, text) choicePrefix = string "- "@@ -49,7 +49,7 @@ char '[' kind <- oneOf "*x " string "] "- text <- manyTill anyChar $ lookAhead (try (seperator <|> string "["))+ text <- manyTill anyChar $ lookAhead (try (seperator <|> string "[" <|> (eof >> return []))) return $ makeOption kind text pOpen = do@@ -88,7 +88,7 @@ pDef = do header <- pHeader many eol- descr <- manyTill chars $ lookAhead (try seperator)+ descr <- manyTill chars $ lookAhead (try (seperator <|> (eof >> return []))) return (header, descr) eol = try (string "\n\r")
src/UI/FileBrowser.hs view
@@ -4,26 +4,25 @@ module UI.FileBrowser (runFileBrowserUI) where import Brick-import Data.List-import Data.Char-import Types-import Parser-import Control.Exception (displayException, try)-import Control.Monad.IO.Class import Brick.Widgets.Border import Brick.Widgets.Center import Brick.Widgets.List import Brick.Widgets.FileBrowser+import Control.Exception (displayException, try)+import Control.Monad.IO.Class import Lens.Micro.Platform+import Parser+import Types import qualified Graphics.Vty as V type Event = () type Name = () data State = State- { _fb :: FileBrowser Name- , _exception :: Maybe String- , _cards :: [Card]- , _filePath :: Maybe FilePath+ { _fb :: FileBrowser Name+ , _exception :: Maybe String+ , _cards :: [Card]+ , _filePath :: Maybe FilePath+ , _showHidden :: Bool } makeLenses ''State@@ -64,7 +63,7 @@ borderWithLabel (txt "Choose a file") $ renderFileBrowser True b help = padTop (Pad 1) $- vBox [ hCenter $ txt "Up/Down: select"+ vBox [ hCenter $ txt "Up/Down: select, h: toggle show hidden files" , hCenter $ txt "/: search, Ctrl-C or Esc: cancel search" , hCenter $ txt "Enter: change directory or select file" , hCenter $ txt "Esc: quit"@@ -81,6 +80,8 @@ halt s V.EvKey (V.KChar 'c') [V.MCtrl] | not (fileBrowserIsSearching b) -> halt s+ V.EvKey (V.KChar 'h') [] | not (fileBrowserIsSearching b) -> let s' = s & showHidden %~ not in+ continue $ s' & fb .~ setFileBrowserEntryFilter (Just (entryFilter (s' ^. showHidden))) b _ -> do b' <- handleFileBrowserEvent ev b let s' = s & fb .~ b'@@ -106,12 +107,14 @@ runFileBrowserUI :: IO (Maybe ([Card], FilePath)) runFileBrowserUI = do browser <- newFileBrowser selectNonDirectories () Nothing- let filteredBrowser = setFileBrowserEntryFilter (Just (fileExtensionMatch' "txt")) browser- s <- defaultMain app (State filteredBrowser Nothing [] Nothing)+ let filteredBrowser = setFileBrowserEntryFilter (Just (entryFilter False)) browser+ s <- defaultMain app (State filteredBrowser Nothing [] Nothing False) let mfp = s ^. filePath return $ fmap (s ^. cards,) mfp -fileExtensionMatch' :: String -> FileInfo -> Bool-fileExtensionMatch' ext i = case fileInfoFileType i of- Just RegularFile -> ('.' : (toLower <$> ext)) `isSuffixOf` (toLower <$> fileInfoFilename i)- _ -> True+entryFilter :: Bool -> FileInfo -> Bool+entryFilter acceptHidden info = fileExtensionMatch "txt" info && (acceptHidden || + case fileInfoFilename info of+ ".." -> True+ '.' : _ -> False+ _ -> True)