diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,13 @@
 # Release history for lsfrom
 
+## 1.0 (2024-01-07)
+- add --after: start with the next file after the specified one
+- add --until: include files only up to the specified file
+- add --before: changes the behaviour of --until
+- add --strict: error if the specified files do not exist
+- the short option for --all is now -A
+-
+
 ## 0.1.1.1 (2022-04-24)
 - add missing test files
 - fix testsuite for lts 12 and earlier
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2018, Jens Petersen
+Copyright (c) 2018 and 2021-2024, Jens Petersen
 
 All rights reserved.
 
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -1,27 +1,83 @@
 module Main (main) where
 
+import Data.List (dropWhileEnd)
 import SimpleCmd
 import SimpleCmdArgs
+import Safe (tailSafe)
 import System.FilePath
 
 import Paths_lsfrom (version)
 
 main :: IO ()
 main =
-  simpleCmdArgs (Just version) "List files from pattern"
-  "lsfrom lists the files in a directory that follow from the given pattern" $
-  lsfrom <$> switchWith 'a' "all" "include hidden (dot) files" <*> strArg "FILEPAT"
+  simpleCmdArgs (Just version) "List directories files starting from file"
+  "lsfrom lists the files in a directory that follow from the given file" $
+  lsfrom
+  <$> switchWith 's' "strict" "fail if specified file(s) do not exist"
+  <*> switchWith 'A' "all" "include hidden (dot) files"
+  <*> switchWith 'a' "after" "files after STARTFILE [default: from STARTFILE]"
+  <*> optional (removeTrailing <$> strOptionWith 'u' "until" "LASTFILE" "files until FILE")
+  <*> switchWith 'b' "before" "files before LASTFILE (only affects --until)"
+  <*> (removeTrailing <$> strArg "STARTFILE")
+  where
+    removeTrailing "" = ""
+    removeTrailing "/" = "/"
+    removeTrailing f =
+      if last f == '/'
+      then removeTrailing $ init f
+      else f
 
-lsfrom :: Bool -> FilePath -> IO ()
-lsfrom hidden file = do
-  let isdir = last file == pathSeparator
-      file' = if isdir then takeDirectory file else file
-      (dir,pat) = splitFileName file'
-      pat' = pat ++ if isdir then [pathSeparator] else ""
-  sorted <- do
-    files <- cmd "ls" $ ["-A" | hidden || head pat == '.'] ++ [dir]
-    lines <$> cmdStdIn "sort" [] (pat' ++ "\n" ++ files)
-  let result = tail $ dropWhile (pat' /=) sorted
-  mapM_ (putStrLn . (renderDir dir </>)) result
+lsfrom :: Bool -> Bool -> Bool -> Maybe FilePath -> Bool -> FilePath -> IO ()
+lsfrom strict hidden after muntil before file =
+  case reverse (splitDirectories file) of
+    [] -> error' "empty filename!"
+    ("":_) -> error' "empty filename!"
+    (entry@(e:_):revdir) -> do
+      let dir = joinPath $ reverse revdir
+      lsout <- cmd "ls" $
+                 ["-A" | hidden || e == '.'] ++ [dir | not (null dir)]
+      let lsEntries = lines lsout
+          entryExists = entry `elem` lsEntries
+          muntilExists =
+            case muntil of
+              Nothing -> Nothing
+              Just until' ->
+                Just (until', until' `elem` lsEntries)
+      listingWith <-
+        lines <$>
+        if strict
+        then return lsout
+        else if entryExists
+             then case muntilExists of
+                    Just (until',False) ->
+                      sortLs $ prepend until' lsout
+                    _ -> return lsout
+             else case muntilExists of
+                    Just (until',False) ->
+                      sortLs $
+                      if entry == until'
+                      then prepend entry lsout
+                      else prepend entry $ prepend until' lsout
+                    _ -> sortLs $ prepend entry lsout
+      let result =
+            takeUntil muntilExists $
+            (if after || not entryExists then tailSafe else id) $
+            dropWhile (entry /=) listingWith
+      mapM_ (putStrLn . (renderDir dir </>)) result
   where
     renderDir dir = if dir == "./" then "" else dir
+
+    sortLs :: String -> IO String
+    sortLs = cmdStdIn "sort" []
+
+    prepend :: String -> String -> String
+    prepend miss ls = miss ++ '\n' : ls
+
+    takeUntil :: Maybe (String,Bool) -> [String] -> [String]
+    takeUntil Nothing es = es
+    takeUntil (Just _) [] = []
+    takeUntil (Just (until',exists)) es =
+      case dropWhileEnd (until' /=) es of
+        [] -> []
+        es' ->
+          (if before || not exists then init else id) es'
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,38 +1,64 @@
 # lsfrom
 
-`lsfrom` lists the files and dirs in a directory starting from the first one
-that matches the given filename prefix or the first filename after that
-if there is no match, using the current locale collation order.
+`lsfrom` lists the files and dirs in a directory starting from
+the given filename or the first file after that
+if the file does not exist, using the current locale collation order.
 
-```
+```shellsession
 $ ls
 A a B C
-$ lsfrom a
-a
-B
-C
+$ echo $(lsfrom a)
+a B C
 $ lsfrom a/
+a
 B
 C
 $ lsfrom /sy
 /sys
-/sysroot
 /tmp
 /usr
 /var
 ```
 
-This may be useful for continuing a script on the content of a directory
+It can be useful for continuing a script on the entries of a directory
 after a failure, etc:
 
 ```shellsession
 $ myscript.sh $(lsfrom next)
 ```
 
+or only running a command on a subrange of files in a directory.
+
+## Usage
+
+`$ lsfrom --version`
+```
+1.0
+```
+`$ lsfrom -h`
+```
+List directories files starting from file
+
+Usage: lsfrom [--version] [-s|--strict] [-A|--all] [-a|--after]
+              [-u|--until LASTFILE] [-b|--before] STARTFILE
+
+  lsfrom lists the files in a directory that follow from the given file
+
+Available options:
+  -h,--help                Show this help text
+  --version                Show version
+  -s,--strict              fail if specified file(s) do not exist
+  -A,--all                 include hidden (dot) files
+  -a,--after               files after STARTFILE [default: from STARTFILE]
+  -u,--until LASTFILE      files until FILE
+  -b,--before              files before LASTFILE (only affects --until)
+```
+
 ## Requirements
 
-It uses system `ls` order to preserve locale collation
-and requires ls with the `-A` option to exclude `.` and `..` (eg coreutils).
+It uses `ls` to list files with locale sorting
+and requires the `-A` option to exclude `.` and `..` (ie coreutils).
+It also uses `sort` when injecting missing marker files.
 It has been tested on Linux.
 
 ## Installation
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/lsfrom.cabal b/lsfrom.cabal
--- a/lsfrom.cabal
+++ b/lsfrom.cabal
@@ -1,10 +1,11 @@
+cabal-version:       2.0
 name:                lsfrom
-version:             0.1.1.1
+version:             1.0
 synopsis:            List directory files starting from a specific name
 description:
-            `lsfrom` lists the contents of a directory starting from
-            a particular prefix and those files after it
-            with respect to locale collation.
+            `lsfrom` lists the entries of a directory starting from
+            a particular file and then the files after it
+            with respect to locale collation ordering.
 
             This can be useful for example for continuing a command or script
             in a directory after a failure.
@@ -12,12 +13,11 @@
 license-file:        LICENSE
 author:              Jens Petersen <petersen@redhat.com>
 maintainer:          Jens Petersen <petersen@redhat.com>
-copyright:           2018,2021-2022  Jens Petersen
+copyright:           2018,2021-2024  Jens Petersen
 category:            Utility
 homepage:            https://github.com/juhp/lsfrom
 bug-reports:         https://github.com/juhp/lsfrom/issues
 build-type:          Simple
-cabal-version:       1.18
 extra-doc-files:     ChangeLog.md
                      README.md
 extra-source-files:  test/files/A
@@ -31,10 +31,12 @@
 executable lsfrom
   main-is:             Main.hs
   other-modules:       Paths_lsfrom
+  autogen-modules:     Paths_lsfrom
   build-depends:       base < 5,
                        filepath,
-                       simple-cmd,
-                       simple-cmd-args >= 0.1.1
+                       safe,
+                       simple-cmd >= 0.1.4,
+                       simple-cmd-args >= 0.1.2
   default-language:    Haskell2010
   ghc-options:        -fwarn-missing-signatures -Wall
   if impl(ghc >= 8.0)
@@ -63,4 +65,4 @@
                , directory >= 1.2.3.0
                , filepath
                , simple-cmd >= 0.1.1
-  build-tools:   lsfrom
+  build-tool-depends:   lsfrom:lsfrom
diff --git a/test/tests.hs b/test/tests.hs
--- a/test/tests.hs
+++ b/test/tests.hs
@@ -4,20 +4,32 @@
 import SimpleCmd
 import System.Directory
 
-lsfrom :: (FilePath, String, [String]) -> IO ()
-lsfrom (dir, arg, expect) = do
+type Test = (FilePath, [String], [String])
+
+lsfrom :: Test -> IO ()
+lsfrom (dir, args, expect) = do
   out <- withCurrentDirectory dir $
-         cmdLines "lsfrom" [arg]
+         cmdLines "lsfrom" args
   unless (out == expect) $ do
-    cmdN "lsfrom" [arg]
+    cmdN "lsfrom" args
     putStrLn $ "returned> " ++ show out
     putStrLn $ "expected> " ++ show expect
     error' "failed"
 
-tests :: [(FilePath, String,[String])]
+tests :: [Test]
 tests =
-  [ ("test/files", "B", ["B","C"])
-  , ("test", "files/B/", ["files/C"])
+  [ ("test/files", ["B"], ["B","C"])
+  , ("test/files", ["-a", "B"], ["C"])
+  , ("test", ["files/C/"], ["files/C"])
+  , ("test/files", ["Bb"], ["C"])
+  , ("test/files", ["-u", "B", "A"], ["A", "B"])
+  , ("test/files", ["-u", "C", "-b", "A"], ["A", "B"])
+  , ("test/files", ["-u", "C", "-b", "-a", "A"], ["B"])
+  , ("test/files", ["-u", "A", "-b", "-a", "C"], [])
+  , ("test/files", ["-u", "B", "-b", "B"], [])
+  , ("test/files", ["-u", "B", "-a", "B"], [])
+  , ("test/files", ["-u", "B", "-a", "-b", "B"], [])
+  , ("test/files", ["-s", "-u", "B", "A"], ["A", "B"])
   ]
 
 main :: IO ()
